Wednesday, November 22, 2017

Mitigating DLL MITM - Manual DLL Importation

Hello, guys!

In my last post I brought a post about DLL Hijacking / Man-In-The-Middle technique with DLL importation. In the end of the post I wrote some countermeasure methods to mitigate this type of hijacking. The method I describe here is efficient and a little tricky for RE, but of course it's "ugly" and manual. It's just an idea, trying to think creatively.

Basically instead of using the IAT to reach the function on DLL you have to manually set the address of the function. To do that we only need the offset of the function in the DLL, get the handle of the DLL module and sum with the offset.

I will use the same example of the last post. You can get the function offset in many ways. In this example I just grab the address from the IAT to get the offset of the function.





With the address we can code in the dll-consume a dynamic function call.



As you can see I create a function-type to create an object of that function-type and then I dynamically set the address of function. This way I know exactly that will go to my function. If I try to load the DLL Fake the program will crash, because Fake image doesn't have the function in the same address. I renamed the function because I imported the windows.h and this header already have a send function.

The only way to bypass this is patching the application or generating an DLL with this function in the same address.



Conclusion


In conclusion we just have to be creative to mitigate flaws in software. Always thinking both in offensive and defensive. Try to break your own programs and at the same time how to mitigate it. Anything at all just contact me. Thanks! :)

Sunday, November 12, 2017

DLL Hijacking - DLL Man-In-The-Middle

Hello, guys!

I hope that everybody is doing fine! :)

I was working in this PoC on my free time and now I could get enough time to bring the technical of it. It take a while because I first wanted to bring some introductory posts before writing the technical stuff. So let's do it!

First of all I hope that you had read my last posts to a better understanding of what I will show here, because I will not explain in details everything. So the prerequisites for this post is:
What I utilized to do this ?

Github Project

Overview


I have been studying more in-depth the PEB hooking (this post is not about PEB hooking) to learn more thoroughly how Windows Internals works. My way to learn is coding, practicing. I like to brush bits :). Basically the PEB hooking stole a module from some process, changing addresses in the LdrModules located in the PEB. But for this I needed a DLL that exports the same functions that the original do.

To export all functions from a DLL I coded the "DLL Exporter" tool to extract the functions exported by some DLL. It access the export directory and generate 2 files for NASM. I included the code generated in the main code of the fake image DLL ASM. Of course for this example it doesn't matter, because I only exported 1 function, anyway it worth to take a look on it to see how it works.

In this example I coded a program that simulate a message exchange, there is no socket connecting to keep it simple. But you got point right ? The program passes the message to a DLL that encodes it and hypothetically would send encoded message to somewhere. 

To do this PoC I made a fake DLL that exports the same function of the original. This fake DLL grabs the message, log it in a file before encoding it and send the execution to the original one, without injecting any code neither in the executable nor original DLL, just rewrites the IAT of fake DLL. I just named the fake image file as the same name of the original image, so when the Windows Loader searches for the DLL it will load the fake one.

Problems


Theoretically I just have to leave the windows load the fake DLL and inside of the fake image I load the original DLL, then I can call all functions that belongs to it. I could do this just with LoadLibrary and GetProcAddress, right ? But imagine a DLL with a LOT of functions, the work I would to do to make everything callable would be huge and painful.

So what I did was to link the original DLL to my fake DLL and there is where I found the problem. When the program loads the fake DLL consequently the original DLL is loaded, since the fake image has the same name as the original image, windows loader will end up linking fake image to itself and a Deadlock is set. So when the fake image is called by the process it can't jump to the original image and keeps calling itself forever. To set everything in the right place I had to alter the IAT (Import Address Table) of the fake DLL.


Solution


As a solution to this problem I had to rewrite the IAT with the original function addresses and I did it with NASM. At this point if you don't know what is a IAT, please read my previous topics and all the references I gave there. The solution is to load the original DLL image, save the AddressOfFunctions (Export Directory), save the IAT (FirstThunk - Import Directory), change the IAT memory protection (protection against writing), then I just iterated through the AddressOfFunction rewriting the addresses to the IAT by the addresses of AddressOfFunctions. Now all my imported functions in the fake image DLL will call the original image DLL functions.

Spliting the Project


