20
Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Embed Size (px)

Citation preview

Page 1: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Win32 ProgrammingLesson 22: DLL Magic Part DeuxAll your base are belong to us…

Page 2: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Where are we? We’ve looked at injection techniques in

general But now it’s time to get specific

Page 3: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Remind Me… What’s the trick we’re trying to pull off?

Page 4: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Injecting DLLs using a Remote Thread Remember, we’re trying to get a DLL into

another process’ address space One way to do this is to create a thread in a

remote process And Windows provides an easy way to do

this…

Page 5: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

So… HANDLE CreateRemoteThread(

   HANDLE hProcess,     PSECURITY_ATTRIBUTES psa,     DWORD dwStackSize,    PTHREAD_START_ROUTINE pfnStartAddr,     PVOID pvParam,     DWORD fdwCreate,     PDWORD pdwThreadId);

Look familiar…?

Page 6: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Problems? Troy, does this solve all our problems? Casey? Chris? Invisible Dan? …

Page 7: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Bingo! This only works if we have code in the

remote thread that we want to execute to load our Trojan DLL…

Hmmm… can we fix it? How do you load a DLL during program

execution?

Page 8: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Right: LoadLibrary But LoadLibrary doesn’t exist (someone tell me why?) So basically, we want to execute a line of code which looks

like this: HANDLE hThread = CreateRemoteThread(

hProcessRemote,  NULL,  0,     LoadLibraryA,  "C:\\MyLib.dll",  0, 

NULL);

BUT this is still wrong… why?

Page 9: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Right: Real address The address of LoadLibraryA as a function

won’t be the same because of relocation But the *real* address of LoadLibraryA in

KERNEL32.DLL will be the same (provided it loads in the same location)

So, how do we get that?

Page 10: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Right: GetProcAddress… GetProcAddress(GetModuleHandle(TEXT("

Kernel32")), "LoadLibraryA"); Easy eh? Predicated on the identical loading of

Kernel32… but that’s quite common But it still doesn’t work right… there’s still

one string attached to this idea…

Page 11: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Right: The STRING “c:\\mylib.dll” The String exists in Process A’s address space,

but we need it to exist in Process B’s Hmmm How can we fix that?

Page 12: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Right: VirtualAllocEx Bingo! PVOID VirtualAllocEx(

    HANDLE hProcess,     PVOID pvAddress,     SIZE_T dwSize,     DWORD flAllocationType,     DWORD flProtect);

Page 13: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

But we’re still not done Processes boundaries stop one process writing

to another… So we need a function which can read and

write Process memory And Windows gives us such a function…

Page 14: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Memory… BOOL ReadProcessMemory(

   HANDLE hProcess,     PVOID pvAddressRemote,    PVOID pvBufferLocal,     DWORD dwSize,     PDWORD pdwNumBytesRead); BOOL WriteProcessMemory(    HANDLE hProcess,     PVOID pvAddressRemote,    PVOID pvBufferLocal,     DWORD dwSize,     PDWORD pdwNumBytesWritten);

Page 15: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

7 Step Process Use the VirtualAllocEx function to allocate memory

in the remote process’s address space. Use the WriteProcessMemory function to copy the

DLL's pathname to the memory allocated in step 1. Use the GetProcAddress function to get the real

address (inside Kernel32.dll) of the LoadLibraryA or LoadLibraryW function.

Use the CreateRemoteThread function to create a thread in the remote process that calls the proper LoadLibrary function, passing it the address of the memory allocated in step 1.

Page 16: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Continued… Use the VirtualFreeEx function to free the

memory allocated in step 1. Use the GetProcAddress function to get the

real address (inside Kernel32.dll) of the FreeLibrary function.

Use the CreateRemoteThread function to create a thread in the remote process that calls LoadLibrary function, passing the remote DLL's HINSTANCE.

Page 17: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Lastly… hProcess = OpenProcess(

   PROCESS_CREATE_THREAD |   // For CreateRemoteThread    PROCESS_VM_OPERATION  |   // For VirtualAllocEx/VirtualFreeEx    PROCESS_VM_WRITE,    // For WriteProcessMemory    FALSE,  dwProcessId);

Page 18: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Next: The Trojan DLL Replace some DLL you want… But you have to export all the same functions

Page 19: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Injecting a DLL via a Debugger Tricky and processor-specific But can work well, as Debuggers have special

privileges

Page 20: Win32 Programming Lesson 22: DLL Magic Part Deux All your base are belong to us…

Injecting Via CreateProcess Have your process spawn the child process suspended. Retrieve the primary thread's starting memory address from

the .exe module's file header. Save the machine instructions at this memory address. Force some hand-coded machine instructions at this address.

The instructions should call LoadLibrary to load a DLL. Resume the child process’s primary thread so that this code

executes. Restore the original instructions back into the starting

address. Let the process continue execution from the starting address

as if nothing had happened