# Scribbles
## Problem
```php hash_hmac('md5', $payload, FLAG),    'payload' => $payload,  ]);
  $ch = curl_init();  curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1" . $_SERVER['REQUEST_URI'] . "?action=log");  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  curl_setopt($ch, CURLOPT_POST, 1);  curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  echo curl_exec($ch);
} else {
  if (hash_hmac('md5', $_POST['payload'], FLAG) !== $_POST['signature']) {    echo 'FAIL';    exit;  }
  parse_str($_POST['payload'], $payload);
  $target = 'files/' . time() . '.' . substr($payload['name'], -20);  $contents = $payload['data'];  $decoded = base64_decode($contents);  $ext = 'raw';
  if (isset($payload['ext'])) {    $ext = (      ( $payload['ext'] == 'j' ) ? 'jpg' :      ( $payload['ext'] == 'p' ) ? 'php' :      ( $payload['ext'] == 'r' ) ? 'raw' : 'file'    );  }
  if ($decoded !== '') {    $contents = $decoded;    $target .= '.' . $ext;  }
  if (strlen($contents) > 37) {    echo 'FAIL';    exit;  }
  file_put_contents($target, $contents);
  echo 'OK';}```
If we request without action parameter, it will construct post payload and send request to self(with action parameter) by curl.
The `hash_hmac` key is `FLAG`, but we don't know the content.
So we can't directly forge the signature.
## Exploit
The vulnerability is on `$payload = "data=$data&name=$name";`
We can't control `$name` variable, but we can use `$data` to control `$name`
Like this: set `$data`: `xxx&name=new_name%00`
The NULL byte will truncate the original name.
Now we can control the file name.
We want to write a webshell and execute it.
But if `$decoded !== ''`, it will append extension to the filename.
So we need to find a way to set `$decoded` empty.
And we know that php's `base64_decode()` will output empty string if its input doesn't contain any valid character.(valid character include `a-z`, `A-Z`, `0-9`, `+`, `/`, ...)
Our goal is writing a non valid character webshell and the length shold be less than 38.
There are some tips, we can use some arithmetic operation like `XOR`, `NOT`, `AND`, ... to construct the php code.
So if we set data to ``` _`;%26name%3Dz.php%00```
`~%9c%9e%8b` is `cat`
so the payload will cat everthing in `../`, then write to `_`.
After we run the `files/time().z.php`, we can get the content of `config.php` in the `files/_`
## Flag
config.php:
```php