Sector Abyss
Klodd Instance
Payload submission happens over your isolated per-team Klodd TCP instance, not this web page.
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...