FakeNet
Description
FakeNet is a tool developed by Andrew Honig and Mike Sikorski. Its objective is to aid the malware analysts in the dynamic analysis of malicious softwares. The tool simulates a network so that malware interacting with a remote host continues to run allowing the analyst to observe the malware’s network activity from within a safe environment. It is able to intercept any traffic, including DNS, HTTP, HTTPS, SMTP, SMTP over SSL and has the ability to display SSL based traffic (e.g. HTTPS, SMTP/SSL) in clear.
For a video demonstration of FakeNet, go here: https://cc.readytalk.com/cc/playback/Playback.do?id=edviq7
Installation
- You can download Fakenet1.0c.zip here: http://downloads.sourceforge.net/project/fakenet/Fakenet1.0c.zip
- Just uncompress the archive in the directory of your choice
Configuration
Structure
|
Configuration file
Configuration file
FakeNet can be configured by editing the FakeNet.cfg file.
PacketDumpOptions
- DumpPackets
- If this option is set then FakeNet will create a packet capture file containing a reconstruction of the network traffic. This is not the same as a packet capture created with a network sniffer.
- Value: Yes|No. Default: Yes
- FilePrefix
- File prefix for the dumped packets
- Notice that the current date and time will follow your prefix (e.g. packets_20131121_191112.pcap)
- Default value: packets
DNSOptions
- ModifyLocalDNS
- This option governs whether the script will modify the local DNS server settings so that DNS queries are routed to the localhost.
- Value: Yes|No. Default: Yes
InvasiveOptions
- EnableDummyService
- If enabled then FakeNet will listen for and display any traffic on any port that isn’t already open. This option installs invasive hooks.
- Value: Yes|No. Default: Yes
- RedirectAllTraffic
- If enabled then FakeNet will redirect all traffic for any IP address to 127.0.0.1. This is useful in capturing traffic that uses hard coded IP addresses. Note: If you enable this service then there is no need to enable the ModifyLocalDNS because all packets will be routed to 127.0.0.1 regardless of their original destination. This option installs invasive hooks.
- Value: Yes|No. Default: Yes
- MaxListeners
- Each time a new port is accessed FakeNet will create a new socket and thread to listen to that port. This takes significant overhead and if a malicious program contains a port scanner that opens up many ports it may cause resource problems. To avoid consuming all resources FakeNet limits the number of connections. The default maximum is 200 listeners, but this can be changed in the configuration file.
- Value: integer. Default: 200
OutputOptions
- DumpHTTPPosts
- If this option is set then FakeNet will create a file each time it receives a POST from an HTTP client and save the file in the local directory. The file is named post_ followed by the date and time of the request and an auto-incrementing integer for the currently running FakeNet instance.
- Value: Yes|No. Default: No
- DumpOutput
- Specifies whether information shown in the console window should be output to a file
- Value: Yes|No. Default: No
- Fileprefix
- Prefix for the output file if DumpOutput is set to Yes
- Default: output
Listeners
Description
Listener lines must start with a listener type from the following options:
- DNSListener
- HTTPListener
- RawListener
- ICMPListener
- PythonListener
Depending on which type of listener, there must also be a specific number of options in the appropriate order. This is case sensitive and will not work without all options specified in the right order in the right case.
The formats for the listeners is as follows:
Listener | Format | Options |
---|---|---|
DNSListener | DNSListener Port:## DNSResponse:##.##.##.## NXDomains:## |
|
HTTPListener | HTTPListener Port:## UseSSL:XXX Webroot:XXXXX |
|
RawListener | RawListener Port:## UseSSL:XXX |
|
ICMPListener | ICMPListener | No option |
PythonListener | PythonListener Port:## StripSSL:XXX ScriptFile:XXXXXX |
|
DNSListener
This rule sets up a DNS listener on port 53:
DNSListener Port:53 DNSResponse:127.0.0.1 NXDomains:0
HTTPListener
This rule sets up a web server listening on port 80:
HTTPListener Port:80 UseSSL:No Webroot:None
HTTPListener
This rule is similar to the above rule except that it's expecting HTTP with SSL/TLS (HTTPS) traffic:
HTTPListener Port:443 UseSSL:Yes Webroot:None
These rules listen on additional ports that are popular used for web traffic:
HTTPListener Port:8443 UseSSL:Yes Webroot:None HTTPListener Port:8080 UseSSL:Yes Webroot:None HTTPListener Port:8000 UseSSL:Yes Webroot:None
RawListener
These rules listen on some formerly popular malware ports and dump the traffic to screen:
RawListener Port:1337 UseSSL:No RawListener Port:31337 UseSSL:Yes
ICMPListener
This enables ICMP listening:
ICMPListener
PythonListener
This enables the sample python script which implements a minimal SMTP server:
PythonListener Port:25 StripSSL:No ScriptFile:sampleSMTP PythonListener Port:465 StripSSL:Yes ScriptFile:sampleSMTP
Extensions
Description
The program supports extensions using python scripts. The python scripts provide an easy to use interface for receiving and sending data received using this tool.
sampleSMTP
A sample script to implement the SMTP protocol is included in the .\extensions\ directory.
import FakeNet #Sample python code for imitating an SMTP server def FN_Init(): pass def FN_NewConnection(context): incomingPacket = "" FakeNet.sendData(context, "220 PracticalMalwareAnalysis.COM STMP Service Ready\r\n") while True: incomingPacket = FakeNet.recvData(context, 4096) if (incomingPacket == ""): break incomingPacket = incomingPacket[:4].upper() if (incomingPacket == "HELO"): FakeNet.sendData(context, "250 PracticalMalwareAnalysis.com\r\n") continue elif (incomingPacket == "MAIL" or incomingPacket == "RCPT" or incomingPacket == "NOOP" or incomingPacket == "RSET"): FakeNet.sendData(context, "250 OK\r\n") elif (incomingPacket == "QUIT"): FakeNet.sendData(context, "221 PracticalMalwareAnalysis.com bye\r\n") break elif (incomingPacket == "DATA"): FakeNet.sendData(context, "354 start mail input, end with <CRLF>.<CRLF>\r\n") dataBuffer = "" while True: incomingPacket = FakeNet.recvData(context, 4096) if (incomingPacket == ""): break dataBuffer = dataBuffer + incomingPacket ending = dataBuffer[-5:] if (dataBuffer[-5:] == '\r\n.\r\n'): break FakeNet.sendData(context, "250 OK\r\n"); else: FakeNet.sendData(context, "503 Command not supported\r\n")
Custom python listeners
Required functions
Your script must have two functions defined:
- FN_Init
- Provides the module an opportunity to perform any necessary initialization steps.
- FN_NewConnection
- Takes a single parameter which is an opaque context structure. This value must be passed as the first parameter to any functions to interact with FakeNet.
- Within the NewConnection function your script should call recvData and sendData (imported from FakeNet) as necessary to send and receive data:
- sendData takes two parameters: the context of the connection and the string to send. The function returns the number of bytes successfully sent.
- recvData also takes two parameters: the context of the connection and the size to use for the internal buffer. The interface using string types and is therefore not well suited for non-ASCII protocols which may contain embedded NULLs. The recvData function returns "" when there is an error or the connection has been closed, so be sure to check for that as a return value. If you continually call recvData without checking for "", then you will create an infinite loop.
- When your FN_NewConnection function returns FakeNet will then close the connection if it is still active.
Multi threading
Special care must be taken in your python scripts to handle the multithreaded aspect of FakeNet. The threading for your python script will be handled by FakeNet, but you must be aware that your script may be called from multiple threads at the same time. You are guaranteed atomicity between calls to FakeNet, but when you call sendData or recvData other python threads will be allowed to run.
Any necessary temporary storage must be stored in a variable local to the function. Also you should not create additional threads using the Python interface and you should not use any python thread synchronization objects. Doing so could interfere with the thread synchronization being performed by FakeNet and cause deadlock. You should also refrain from calling blocking functions from within your python script (other than sendData and recvData) because if your code blocks then no other python threads will be able to run until your code either returns from FN_NewConnection or calls sendData or recvData.
Enabling extension
To enable a python extension add a new line in the configuration file as shown on the below examples:
PythonListener Port:25 StripSSL:No ScriptFile:sampleSMTP PythonListener Port:465 StripSSL:Yes ScriptFile:sampleSMTP
Usage
Syntax
You can call fakenet.exe from command line, with an optional parameter (see the options)
C:\>fakenet [option]
Options
- -r
- Restores system settings from a previously crashed FakeNet instance.
- This can be used to restore network settings if FakeNet for some reason doesn't restore network settings on exit. This should be rare because FakeNet has a top level exception handler that restores network settings under any normal exits or crashes.
- -d
- This instructs FakeNet to print debug output (required in case you file a bug report)
Usage examples
Start FakeNet
Let's start FakeNet:
C:\tools\Fakenet>FakeNet.exe FakeNet Version 1.0 [Starting program, for help open a web browser and surf to any URL.] [Press CTRL-C to exit.] [Modifying local DNS Settings.] Scanning Installed Providers Installing Layered Providers Preparing To Reoder Installed Chains Reodering Installed Chains Saving New Protocol Order [Listening for traffic on port 80.] [Listening for SSL traffic on port 443.] [Listening for SSL traffic on port 8443.] [Listening for traffic on port 8080.] [Listening for traffic on port 8000.] [Listening for traffic on port 1337.] [Listening for SSL traffic on port 31337.] [Listening for SSL traffic on port 465.] [Listening for traffic on port 25.] [Listening for ICMP traffic.] [Listening for DNS traffic on port: 53.]
We see that all services have started and that KakeNet is now listening to the above ports.
HTTP traffic
Let's see how FakeNet is intercepting HTTP traffic. We'll open Internet Explorer and browse the http://www.evil.com/malicious.pdf URL.
As you can see on the below screenshot, FakeNet has successfully intercepted the DNS and HTTP requests and has opened the PDF file. Notice that FakeNet has understood that we were requesting a PDF file (whatever name is requested) and has returned the one stored in .\defaultFiles\FakeNet.pdf.
Here is the output:
[DNS Query Received.] Domain name: www.evil.com [DNS Response sent.] [Received new connection on port: 80.] [New request on port 80.] GET /malicious.pdf HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */* Accept-Language: fr Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727) Host: www.evil.com Connection: Keep-Alive [Sent http response to client.]
Notice that the DNS request has first been intercepted ([DNS Query Received.]) and FakeNet has replied with our localhost ([DNS Response sent.]). The second part of the log shows that the HTTP request has been intercepted as well (malicious.pdf).
HTTPS traffic
FakeNet has the ability to intercept HTTPS traffic, which is very convenient to analyze malware that crypt the HTTP traffic trough SSL. Let's simulate following request: https://www.evil.com/malicious.exe.
As our certificate is not approved, following popup appears. It does not really matter since we are just testing the malware features.
The malicious executable is downloaded. If we accept to start it, it pops up a message to indicate the executable is launched:
And here is the outut:
[Received new connection on port: 443.] [New request on port 443 with SSL.] [Received unsupported HTTP request.] [Received new connection on port: 443.] [New request on port 443 with SSL.] GET /malicious.exe HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */* Accept-Language: fr Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727) Host: www.evil.com Connection: Keep-Alive [Sent http response to client.]
SMTP traffic (No SSL, port 25/tcp)
Now, let's simulate a mail that would be sent by the malware. Prior to this test, I've configured Outlook Express as follows:
Key | Value |
---|---|
User name | I am the Victim |
User email | [email protected] |
POP3 / port | pop.corporate.com / 25/tcp |
SMTP / port | smtp.corporate.com / 110/tcp |
For the simulation, I've sent a mail as follows:
The output first shows a DNS query to resolve our fake smtp.corporate.com domain:
[DNS Query Received.] Domain name: smtp.corporate.com [DNS Response sent.]
Followed by the connection details:
[Received new connection on port: 25.] 220 PracticalMalwareAnalysis.COM STMP Service Ready [New Data on port 25.] HELO malware418ee9f 250 PracticalMalwareAnalysis.com [New Data on port 25.] RSET 250 OK
And the email headers:
[New Data on port 25.] MAIL FROM: <[email protected]> 250 OK [New Data on port 25.] RCPT TO: <[email protected]> 250 OK [New Data on port 25.] DATA 354 start mail input, end with <CRLF>.<CRLF>
And the content of the email:
[New Data on port 25.] Message-ID: <CDF3C1D6C1C44847B36C297C0A864318@malware418ee9f> From: "I am the Victim" <[email protected]> To: <[email protected]> Subject: New victim Date: Fri, 22 Nov 2013 10:35:33 +0100 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0007_01CEE76E.92876A50" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.5512 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5512 This is a multi-part message in MIME format. ------=_NextPart_000_0007_01CEE76E.92876A50 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable A new PC has been infected! ------=_NextPart_000_0007_01CEE76E.92876A50 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META http-equiv=3DContent-Type content=3D"text/html; =charset=3Diso-8859-1"> <META content=3D"MSHTML 6.00.2900.5512" name=3DGENERATOR> <STYLE></STYLE> </HEAD> <BODY bgColor=3D#ffffff> <DIV> <P><FONT face=3DArial size=3D2>A new PC has been=20infected!</FONT></P></DIV></BODY></HTML> ------=_NextPart_000_0007_01CEE76E.92876A50-- [New Data on port 25.] . 250 OK [New Data on port 25.]
SMTP traffic (SSL, port 465/tcp)
Now, let's do the same test as previously but using a SSL connection for the SMTP traffic:
Of course, it pops up a notification informing that our certificate can not be trusted. Notice that the below output appears in clear though it uses SSL. It's because FakeNet was in the middle of the communication (MITM) and was able to intercept the traffic.
[DNS Query Received.] Domain name: smtp.corporate.com [DNS Response sent.] [Received new connection on port: 465.] 220 PracticalMalwareAnalysis.COM STMP Service Ready [New Data on port 465 with SSL.] HELO malware418ee9f 250 PracticalMalwareAnalysis.com [New Data on port 465 with SSL.] MAIL FROM: <[email protected]> 250 OK [New Data on port 465 with SSL.] RCPT TO: <[email protected]> 250 OK [New Data on port 465 with SSL.] DATA 354 start mail input, end with <CRLF>.<CRLF> [New Data on port 465 with SSL.] Message-ID: <AAE2C6ED65DC409A8A2D8BD488BF41E1@malware418ee9f> From: "I am the Victim" <[email protected]> To: <[email protected]> Subject: New infected machine Date: Fri, 22 Nov 2013 10:54:52 +0100 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0004_01CEE771.45B825E0" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.5512 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5512 This is a multi-part message in MIME format. ------=_NextPart_000_0004_01CEE771.45B825E0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable A new machine has been infected. ------=_NextPart_000_0004_01CEE771.45B825E0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META http-equiv=3DContent-Type content=3D"text/html; = charset=3Diso-8859-1"> <META content=3D"MSHTML 6.00.2900.5512" name=3DGENERATOR> <STYLE></STYLE> </HEAD> <BODY bgColor=3D#ffffff> <DIV><FONT face=3DArial size=3D2>A new machine has been=20 infected.</FONT></DIV></BODY></HTML> ------=_NextPart_000_0004_01CEE771.45B825E0-- [New Data on port 465 with SSL.] . 250 OK [New Data on port 465 with SSL.]
Real case scenario
In this example, we will use FakeNet against a malware identified as TrojanDownloader:Win32/Cutwail.BW (Microsoft), which MD5sum is 2422279645dc3f8f9201bf042122d6d5:
- Virustotal: https://www.virustotal.com/en/file/501b0b423d1cf3d6d4cdddffc8197ba049744d4c00ce2f37e5e78dd8f33d7990/analysis/1385142193/
- Malwr sandbox analysis: https://malwr.com/analysis/MDFmMTZkMmQ2MWUxNDhiZDg2NTg4NGJhMjlhYTBhMWY/
- Download: https://www.dropbox.com/s/envytizk8zc31aj/2422279645dc3f8f9201bf042122d6d5.zip (pass: infected)
As soon as the malware is started, FakeNet displays so many information that we don't have time to read them... Below is an extract of the output:
[Received new connection on port: 80.] [Python connection closed.] Domain name: tahoo.com User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) 220 PracticalMalwareAnalysis.COM STMP Service Ready [New request on port 80[New request on port 80[New request on port 80[New reques t on port 80[DNS Response sent.] [Received new connection on port: 80.] [DNS Query Received.] Domain name: grayfoot.mailshell.com [DNS Response sent.] [DNS Query Received.] Domain name: axelero.hu .] POST /?ptrxcz_pz9JTcmx6GQZju3DMWfq09JScmw6FP HTTP/1.1 Accept: */* Accept-Language: en-us Content-Type: application/octet-stream Content-Length: 218 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) .] .] .] [New Data on port 25 Host: stc.com.sa [New request on port 80[DNS Response sent.] [Received new connection on port: 80.] .] POST /?ptrxcz_Vgq0AJTcmx6GPYit2CLVepy8HRaku4 HTTP/1.1 Accept: */* Accept-Language: en-us Content-Type: application/octet-stream Content-Length: 143 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) Connection: Keep-Alive .] POST / HTTP/1.1 POST /?ptrxcz_Udox7GSgucs4HVjyAOao3FOYis2BLU HTTP/1.1 POST / HTTP/1.1 Host: intelnet.net.gt [New request on port 80.] POST /?ptrxcz_AKUdox7GQZjt3CMVfpz8IRbkv4ENXg HTTP/1.1 Accept: */* Accept-Language: en-us Content-Type: application/octet-stream Content-Length: 135 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) Host: grayfoot.mailshell.com Connection: Keep-Alive Cache-Control: no-cache Received post with 135 bytes. Connection: Keep-Alive Cache-Control: no-cache Received post with 218 bytes. Accept: */* Accept-Language: en-us Content-Type: application/octet-stream Content-Length: 94 Accept: */* Accept: */* ÀµÏ▒Ƚ┤ûªäÁ▲ /À)☻ÿ©9ó¹║╔►ù╝î¥A¢O╣¥¥ù←'┴ı«©┴¡\!─h Îâ^èÏ♂┴4┌▬║Ø█┘┤→¦®§▒Ì_*+Ó7♂½ß kAÒ┬f¥õàa;µU┬Ðþ↑¢NÚ█À╦Û¬▓Hýu‼▀Ý1♫\´<♂Ý<k¶‗é~Ú¾Ùdi §↔└ ÷ Cache-Control: no-cache Host: tahoo.com [Received new connection on port: 80.] 503 Command not supported Accept-Language: en-us Accept-Language: en-us User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) [DNS Query Received.] Domain name: schoolsports.com [DNS Response sent.] [Received new connection on port: 25.] Host: croeso.com Connection: Keep-Alive Cache-Control: no-cache Received post with 94 bytes. Content-Type: application/octet-stream Content-Type: application/octet-stream Connection: Keep-Alive [Received new connection on port: 80.] 220 PracticalMalwareAnalysis.COM STMP Service Ready [New Data on port 25.] Vï@↓³yϹÐ♫®³◄Aê²ío?■▬♠$ ïÏ┌503 Command not supported [Received new connection on port: 80.] Received post with 76 bytes. Cache-Control: no-cache Received post with 143 bytes. Content-Length: 68 Content-Length: 95 [New request on port 80[Modifying local DNS Settings.]
Very interesting to notice that FakeDNS has identified the DNS queries, traffic on port 80/tcp (HTTP POST requests) as well as a suspicious traffic on port 25/tcp. FakeNet has saved the pcap file that we can open with Wireshark, but this traffic does not look like a standard SMTP traffic:
With only FakeNet, we can't conclude what this traffic is. However, the tool has provided us with a lot of usefull information to start our analysis:
- DNS queries
- List of POST requests
- Frequency of the requests indicating the malware intentions
- A suspicious traffic on port 25/tcp that we would need to anlyze in more details (i.e. by disassembling the executable)