omni-koth

Sector Abyss

current tick 0 next tick --s next rCTF sync -- ticks

Klodd Instance

Payload submission happens over your isolated per-team Klodd TCP instance, not this web page.

Launch Instance

After Klodd starts your instance, connect with the host and port shown there:

nc <team-instance-host> <team-instance-port>

The service asks for your team id and KOTH token from your rCTF profile, then opens the challenge menu.


Your State

Rules

# Sector Abyss

Write the shortest possible 16-bit x86 real-mode bootsector that extracts an ABYSSFS message from a hostile virtual disk.

## Submission Format

Submit raw hex machine code only.

Assembly source, NASM/GAS syntax, ELF/COM files, `0x` prefixes, objdump output, and shell commands are not accepted. Whitespace between hex bytes is allowed.

Maximum counted payload length: 510 bytes.

The validator pads sector 0 with zeroes and appends `55 aa` at bytes 510-511 automatically. Padding and the automatic boot signature do not count toward your payload length.

## Boot Environment

Payload bytes are loaded at physical address `0x7c00`.

Initial state:

```txt
CS:IP = 0000:7c00
DS = ES = SS = 0000
SP = 7000
DL = 80
AX = BX = CX = SI = DI = BP = 0000
Direction flag clear
```

The emulator is deterministic. It exposes RAM, registers, an emulated read-only disk, INT 10h output, INT 13h sector reads, and a cycle/instruction counter.

Unsupported opcodes fail closed.

## Memory Map

```txt
00000-005ff  emulator low memory
06000-07bff  stack/scratch-safe area
07c00-07dff  submitted bootsector
08000-9ffff  scratch RAM
b8000-b8f9f  VGA text memory
```

Memory accesses must stay inside the 1 MiB real-mode address space. The virtual disk is read-only.

## Output

Accepted output methods:

```txt
INT 10h AH=0Eh teletype, character in AL
Direct writes to VGA text memory at B800:0000
```

The captured output must exactly match the expected message for every disk variant.

After output, the payload must execute `HLT` or enter a recognized safe idle loop such as `jmp $`.

## Disk Input

Use emulated INT 13h sector reads:

```txt
AH = 02h
AL = sector count
CH = cylinder
CL = sector number, 1-based
DH = head
DL = drive, initialized to 80h
ES:BX = destination buffer
```

The challenge disk uses a simple geometry:

```txt
1 head
64 sectors per track
LBA = CH * 64 + DH * 64 + (CL & 3f) - 1
```

Reads outside the virtual disk, too many reads, or writes past memory bounds are rejected.

## ABYSSFS Layout

```txt
sector 0  submitted bootsector
sector 1  decoy header
sector 2  ABYSSFS superblock
sector 3  pointer table
sector 4+ real fragments, fake fragments, decoys, checksum blocks, and noise
```

Superblock at sector 2:

```txt
00..05  magic "ABYSSF"
06      version, currently 01
07      fragment count
08..09  index seed, little endian
0a      checksum seed
0b      transform flags
0c      pointer table start sector
0d      decoy density
0e      final output length
0f      first pointer index
10      total sector count
11      sectors per track, currently 64
12      message seed
```

Pointer entries are 8 bytes each and start at the pointer table sector:

```txt
00..01  sector number XOR index_seed, little endian
02      fragment length
03      fragment order
04      checksum nibble
05      transform selector
06      next pointer index, ff terminates
07      salt/noise
```

Entries are not stored in message order. Start at `first_pointer_index` and follow `next pointer index`.

## Decoding

For each fragment byte, use the global output byte index `i`, the superblock `message_seed`, and the entry `transform_selector`.

```txt
raw = fragment_byte
rot = (i + message_seed + transform_selector) & 7
x = ror8(raw, rot)
x = x XOR ((message_seed + i * 17 + transform_selector * 29) & ff)
plain[i] = (x - previous_plain_byte) & ff
previous_plain_byte = plain[i]
```

Checksum nibble:

```txt
checksum = checksum_seed + order * 17 + transform_selector * 31
checksum = checksum + every encoded fragment byte
checksum_nibble = ((checksum >> 4) XOR checksum) & 0f
```

You do not have to print checksum data, but a correct parser can use it to reject decoys.

## Public Disk

Public variant:

```txt
seed = a8a5
expected output = OMNI{ABYSSFS_PUBLIC}
```

Hidden variants use the same ABYSSFS format with different seeds, layouts, fragment orders, decoys, and expected outputs.

Hardcoded sector offsets will not pass.

## Validation Limits

```txt
max payload bytes: 510
max instructions: 80000
max cycles: 220000
max disk reads: 96
max sectors read: 128
max output bytes: 160
```

## Ranking

Valid submissions are ranked by:

```txt
1. shortest decoded machine-code payload length
2. fewest total cycles across validation disks
3. fewest total sectors read
4. lowest measured memory write high-water mark
5. earliest valid submission time
6. validator runtime as final platform tie-breaker
```

The platform encodes this tuple into one numeric rank value so it can use the existing KOTH tick scorer.

## Security Model

Submitted code is never executed natively. The validator does not run NASM, GAS, objdump, QEMU, shell commands, or host tooling on player input.

Player code runs only inside the deterministic TypeScript emulator. It has no filesystem, network, environment variable, or syscall access.

## Example Invalid Submissions

```txt
mov ah, 0x0e        # assembly source, rejected
0xB40E             # 0x prefixes, rejected
zzzz               # invalid hex, rejected
b40ecd10f4         # prints the wrong output, rejected
```

Your State

Enter a team id to load your current state.

Live Leaderboard

Loading...