In 2012, SSRF attacks have become an actual threat rather than something exotic. The research in this field which has been performed by Alexander Polyakov, Vladimir Vorontsov, and other infosec professionals has almost comprised the big picture of various SSRF attack methods and possible consequences. Nevertheless, some gaps still exist because the topic has been researched for a relatively short time.
This article describes a small peculiarity of the FTP protocol which allows using an SSRF-enabling vulnerability to relay DoS attacks both to external and internal systems (including the system that is vulnerable to DoS), in addition to retrieving information and developing the SSRF attack vector.
A little theory from the previous century (can be skipped)
One of the oldest DoS attack methods is SYN flood. The attacker overloads the attacked service with SYN packets, ignoring SYN/ACK response. Thus, a lot of half-open connections appear at the victim host. In the end, the victim is even unable to respond to a perfectly normal and legitimate connection request. This attack method is as old as the Internet itself, with the first official classification (composed by CERT researchers) issued back in 1996. Currently, there are several ways to fight SYN floods, like SYN cookies, SYN cache, filtration and adaptive processing at gateways. Using a half-open connection rather than a completely open one has several benefits: the attacked side does not process the response, and, even better, the outgoing SYN requests can include any IP address, thus concealing the attacker. An open connection attack may be more effective in terms of counter defense, but it is much harder to conduct it correctly (unless it is a DDoS attack). SSRF can help emulate an open connection DoS attack while the IP address of the attacker will still be concealed from the victim.
Assume that we have a host which has an SSRF-enabling vulnerability. It can be an XXE injection, an incorrect server redirect, CRLF response splitting, or a simple file_get_contents() with a user-controlled argument in PHP. By sending a certain URI to the host, we can make it execute a request using the corresponding protocol. The obvious way to relay a DDoS attack would be to send an HTTP-URI like http://ddos-victim-to-be:service-port/. But the HTTP protocol implies that the client sends the first request, so the connection between the relay host and the victim host will be quickly terminated. There are not so many other URI types to choose from: apart from HTTP, FTP is the only one supported by almost all the popular technologies where SSRF is possible. At first, transmitting a URI likeftp://ddos-victim-to-be:service-port/ looks quite promising because the FTP client waits for a handshake from the server ("220 FTP server ready") before sending commands. Sadly, most FTP clients have a small connection timeout, so if the server does not respond for 5-10 seconds, they will simply terminate the connection. Most SSRF-enabling server technologies will terminate the connection with the potential victim upon termination of the connection which contained the SSRF attack. Another obstruction: the client will immediately disconnect when it receives a server response that is not the standard handshake. But there is yet hope: FTP through SSRF can still be used to relay DoS attacks. You just need to remember the certain features of the protocol.
To work with an FTP server, the client uses two connection types: control connection and data connection. The former is used to exchange commands and their results between server and client, the latter is used to actually transfer data (catalog listings, text and binary files etc.). FTP can work in active or passive mode, which affects the way data connections are established.
An FTP client in active mode creates a control connection to the server, sends over its IP address and port number (must differ from the number of the control connection client port), and waits for the server to launch the connection with the specified address and port.
Modern networks typically use passive mode because the client may be behind NAT or firewall. In this case, an FTP client send the passive mode command to the server and, upon getting from the server its IP address and port number, opens a data connection from an arbitrary client port to the specified address and port. The most interesting thing about passive mode is that after the client connects to the server data channel, it waits for the server to start data transmission. In most FTP clients, the timeouts of such connections are similar to the timeouts of TCP connections. A while ago, active mode on FTP servers was widely used to conduct scans like "FTP BOUNCE" and open connection DoS attacks. SSRF allows using an FTP client in passive mode to conduct open connection DoS attacks.
A client in data connection mode always waits for the server to transmit data, so the following attack scheme is executable (see figure 1). The attacker sets up a fake FTP server (0) somewhere, which will transmit the victim's address as the address of data connection. Furthermore, it is possible to transmit ftp://fake-ftp-address/file.txt (1) as the URI in the SSRF attack. Then, the SSRF-enabling host (the relay host) will connect to the fake FTP server, try to download the file (2), and get the victim's address and port as the address and port to be used for passive connection. The established connection (4) between the relay host and the victim will be active for no less than 60 seconds (if the service at the victim host waits for some kind of data from the client, HTTP and LDAP do this, for example). A pleasant bonus: as soon as the data connection is established, the control connection between the fake FTP server and the relay host may be terminated. The data connection will not be affected until data transmission is finished or until it times out. Therefore, if a fake FTP + SSRF attack is conducted repeatedly, the victim host will receive a flood of connections which is only limited by the power and settings of the relay host web server. At the same time, the fake FTP server will not be heavily loaded. If our fake server can process 100 requests in a second, as many as 6000 connections to the victim host will be established within the first minute. Moreover, the victim host will never know the IP of the attacker.
There is only one question left: how do we send the victim's address to the client (the relay host)?
In the modern version of FTP, two commands are responsible for passive mode setup: PASV and EPSV. The main difference between them is the response.
PASV response syntax:
227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
(where a1-a4 are the IP address octets in decimal notation, and the port is represented as 256*p1 + p2)
EPSV syntax is slightly different:
229 Entering Extended Passive Mode (|||p|)
(where p is the port)
Thus, EPSV, being the newer command (described in RFC 2428), forbids specifying a different IP address to establish a data connection, so the FTP client considers this address by default to be the same as the server address in the control connection. The elegant and consistent attack idea seems to be ruined. But in reality, if the server responds with "500 command not implemented" to an EPSV command, the vast majority of FTP clients will offer a PASV command instead. And this command can be used to transmit the address and port of the victim service. What's more, the connection to the FTP client may be terminated immediately after getting the RETR (retrieve file) command from it.
Example: Assume that we have a JSP servlet which is operated by Java 1.6.x and vulnerable to XXE. By sending, for example, "<!ENTITY J SYSTEM "ftp://fake-ftp-address/file">" as an external entity, we can initiate its connection to the fake FTP. The fake FTP should then execute the following sequence of commands for the attack to succeed:
220 i58 FTP server ready.
331 Guest login ok, send your email address as password.
230 Guest login ok, access restrictions apply.
200 Type set to I.
EPSV ALL (2)
500 Command not implemented, superfluous at this site. (2)
227 Entering Passive Mode (vic,tim,server,ip,0,80).(3)
150 Opening BINARY mode data connection for 'file' (5000000 bytes).
[this is where the fake FTP server is free to terminate the connection]
How it looks in WireShark (192.168.200.138 is the fake FTP, 192.168.200.128 is the relay, 46.4.x.x is the victim)
It is important that the fake FTP must respond with an error to any active mode commands (e.g. EPRT) and any new generation passive mode commands (EPSV, EPSV ALL), so that the FTP client has no choice but to use the obsolete PASC command. In addition, the file size given as a response to the RETR command must be big enough for the FTP client to sustain the connection even after the attacked service sends over some data.
Different SSRF-enabling web technologies use different FTP clients. The clients have their own features, which may restrict the possibilities of relaying DoS via the ftp:// URI scheme. The features of various FTP clients are summarized in the table below:
|Java 1.7||Only supports data connections to 127.0.0.1 and to the FTP server address*|
* Sometimes, a fake FTP server is not necessary because control FTP connections time out after 60 seconds in this technology, and if the attacked service does not return (incorrect) data, ftp://victim-address/file.txt can be transferred directly as the URI in the SSRF attack. If you are lucky, the FTP connection will not be terminated even after the termination of the connection which contained the SSRF attack.
** When an XXE injection is executed in ASP.Net, the control FTP connection to the remote host is established with a 60 seconds timeout. Moreover, the connection to the victim is sustained after the termination of the connection which contained the SSRF attack. This means that a direct relaying attack is possible even though PASV is not supported.
It is amusing that Java 1.7 forbids data connections to an address which differs from the control connection address, even if PASV is used. However, while the developers implemented the correction, they forgot about local loop, so this technique can be used to cause DoS on the internal services of the host, even if they are protected by a firewall. A field example is an old version of SAP Portal which allowed SSRF attacks via XXE. The portal crashed after about 50 requests where the attack was relayed to the local SAP web server with an FTP type URI.
How to prevent such attacks? If there are no SSRF-enabling vulnerabilities, this technique will not work, of course. Leaving out the point that there are no FTP servers left in the world which would not support RFC 2428, so the developers of FTP libraries ought to forbid using PASV at all, I have a piece of advice. Like Oracle developers did in the last version of Java, it is possible to forbid data connections to any host which is not the local loop or the FTP server itself. But, evidently, this "correction" will not provide complete protection against DoS relaying. Strict filtration of outgoing connections may help, and this can even be done by the server administrator or the ISO, but this is the case where the cure is more dangerous than the disease. It will not prevent DoS relaying via local loop either.
Nothing new or undiscovered is described here, but it is all the more amusing to see how discovering new types of attacks reanimates long-forgotten techniques.
An article by Alexander Bolshev,
ERPScan seniour researcher