Clone wiki

Challenge11 / Stage4

Stage 3

Analysis without Discrete Logarithm Calculation

Without cracking the stage 2 encryption, it has not been possible to fully reverse this payload stage. However, based on known prior behaviour patterns, it is possible to make some reasonable estimations.

In examining the encrypted traffic between and its server, we notice that, in packet #30, communicates a null byte to the server. Based on known prior behaviour, we hypothesis that this packet marks entry into the stage 3 payload by writing back the stage 3 payload's entry offset (after it has been zeroed):

Stage 3 Sequence Diagram

Based on similar observations, we infer a similar split between the stage 3 and 4 payloads.

We now note that the stage 3 payload appears to download 9862735 bytes (in packet's #32-#199) which we shall assume make up the stage 4 payload. As we hypothesis that an entry byte needs to be specified for the stage 4 payload, we note that this byte could be read from this downloaded data. Additionally, as we have previously witnessed Adler32 being used to perform checksumming of downloaded payloads, so we presume that it is used again here. So, we speculate that:

  • 4 bytes of the data is used for checksumming information
  • and 1 byte is used to specify a starting offset.

Thus, we estimate that the stage 4 payload consists of the first 986270 downloaded bytes of packets #32-#199.

Analysis with Discrete Logarithm Calculation

Note: the following analysis was performed using the results of Ruud Schramp's discrete logarithm calculation.

VirusTotal does not report the shellcode as being known to the majority of its 41 AV agents (only McAfee-GW-Edition complains).

We reverse stage 3 using the demo version of IDA Pro on a compiled version of honeynet_stage3_payload.S (this file has been created by editing the output of x86dis).

From the IDA Pro disassembly of stage 3 and /usr/src/sys/kern/syscalls.master, we note that:

  • the system call at line 0x360 (called via lines 0x12C, 0x17B and 0x2EF) is a call to FreeBSD function number 0x03
    • i.e. ssize_t read(int fd, void *buf, size_t nbyte) (see read manpage)
  • the system call at line 0x360 (called via line 0x2AC) is a call to FreeBSD function number 0x04
    • i.e. ssize_t write(int fd, const void *buf, size_t nbyte) (see write manpage)
  • the system call at line 0x5E is a call to FreeBSD function number 0x14
    • i.e. pid_t getpid(void) (see getpid manpage)
  • the system call at line 0x106 is a call to FreeBSD function number 0x49
    • i.e. int munmap(void *addr, size_t len) (see munmap manpage)
  • the system call at line 0x305 is a call to FreeBSD function number 0x4A
    • i.e. int mprotect(const void *addr, size_t len, int prot) (see mprotect manpage)
  • the system call at line 0x7C is a call to FreeBSD function number 0xCA
  • the system call at line 0x1E3 is a call to FreeBSD function number 0x1DD
    • i.e. caddr_t mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t pos) (see mmap manpage and /include/sys/mman.h)

Additionally, we note that:

  • register EBX is set to contain the 3rd argument passed when stage 3 is called, and this register value is not altered anywhere within the stage 3 payload
    • i.e. with the exception of the stage 3 prologue and epilogue, EBX always points to ENCRYPT_process_bytes within the stage 3 payload
  • if stage 3 is called with a null value for ENCRYPT_process_bytes, then no Rabbit encryption/decryption is performed

Stage 3 Sequence Diagram

Stage 3 Sequence Diagram

Using PyDBG and Scapy Python code (running within a VMWare Windows XP SP2 virtual machine) we can now automatically extract our stage 4 payload (saved as honeynet_stage4_payload.section0.elf [MD5: 2c659b3003bd51ca3ba62a8f4db287e1] and honeynet_stage4_payload.section1.elf [MD5: bec7ab003e5988d2ba98140f90ec60df]).

See for a copy of this extraction code and stage2_to_4_unpacker.log for the logged output in running this code.