jussihi / SMM-Rootkit

SMM rootkit similar to LoJax or MosaicRegressor
GNU General Public License v3.0
102 stars 25 forks source link

Rootkit cannot find target process #3

Closed deadly-platypus closed 2 years ago

deadly-platypus commented 2 years ago

I am probably missing something, but I cannot figure out what is happening. When running Windows 10 in QEMU, smm_target.exe cannot is never found, regardless if nothing special is running in the target OS or windows_x64_umd_iat.exe is running as administer. When the target is booting, the root kit finds the following information and offsets:

== Initializing windows context struct ==
  Cleaning up old Windows struct ...
  Dynamic memory allocated before WinCtx init: -72960
  PML4: 0x1ad000 Kernel entrypoint: 0x7f8d320cff0
  Trying to find Ntos kernel ... 
  Kernel found!
  NT kernel: 0x7f8d3600000
  Parsing Windows kernel exports ...
  Parsing export table for 64-bit module ...
  Finished Export Table.. NameAmount 3062
  Dynamically allocating table ...
  Filling the export list ...
  Export list successfully filled!
  PsInitialSystemProcess: 0x7f8d2903be0
  SystemProcess: 0x41790e5a0fc0
  NtVer: 1000
  NtBuild 19044
== Windows offsets set! ==
deadly-platypus commented 2 years ago

The rootkit repeatedly prints out

==  Finding target process ... ==

  Could not find target process ... We will try again :-)

after the above output.

jussihi commented 2 years ago

Can you print out the process list (process names)?

I.e., add a printout after line https://github.com/jussihi/SMM-Rootkit/blob/bbb79520cb5d2e92e1f0e98672efa3df7a5b72d3/SMM%20Rootkit/SMMRootkit/WinTools.c#L831 for the name. See if the process list is correct.

jussihi commented 2 years ago

Ah, it might be that you've misunderstood something. As a target program, you should compile the target program and rename it to "smm_target.exe". Then run it on the virtual machine.

The assembly code and C code from the hook folder have already been compiled and embedded to the SMM rootkit itself, the resulting shellcode can be found from WinUmdIATHook.c. Hope this enlightens the way it works for you!

deadly-platypus commented 2 years ago

Renaming the target program did not work, so I'll print out the process list and let you know the output.

deadly-platypus commented 2 years ago

Looks like the names we are getting are incorrect

