// HackTheBox  ·  writeup

Lupin

HackTheBox Medium PythonpefileCapstonestringsBlockscout
Malware Analysis

Scenario

In this challenge, players will reverse engineer the executable to uncover the attacker’s tactics, techniques, and procedures (TTPs), gaining hands-on experience in binary analysis, persistence detection, and identifying malicious network behavior to support endpoint security operations.

Executive Summary

The sample is a 32-bit Windows executable with mid-range entropy, so it is not heavily packed and its strings and code read cleanly. It replicates itself under one service-style name, gates execution on the system locale, and forces fresh data from its C2 by evicting the URL cache entry before each request. Its core function is a clipper: it joins the clipboard viewer chain, reacts to change notifications, and overwrites copied wallet addresses with an attacker-controlled one hard-coded in the binary. It also sends SSDP discovery probes to the standard multicast group. Resolving the victim’s ENS name and following the attacker wallet on a public block explorer tied the sample to a real on-chain transfer, and the overall behaviour set pointed to a known commodity botnet family.

Artifacts

Tip: A stripped PE has no function labels. Scanning for push ebp; mov ebp, esp prologues and then locating callers of an imported API gives workable function starts. Treat the boundaries as heuristic.

Defense Evasion

Q1 — What is the entropy value of the executable file, truncated to three decimal places?

Shannon entropy over the raw bytes of the whole file comes out well below the 7+ range of a packed or encrypted binary, which says the code and strings are readable and static analysis will work. Truncate rather than round: the raw value runs past the third decimal, so the third digit stays as it is.

python3 -I -c "import math,collections,sys;d=open(sys.argv[1],'rb').read();c=collections.Counter(d);print(-sum(v/len(d)*math.log2(v/len(d)) for v in c.values()))" optimize.exe
Click flag to reveal 6.414
Q3 — Following filename verification, which Win32 API does the binary use to enforce region-based execution constraints?

From Q2 the sample checks its own filename first. The code that follows reads region information through a locale API, which is the geo-gate: the sample stops on systems in certain regions. List the imports for locale-related names, then disassemble around the call that follows the filename comparison with Capstone (the function at 0x40ea40). This one was reasoned from the purpose of the call in that function and the 14-character format mask, not read from a labelled artifact.

python3 -I -c "import pefile,sys;pe=pefile.PE(sys.argv[1]);[print(f.name.decode()) for i in pe.DIRECTORY_ENTRY_IMPORT for f in i.imports if f.name]" optimize.exe | grep -i locale

Hint: Look for Get*Locale* style imports, then check which one is called right after the filename comparison.

Click flag to reveal GetLocaleInfoA

Persistence

Q2 — What is the consistent filename used by the malware when replicating itself across different locations?

Dump the UTF-16 strings and read .rdata around the odd identifier l9n7b5f2r. A wide-string executable name sits right beside it, built to look like a Windows service binary. Every copy of the sample is written under that name.

strings -el optimize.exe | grep -i -B2 -A2 'l9n7b5f2r'
Click to reveal answer syscrondvr.exe

Command and Control

Q4 — The function at relative address 0x407680 makes a WinAPI call immediately before initiating the network request. Which WinAPI function does it call to ensure fresh data is retrieved from the C2 server?

Disassemble the function at 0x407680 and walk its calls in order. The WinINet call that sits at 0x407767, just before the request goes out, evicts the URL from the local cache, so the fetch hits the server instead of a stale cached copy. Confirm the name against the WinINet entries in the import table.

python3 -I -c "import pefile,sys;pe=pefile.PE(sys.argv[1]);[print(i.dll.decode(),f.name.decode()) for i in pe.DIRECTORY_ENTRY_IMPORT for f in i.imports if f.name]" optimize.exe | grep -iE 'Url|Internet'
Click to reveal answer DeleteUrlCacheEntry

Collection

Q5 — Samira noticed unusual behavior during the paste operation — what is the relative address of the function that is responsible for this strange activity?

Clipboard hijacking lives in a window procedure registered as a clipboard viewer. Scan the disassembly for call sites of SetClipboardViewer, GetClipboardData and DefWindowProcA: one function holds all three, which makes it the clipboard window proc. This was reasoned from that API combination, not read from a symbol.

python3 -I -c "import pefile,sys;pe=pefile.PE(sys.argv[1]);[print(i.dll.decode(),f.name.decode()) for i in pe.DIRECTORY_ENTRY_IMPORT for f in i.imports if f.name]" optimize.exe | grep -iE 'Clipboard|DefWindowProc'
Click flag to reveal 0x405B90
Q6 — Which Windows message, serves as the primary trigger for initiating the clipboard content?

A program registered with SetClipboardViewer is notified of every clipboard change by one window message, and the window proc from Q5 acts on it. The two-part, underscore-separated format mask fits only that message. This came from the viewer-chain mechanism, not from an immediate value read in the code.

Hint: Think about what Windows sends a clipboard viewer when the clipboard contents change.

Click to reveal answer WM_DRAWCLIPBOARD
Q7 — What is the relative address of the function used to modify Samira's clipboard content by replacing it with new data?

The replacement is a separate routine from the watcher in Q5. Find the caller that chains OpenClipboard, EmptyClipboard and SetClipboardData: it empties the victim’s clipboard and writes the attacker’s data in its place. As with Q5, the address comes from that API combination in the Capstone scan.

