# PHP101 - wargame[.]vn
## chall 01
- Welcome

`FLAG{ddf1ea89-cd89-4da3-98bc-08028ac4dc7e}`
## chall 02
```php
<?php
include __DIR__.'/../../secret.php';
error_reporting(0);
highlight_file(__FILE__);
die(base64_encode(hex2bin(strrev(bin2hex(str_rot13(print_flag(2))))))); 1wc39mNzY4NDE1NTk9JD5vbm0mNDQ0PSQ5MHU9L2g+YHQ2NTB7dF5JU1
```
- decode đoạn mã:
```php
print(str_rot13(hex2bin(strrev(bin2hex(base64_decode($text))))));
```
`FLAG{c564ca8b-5c94-4446-aba4-955148676bfc}`
## chall 03
```php
<?php
if(isset($_GET['number'])) {
$number = $_GET['number'];
if ($number === '1337'){
die('No');
}
if (intval($number, 0) === 1337){
die(print_flag(3));
}
}
```
- `GET /challenge/3/?number=%20%201337`
- `%20` là dấu cách `space`
- cũng có thể truyền input là `1337blabla...` vì intval() với string gặp ký tự khác digit sẽ dừng. [link](https://www.php.net/manual/en/function.intval.php)


`FLAG{554382f3-960e-4859-9c79-c64ecd4445e7}`
## chall 04
```php
<?php
if(isset($_GET[0]) && isset($_GET[1])){
if($_GET[0] != $_GET[1]){
if (md5($_GET[0]) === md5($_GET[1])){
die(print_flag(4));
}
}
}
```
- đây là php magic hash
- ~~lấy một cặp hash md5 bất kỳ~~ [link](https://github.com/spaze/hashes)

`FLAG{82104890-f270-4d27-b4e4-638a940ffdcf}`
#### ngộ nhận
- hash collision có là do php loose comparision( hai dấu `==` )

- ở chall 04 này so sánh chặt `===`? thì sẽ lấy cặp real collision


- cũng có thể truyền hai mảng vào
> GET /challenge/4/?0[]=foo&1[]=bar
vì md5() không thể hash kiểu dữ liệu array sẽ trả về NULL, và NULL === NULL -> flag
## chall 05
```php!
if(isset($_GET['inp'])){
$inp = $_GET['inp'];
if(((array)simplexml_load_string(file_get_contents($inp))->f->l->a->g)[0] === 'flagggggggggggggg') {
die(print_flag(5));
}
}
```
- lấy data qua hàm file_get_contents()
- convert to xml
- access attribute con lần lượt f -> l -> a -> g
- convert to array và check nếu array[0] === 'flagggggggggggggg'
=> vậy có thể dựng xml với content như sau
`<root><f><l><a><g>flagggggggggggggg</g></a></l></f></root>`

- hàm simple_xml_load_string() nhận data từ hàm file_get_contents().
- file_get_contents() hỗ trợ remote file. ta dựng httpserver host file xml, và public ra ngoài bằng ngrok
- GET /challenge/5/index.php?inp=`https://e961-113-185-53-220.ngrok-free.app/file_xml`

`FLAG{19ee9d17-7f23-4c03-b702-4276246ccdb2}`
## chall 06
```php!
if(isset($_GET['number'])){
$number = $_GET['number'];
if(preg_match('/[0-9]/', $number)){
die('waf');
} elseif (intval($number)){
die(print_flag(6));
}
}
```
- regex check nếu input chứa số 0 tới 9 thì die
- và nếu intval() return true thì có flag
- thử search qua hàm intval()
- nếu truyền mảng number[] preg_match() không thể match và return false(với php 8. trở lên báo lỗi và dừng chương trình)

>php 7.4.3

>php 8.0.0

`FLAG{2352ca3b-c94e-450b-b69a-1938cab26571}`
- mình có ý tưởng truyền get param vào vì đọc được 1 bài viêt của a thanhlocpanda

## chall 07
## chall 08
```php!
if(isset($_GET['u'])){
if(preg_match('/admin/', $_GET['u'])) die('no no no');
$u = urldecode($_GET['u']);
if($u == 'admin'){
die(print_flag(8));
}
}
```
- nếu match input có từ `admin` thì die;
- sau đó decode $u, lại so sánh tiếp `u == 'admin'`? true thì trả flag
- vậy encode url 2 lần:


`FLAG{0406eb88-39ce-4dcc-bace-b058a7e57dd0}`
## chall 09
```php=
if(isset($_GET['say']) && strlen($_GET['say']) < 28){
$say = preg_replace('/^(.*)flag(.*)$/', 'waf', $_GET['say']);
if(preg_match('/give_me_the_flag/', $say)){
die(print_flag(9));
}
}
```
- regex check: `^` là check ở đầu dòng, `$` là kết thúc dòng

- nếu input có nhiều dòng, regex match trên sẽ trả về false

>expect `waf` instead of `flag here`
- `/^(.*)flag(.*)$/` không hoạt động như ý vì khi preg_match() dùng regex có `^`, nó chỉ check dòng đầu tiên thôi, nếu payload có nhiều dòng thì sẽ bypass dễ dàng

`FLAG{62e0d117-93af-4e36-957c-3841d1ae7100}`
- dựng local
## chall 10
...
```php=
<?php
include __DIR__.'/../../secret.php';
error_reporting(0);
class Get_Flag{
public $get = True;
public function __destruct(){
if($this->get === True){
die(print_flag(10));
}
}
public function __wakeup(){
$this->get = False;
}
}
if(isset($_GET['get_flag.php'])){
unserialize($_GET['get_flag.php']);
}
highlight_file(__F
```
sử dụng fast destruct [link](https://github.com/ambionics/phpggc?tab=readme-ov-file#fast-destruct)