#!/usr/bin/env python3
"""
Look for complete key sequences by examining regions around authentication
"""
import csv

with open('export.csv', 'r') as f:
    reader = list(csv.DictReader(f))

print("[*] Examining regions around line 67000-68500 (where we found data)...\n")

# Look at the region where we found sector data
start = 66500
end = 68500

print("[*] Looking for sequences of 6 consecutive MOSI bytes that could be keys...\n")

# Extract all MOSI bytes in this region
mosi_stream = []
for i in range(start, min(end, len(reader))):
    row = reader[i]
    if row['type'] == 'result' and row['mosi'] and row['mosi'].startswith('0x'):
        mosi_stream.append((i, int(row['mosi'], 16)))

print(f"[+] Extracted {len(mosi_stream)} MOSI bytes from lines {start}-{end}\n")

# Look for specific patterns: key register writes followed by data
# MFRC522: Write to register format is (address & 0x7E)
# Key registers are 0x0C-0x11

print("[*] Searching for command sequences...\n")

key_candidates = []

for i in range(len(mosi_stream) - 7):
    line_num, byte_val = mosi_stream[i]
    
    # Look for write to key register 0x0C (first key byte)
    if byte_val == 0x0C:
        # Next 6 bytes might be the key
        potential_key = []
        for j in range(1, 7):
            if i + j < len(mosi_stream):
                potential_key.append(mosi_stream[i+j][1])
        
        if len(potential_key) == 6:
            # Check if this looks like a valid key (not all zeros, not sequential)
            if not all(b == 0 for b in potential_key):
                key_hex = ''.join(f'{b:02x}' for b in potential_key)
                key_candidates.append((line_num, key_hex, potential_key))
                print(f"Line {line_num}: After 0x0C -> {key_hex}")

# Also look for any 6-byte sequences that look like LCG outputs
print("\n[*] Looking for 6-byte patterns that could be LCG outputs...\n")

for i in range(len(mosi_stream) - 5):
    seq = [mosi_stream[i+j][1] for j in range(6)]
    line_num = mosi_stream[i][0]
    
    # Split into two 3-byte values
    val1 = (seq[0] << 16) | (seq[1] << 8) | seq[2]
    val2 = (seq[3] << 16) | (seq[4] << 8) | seq[5]
    
    # Check if these could be LCG outputs (< 0xFFFFFF, not trivial)
    if 0x100000 < val1 < 0xFFFFFF and 0x100000 < val2 < 0xFFFFFF:
        # Check if they're not just repeating patterns
        if val1 != val2 and seq[0] != seq[3]:
            key_hex = ''.join(f'{b:02x}' for b in seq)
            
            # Try to crack LCG
            def lcg_step(seed):
                return (seed * 0x52c6425d + 0xcc52c) % (2**32)
            
            def lcg_inverse(x):
                a = 0x52c6425d
                c = 0xcc52c
                a_inv = pow(a, -1, 2**32)
                return ((x - c) * a_inv) % (2**32)
            
            def crack(out4, out5):
                for upper in range(256):
                    state4 = (upper << 24) | out4
                    state5 = lcg_step(state4)
                    if (state5 % 0xffffff) == out5:
                        state = state4
                        for _ in range(4):
                            state = lcg_inverse(state)
                        return state
                return None
            
            passcode = crack(val1, val2)
            
            if passcode:
                print(f"\n{'='*70}")
                print(f"POTENTIAL PASSCODE FOUND!")
                print(f"Line {line_num}: {key_hex}")
                print(f"Keys: [{val1:06x}] [{val2:06x}]")
                print(f"Passcode: {passcode}")
                print(f"{'='*70}\n")
                
                # Test it
                import requests
                
                def generate_keys(pc):
                    seed = pc
                    keys = []
                    for _ in range(6):
                        seed = lcg_step(seed)
                        keys.append(seed % 0xffffff)
                    return keys
                
                keys = generate_keys(passcode)
                print(f"Generated keys:")
                for idx, k in enumerate(keys):
                    print(f"  Key {idx}: {k:06x}")
                
                # Build auth code
                key_bytes = []
                for key in keys[4:6]:
                    key_bytes.extend([key >> 16, (key >> 8) & 0xFF, key & 0xFF])
                key_hex_final = ''.join(f'{b:02x}' for b in key_bytes)
                
                sector_22 = '0292640464020a820860081608cd0833'
                auth_code = sector_22 + key_hex_final
                
                data = {
                    'uid': '04f6555b',
                    'username': '6178656c5f6f757472756e',
                    'authorization_code': auth_code,
                    'access_level': '085e0831084d084f0886083408cd081f'
                }
                
                try:
                    r = requests.post('http://154.57.164.76:32127/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!!!")
                        print(f"FLAG: {result['flag']}")
                        print(f"{'='*70}")
                        exit(0)
                    else:
                        print(f"API Response: {result}")
                except Exception as e:
                    print(f"API Error: {e}")

print("\n[*] Search complete")
