← Back to Writeups
CUSTOMMediumForensics

Новый сотрудник (New Employee)

XESXOR9/2/20265 min read
#forensics#custom#medium#caps_lock_state_machine#csrf_bypass#keyboard_scancode_mapping#usb_hid_decoding#linux

Новый сотрудник (New Employee)

Platform: hackerlab | Category: Forensics | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-06 | Status: Solved Techniques: caps_lock_state_machine, csrf_bypass, keyboard_scancode_mapping, usb_hid_decoding

Summary

Task: PCAP file with USB traffic from a sniffer planted on a new employee. Solution: Decode USB HID keyboard data to recover keystrokes, extract Pastebin URL and password, retrieve the flag from password-protected paste.

Новый сотрудник (New Employee) - HackerLab

Description

"Недавно у нас появился новый коллега, поэтому мы ему подкинули... сниффер. Посмотрим, что он делает в рабочее время :)"

"We recently got a new colleague, so we planted a... sniffer on him. Let's see what he does during work hours :)"

Files: new_worker_sniff.zip (contains New_worker_sniff.pcap, 17MB)

Analysis

1. Initial PCAP Analysis

bash
# Распаковка архива
unzip new_worker_sniff.zip

# Анализ иерархии протоколов
tshark -r New_worker_sniff.pcap -q -z io,phs

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Discovered:

  • USB traffic: 1240 frames
  • TCP/TLS traffic (encrypted)
  • DNS queries
  • QUIC traffic

2. USB HID Keyboard Identification

USB HID (Human Interface Device) keyboards transmit data in 8-byte format:

  • Byte 0: Modifiers (Shift, Ctrl, Alt)
  • Byte 1: Reserved
  • Bytes 2-7: Key codes (up to 6 simultaneous key presses)
bash
# Извлечение USB HID данных
tshark -r New_worker_sniff.pcap \
    -Y "usb.transfer_type == 0x01 && usb.data_len == 8" \
    -T fields -e usbhid.data

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Found 556 packets with keyboard data.

3. USB HID Keyboard Format

BytePurpose
0Modifiers: bit0=LCtrl, bit1=LShift, bit2=LAlt, bit5=RShift
1Reserved (always 0x00)
2-7Scan codes of pressed keys

Modifiers:

  • 0x02 = Left Shift
  • 0x20 = Right Shift
  • 0x01 = Left Ctrl
  • 0x04 = Left Alt

Solution

USB HID Keyboard Decoder

python
#!/usr/bin/env python3
"""
USB HID Keyboard Decoder for PCAP analysis
Decodes USB keyboard scan codes to readable text
"""
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

import subprocess
import sys

# USB HID Keyboard scan code mapping (US layout)
SCAN_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'),  # Tab
    0x2C: (' ', ' '),    # Space
    
    0x2D: ('-', '_'), 0x2E: ('=', '+'), 0x2F: ('[', '{'), 0x30: (']', '}'),
    0x31: ('\\', '|'), 0x33: (';', ':'), 0x34: ("'", '"'), 0x35: ('`', '~'),
    0x36: (',', '<'), 0x37: ('.', '>'), 0x38: ('/', '?'),
    
    0x39: ('[CAPSLOCK]', '[CAPSLOCK]'),
    
    # Function keys
    0x3A: ('[F1]', '[F1]'), 0x3B: ('[F2]', '[F2]'), 0x3C: ('[F3]', '[F3]'),
    0x3D: ('[F4]', '[F4]'), 0x3E: ('[F5]', '[F5]'), 0x3F: ('[F6]', '[F6]'),
    0x40: ('[F7]', '[F7]'), 0x41: ('[F8]', '[F8]'), 0x42: ('[F9]', '[F9]'),
    0x43: ('[F10]', '[F10]'), 0x44: ('[F11]', '[F11]'), 0x45: ('[F12]', '[F12]'),
    
    # Navigation
    0x4F: ('[RIGHT]', '[RIGHT]'), 0x50: ('[LEFT]', '[LEFT]'),
    0x51: ('[DOWN]', '[DOWN]'), 0x52: ('[UP]', '[UP]'),
}
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍


