Tags: web 


This is the shortest of the web challenges, totaling only five lines in `index.php`:


Unlike in the other web challenges, the socket that php-fpm listens on is a regular TCP socket, not a UNIX one:

This suggests we try to reuse our trick from [heiko](https://github.com/dfyz/ctf-writeups/tree/master/hxp-2020/heiko) with a slight modification.
As before, we first save a malicious PHP script that runs `/readflag` to `/tmp/`. After that, since we don't have a shell and can't talk to the PHP socket directly,
we trick `file_*_contents()` into connecting to the socket and sending a FastCGI message that would execute the malicious script.

We can craft such a message in [a few lines of Python](https://github.com/dfyz/ctf-writeups/blob/master/hxp-2020/resonator/exploit.py#L40).
However, because the FastCGI protocol is binary, the hard part is figuring out how to deliver it over the socket. We decided to implement a fake FTP server (again, [a small Python script](https://github.com/dfyz/ctf-writeups/blob/master/hxp-2020/resonator/fake_ftp.py))
that redirects PHP to `` when `file_put_contents()` is called and PHP tries to open a data connection in passive mode.

Here's how it works:

![This FTP is so fake](fake_ftp.png)

The only minor detail remaining is how to send the flag to us after spawning `/readflag` because `file_put_contents()` that talks to FTP
obviously won't send anything back to the client. Our PHP payload saves the flag in `/tmp/whatever` and makes it readonly:
/tmp/{FLAG_TXT_ID}.txt && chmod 444 /tmp/{FLAG_TXT_ID}.txt"); ?>

This means that the flag can't be overwritten by `file_put_contents()` and we can retrieve it simply with `GET /index.php?file=/tmp/whatever`.
Combining all the pieces, we run [the exploit](https://github.com/dfyz/ctf-writeups/blob/master/hxp-2020/resonator/exploit.py) and finally get what we want:
PS> python .\exploit.py [REDACTED_IP]

Original writeup (https://github.com/dfyz/ctf-writeups/blob/master/hxp-2020/resonator).