I will give a brief explanation about the source code. I left comments in the source to help in the reading, but the code itself is self explanatory. Anyway any doubt or question just contact me. In the next posts I will bring CMake files to make easy to compile, for now I just make some PowerShell scripts to do it in each folder.
  • Folders
    • dll
      • This folder have the code of the dllsend.dll.
    • dll-consume
      • This folder contains the code of the program to consume the dllsend.dll.
    • dll-exporter
      • This folder contains the program that receives a DLL in the command and generate two files. dll_parameter.dll.ext and dll_parameter.dll.subs.
        • dll_parameter.dll.ext contains the "extern" code of all exported functions to append in the ASM code.
        • dll_parameter.dll.subs contains the function declaration to append in the ASM code.
    • dll-fake-asm
      • This folder contains the body of the fake DLL image. I coded all the process using NASM and GoLink to link the compiled object with the original DLL image.
      • make.ps1 has the logic to link the fake DLL image. 
      • In the GoLink you have to inform all the exported functions. In this case you can adapt the DLL Exporter to generate this part easily.

Walking through the process


I will assume that you have compiled everything and I will just walk to the main parts of the process. The dll-consume is very straight forward, you type your message, then it back to you with the encoded string and the it's hex dump.

dll-consume compiled

So as I mentioned before I just renamed the original DLL adding a "2" in the end. So let's see what happen inside of this process. You will see that since the fake DLL is pure ASM code it's size is tinier than the original image DLL compiled with GCC. 

List of files

So I already mentioned before how to find the OEP (Original Entry Point) of the programs compiled in GCC. You can find the pattern that GCC uses to do this or you can go directly in the inter-modular calls made by this module m.exe. This is the main function:

Main function of m.exe

As I always said, take a moment to walk-through the program, it's important to train your eyes with assembly code. In the image above you will see the IAT of the m.exe module in the line that calls the send function where you see a jump to imported function. At this point in debugging you can see all the modules loaded in the memory tab. Since original DLL was loaded in the entry function of my fake image DLL it is already loaded in the memory tab.

Memory mapping

The main/entry code of the fake image DLL already was executed when the Windows Loader loaded the fake image. To step through this part in the debugger you can check Dll Entry option in the preferences.

Dll Entry - Debugging

I already set a breakpoint in the send call, then I stepped into until I get the fake send function.

As you can see it's pretty straight forward. I imported some C functions to save the message in the file log.bin. Opened a handle to the file, wrote to it and closed the handle. After the log process, I restored the register context and jumped to the original send function.

I could enhanced this fake send function more to make the log better, but it useless. To practice ASM, try to enhance it inside the fake DLL code. Make a breakline in each message and save it to the log.bin, if you analyze the code you will see that is easy.

Fake function 'send' disassembled

I will not step-by-step through the IAT rewriting, I leave to you to debug it. Open the DLL on CFF Explorer and debug the entry function of fake DLL. The code itself has a lot of comments. Any help that you may need just contact me, I would be glad to help. ☺

Countermeasures ?


There are some countermeasure against it, you just have to be creative about it. For this you could check the MD5 of the DLL before call it or you could count how many modules are loaded in the process memory space. As you saw in the walk-through there is a exceeding module dllsend2.dll and with this information you can define if your application has been compromised or not.

Anyway it's hard to fight against these things. In RE world, programmers have to do all they can to make the work of reversers as hard as possible in order to avoid the RE itself.

Conclusion


In computer world everything is possible it's just a time to understand how to do it. I did this PoC for learning purposes and a better understand the Windows Internals. I hope that with this technical example you can learn a little with it too. Thanks for reading.

I didn't walked through the loading process of fake image DLL because I think my comments in the code are pretty self explanatory. Anyway any questions feel free to contact me. 

Saturday, November 4, 2017

PEB - Process Block Environment

Hello again! ✌

First of all I do apologize for any mistake that I might made here. I'm always open to opinions and tips. I hope this can be useful to somebody.

In this post I will try to introduce you to the concept of PEB (Process Environment Block) that is a structure in the Windows's processes containing very important information, it's important to know it better. But before to get into it I will try to introduce you to some basic concepts like, what is Process, Thread and Jobs. We need to know the difference, because they have different structures.

