# CTF Challenge: RFID Access Control - Complete Analysis

## Challenge Overview
- **Objective**: Unlock a door by sending valid RFID credentials to API
- **Files**: `ota_reader_update.py` (reader code), `access_reader_logic_data.sal` (logic capture)
- **API**: `http://154.57.164.61:31938/api`

## What We Know (CONFIRMED ✓)

### API Expects These Parameters:
```python
{
    'uid': '04f6555b',                    # ✓ CONFIRMED
    'username': '74657074617374',          # ✓ CONFIRMED ("teptast")
    'authorization_code': auth_code + keys,  # ❌ MISSING
    'access_level': access_level            # ❌ MISSING
}
```

### Current Status:
- **Server Response**: `{'door_status': 'Locked', 'flag': 'HTB{}'}`
- This means UID and username are CORRECT but auth_code and access_level are wrong

## How The System Works

### From ota_reader_update.py:
1. **Reads 3 MIFARE Classic sectors**: 8, 22, 34
2. **Generates keys using LCG**:
   ```python
   next = (seed * 0x52c6425d + 0xcc52c) % 2^32
   key = next % 0xffffff
   ```
3. **Sector mapping**:
   - Sector 8: Username (we have: "teptast")
   - Sector 22: Authorization code (16 bytes) - NEED THIS
   - Sector 34: Access level (16 bytes) - NEED THIS
4. **Final auth_code** = sector_22_data + generated_keys[4:6]

## What We Need

### Missing Data:
1. **Sector 22 data** (16 bytes hex)
2. **Sector 34 data** (16 bytes hex)  
3. **Passcode** (seed for LCG key generation)

### Where It Is:
The logic capture `access_reader_logic_data.sal` contains SPI communication between MFRC522 RFID reader and card showing:
- 4 digital channels (SPI: MISO, MOSI, SCK, CS)
- The READ commands for sectors 8, 22, 34
- The 16-byte responses from each sector

## Solution Path

### Option A: Use Saleae Logic 2 (Recommended)
1. Open `access_reader_logic_data.sal`
2. Add SPI Analyzer:
   - Clock: Channel 2 (dense regular pattern)
   - MISO/MOSI: Channels 0/1
   - Enable: Channel 3
3. Export decoded bytes as CSV
4. Extract 16-byte blocks from sector reads
5. Use those in exploit script

### Option B: Parse Binary Directly
The extracted `digital-X.bin` files use Saleae format:
- Header: `<SALEAE>` + version + type
- Problem: Files report as "type 100" (undocumented analog format)
- .sal format itself is not officially documented

### Option C: Brute Force
With valid UID/username, could brute force:
- Passcode: 0 to 2^32 (infeasible)
- Common sector patterns + passcode (more feasible)

## Exploit Script Structure

```python
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

# NEED THESE VALUES:
sector_22_hex = "????????????????????????????????"  # 16 bytes
sector_34_hex = "????????????????????????????????"  # 16 bytes
passcode = 0x????????  # Unknown

keys = generate_keys(passcode)
key_bytes = []
for key in keys[4:6]:  # Last 2 keys for sector 34
    key_bytes.extend([key >> 16, (key >> 8) & 0xFF, key & 0xFF])

auth_code = sector_22_hex + ''.join(f'{b:02x}' for b in key_bytes)

payload = {
    'uid': '04f6555b',
    'username': '74657074617374',
    'authorization_code': auth_code,
    'access_level': sector_34_hex
}

response = requests.post('http://154.57.164.61:31938/api', data=payload)
# Should return: {'door_status': 'Unlocked', 'flag': 'HTB{...}'}
```

## Next Steps

1. **Export from Saleae**: Add SPI analyzer → export CSV → parse for sector data
2. **Parse exported CSV**: Look for 16-byte data blocks following READ commands
3. **Try common values**: Default FF/00 patterns with passcode brute force (0-65535)
4. **Submit**: Once we have all 3 values, submit to API for flag

## Tools & Resources
- Saleae Logic 2: https://www.saleae.com/downloads/
- Similar CTF writeups: https://anniequus.com/posts/htb-hardware-writeups/
- MIFARE Classic: 1KB cards, 16 sectors, 4 blocks each, 16 bytes per block
