ACG Second Challenge Write-up
This is a write up on how to solve our second ctf challenge called “PHP-T3st3r” which is an online vulnerable PHP interpreter.
As mentioned in the description of the task our mission is to read a sensitive file stored in /psycor/flag.php.
The first thing that comes to mind is to try reading the file directly using the readfile function, however the readfile function does not work when the wrapper ‘file://’ is disabled, same thing for file_get_contents function and other file access functions are also disabled 🙁
If we try to execute a command using the system function we get a warning indicating that this function is also disabled.
Okay, let’s dig a little deeper and check what functions are disabled and other juicy information using the phpinfo function.
The most useful functions are disabled, so let’s change the tactic and go through more serious stuff.
What is PHP-FPM?
PHP-FPM is the process manager of FastCGI protocol.
- PHP-FPM is a service of multiple processes: several workers to deal with requests and one master to manage those workers. To get the information of each worker processes, FPM even uses structures of fpm_scoreboard_s and fpm_scoreboard_proc_s to record their statuses.
- This is a nice picture to understand the request flow of PHP-FPM. First, our HTTP request would be converted to the format of FastCGI by Nginx worker and be sent to FPM worker. There are two kinds of socket implemented on FPM: one is TCP socket(127.0.0.1:9000) and another is UNIX socket(unix:///var/run/php7.0-fpm.sock), this can be set by fastcgi_pass in the nginx conf file.
In the task we switched PHP-FPM to listen on a unix socket rather than a TCP socket.
Note : The phpinfo function clearly indicates the php version, so looking a little more deeply we found that the default path for the socket was in /run/php/php7.0-fpm.sock .
Now we can communicate with the socket and kindly ask it to return the file /psyco/flag.php 🙂
The picture below describes the nginx and PHP interaction process.
Here we can communicate with the socket only in binary mode, so we can use this ruby script to return the call in binary format. https://raw.githubusercontent.com/ONsec-Lab/scripts/master/fastcgipacket.rb
Now, it’s time to run our final php code and get the flag.
During the challenge we received another solution from BENAMAROUCHE ABDELMOUMEN, it consists to use this exploit https://github.com/mm0r1/exploits/blob/master/php7-gc-bypass/exploit.php to bypass all disabled functions
This exploit should work on all PHP 7.0-7.3 versions with nginx only.
We hope you enjoyed reading this write up, see you on next challenges