python3 -I -c "import pefile,sys;pe=pefile.PE(sys.argv[1]);[print(i.dll.decode(),f.name.decode()) for i in pe.DIRECTORY_ENTRY_IMPORT for f in i.imports if f.name]" optimize.exe | grep -iE 'Clipboard'

Gotcha: The Q5 function reads the clipboard; the one that writes it is a different function.

Click flag to reveal 0x404A60

Impact

Q8 — A transaction was made from "jamilaaidos.eth"; what is the transaction hash associated with the user latest operation?

Resolve the ENS name to its Ethereum address with the ENS data API, then list that address’s transactions on a Blockscout explorer. One of them is a transfer to the attacker wallet hard-coded in the binary, dated 2025-05-14, and that is the transaction tied to the sample. The address also has a later, unrelated transaction from 2026, which is not what the question wants.

curl -s https://api.ensdata.net/jamilaaidos.eth

Gotcha: The binary contains a 66-character 0x string that fits the format mask exactly. It is not a transaction for this ENS user, so check it on the explorer before trusting it.

Click to reveal answer 0xab2d474dad344da1e3b7ece6e7022c3295c52b176978337be82288a59e5a2a40

Discovery

Q9 — What specific multicast IP address is targeted by the SSDP M-SEARCH discovery probes?

Search the strings for M-SEARCH. The probe template sits next to its HOST: header, which carries the SSDP multicast group address and port.

strings optimize.exe | grep -A4 'M-SEARCH'
Click flag to reveal 239.255.255.250
Q10 — What standard UDP port number is used for the SSDP M-SEARCH discovery requests?

Same template as Q9: the port is the suffix on the HOST: header value.

strings optimize.exe | grep 'HOST:'
Click to reveal answer 1900

Attribution

Q11 — What is the malware family associated with the malware?

No hash lookup was done for this one. The family was reasoned from the behaviour set: a clipboard hijacker for crypto addresses, self-replication under a fixed system-looking name with removable-drive spread, and a DriveSecManager.exe string in the binary. That combination fits a well-known commodity botnet that was accepted as the answer. Because it rests on behaviour and not on an antivirus label, confirm with a hash lookup before relying on it in a report.

Tip: The 8-character mask narrows the field fast. Match it against families known for clippers and USB spreading.

Click flag to reveal phorpiex

Attack Summary

PhaseAction
Defense EvasionUnpacked, mid-entropy PE; readable strings and code
PersistenceReplicates itself under one fixed service-style filename
Defense EvasionVerifies its own filename, then reads locale information to gate execution by region
Command and ControlDeletes the URL cache entry before each C2 request to force fresh data
CollectionRegisters in the clipboard viewer chain and reacts to clipboard-change messages
ImpactEmpties the clipboard and writes an attacker wallet address in its place
ImpactVictim funds move to the attacker wallet on-chain
DiscoverySends SSDP M-SEARCH probes to the multicast group

IOCs

TypeValue
Fileoptimize.exe (81,920 bytes, entropy 6.414)
Filenamesyscrondvr.exe
FilenameDriveSecManager.exe
Network239.255.255[.]250:1900/udp (SSDP M-SEARCH)
Transaction0xab2d474dad344da1e3b7ece6e7022c3295c52b176978337be82288a59e5a2a40
ENS namejamilaaidos[.]eth

MITRE ATT&CK

TechniqueIDDescription
Obfuscated Files or InformationT1027Entropy check to judge whether the sample is packed
System Location Discovery: System Language DiscoveryT1614.001Locale lookup used to gate execution by region
Application Layer Protocol: Web ProtocolsT1071.001HTTP fetches from C2 with the cache entry deleted first
Clipboard DataT1115Clipboard viewer chain reads copied content
Data Manipulation: Transmitted Data ManipulationT1565.002Clipboard contents replaced with an attacker wallet
Network Service DiscoveryT1046SSDP M-SEARCH probes to the multicast group
Replication Through Removable MediaT1091USB-spreading behaviour used to attribute the family (inferred)

Defender Takeaways

Clipboard viewer registration from an unsigned process is a detection primitive. SetClipboardViewer together with SetClipboardData in a binary with no UI is the clipper signature. Static YARA on that import combination catches the family, and runtime EDR can flag processes that rewrite the clipboard moments after a copy.

Users should verify wallet addresses after pasting. The attack only works if the victim sends funds to the pasted address unchecked. Wallet software that matches against an address book or asks for confirmation of the first and last characters defeats the swap.

Fixed filenames make good hunting seeds. The sample copies itself everywhere under one service-looking name. A file-creation rule for that name outside System32, or a service-sounding name running from a user profile or removable drive, is cheap and precise.

SSDP from a workstation process is unusual. A non-browser process sending M-SEARCH to the multicast group on UDP 1900 deserves a look. Network sensors can alert on it, and it often accompanies removable-media or lateral activity.

Conclusion

The sample is small and unpacked, yet it quietly redirects a victim’s crypto transfers by rewriting the clipboard. The on-chain trail, through the ENS name and the wallet hard-coded in the binary, shows the theft is real and traceable, while the code itself gives defenders plenty of static hooks.