==  Finding target process ... ==
---- NAME: `ߡ| ----

There is only one name that gets tested, and it is always that alien glyph above.

deadly-platypus commented 2 years ago

It looks like winGlobal->offsets.imageFileName is incorrect. They are hardcoded, and likely different with the new NT Version causing #1. How are these offsets calculated?

jussihi commented 2 years ago

A-ha! Time to do more reversing... I will get back to this issue once I have time. Please be patient. Meanwhile you can try to reverse them yourself and try to check if the dirbase etc are correct.

Current offsets are set up at https://github.com/jussihi/SMM-Rootkit/blob/bbb79520cb5d2e92e1f0e98672efa3df7a5b72d3/SMM%20Rootkit/SMMRootkit/WinTools.c#L263

jussihi commented 2 years ago

@deadly-platypus , actually rain had already patched this in our internal repo. Please find his PR from https://github.com/jussihi/SMM-Rootkit/pull/5/commits/79a945290ca0f55884beca32e98d73181418a61e. Could you try and see if it fixes the issue? Report back here & PR if it works/does not.

Thank you!

deadly-platypus commented 2 years ago

The offsets in the PR worked!

However, the guest hangs once the target process is found. I am looking into what is happening.

jussihi commented 2 years ago

Great! Can you see any printouts after it has found the process?

deadly-platypus commented 2 years ago

Yeah, I do get some print outs:

==  Found and dumped process! Starting IAT Hooking ==
  Getting process IAT Thunk ...
  Allocating 196608 bytes of memory for the PE image ...
Allocated pages
    The target seems to be 64-bit...
    IAT: Comparing GetCurrentProcessId
  Finding process sections for code & write caves ...
  Suitable caves found! Dumping kernel32.dll exports ...
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName CloseHandle!
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName CreateFileA!
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName CreateProcessA!
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName CreateThread!
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName GetExitCodeProcess!
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName ReadFile!
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName WriteFile!
  EAT Buffer filled with 1633 exported names in it!
  EAT: Found ProcName LocalAlloc!

== IAT Hooking done! Now waiting for execution :-) == 

  UMD: Execution succeeded! Restoring ...

Once this is printed, the guest stops responding, and the virtual machine console does not print anything else. The guest is doing something however, since its CPU load is continuously maxed out.

deadly-platypus commented 2 years ago

Also, judging from the code, there should be a file C:\smm.txt that contains the string Hello from SMM! that is created by the shellcode. Is that correct? When I restart the guest, that file does not exist. I have confirmed that the shellcode in WinUmdIATHook.c is the same code that is generated by compiling the source in shellcode, and it looks correct to me.

jussihi commented 2 years ago

Ah, the restoration code most probably crashes the guest.

From WinUmdIATHook.c, comment out lines 216-239 and try again.

I also used to have this problem time to time, and just not cleaning up the hook afterwards solved the issue for me. It is most probably a race condition (i.e., the guest is running the code which we inserted before, and since we null it in SMM the CPU will get really disoriented and the system will crash). If you have time, you can check which part of the cleanup process actually causes the crash and try to fix it :-) There might even be a bug in the cleanup routine! It was written by a human after all :)

jussihi commented 2 years ago

Also, judging from the code, there should be a file C:\smm.txt that contains the string Hello from SMM! that is created by the shellcode. Is that correct? When I restart the guest, that file does not exist. I have confirmed that the shellcode in WinUmdIATHook.c is the same code that is generated by compiling the source in shellcode, and it looks correct to me.

Yes, you are correct. There should be a file "C:\smm.txt" But I think that SMM execution here is so quick that the file contents (smm.txt) are not flushed/synced to hard disk before the guest crashes. Please see my above comment and check if you can get the file to show up with its instructions!

deadly-platypus commented 2 years ago

You mean not cleaning up isn't the standard in Windows development? I'll check and report back.

deadly-platypus commented 2 years ago

After commenting out the clean up code, the guest no longer hangs. However, the file still does not appear. I tried forcing the OS to reread the disk again, in case of cache problems, by restarting the guest, and still nothing. Trying to debug this, I noticed that the shellcode writes 0xff to the context Status member. Printing out that status member in WindowsUmdIATHookStage3 it reads 0x18 after the call to v_memReadMultiPage. Could we be writing function pointer values to the incorrect location, and then the shellcode exits early at the first check?

deadly-platypus commented 2 years ago

Alas, when I have smm_target print the location of CreateFileA and have the IAT Hook print out the address it finds for CreateFileA, they match. However, when we read back the context in WindowsUmdIATHookStage3, the CreateFileA pointer is incorrect. I am going to try to verify the context we write is correct.

deadly-platypus commented 2 years ago

Is there a reason why v_memReadMultiPage is used on line 201 of WinUmdIATHook.c? If I change that to just v_memRead the context CreateFileA function pointer becomes correct. However, the status still is not 0xff, even if I zero that value before writing to the target process. Unless you have another way to test, I think that the shellcode will need to be modified to write different values to status depending on the path taken.

jussihi commented 2 years ago

Good to hear it's not crashing anymore.

First things first: once the hook is installed from SMM, do you execute the hooked function from the smm_target? I.e., GetCurrentProcessId(). Now that the GetCurrentProcessId() is hooked, it should execute the shellcode whenever you call GetCurrentProcessId() from the target process.

In other words, once the smm_target is running and the SMM rootkit tells you that the hook was installed correctly via the serial console, you need to press enter once (in smm_target.exe console window) to trigger the GetCurrentProcessId() call in smm_target.exe: https://github.com/jussihi/SMM-Rootkit/blob/master/target_tests/windows_x64_umd_iat/windows_x64_umd_iat/windows_x64_umd_iat.cpp#L14

Also, make sure to run smm_target.exe as administrator (so that the program has rights to write to C:/)

jussihi commented 2 years ago

Is there a reason why v_memReadMultiPage is used on line 201 of WinUmdIATHook.c? If I change that to just v_memRead the context CreateFileA function pointer becomes correct. However, the status still is not 0xff, even if I zero that value before writing to the target process. Unless you have another way to test, I think that the shellcode will need to be modified to write different values to status depending on the path taken.

v_memReadMultiPage was used because the write area could span over a physical page boundary. That code should™ work

jussihi commented 2 years ago

@deadly-platypus , is there any issues still? Should I debug the usermode IAT hook myself?

deadly-platypus commented 2 years ago

sorry for the delay...I forgot that I needed to actually type in text and not just hit enter. I can confirm that everything works properly now, our long national nightmare is over, and I'm closing the issue. Thanks for your extensive help!