FakeNet Genie: Improving Dynamic Malware Analysis with Cheat Codes for FakeNet-NG

As developers of the network simulation tool FakeNet-NG, reverse
engineers on the FireEye FLARE team, and malware analysis instructors,
we get to see how different analysts use FakeNet-NG and the challenges
they face. We have learned that FakeNet-NG provides many useful
features and solutions of which our users are often unaware. In this
blog post, we will showcase some cheat codes to level up your network
analysis with FakeNet-NG. We will introduce custom responses and
demonstrate powerful features such as executing commands on connection
events and decrypting SSL traffic.

Since its first release
in 2016
, we have improved FakeNet-NG
by adding new features such as Linux
support
and content-based
protocol detection
. We recently updated FakeNet-NG with one of
our most requested features: custom responses for HTTP and binary protocols.

This blog post offers seven “stages” to help you master
different FakeNet-NG strategies. We present them in terms of common
scenarios we encounter when analyzing malware. Feel free to skip to
the section relevant to your current analysis and/or adapt them to
your individual needs. The stages are presented as follows:

  1. Custom File Responses
  2. Custom Binary Protocols
  3. Custom HTTP Responses
  4. Manual Custom Responses
  5. Blacklisting Processes
  6. Executing Commands on Connection
    Events
  7. Decrypting SSL Traffic

Read on to upgrade your skill tree and become a FakeNet-NG pro!

Before You Start: Configuring FakeNet-NG

Here is a quick reference for FakeNet-NG configurations and log data locations.

  1. Configuration files are in fakenetconfigs. You can modify default.ini or copy it to a new file and point
    FakeNet-NG to the alternate configuration with -c. Ex: fakenet.py -c
    custom.ini.
  2. Default files are at fakenetdefaultFiles and Listener
    implementations are at fakenetlisteners.
  3. The fakenetconfigsdefault.ini default
    configuration includes global configuration settings and individual
    Listener configurations.
  4. Custom response configuration
    samples are included in the directory fakenetconfigs in the files CustomProviderExample.py, sample_custom_response.ini, and sample_raw_response.txt.
  5. The install
    location for FakeNet-NG in FLARE VM is C:Python27libsite-packagesfakenet. You will
    find the subdirectories containing the defaultFiles, configs,
    and listeners in this directory.
  6. In FLARE VM, FakeNet-NG packet capture files and HTTP requests
    can be found on the Desktop in the fakenet_logs directory

Stage 1: Custom File Responses

As you may have noticed, FakeNet-NG is not limited to serving HTML
pages. Depending on the file type requested, FakeNet-NG can serve PE
files, ELF files, JPG, GIF, etc. FakeNet-NG is configured with several
default files for common types and can also be configured to serve up
custom files. The defaultFiles directory
contains several types of files for standard responses. For example,
if malware sends an FTP GET request for evil.exe, FakeNet-NG will respond with the file
defaultFilesFakeNetMini.exe (the default
response for .exe requests). This file is a valid Portable Executable
file that displays a message box. By providing an actual PE file, we
can observe the malware as it attempts to download and execute a
malicious payload. An example FTP session and subsequent execution of
the downloaded default file is shown in Figure 1.


Figure 1: Using FTP to download
FakeNet-NG’s default executable response

Most requests are adequately handled by this system. However,
malware sometimes expects a file with a specific format, such as an
image with an embedded PowerShell script, or an executable with a hash
appended to the file for an integrity check . In cases like these, you
can replace one of the default files with a file that meets the
malware’s expectation. There is also an option in each of the relevant
Listeners (modules that implement network protocols) configurations to
modify the defaultFiles path. This allows
FakeNet-NG to serve different files without overwriting or modifying
default data. A customized FakeNet.html
file is shown in Figure 2.


Figure 2: Modify the default FakeNet.html
file to customize the response

Stage 2: Custom Binary Protocols

Many malware samples implement custom binary protocols which require
specific byte sequences. For example, malware in the GH0ST family may
require each message to begin with a signature such as
“GH0ST”. The default FakeNet-NG RawListener responds to unknown requests with an
echo, i.e. it sends the same data that it has received. This behavior
is typically sufficient. However, in cases where a custom response is
required, you can still send the data the malware expects.