Like I always said, I will keep this post simple and objective. In the end of the post I will leave good references so you can do your own in-depth researches. If you really want to know the Windows you need to get the Windows Internals book it is a must to know more this operating system.


Processes


The concept of process and programs are important to understand. A process is not a program, programs are sequences of instructions and processes are containers where the programs are included along with other properties and resources. So in order to run a Window's program a container is needed, where it can run freely with everything it needs is already within. Windows certifies that.

A Windows process comprehends basically:

  • Private Virtual Address
    • A private virtual space in memory to allocate everything the program may need to run.
    • Processes can't access others processes's virtual memory space if there is nothing allowing it.
  • Program
    • The program is the part of the process that has instructions to the processor execute.
  • List of Handles
    • Handles are pointers to resources allocated in memory utilized by the program like Synchronization objects (Basically are shared objects between threads), opened files and so on.
  • Security Information
    • All security information about the process like, user, group of user, privileges in the system, User Account Control (UAC), session and so on.
  • Process ID
    • Unique identifier of the process.
  • Threads
    • At least one thread will be running for any given process.

If you read my last post about PE files you should can correlate in some way processes with PE files in-memory. When attempt to create a new process in the system with one very known API like CreateProcess, it expects in the first parameter (lpApplicationName) a valid PE file to load it in memory, even if the file doesn't have the extension .exe.

It's important to say that CreateProcess is an API of Windows, but it is a high-level one so to speak. For example we have default processes that are created in the beginning of boot process of Windows, like Smss.exe. Smss (Session manager) isn't created by CreateProcess, instead it is created by NtCreateUserProcess (Ntdll) since it is created directly by the Kernel.

There is a difference between native processes and normal proceses that are created after the Windows boot initialization.  These native processes like Smss.exe, Csrss.exe and so on cannot be created as a common process, the CreateProcessInternalW will reject native images. There are some functions used to create a process, but all of them will end up calling CreateProcessInternalW that is the last documented function called in the process creation no matter which one was called first.

All processes created in the system have a structure called EPROCESS (Executive Process) and is maintained in the system address space (memory space reserved for the Windows system).  And as we will speak later in this post also maintains a structure in the user address space called PEB (Process Environment Block). So just have in mind that Windows maintain a structure for everything that it creates. In these structures always have a reference in memory for each information it keeps. So when the "process" is executing in user-mode (user address space) it uses the PEB as a reference to access the objects allocated in memory. When the execution is in kernel-mode (kernel address space) and needs to access some information about processes it uses the EPROCESS. However even being the main representations of processes's structures in each side of the operating system (kernel-mode and user-mode) there are more structures created by another processes, Windows Internals cover this thoroughly.

So as mentioned before the process isn't the program itself, thus when a process is created a thread is created with it to execute the main program function. It's important to know this difference, thread execute the program and is the thread that have all CPU context to execute.

Threads


Thread is basically piece of primitive code and a structure in the process block that contains the processor context information. So what runs the program is the thread. Properties of the Thread:

  • The Processor Context
    • State of CPU registers, the information of the program state is contained in the thread context.
  • Stack information
    • One stack to the kernel-mode and user-mode.
  • Thread ID
    • Unique identifier of the thread.

Since we have a lot of programs running in our machine the processor must know the state of each program running simultaneously. Basically when the Windows is switching between the threads it replaces the processor context of each thread, this way the system never lost the state of the program since it's last ran.

Thread is a program that can run in user-mode and kernel-mode it must have a stack for each one. As the process have the PEB structure, thread have the TEB structure both of them are in the user-mode. The system maintains structures both in user-mode and kernel-mode, so in this way the user-mode components that wants to grab information about processes or threads doesn't need to make any system call.

As the process, the thread have an executive thread (ETHREAD) structure to represent the thread object in the system address space for Kernel usage. There are more structures maintained by the system for the same thread and process, for example since Windows Architecture can support more than it's own subsystem (Windows Subsystem - Csrss.exe) it creates the CSR_THREAD and also creates the CSR_PROCESS. These structures are maintained by the Windows Subsystem for internal purposes.

