Perform static analysis of the provided binary to uncover its configuration, encryption logic, signal handling, and self-deletion behavior. Use IDA Pro or Ghidra to answer the questions. Do not execute the sample.
The sample is a Linux ransomware binary built around a hardcoded four-digit victim ID. On start it reads the local account database, writes the collected host details to a temp file named after that ID, and uploads the result over FTP after normalising filenames. A command-line option table supplies the extensions to encrypt, and a signal handler can either confirm or abort the directory traversal. Files are encrypted in fixed-size chunks, a ransom note pointing to a Tor hidden service is dropped in the home directory, and the binary unlinks itself afterwards unless the operator opts out. All of it is recoverable statically from the disassembly and .rodata.
danger.txt. Extract into work/, never run itfile, strings, nm for triage, objdump -d and objdump -s -j .rodata for the logic and constantsTip: The binary keeps its function symbols (
lp_generate_id,lp_save_system_info,lp_signal_handler,lp_encrypt_handler,lp_upload_handler).nmgives the map; disassemble each function instead of readingmaintop to bottom.
The ID is a string literal in .rodata that main copies into its id variable, and every later filename is built from it. Dump .rodata and find the four-digit string, then confirm in main that the address is the one stored into id.
objdump -s -j .rodata harvest
Disassemble lp_generate_id. It allocates 5 bytes, takes rand() modulo 10000 and calls snprintf with a size of 5. The format string address loaded before the call points into .rodata. Four digits plus the terminator fills the buffer exactly, which explains the width. This function is the generic ID generator; the ID in Q1 is the one actually hardcoded in main.
objdump -d harvest --disassemble=lp_generate_id
The system-information routine opens the local account database. The path appears as a string in .rodata next to the other collection strings and is passed straight to the file open call.
strings -a harvest | grep -E "^/(etc|tmp|proc)"
From Q1 the ID is 1606. lp_save_system_info builds its output name with sprintf(filename, "/tmp/%s.txt", id) and opens it for writing, so the path is the format string with the ID substituted. The disassembly shows the format and the fopen on the result.
objdump -d harvest --disassemble=lp_save_system_info
lp_upload_handler calls lp_replace(name, ' ', 0x5f) before building the FTP target. The third argument is the replacement byte, 0x5f, which is the underscore.
objdump -d harvest --disassemble=lp_upload_handler
The option table in .rodata pairs each long option with a help string. The entry described as target file extensions is the one that feeds the encryption filter.
objdump -s -j .rodata harvest
In lp_encrypt_handler the loop reads each file with read(fd, buf, 0x1000) before encrypting the buffer and writing it back. 0x1000 is 4096.
objdump -d harvest --disassemble=lp_encrypt_handler
lp_signal_handler checks confirm, then compares the signal number against a constant. A match clears confirm; any other signal falls through to the path that sets the stop request. The compare is against 2, which is SIGINT.
objdump -d harvest --disassemble=lp_signal_handler
The ransom note text is a single string in .rodata, so strings finds the hidden-service address directly.
strings -a harvest | grep -i onion
A destruct boolean defaults to true, and at the end of the run main calls unlink(argv[0]) when it is set. The option table has a flag that toggles it off, so self-deletion is the default and the flag is the opt-out. This is the reverse of what the name suggests: passing it does not trigger destruction, it prevents it.
objdump -d harvest --disassemble=main
Gotcha: The flag name reads like an instruction to self-destruct. The default is already destructive, and passing the flag flips it off.
| Phase | Action |
|---|---|
| Execution | Binary starts with a hardcoded victim ID used to name all of its artifacts |
| Discovery | Reads /etc/passwd to enumerate user accounts |
| Collection | Writes host information to /tmp/<id>.txt |
| Exfiltration | Normalises filenames (spaces to underscores) and uploads over FTP |
| Impact | Encrypts files matching the exts list in 4096-byte chunks |
| Impact | Signal handler can clear the confirm flag or request traversal stop |
| Impact | Drops a ransom note with a Tor hidden-service address in the home directory |
| Defense Evasion | Unlinks its own binary unless the opt-out flag is passed |
| Type | Value |
|---|---|
| Victim ID | 1606 |
| Staging file | /tmp/1606.txt |
| Tor hidden service | kd24u5e4ggp2m4k4w23lm5fu1nurmme6ugrwi9btachx83lpw1t6qlxf[.]onion |
| Recon target | /etc/passwd |
| CLI options | --exts, --destruct |
| Technique | ID | Description |
|---|---|---|
| Command and Scripting Interpreter: Unix Shell | T1059.004 | Operator-driven command-line options control targeting and behaviour |
| System Information Discovery | T1082 | Host details collected into the staging file |
| Account Discovery: Local Account | T1087.001 | Reads /etc/passwd |
| Data Staged: Local Data Staging | T1074.001 | Output written to /tmp/1606.txt |
| Exfiltration Over Unencrypted Non-C2 Protocol | T1048.003 | Upload handler sends files over FTP |
| Indicator Removal: File Deletion | T1070.004 | unlink(argv[0]) after execution |
| Data Encrypted for Impact | T1486 | Chunked file encryption and Tor ransom note |
Hunt for unattended FTP from servers. The upload handler speaks plain FTP after cleaning up filenames. Outbound FTP from a Linux host that has no business using it is a clean, low-noise detection, and egress filtering would have cut off the exfiltration path.
Watch for small text files in /tmp named with four digits. The staging file is predictable (/tmp/<id>.txt) and holds host and account information. File-creation monitoring on /tmp with a numeric-name pattern, followed by a network upload, is a usable behavioural rule.
Treat a process that unlinks its own executable as suspicious. Self-deletion is the default here, so the binary is gone from disk after a normal run. Process telemetry that records the image path and hash at launch, plus memory capture, preserves what the filesystem will not.
A hardcoded ID is a pivot for scoping. The same string names the staging file and ties activity to one victim record. Searching fleet-wide for the ID and the ransom-note onion address shows how far a single sample spread.
The binary needs nothing but a disassembler to explain itself: ID, staging path, targeting option, chunk size, ransom note and self-delete default are all plain constants. Self-deletion by default means the sample is rarely on disk afterwards, so the telemetry captured at launch is what matters.