#!/usr/bin/env python3
"""
Extract FULL 16 bytes from each sector
"""
import csv
import requests

def lcg_step(seed):
    return (seed * 0x52c6425d + 0xcc52c) % (2**32)

def generate_keys(passcode):
    seed = passcode
    keys = []
    for _ in range(6):
        seed = lcg_step(seed)
        keys.append(seed % 0xffffff)
    return keys

with open('export.csv', 'r') as f:
    reader = list(csv.DictReader(f))

def extract_sector(start_line, label):
    """Extract 16 data bytes by taking every other MISO byte"""
    miso_bytes = []
    
    for i in range(start_line, min(start_line + 70, len(reader))):
        row = reader[i]
        if row['type'] == 'result' and row['miso'] and row['miso'].startswith('0x'):
            miso_bytes.append(int(row['miso'], 16))
    
    # Take every other byte (data bytes at odd indices)
    data = [miso_bytes[i] for i in range(1, min(len(miso_bytes), 33), 2)][:16]
    
    if len(data) == 16:
        hex_str = ''.join(f'{b:02x}' for b in data)
        ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in data)
        
        print(f"\n{label}:")
        print(f"  {hex_str}")
        print(f"  '{ascii_str}'")
        
        return hex_str
    else:
        print(f"\n{label}: Only got {len(data)} bytes")
        return None

print("[*] Extracting full 16-byte sectors...")

# Need to find where sector 8 data actually starts - not at the READ command
# Let me try line 67914 (after the READ at 67864)
sector_8_hex = extract_sector(67914, "Sector 8 (Username)")

# Sectors 22 and 34 start right after their MOSI commands
sector_22_hex = extract_sector(68312, "Sector 22 (Auth Code)")
sector_34_hex = extract_sector(69112, "Sector 34 (Access Level)")

if sector_8_hex and sector_22_hex and sector_34_hex:
    print(f"\n{'='*70}")
    print("SUCCESS! All sectors extracted")
    print(f"{'='*70}")
    
    # Try to decode username from sector 8
    username_hex = sector_8_hex.replace('00', '').strip()
    if not username_hex:
        username_hex = sector_8_hex
    
    print(f"\nUID: 04f6555b")
    print(f"Username: {username_hex}")
    
    # Test with common passcodes
    print(f"\n[*] Testing with passcodes...")
    for pc in [0, 1, 42, 1234, 0x1337, 0x4242, 13337, 31337, 65535]:
        keys = generate_keys(pc)
        key_bytes = []
        for key in keys[4:6]:
            key_bytes.extend([key >> 16, (key >> 8) & 0xFF, key & 0xFF])
        key_hex = ''.join(f'{b:02x}' for b in key_bytes)
        
        auth_code = sector_22_hex + key_hex
        
        data = {
            'uid': '04f6555b',
            'username': username_hex,
            'authorization_code': auth_code,
            'access_level': sector_34_hex
        }
        
        try:
            r = requests.post('http://154.57.164.61:31938/api', data=data, timeout=3)
            result = r.json()
            
            if result.get('flag') and len(result.get('flag', '')) > 5:
                print(f"\n{'='*70}")
                print(f"SUCCESS! Passcode: {pc}")
                print(f"FLAG: {result['flag']}")
                print(f"{'='*70}")
                exit(0)
            else:
                print(f"  {pc:06}: {result.get('door_status', 'Unknown')}")
        except Exception as e:
            print(f"  {pc:06}: Error")
    
    print("\n[!] Need to brute force...")
else:
    print("\n[-] Failed to extract all sectors")