Custom TCP and UDP responses are now possible with FakeNet-NG.
Consider a hypothetical malware sample that beacons the string “Hello”
to its command and control (C2) server and waits for a response packet
that begins with “FLARE” followed by a numeric command (0-9). We will
now demonstrate several interesting ways FakeNet-NG can handle this scenario.

Static Custom Response

You can configure how the TCP and/or UDP Raw Listeners respond to
traffic. In this example we tell FakeNet-NG how to respond to any TCP
raw request (no protocol detected). First uncomment the Custom configuration option in the RawTCPListener section of fakenet/configs/default.ini as illustrated in
Figure 3.

[RawTCPListener]
Enabled:    
True
Port:        1337
Protocol:    TCP
Listener:    RawListener
UseSSL:      No
Timeout:     10
Hidden:      False
# To read
about customizing responses, see docs/CustomResponse.md
Custom:    sample_custom_response.ini

Figure 3: Activate custom TCP response

Next configure the TcpRawFile custom
response in fakenetconfigssample_custom_response.ini as
demonstrated in Figure 4. Make sure to comment-out or replace the
default RawTCPListener instance.

[ExampleTCP]
InstanceName:    
RawTCPListener
ListenerType:     TCP
TcpRawFile:       flare_command.txt

Figure 4: TCP static custom response specifications

Create the file fakenetconfigsflare_command.txt with the content
FLARE0. TCP responses will now be
generated from the contents of the file.

Dynamic Custom Response

Perhaps you want to issue commands dynamically rather than
committing to a specific command in flare_command.txt. This can be achieved
programmatically. Configure the TcpDynamic
custom response in fakenetconfigssample_custom_response.ini as
demonstrated in Figure 5. Make sure to comment-out or replace the
existing RawTCPListener instance.

[ExampleTCP]
InstanceName:    
RawTCPListener
TcpDynamic:      
flare_command.py

Figure 5: TCP dynamic custom response specifications

The file fakenetconfigsCustomProviderExample.py can be
used as a template for our dynamic response file flare_command.py. We modify the HandleTcp() function and produce the new file
fakenetconfigsflare_command.py as
illustrated in Figure 6. Now you can choose each command as the
malware executes. Figure 7 demonstrates issuing commands dynamically
using this configuration.

import socket

def HandleTcp(sock):

    while True:
        try:
            data = None

            data = sock.recv(1024)
 
      except socket.timeout:
           
pass

        if not data:
           
break

        resp = raw_input(‘nEnter a numeric
command: ‘)
        command = bytes(‘FLARE’ + resp +
‘n’)
        sock.sendall(command)

Figure 6: TCP dynamic response script


Figure 7: Issue TCP dynamic commands

Stage 3: Custom HTTP Responses

Malware frequently implements its own encryption scheme on top of
the popular HTTP protocol. For example, your sample may send an HTTP
GET request to /comm.php?nonce=<random> and expect the C2
server response to be RC4 encrypted with the nonce value. This process
is illustrated in Figure 8. How can we easily force the malware to
execute its critical code path to observe or debug its behaviors?


Figure 8: Malware example that expects a
specific key based on beacon data

For cases like these we recently introduced support for HTTP custom
responses. Like TCP custom responses, the HTTPListener also has a new setting named Custom that enables dynamic HTTP responses. This
setting also allows FakeNet-NG to select the appropriate responses
matching specific hosts or URIs. With this feature, we can now quickly
write a small Python script to handle the HTTP traffic dynamically
based upon our malware sample.

Start by uncommenting the Custom configuration option in the HTTPListener80 section as illustrated in Figure 9.

[HTTPListener80]
Enabled:    
True
Port:        80
Protocol:    TCP
Listener:    HTTPListener
UseSSL:      No
Webroot:     defaultFiles/
Timeout:     10
#ProcessBlackList: dmclient.exe, OneDrive.exe, svchost.exe,
backgroundTaskHost.exe, GoogleUpdate.exe, chrome.exe
DumpHTTPPosts: Yes
DumpHTTPPostsFilePrefix: http
Hidden:      False
# To read about customizing
responses, see docs/CustomResponse.md
Custom:   
sample_custom_response.ini

