APC

avril 1st, 2007 at 01:42 admin

Toujours en quête d’idées folles je suis tombé sur un truc funny en lisant le SDK, c’est marrant de se dire que tout le monde utilise cette fonctionnalité pour faire des choses « utiles » alors que moi je la détourne dans le but d’avancer mon projet personnel intitulé « CONQUERIR LE MONDE OU RIEN ! »
Il s’agit juste d’une technique d’injection de code Userland dont le principal intérêt est qu’on ne sait pas vraiment quand notre code sera exécuté :]


Les APC (Asynchronous Procedure Calls) permettent d’interrompre l’exécution d’un thread, si celui-ci l’autorise, pour pouvoir exécuté une routine. La chose est simple, on copie dans l’espace mémoire du process notre routine et on l’a met en file d’attente avec la fonction QueueUserAPC() puis on attend (environ 5 mins au micro-ondes). Pour lancer cette routine le thread doit passer dans un état dit « Alertable », il ne le fait que si le paramètre bAlertable des API suivantes est mit à vrai :

SleepEx,
SignalObjectAndWait,
WaitForSingleObjectEx,
WaitForMultipleObjectsEx,
MsgWaitForMultipleObjectsEx

Clairement notre procédure mise en attente à peu de chance d’être lancer immédiatement, pour avoir plus de chance on la met en file d’attente sur tout les thread du process. Je l’ai testé sur le Notepad et c’est quand je fais Fichier->Ouvrir que ma procédure injectée est lancé, surement à cause de l’appel à GetOpenFileName() qui load le menu pour choisir le fichier à ouvrir.

Après avoir mit un BP sur l’API native ZwWaitForSingleObject dans ntdll et tracer le notepad, j’arrive à la call stack :

Call stack of main thread
Address    Stack      Procedure / arguments                 Called from                   Frame
0007D2B0   77E60ACB   ? kernel32.WaitForSingleObjectEx      RPCRT4.77E60AC5
0007D2B4   00000131     hObject = 00000131
0007D2B8   000DBBA0     Timeout = 900000. ms
0007D2BC   00000001     fAlertable = TRUE <--W00T
0007D2CC   77E60A81   ? RPCRT4.77E60AA9                     RPCRT4.77E60A7C
0007D2F0   77E652C7   RPCRT4.77E60A64                       RPCRT4.77E652C2               0007D2EC
0007D318   77E6520D   Includes RPCRT4.77E652C7              RPCRT4.77E6520A               0007D314
0007D338   77E6565F   RPCRT4.77E60833                       RPCRT4.77E6565A               0007D334
0007D440   77E653ED   RPCRT4.77E6553D                       RPCRT4.77E653E8               0007D43C
0007D488   77E64CF6   RPCRT4.77E65372                       RPCRT4.77E64CF1               0007D484
0007D4D8   77E64E0D   ? RPCRT4.77E64BEB                     RPCRT4.77E64E08               0007D4D4
0007D51C   77E64D5C   ? RPCRT4.77E64D85                     RPCRT4.77E64D57               0007D518
0007D580   77E600AC   RPCRT4.77E600DC                       RPCRT4.77E600A7               0007D57C
0007D5B0   77E58DC9   Includes RPCRT4.77E600AC              RPCRT4.77E58DC6               0007D5AC
0007D5C8   77E58E00   RPCRT4.I_RpcGetBufferWithObject       RPCRT4.77E58DFB               0007D5C4
0007D5D8   77E5942D   RPCRT4.I_RpcGetBuffer                 RPCRT4.77E59428               0007D5D4
0007D5E8   77ED360B   ? RPCRT4.NdrGetBuffer                 RPCRT4.77ED3606               0007D5E4
0007D9C8   77DB1CD0   ?         ADVAPI32.77DB1CCB             0007D9C4
0007D9DC   77DB1C52   ADVAPI32.77DB1CB5                     ADVAPI32.77DB1C4D             0007D9D8
0007DA30   77DCCB54   ? ADVAPI32.LsaOpenPolicy              ADVAPI32.77DCCB4F             0007DA2C
0007DA84   778E8FEB   Includes ADVAPI32.77DCCB54            778E8FE9                      0007DA80
0007DAA4   778EA005   778EA091                              778EA000                      0007DAA0
0007DAD4   778E9068   ? 778E9FE8                            778E9063                      0007DAD0
0007DB18   7CA0F5AE   ? 778E902D                            SHELL32.7CA0F5A8              0007DB14
0007DB98   7CA0F54C   SHELL32.7CA0F581                      SHELL32.7CA0F547              0007DB94
0007DBB0   7CA0F425   SHELL32.7CA0F4FB                      SHELL32.7CA0F420              0007DBAC
0007DBD0   7CA0F4F1   SHELL32.7CA0F3D9                      SHELL32.7CA0F4EC              0007DBCC
0007DBF8   7C9FA276   SHELL32.7C9FA29D                      SHELL32.7C9FA271              0007DBF4
0007DC14   7CA00019   SHELL32.7C9FA230                      SHELL32.7CA00014              0007DC10
0007DC48   7C9FDF0F   SHELL32.7C9FE3E1                      SHELL32.7C9FDF0A              0007DC44
0007DCAC   7C9FDE50   Includes SHELL32.7C9FDF0F             SHELL32.7C9FDE4D              0007DCA8
0007DD14   7C9FE07B   Includes SHELL32.7C9FDE50             SHELL32.7C9FE078              0007DD10
0007DD3C   7C9FE019   SHELL32.7C9FE059                      SHELL32.7C9FE014              0007DD38

