#!/usr/bin/env python3
"""
Advanced Cryptography Challenge Exploitation Script
Author: CTF Player
Usage: python3 exploit.py http://target-ip
"""

import sys
import json
import base64
import requests
import time

class CryptoExploit:
    def __init__(self, target):
        self.target = target.rstrip('/')
        self.session = requests.Session()
        
    def get_challenge(self):
        """Fetch challenge data from API"""
        url = f"{self.target}/crypto1/?api&action=get_challenge"
        resp = self.session.get(url)
        return resp.json()
    
    def decrypt_rsa(self, cipher_b64):
        """Attempt RSA decryption (if we have private key)"""
        url = f"{self.target}/crypto1/?api&action=decrypt&cipher={cipher_b64}"
        resp = self.session.get(url)
        return resp.json()
    
    def verify_token(self, token):
        """Test token verification (timing attack vector)"""
        url = f"{self.target}/crypto1/?api&action=verify&token={token}"
        start = time.perf_counter()
        resp = self.session.get(url)
        elapsed = time.perf_counter() - start
        return resp.json(), elapsed
    
    def analyze_ecb(self, ciphertext):
        """Analyze ECB mode patterns"""
        # ECB shows identical blocks for identical plaintext
        blocks = [ciphertext[i:i+32] for i in range(0, len(ciphertext), 32)]
        unique_blocks = len(set(blocks))
        print(f"[*] ECB Analysis: {len(blocks)} blocks, {unique_blocks} unique")
        
        if unique_blocks < len(blocks):
            print("[!] ECB Vulnerability Detected: Repeating blocks")
            return True
        return False
    
    def xor_crib_drag(self, ciphertext, known_plaintext):
        """XOR known-plaintext attack"""
        try:
            cipher_bytes = base64.b64decode(ciphertext)
            known_bytes = known_plaintext.encode()
            
            if len(cipher_bytes) >= len(known_bytes):
                key_candidate = bytes([c ^ k for c, k in zip(cipher_bytes[:len(known_bytes)], known_bytes)])
                print(f"[*] XOR Key Candidate: {key_candidate.hex()}")
                return key_candidate
        except:
            pass
        return None
    
    def timing_attack(self, token_length=32):
        """Perform timing attack on token verification"""
        charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-{}"
        known = ""
        
        print("[*] Starting timing attack...")
        
        for position in range(token_length):
            times = {}
            
            for char in charset:
                test_token = known + char + "A" * (token_length - len(known) - 1)
                _, elapsed = self.verify_token(test_token)
                times[char] = elapsed
            
            # Character with longest response is likely correct
            best_char = max(times, key=times.get)
            known += best_char
            print(f"[*] Progress: {known}")
            
            # Sort and show top candidates
            sorted_times = sorted(times.items(), key=lambda x: x[1], reverse=True)[:3]
            print(f"    Top candidates: {sorted_times}")
        
        return known
    
    def exploit_all(self):
        """Main exploitation function"""
        print(f"[*] Targeting: {self.target}")
        print("[*] Fetching challenge data...")
        
        # Step 1: Get challenge data
        try:
            data = self.get_challenge()
            
            if data.get('status') != 'success':
                print("[!] Failed to get challenge data")
                return
        except Exception as e:
            print(f"[!] Error getting challenge: {e}")
            return
        
        print("[+] Challenge data retrieved")
        
        # Step 2: Save data to files
        with open('challenge_data.json', 'w') as f:
            json.dump(data, f, indent=2)
        
        if 'public_key' in data:
            with open('public_key.pem', 'w') as f:
                f.write(data['public_key'])
        
        print("\n" + "="*50)
        print("[*] EXPLOITATION NEXT STEPS:")
        print("="*50)
        print("1. Factor RSA modulus with YAFU or msieve")
        print("2. Analyze ECB patterns for repeating blocks")
        print("3. Perform padding oracle attack on CBC cipher")
        print("4. Use XOR known-plaintext attack (crib dragging)")
        print("5. Complete timing attack for final token")
        print("6. Combine all flag parts")
        print("\n[*] Tools to use:")
        print("   - yafu (RSA factorization)")
        print("   - openssl (ECB/CBC analysis)")
        print("   - padbuster (padding oracle)")
        print("   - xortool (XOR analysis)")
        print("   - python requests (timing attack)")
        
        print("\n[+] Data saved to challenge_data.json and public_key.pem")
        print("[*] Run: python3 exploit.py http://your-target-ip")

def main():
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} http://target-ip")
        print(f"Example: {sys.argv[0]} http://192.168.1.100")
        sys.exit(1)
    
    target = sys.argv[1]
    exploit = CryptoExploit(target)
    
    try:
        exploit.exploit_all()
    except KeyboardInterrupt:
        print("\n[*] Exploitation interrupted")
    except Exception as e:
        print(f"[!] Error: {e}")

if __name__ == "__main__":
    main()