def extract_usb_hid_data(pcap_file):
    """Extract USB HID keyboard data from PCAP using tshark"""
    cmd = [
        'tshark', '-r', pcap_file,
        '-Y', 'usb.transfer_type == 0x01 && usb.data_len == 8',
        '-T', 'fields', '-e', 'usbhid.data'
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    return [line.strip() for line in result.stdout.strip().split('\n') if line.strip()]


def decode_keystrokes(hid_data_list):
    """Decode USB HID data to keystrokes with CAPS LOCK state tracking"""
    output = []
    caps_lock = False
    prev_keys = set()
    
    for hid_data in hid_data_list:
        try:
            data = bytes.fromhex(hid_data.replace(':', ''))
        except ValueError:
            continue
        
        if len(data) != 8:
            continue
        
        modifier = data[0]
        current_keys = set(data[2:8]) - {0}
        
        # Process only newly pressed keys
        new_keys = current_keys - prev_keys
        prev_keys = current_keys
        
        for key in new_keys:
            # Handle CAPS LOCK toggle
            if key == 0x39:
                caps_lock = not caps_lock
                continue
            
            if key not in SCAN_CODES:
                continue
            
            char_lower, char_upper = SCAN_CODES[key]
            
            # Determine if shift is active
            shift_pressed = (modifier & 0x22) != 0  # Left or Right Shift
            
            # For letters, CAPS LOCK inverts the shift behavior
            if char_lower.isalpha():
                use_upper = shift_pressed ^ caps_lock
            else:
                use_upper = shift_pressed
            
            output.append(char_upper if use_upper else char_lower)
    
    return ''.join(output)
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍


def main():
    if len(sys.argv) < 2:
        print("Usage: python3 usb_keyboard_decoder.py <pcap_file>")
        sys.exit(1)
    
    pcap_file = sys.argv[1]
    print(f"[*] Extracting USB HID data from {pcap_file}...")
    
    hid_data = extract_usb_hid_data(pcap_file)
    print(f"[*] Found {len(hid_data)} keyboard packets")
    
    decoded = decode_keystrokes(hid_data)
    print(f"\n[+] Decoded keystrokes:\n")
    print(decoded)


if __name__ == '__main__':
    main()

Decoding Result

telegram
where is secret note bro?
https://pastebin.com/BBNRNDDG
wHueguJM7P
Keychron 3v3

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Discovered:

  1. Search for "telegram"
  2. Question "where is secret note bro?"
  3. URL: https://pastebin.com/BBNRNDDG
  4. Password: wHueguJM7P
  5. Search for keyboard "Keychron 3v3"

Retrieving the Flag from Pastebin

Pastebin is password-protected. Using the discovered password:

bash
# Получаем CSRF токен
CSRF=$(curl -s -c cookies.txt https://pastebin.com/BBNRNDDG | \
    grep -oP 'name="_csrf-frontend" value="\K[^"]+')

# Отправляем пароль
curl -s -b cookies.txt -c cookies.txt \
    -X POST "https://pastebin.com/BBNRNDDG" \
    -d "_csrf-frontend=$CSRF&PostPasswordVerificationForm%5Bpassword%5D=wHueguJM7P" \
    | grep -oP 'CODEBY\{[^}]+\}'

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Pastebin content:

"Отличная работа, друг! Забирай флаг и отдыхай - CODEBY{REDACTED}."

USB HID Reference

Modifier Byte (Byte 0)

BitModifier
0Left Ctrl
1Left Shift
2Left Alt
3Left GUI (Win)
4Right Ctrl
5Right Shift
6Right Alt
7Right GUI

Common Scan Codes

CodeKeyCodeKey
0x04-0x1Da-z0x1E-0x271-0
0x28Enter0x2ABackspace
0x2CSpace0x39Caps Lock
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Lessons

  1. USB HID keyboard sniffing is a real security threat
  2. Hardware keyloggers can intercept all input
  3. It's important to account for CAPS LOCK state when decoding
  4. Passwords typed on keyboard can be fully recovered from USB traffic ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