Figure 9: HTTP Listener configuration

Next configure the HttpDynamic custom
response in fakenetconfigssample_custom_response.ini as
demonstrated in Figure 10. Make sure to comment-out or replace the
default HttpDynamic instance.

[Example2]
ListenerType:    
HTTP
HttpURIs:         comm.php
HttpDynamic:      http_example.py

Figure 10: HttpDynamic configuration

The file fakenetconfigsCustomProviderExample.py can be
used as a template for our dynamic response file http_example.py. We modify the HandleRequest() function as illustrated in Figure
11. FakeNet-NG will now encrypt responses dynamically with the nonce.

import socket
from arc4 import
ARC4

# To read about customizing HTTP responses,
see docs/CustomResponse.md

def HandleRequest(req, method,
post_data=None):
    “””Sample dynamic
HTTP response handler.

    Parameters
    ———-
    req : BaseHTTPServer.BaseHTTPRequestHandler
     
  The BaseHTTPRequestHandler that recevied the request
    method: str
        The HTTP method, either
‘HEAD’, ‘GET’, ‘POST’ as of this writing
   
post_data: str
        The HTTP post data received by
calling `rfile.read()` against the
       
BaseHTTPRequestHandler that received the request.
   
“””

 

    response = ‘Ahoyrn’

    nonce = req.path.split(‘=’)[1]
 
  arc4 = ARC4(nonce)
    response =
arc4.encrypt(response)

    req.send_response(200)
   
req.send_header(‘Content-Length’, len(response))
   
req.end_headers()
   
req.wfile.write(response)

Figure 11: Dynamic HTTP request handler

Stage 4: Manual Custom Responses

For even more flexibility, the all-powerful networking utility netcat can be used to stand-in for FakeNet-NG
listeners. For example, you may want to use netcat to act as a C2 server and issue commands
dynamically during execution on port 80. Launch a netcat listener before starting FakeNet-NG, and
traffic destined for the corresponding port will be diverted to the
netcat listener. You can then issue
commands dynamically using the netcat
interface as seen in Figure 12.


Figure 12: Use ncat.exe to manually
handle traffic

FakeNet-NG’s custom response capabilities are diverse. Read the documentation
to learn how to boost your custom response high score.

Stage 5: Blacklisting Processes

Some analysts prefer to debug malware from a separate system. There
are many reasons to do this; most commonly to preserve the IDA
database and other saved data when malware inevitably corrupts the
environment. The process usually involves configuring two virtual
machines on a host-only network. In this setup, FakeNet-NG intercepts
network traffic between the two machines, which renders remote
debugging impossible. To overcome this obstacle, we can blacklist the
debug server by instructing FakeNet-NG to ignore traffic from the
debug server process.

When debugging remotely with IDA Pro, the standard debug server
process for a 32-bit Portable Executable is win32_remote.exe (or dbgsrv.exe for WinDbg). All you need to do is add
the process names to the ProcessBlackList
configuration as demonstrated in Figure 13. Then, the debug servers
can still communicate freely with IDA Pro while all other network
traffic is captured and redirected by FakeNet-NG.

# Specify processes to ignore when
diverting traffic. Windows example used here.
ProcessBlackList: win32_remote.exe, dbgsrv.exe

Figure 13: Modified configs/default.ini to allow
remote debugging with IDA Pro

Blacklisting is also useful to filter out noisy processes from
polluting Fakenet-NG captured network traffic. Examples include
processes that attempt to update the Windows system or other malware
analysis tools.

Additional settings are available for blacklisting ports and hosts.
Please see the README for more
details about blacklisting and whitelisting.

Stage 6: Executing Commands on Connection Events

Fakenet-NG can be configured to execute commands when a connection
is made to a Listener. For example, this option can be used to attach
a debugger to a running sample upon a connection attempt. Imagine a
scenario where we analyze the packed sample named Lab18-01.exe from the Practical Malware
Analysis labs
. Using dynamic analysis, we can see that the
malware beacons to its C2 server over TCP port 80 using the HTTP
protocol as seen in Figure 14.


