-
[Clear] WACon CTF 2022 interspace WriteupCTF/WACon CTF 2022 2022. 6. 27. 21:49
주어진 소스파일을 분석해보자.
#!/usr/bin/env python3 import difflib import itertools import random import os import re import signal import string import time def bye(*args): print("Bye!") exit(1) signal.signal(signal.SIGALRM, bye) signal.alarm(5) STEPS = 10 FLAG = os.environ.get("FLAG", "WACon{fake-flag}") print("Flag distance calculator:") for i in range(STEPS): candidate = input("> ").strip() if candidate == FLAG: print("Congratulations!") exit(0) elif candidate: print(1 - difflib.SequenceMatcher(None, candidate, FLAG).ratio()) ##### ............................................................... (1) bye()
(1)의 내용이 함수인데, 유사도를 반환해주는 함수이다.(1-ratio 형식으로 반환해주길래 헷갈려서, 테스트 코드에서는 원래 ratio가 반환되도록 처리했다.)
즉, 유사도를 높혀가며 플래그를 추출해내면 된다.
하지만 단순히 BruteForce를 하기에는 경우의수가 너무 많아서 확률을 줄여보기로 하였다.
첫 번째로는 사용되는 문자들을 추출해보았다. 로컬에서 테스트해본결과 전혀 사용되지 않는 문자는 ratio가 0으로 나오기때문에, 출력가능한 문자를 하나씩 넣어보면서 ratio가 0이 아닌 문자들을 추출해보았다.
from pwn import * import base64 import binascii import sys import string from itertools import product, permutations p=remote("175.123.252.156", 9000) flagPrintable = string.printable[:94]+"zzzzzz" #print(flagPrintable) #print(len(flagPrintable)) realFlagPrintable = b'' c = 0 for i in range(len(flagPrintable)) :#0):#len(flagPrintable)) : p=remote("175.123.252.156", 9000) print(p.recv(1024)) for i in range(10) : i = c+i str = bytes(flagPrintable[i],"utf-8") print(str) #req = b"WAcon{" + str + b"}\n" p.send(str+b"\n") #req = b"WACon{" + b"interspace_is_made_of_"+b"tr"+str+b"_and_distance" + b"}\n" #print(req) #p.send(req) recv = float(p.recv(1024).split(b'\n')[0].decode('utf-8')) #recv = p.recv(1024) realRatio = 1-recv print(realRatio) if realRatio != 0.0 : realFlagPrintable += str #print(recv) c += 10 if c==100 : break p.close() print(realFlagPrintable) # acdefimnoprstACW_{}
위 코드의 실행 결과 사용되는 문자열의 종류을 알 수 있었다.
다음으로는 각 문자를 하나씩 개수를 늘려가며, 확률이 최대가 되는 지점을 찾아 각 문자가 몇번씩 사용되는지 파악해보았다.
예를들어 a문자를 WACon{a}, WACon{aa}, WACon{aaa} ... 처럼 입력해보았을 때, a가 4번 사용될때까지는 ratio가 증가하다가 a가 5번 사용되면 다시 ratio가 감소한다. 이런 케이스에서는 a가 4번 사용된다는 원리이다.
for i in range(len(realFlagPrintable)) :#0): #len(realFlagPrintable)) : #print(bytes(realFlagPrintable[i],"utf-8")) p=remote("175.123.252.156", 9000) print(p.recv(1024)) c = b'' #countArr = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] #ratioArr = [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] for j in range(10) : req = b"WAcon{" + c + b"}\n" p.send(req) recv = float(p.recv(1024).split(b'\n')[0].decode('utf-8')) realRatio = 1-recv if realRatio > ratioArr[i] : ratioArr[i] = realRatio countArr[i] = j print(realRatio) print(c) print("") c+=bytes(realFlagPrintable[i],"utf-8") p.close() print(countArr) # [4, 2, 2, 5, 1, 3, 1, 3, 1, 2, 2, 3, 2, 0, 0, 0, 6, 0, 0] // acdefimnoprstACW_{} // WACon{}
위 결과를 통해 얻은 내용을 정리하면, WACon{} 안에 들어갈 내용은 아래와 같다.
aaaaccddeeeeefiiimnnnopprrssstt______ //37자
위 내용까지 추출하고 문제 제목이 interspace임을 기반으로 해당 문자열이 포함되어있을 것이라고 생각하고, _가 6번 쓰이니 총 7단어가 나올것이라고 생각하고 게싱을 시작했다..
꽤 오랜 시간이 걸려서 결국 플래그를 획득했다.
FLAG : WACon{interspace_is_made_of_inter_and_space}
----------------------------------------------------------------------------------------------------------------------
ST4RT 팀에서는 총 두 팀으로 나눠서 이번 대회에 참가했는데, 다른 팀은 아래 아이디어로 문제를 해결했다고 한다.
위 방법으로 케이스를 줄여놓고 아래 아이디어를 적용시켰으면 보다 빠르게 플래그를 획득 할 수 있었을 것 같다.
반응형'CTF > WACon CTF 2022' 카테고리의 다른 글
[Study] WACon CTF 2022 Kuncɛlan Writeup (0) 2022.06.27