The scheduler and dispatcher are the components in the Windows to switch threads. They are responsible to load the thread context to continue or starts to execution of a program. Basically threads can be interrupted or they just gives up of the processor when they finish execution. When a thread becomes idle, then the components mentioned before put this thread in wait and switch to another thread. Every thread have a time-limit (quantum) to run, when it reaches this time-limit the components put the thread in wait and switch to another thread. This process is continuous. The scheduling decisions are made based in the dispatcher-database, is group of structures maintained by processor with all thread's information like priority, state and so on.

So basically processes are containers and threads run programs. Threads run programs that need resources from processes. Just to make it very clear. So when you debug any "process" you must to know actually which thread you are executing/debugging.

Jobs


Jobs are an extension of the process model. Basically it can manage and manipulate one or multiple processes as a unit. So working with a Job is work with all processes linked to it. There is a plenty system mechanisms that the Job can manipulate and various process-related, I/O-related and CPU-related limits that can be manipulated by the job. To a more thorough look on Jobs subject, please search for it in Windows Internals.

The PEB


All processes loaded in the windows have a Executive Process Structure (EPROCESS) that points and maintain many structures relative to it's execution in the system. Here we will just talk about the PEB (Process Environment Block). The PEB is created by the kernel through MmCreatePeb function after setting up the EPROCESS structure. As we already discussed before, this structure is useful on sharing information about the process without transiting between user-mode and kernel-mode. So the main structure is the EPROCESS (Executive Process) that is located in System Address Space (Kernel) and has a pointer (EPROCESS_ADDRESS+0x01B0 *Peb) to PEB that is located in User Address Space (User-Mode).

The PEB is located in the memory segment fs in 32bits architecture and gs in the 64bits architecture at offset 0x30. Actually in one of these memory segments is located the TEB (Thread Environment Block) structure that has the member ProcessEnvironmentBlock (TEB_ADDRESS+0x30) with a pointer to the PEB. Another way to get the PEB address is only with semi-documented or undocumented functions. To get a better view of the structure access the link below (OpenRCE - PDF). Note that it isn't exactly the same as the up-to-date windows version, but still fits to visualize the internal structure.


Would be very expensive to access process information through system calls (system address space),  PEB came to enhance performance making process information available in the user address space. Some components of the windows that resides in the user address space need to access information about the process, like the image loader, heap manager and some other components.

PEB structure has a lot of member-fields that you can check on the link I posted above from OpenRCE. In this post I will write about two of them:

  • Loader Database (PEB_LDR_DATA)
  • Process Heap


Loader Database / PEB_LDR_DATA


In the previous post we discussed about the PE File and I assume that you have looked at least a little in the reference I gave. So this structure is represented by the PEB's member Ldr. Inside of this field/member Ldr (PEB_LDR_DATA) we have three linked lists that works linking the modules loaded in the process, almost like an array. The linked lists are InLoadOrderModuleList, InMemoryOrderModuleList, InInitializationOrderModuleList. They are ordered differently from each other and like the name of each one suggests, loaded order, memory location order, initialization order.

Each loaded module is represented as another structure LDR_MODULE, storing the information about the module loaded and the rest of linked list. So any PE file that this process needs to use and has loaded in memory is located in this structure. Let's see how the LDR_MODULE structure looks like:

LDR_MODULE Structure

As you can see the three first members of structure is the linked list and after it there are information about the module itself like,  BaseAddress, BaseDllName and so on. So you wanna know the modules loaded by some process ? PEB_LDR_DATA is the way.

Process Heap


In the PEB structure there are two undocumented pointer to heaps. In the offset PEB_ADDRESS+0x18, the ProcessHeap member has the address of the first created heap and the PEB_ADDRESS+0x90, the ProcessHeaps member is a pointer to an array of all heaps created. When the process is created by a debugger in first heap there are two fields, ForceFlags and Flags that are set to tell the kernel if the process was created by a debugger or not. Some debugger like x64dbg already have the option "Hide Debugger" to unset these fields.

In the reference below I listed some good resource to analyze. The offset relative to PEB_ADDRESS can variate due the Windows Version. There is a good repo in github from al-khaser there are many anti-"everything" techniques including ForceFlags and Flags which I said here. Check it out. :)

References


Windows Objects

Objects in windows are referred as kernel objects . They provide a link or an way to use any objects functionality according with the object...