Figure 14: Malware beacons to its C2
server over TCP port 80

Wouldn’t it be nice if we could magically attach a debugger to Lab18-01.exe when a connection is made? We could
speedrun the sample and bypass the entire unpacking stub and any
potential anti-debugging tricks the sample may employ.

To configure Fakenet-NG to launch and attach a debugger to any
process, modify the [HTTPListener80] section
in the fakenetconfigsdefault.ini to
include the ExecuteCmd option. Figure 15
shows an example of a complete [HTTPListener80] section.

[HTTPListener80]
Enabled:    
True
Port:        80
Protocol:    TCP
Listener:    HTTPListener
UseSSL:      No
Webroot:     defaultFiles/
Timeout:     10
DumpHTTPPosts: Yes
DumpHTTPPostsFilePrefix: http
Hidden:      False
# Execute x32dbg –p to attach to a
debugger. {pid} is filled in automatically by Fakenet-NG
ExecuteCmd: x32dbg.exe -p {pid}

Figure 15: Execute command option to run and
attach x32dbg

In this example, we configure the HTTPListener on port 80 to execute the debugger
x32dbg.exe, which will attach to a running
process whose process ID is determined at runtime. When a connection
is made to HTTPListener, FakeNet-NG will
automatically replace the string {pid} with
the process ID of the process that makes the connection. For a
complete list of supported variables, please refer to the Documentation.

Upon restarting Fakenet-NG and running the sample again, we see
x32dbg launch and automatically attach to
Lab18-01.exe. We can now use memory
dumping tools such as Scylla or the OllyDumpEx plugin to dump the executable and
proceed to static analysis. This is demonstrated in Figure 16 and
Figure 17.


Figure 16: Using FakeNet-NG to attach
x32dbg to the sample (animated)


Figure 17: Fakenet-NG executes x32dbg
upon connection to practicalmalwareanalysis.com

Stage 7: Decrypting SSL Traffic

Often malware uses SSL for network communication, which hinders
traffic analysis considerably as the packet data is encrypted. Using
Fakenet-NG’s ProxyListener, you can create a
packet capture with decrypted traffic. This can be done using the
protocol detection feature.

The proxy can detect SSL, and “man-in-the-middle” the
socket in SSL using Python’s OpenSSL library. It then maintains
full-duplex connections with the malware and with the HTTP Listener,
with both sides unaware of the other. Consequently, there is a stream
of cleartext HTTP traffic between the Proxy and the HTTP Listener, as
seen in Figure 18.


Figure 18: Cleartext streams between
Fakenet-NG components

In order to keep FakeNet-NG as simple as possible, current default
settings for FakeNet-NG do not have the proxy intercept HTTPS traffic
on port 443 and create the decrypted stream. To proxy the data you
need to set the HTTPListener443 Hidden
attribute to True as demonstrated in Figure
19. This tells the proxy to intercept packets and detect the protocol
based on packet contents. Please read
our blog post
 on the proxy and protocol detection to learn more
about this advanced feature.

[HTTPListener443]
Enabled:    
True
Port:        443
Protocol:    TCP
Listener:    HTTPListener
UseSSL:      Yes
Webroot:     defaultFiles/
DumpHTTPPosts: Yes
DumpHTTPPostsFilePrefix: http
Hidden:     
True

Figure 19: Hide the listener so the traffic will
be proxied

We can now examine the packet capture produced by Fakenet-NG. The
cleartext can be found in a TCP stream between an ephemeral port on
localhost (ProxyListener) and port 80 on
localhost (HTTPListener). This is
demonstrated in Figure 20.


Figure 20: Cleartext traffic between
HTTPListener and Proxy Listener

Conclusion (New Game+)

Fakenet-NG is the de facto standard network simulation tool for
malware analysis. It runs without installation and is included in
FLARE VM. In addition to its proven and tested default settings,
Fakenet offers countless capabilities and configuration options. In
this blog post we have presented several tricks to handle common
analysis scenarios. To download the latest version, to see a complete
list of all configuration options, or to contribute to Fakenet-NG,
please see our Github repository.