Closed deadly-platypus closed 2 years ago
The rootkit repeatedly prints out
== Finding target process ... ==
Could not find target process ... We will try again :-)
after the above output.
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.
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!
Renaming the target program did not work, so I'll print out the process list and let you know the output.
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.
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?
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
@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!
The offsets in the PR worked!
However, the guest hangs once the target process is found. I am looking into what is happening.
Great! Can you see any printouts after it has found the process?
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.
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.
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 :)
Also, judging from the code, there should be a file
C:\smm.txt
that contains the stringHello 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 inWinUmdIATHook.c
is the same code that is generated by compiling the source inshellcode
, 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!
You mean not cleaning up isn't the standard in Windows development? I'll check and report back.
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?
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.
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.
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:/)
Is there a reason why
v_memReadMultiPage
is used on line 201 ofWinUmdIATHook.c
? If I change that to justv_memRead
the contextCreateFileA
function pointer becomes correct. However, the status still is not0xff
, 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
@deadly-platypus , is there any issues still? Should I debug the usermode IAT hook myself?
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!
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 orwindows_x64_umd_iat.exe
is running as administer. When the target is booting, the root kit finds the following information and offsets: