Log in

View Full Version : why Opcode0x90's "dll Injection shield" fails against RtlCreateUserThead


BanMe
July 22nd, 2009, 21:17
I've still got alot of bugs to work out in the server..and I need to implement a way to do multiple hooks from the shared section and also develop a way to request new 'plugable code' without deleting the previous plugin loaded into the mapped section..and figure out why after 3 client connections to a "reusable" thread the it mysteriously blows up..

but enough about problems on with this post..

put Simply RtlCreateUserThread does not call Into BaseThreadStartThunk. to remedy this and improve upon opcode0x90's 'Dll Shield' I am placing my hook on LdrpCallInitRoutine which then in turn call's BaseThreadStartThunk (if CreateThread or CreateRemoteThread.)
In the Call to RtlCreateUserThread LdrpCallInitRoutine calls the passed in function directly. so placing a hook here covers CreateThread CreateRemoteThread RtlCreateUserThread NtCreateThread..you get it..

doing this during runtime can prevent all 'injected' threads from executing..placing a hook\breakpoint here 'pre' runtime will capture the 'Main' thread during initialization after tls has executed but w/e..also jmping over the call to ZwTestAlert Will prevent a Thread from being directed to the BaseThreadStartThunk routine.

hehe more fun and research for me

regards BanMe

BanMe
July 23rd, 2009, 22:24
imma mook, of course it will error on the 3rd thread.. i never changed the the Handle State back to ObTSuspended...lol that makes no sense to anyone but me and very few ppl...woohoo!!!

Kayaker
July 23rd, 2009, 22:49
Glad you're enjoying yourself

BanMe
July 24th, 2009, 13:38
lol if I didn't enjoy myself..there would be a whole lot less joy in my life,
and far less things to laugh at.. If you cant laugh at yourself, and review your mistakes with 20/20 rearview vision,I think life would be pointless..

I've also figured out a way to do mutliple 'plugable' code objects as well 'real' plugins..

BanMe
July 24th, 2009, 22:21
after more investigation hooking LdrpCallInitRoutine also calls Tls.. as can be seen in LdrpCallTlsInitializers..
Code:

7C91B839 > $ 6A 18 PUSH 18
7C91B83B . 68 90B8917C PUSH ntdll.7C91B890
7C91B840 . E8 8630FFFF CALL ntdll._SEH_prolog
7C91B845 . 8D45 D8 LEA EAX,DWORD PTR SS:[EBP-28]
7C91B848 . 50 PUSH EAX
7C91B849 . 6A 09 PUSH 9
7C91B84B . 6A 01 PUSH 1
7C91B84D . 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
7C91B850 . 57 PUSH EDI
7C91B851 . E8 F04AFFFF CALL ntdll.RtlImageDirectoryEntryToData
7C91B856 . 33DB XOR EBX,EBX
7C91B858 . 895D FC MOV DWORD PTR SS:[EBP-4],EBX
7C91B85B . 3BC3 CMP EAX,EBX
7C91B85D . 74 20 JE SHORT ntdll.7C91B87F
7C91B85F . 8B70 0C MOV ESI,DWORD PTR DS:[EAX+C]
7C91B862 . 8975 E0 MOV DWORD PTR SS:[EBP-20],ESI
7C91B865 . 3BF3 CMP ESI,EBX
7C91B867 . 74 16 JE SHORT ntdll.7C91B87F
7C91B869 . 381D C1E1977C CMP BYTE PTR DS:[ShowSnaps],BL
7C91B86F . 0F85 71120200 JNZ ntdll.7C93CAE6
7C91B875 > 8B06 MOV EAX,DWORD PTR DS:[ESI]
7C91B877 . 3BC3 CMP EAX,EBX
7C91B879 . 0F85 7C120200 JNZ ntdll.7C93CAFB
7C91B87F > 834D FC FF OR DWORD PTR SS:[EBP-4],FFFFFFFF
7C91B883 . E8 7E30FFFF CALL ntdll._SEH_epilog
7C91B888 . C2 0800 RETN 8


if/and if not showsnaps this is executed..with another check on showsnaps.. as to why..iono..couldnt have changed much in the nanosecond of execution time o0..but w.e

Code:

7C93CAFB > 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
7C93CAFE . 83C6 04 ADD ESI,4
7C93CB01 . 8975 E0 MOV DWORD PTR SS:[EBP-20],ESI
7C93CB04 . 381D C1E1977C CMP BYTE PTR DS:[ShowSnaps],BL
7C93CB0A . 74 0F JE SHORT ntdll.7C93CB1B
7C93CB0C . 50 PUSH EAX ; /Arg3
7C93CB0D . 57 PUSH EDI ; |Arg2
7C93CB0E . 68 C2CB937C PUSH ntdll.7C93CBC2 ; |Arg1 = 7C93CBC2 ASCII "LDR: Calling Tls Callback Imagebase %p Function %p
"
7C93CB13 . E8 BF3AFFFF CALL ntdll.DbgPrint ; \DbgPrint
7C93CB18 . 83C4 0C ADD ESP,0C
7C93CB1B > 53 PUSH EBX ; /Arg4
7C93CB1C . FF75 0C PUSH DWORD PTR SS:[EBP+C] ; |Arg3
7C93CB1F . 57 PUSH EDI ; |Arg2
7C93CB20 . FF75 E4 PUSH DWORD PTR SS:[EBP-1C] ; |Arg1
7C93CB23 . E8 4E46FCFF CALL ntdll.LdrpCallInitRoutine ; \LdrpCallInitRoutine
//jumps back to LdrpCallTlsInitializers for SEH cleanup or further Tls calls..
7C93CB28 .^E9 48EDFDFF JMP ntdll.7C91B875


I hope this helps some, for this definitly cuts down on some of my worries
regards BanMe

Kayaker
July 24th, 2009, 23:49
Quote:
[Originally Posted by BanMe;82036]
In the Call to RtlCreateUserThread LdrpCallInitRoutine calls the passed in function directly. so placing a hook here covers CreateThread CreateRemoteThread RtlCreateUserThread NtCreateThread..you get it..


Possibly also USER32!ClientThreadSetup, which is the first KiUserCallbackDispatcher execution from the Peb->KernelCallbackTable.

Taking a cue from

A catalog of NTDLL kernel mode to user mode callbacks, part 5: KiUserCallbackDispatch
http://www.woodmann.com/forum/showthread.php?t=11155


0:000> bp ntdll!KiUserCallbackDispatcher
0:000> g

Breakpoint 0 hit

Code:

ntdll!KiUserCallbackDispatcher:
7c90e460 add esp,4
7c90e463 pop edx
7c90e464 mov eax,dword ptr fs:[00000018h] fs:003b:00000018=7ffde000
7c90e46a mov eax,dword ptr [eax+30h] ds:0023:7ffde030=7ffdf000
7c90e46d mov eax,dword ptr [eax+2Ch] ds:0023:7ffdf02c={USER32!apfnDispatch (7e412970)}
7c90e470 call dword ptr [eax+edx*4] 7e412aa0={USER32!__ClientThreadSetup (7e41a13e)}
7c90e473 xor ecx,ecx
7c90e475 xor edx,edx
7c90e477 int 2Bh



The stack after a bit of tracing:

Code:
0:000> kc

ntdll!ZwCallbackReturn
USER32!LoadAppDlls
USER32!ClientThreadSetup
USER32!__ClientThreadSetup
ntdll!KiUserCallbackDispatcher
GDI32!NtGdiInit
USER32!_UserClientDllInitialize
ntdll!LdrpCallInitRoutine
ntdll!LdrpRunInitializeRoutines
ntdll!LdrpInitializeProcess
ntdll!_LdrpInitialize
ntdll!KiUserApcDispatcher



I couldn't generate the same output, but this stack dump traces things back to nt!PsConvertToGuiThread

http://www.dumpanalysis.org/blog/2009/05/23/collapsed-stack-trace/


The second breakpoint hit of KiUserCallbackDispatcher is interesting:

Code:
USER32!__ClientLoadMenu
ntdll!KiUserCallbackDispatcher
USER32!NtUserCreateWindowEx
USER32!_CreateWindowEx
USER32!CreateWindowExW
notepad!NPInit
notepad!WinMain
notepad!WinMainCRTStartup
kernel32!BaseProcessStart



Something else to think about

BanMe
July 25th, 2009, 00:20
yay!!!

so by the looks of the the CRT call BaseProcessStart Directly, that nothing for we all know threads do the actual execution.. the code in BaseProcessStart is mostly not uninteresting...I truely abhore the CRT and all things # but this definitly will take some investigation to make sure MISL can be manipulated and controled just as well as regular apps..also after digging into Kliessners Blackhat paper..(not released to public..and I wont release it..)I think I can rig up a Native Thread capable of calling win32k.sys functions without loading user32..good ol NtSystemDebugControl and a lil brain power..seeing how I got a Handle to WindowStation and desktop in native mode, I think screw consoles and go all out.... so much to do with initialization tracking...and maybe this can be a be used in some way as a first step towards Kernel Mode GUI's.. which sounds down right scary.. but there is a old thread on rootkit.com discussing this very topic..

Thank you so much Kayaker I appreciate your help and diligence\intelligence,more then I can say with mere words..

regards BanMe

BanMe
July 25th, 2009, 09:30
my gdm ADD came into play above...Can't even stay on topic in my own posts...:/

http://translate.google.com/translate?hl=en&sl=zh-CN&u=http://blog.csdn.net/eaglenet/archive/2006/02/19/602757.aspx&ei=-A5rSt7jJcKFtge40enHBQ&sa=X&oi=translate&resnum=9&ct=result&prev=/search%3Fq%3DLdrpCallTlsInitializers%26hl%3Den%26rls%3Dcom.microsoft:en-us:IE-SearchBox

this is a excellent source of more information for all those interested in how the Ldr works


good ol chinese CSDN..

BanMe
July 26th, 2009, 18:48
Wait second... after rereading kakayers post 10 times..and grasping the concept more..as it takes me a bit..but I ruminate with time...I guess...user32 does not have a entry point defined in the pe.the entry point is defined somewhere at the function described above as it 'seems to me'..still trying to track where that value is written to..but anyway this still helps in the 'idea' of calling win32k.sys without 'truely' loading user32..just have to pick this value out of teh client after a Module Load with Alignment call and mimic it in a different thread while preventing the load of the Other AppInit Dll's..oh what fun it is to have a crazy mind!!