Pechatnaya Mashinka
Pechatnaya Mashinka
Platform: hackerlab | Category: Misc | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2025-12-25 | Status: Solved Techniques: PCAP analysis with tshark, USB HID keyboard traffic analysis, USB scan code decoding
Summary
Task: Analyze a strange dump file. Solution: Extract USB HID keyboard traffic from PCAP and decode scan codes to recover typed text containing the flag.
Pechatnaya Mashinka - Hackerlab
Description
К нам в руки попал какой-то странный дамп. Поможешь разобраться?
The task name "Печатная машинка" (Typewriter) hints at keyboard input.
Analysis
1. File Identification
bash read-only • copy allowedfile task.pcap # task.pcap: pcap capture file, microsecond ts (little-endian) - version 2.4 (USB with USBPcap header, capture length 65535)
This is a USB capture file - a USB traffic dump.
2. Extracting USB HID Data
bash read-only • copy allowedtshark -r task.pcap -T fields -e usb.capdata > usb_data.txt
We get data like:
0000090000000000
0000000000000000
00000f0000000000
...
0100060000000000
0100120000000000
3. USB HID Keyboard Report Structure
8-byte HID keyboard report:
- Byte 0: Modifier keys (Shift, Ctrl, Alt, etc.)
- Byte 1: Reserved (always 0)
- Byte 2: Keycode 1
- Bytes 3-7: Additional keycodes (for key rollover)
Modifier byte:
- 0x01 = Left Ctrl (but in this capture it's used as Shift!)
- 0x02 = Left Shift (standard)
- 0x20 = Right Shift
4. Key Observation
In this capture, modifier byte 0x01 is used as Shift (non-standard). This is evident from context - uppercase letters in "CODEBY{" have modifier 0x01.
Solution
python read-only • copy allowed#!/usr/bin/env python3 """ USB HID Keyboard decoder for CTF task "Печатная машинка" """ # USB HID Keyboard scan codes to characters # Reference: https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf KEY_CODES = { 0x04: ('a', 'A'), 0x05: ('b', 'B'), 0x06: ('c', 'C'), 0x07: ('d', 'D'), 0x08: ('e', 'E'), 0x09: ('f', 'F'), 0x0a: ('g', 'G'), 0x0b: ('h', 'H'), 0x0c: ('i', 'I'), 0x0d: ('j', 'J'), 0x0e: ('k', 'K'), 0x0f: ('l', 'L'), 0x10: ('m', 'M'), 0x11: ('n', 'N'), 0x12: ('o', 'O'), 0x13: ('p', 'P'), 0x14: ('q', 'Q'), 0x15: ('r', 'R'), 0x16: ('s', 'S'), 0x17: ('t', 'T'), 0x18: ('u', 'U'), 0x19: ('v', 'V'), 0x1a: ('w', 'W'), 0x1b: ('x', 'X'), 0x1c: ('y', 'Y'), 0x1d: ('z', 'Z'), 0x1e: ('1', '!'), 0x1f: ('2', '@'), 0x20: ('3', '#'), 0x21: ('4', '$'), 0x22: ('5', '%'), 0x23: ('6', '^'), 0x24: ('7', '&'), 0x25: ('8', '*'), 0x26: ('9', '('), 0x27: ('0', ')'), 0x28: ('\n', '\n'), # Enter 0x29: ('[ESC]', '[ESC]'), 0x2a: ('[BACKSPACE]', '[BACKSPACE]'), 0x2b: ('\t', '\t'), 0x2c: (' ', ' '), # Space 0x2d: ('-', '_'), 0x2e: ('=', '+'), 0x2f: ('[', '{'), 0x30: (']', '}'), 0x31: ('\\', '|'), 0x33: (';', ':'), 0x34: ("'", '"'), 0x35: ('`', '~'), 0x36: (',', '<'), 0x37: ('.', '>'), 0x38: ('/', '?'), } def decode_usb_keyboard(data_file): result = [] with open(data_file, 'r') as f: for line in f: line = line.strip() if not line or len(line) < 16: continue # Parse hex data try: data = bytes.fromhex(line) except: continue if len(data) < 3: continue modifier = data[0] keycode = data[2] # Skip if no key pressed (key release events) if keycode == 0: continue # Check if Shift is pressed # In this capture: 0x01 seems to act as Shift (non-standard) # Standard: 0x02 = Left Shift, 0x20 = Right Shift shift = (modifier & 0x23) != 0 # Include 0x01 as shift if keycode in KEY_CODES: char = KEY_CODES[keycode][1 if shift else 0] result.append(char) else: result.append(f'[0x{keycode:02x}]') return ''.join(result) if __name__ == '__main__': decoded = decode_usb_keyboard('usb_data.txt') print("Decoded keyboard input:") print(decoded)
Execution
bash read-only • copy allowedpython3 solve.py # Decoded keyboard input: # flag = CODEBY{REDACTED}
Useful Commands
bash read-only • copy allowed# Extract USB data via tshark tshark -r task.pcap -T fields -e usb.capdata # Alternatively via Wireshark filter usb.transfer_type == 0x01 && usb.data_len == 8
References
- USB HID Usage Tables
- USB Keyboard Scan Codes