The issue here arises from the fact that curl by default has the option CURLOPT_FTP_SKIP_PASV_IP disabled by default.
As a result, an attacker controlling the URL used by curl, can perform port scanning on behalf of the server where curl is running.
This can be achieved by setting up a custom FTP server that would setup the data channel through the PASV command using the port scanning target IP and port in the PASV connection info.
One good target for this issue are web applications vulnerable to SSRF.
So we can differentiate between open, closed and filtered ports with the following:
Open ports
curl will reply with TYPE after the PASV command
example:
Received: USER anonymous in 5
Received: PASS [email protected] in 5
Received: PWD in 5ms
Received: EPSV in 6ms
Received: PASV in 6ms
Received: TYPE I in 6ms
Received: SIZE whatever in 5ms
Received: RETR whatever in 5ms
Filtered
curl will timeout after the PASV command
example:
Received: USER anonymous in 6
Received: PASS [email protected] in 5
Received: PWD in 5ms
Received: EPSV in 6ms
Received: PASV in 5ms
Received: in 1011ms
Closed
curl will close the control channel connection immediately after PASV
example:
Received: USER anonymous in 6ms
Received: PASS [email protected] in 6ms
Received: PWD in 5ms
Received: EPSV in 5ms
Received: PASV in 5ms
Received: in 5ms
In the attachments, I have included an ftp server (F1088885) that automates these steps.
Usage:
./ssrf_pasvaggresvftp.sh -t 127.0.0.1/31 -p 80,8000-8100 -x ./ftp_curl.sh -vv
the file included in the -x option is supposed to trigger the ssrf on the target server that would lead to the call of curl with the attacker’s URL. In this case we simulate the issue by calling curl locally. The attachment F1088859 is the script used in the example.
Through the port scanning, an attacker could uncover services running in the internal network.
It could also be possible to perform version enumeration or other information disclosure if the attacker can get back the results of curl.
For example, an attacker points curl at host:22 for the data channel . If an ssh server is running on that host, then it will reply with its version which is then disclosed to the attacker.
Ultimately, this issue can be used as a stepping stone to launch further attacks on the vulnerable server.