Là notre APC sera exécuté car le thread va devenir Alertable.
Ha on me dit dans l’oreillette qu’on y comprend rien, éclaircissons tout cela :)

C:\ProgHack\c>StackWatcher notepad.exe

Thread ID : 2232
0x77e60a64 : RPCRT4!UTIL_GetOverlappedResultEx+0x1d
0x77e65263 : RPCRT4!CO_SyncRecv+0x71
0x77e60833 : RPCRT4!OSF_CCONNECTION::TransSendReceive+0x9d
0x77e6553d : RPCRT4!OSF_CCONNECTION::SendBindPacket+0x575
0x77e65372 : RPCRT4!OSF_CCONNECTION::ActuallyDoBinding+0xa6
0x77e64beb : RPCRT4!OSF_CCONNECTION::OpenConnectionAndBind+0x20f
0x77e64d85 : RPCRT4!OSF_CCALL::BindToServer+0xed
0x77e600dc : RPCRT4!OSF_BINDING_HANDLE::AllocateCCall+0x2b0
0x77e60084 : RPCRT4!OSF_BINDING_HANDLE::NegotiateTransferSyntax+0x28
0x77e58d81 : RPCRT4!I_RpcGetBufferWithObject+0x5b
0x77e58df1 : RPCRT4!I_RpcGetBuffer+0xf
0x77e59405 : RPCRT4!NdrGetBuffer+0x28
0x77ed34d0 : RPCRT4!NdrClientCall2+0x195
0x77db1cb5 : ADVAPI32!LsarOpenPolicy2+0x1b
0x77db1c0f : ADVAPI32!LsaOpenPolicy+0x95
0x77dccaf6 : ADVAPI32!LookupPrivilegeValueW+0x66
0x778ea091 : SETUPAPI!EnablePnPPrivileges+0x2d
0x778e9fe8 : SETUPAPI!PnPGetGlobalHandles+0x1d
0x778e902d : SETUPAPI!CM_Get_Device_Interface_List_Size_ExW+0x45
0x7ca0f581 : SHELL32!CMountPoint::_EnumVolumes+0xc5
0x7ca0f4fb : SHELL32!CMountPoint::_InitLocalDriveHelper+0x52
0x7ca0f3d9 : SHELL32!CMountPoint::_InitLocalDrives+0xc8
0x7c9fa29d : SHELL32!CMountPoint::_GetMountPointDL+0x48
0x7c9fa230 : SHELL32!CMountPoint::GetMountPoint+0x46
0x7c9fe3e1 : SHELL32!CDrivesFolder::_FillIDDrive+0x5c
0x7c9fde70 : SHELL32!CDrivesFolder::ParseDisplayName+0x9f
0x7c9fdddf : SHELL32!CRegFolder::ParseDisplayName+0x93
0x7c9fe059 : SHELL32!CDesktopFolder::_ChildParseDisplayName+0x22
0x7c9fdf96 : SHELL32!CDesktopFolder::ParseDisplayName+0x7e
0x7c9fdddf : SHELL32!CRegFolder::ParseDisplayName+0x93
0x7c9fdd09 : SHELL32!SHParseDisplayName+0xa3
0x7c9fe2f9 : SHELL32!ILCreateFromPathEx+0x3d
0x7ca01b98 : SHELL32!_CreateFolderIDList+0x102
0x7c9ff293 : SHELL32!_GetFolderIDListCached+0x84
0x7c9ff3ed : SHELL32!SHGetFolderLocation+0x9e
0x7c9ff46f : SHELL32!SHGetSpecialFolderLocation+0x17
0x7634545c : comdlg32!CFileOpenBrowser::InitLookIn+0x51
0x763436d1 : comdlg32!InitLocation+0x102
0x763425e4 : comdlg32!OpenDlgProc+0x3af
0x77d1870c : USER32!InternalCallWinProc+0x28
0x77d240d8 : USER32!UserCallDlgProcCheckWow+0x146
0x77d23f5a : USER32!DefDlgProcWorker+0xa8
0x77d1b7d3 : USER32!SendMessageWorker+0x448
0x77d24956 : USER32!InternalCreateDialog+0x9df
0x77d26110 : USER32!InternalDialogBox+0xa9
0x77d261d2 : USER32!DialogBoxIndirectParamAorW+0x37
0x77d32043 : USER32!DialogBoxIndirectParamW+0x1b
0x763433ee : comdlg32!NewGetFileName+0x240
0x763433d6 : comdlg32!NewGetOpenFileName+0xf
0x76343324 : comdlg32!GetFileName+0x35d
0x76357c65 : comdlg32!GetOpenFileNameW+0x62 <---LOL !
0x1002b87 : notepad!NPCommand+0x202
0x1003429 : notepad!NPWndProc+0x4fe
0x77d1870c : USER32!InternalCallWinProc+0x28
0x77d1875f : USER32!UserCallWinProcCheckWow+0x150
0x77d188f1 : USER32!DispatchMessageWorker+0x306
0x77d18a01 : USER32!DispatchMessageW+0xf
0x1002936 : notepad!WinMain+0xdc
0x100739d : notepad!WinMainCRTStartup+0x174

Ha c’est beaucoup mieux, si on regarde dans RPC4CRT.dll à la fonction CO_SyncRecv :

push    [ebp+dwMilliseconds] ; dwMilliseconds
lea     eax, [ebp+arg_0]
push    1               ; bAlertable <-- W00T :}
push    eax             ; int
lea     eax, [esi+34h]
push    eax             ; int
push    esi             ; int
call    ?UTIL_GetOverlappedResultEx@@YGJPAXPAU_OVERLAPPED@@PAKHK@Z

Je rappel juste pour ceux dont le cerveau aurait BSOD que c’est la fonction GetOpenFileNameW qui est appelé quand on fait Fichier->Ouvrir :p

Bref une technique marrante qui à l’avantage de ne pas crée de nouveau thread. De plus si le thread visé tourne avec des privilèges supérieur alors votre routine, si elle est lancée, les aura aussi :]

Le code/binaire ici :
http://ivanlef0u.fr/repo/APC.rar

Enjoy !

ps : Ce post n’est pas un toto d’avril :p

Entry Filed under: Non classé


Calendar

octobre 2021
L Ma Me J V S D
« fév    
 123
45678910
11121314151617
18192021222324
25262728293031

Most Recent Posts