- 공유 링크 만들기
- X
- 이메일
- 기타 앱
파일 링크
https://github.com/ctfs/write-ups-2015/tree/master/volgactf-quals-2015/stego/captcha
파일을 다운로드 받으면 'i' 라는 png 파일이 달랑 하나가 있다.
png 파일을 헥스에디터로 확인해보면 다른 png 파일들이 존재하는 것을 알 수 있다.
모든 png 파일을 꺼낸 후 꺼낸 순서대로 차례대로 적혀있는 글자를 이어주면 base64 인코딩 된 값임을 알 수 있다.
직접 그림에 있는 글자를 인식하지 않아도 글자가 적혀있는 png파일에 대한 해쉬값을 이용해서 같은 해쉬값끼리 똑같은 문자로 인식시켜주면 된다.
import md5 import base64 def GetMD5(fileName) : f = open(fileName, "rb") data = f.read() result = md5.md5(data).hexdigest() f.close() return result pngHeader = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A" pngDataList = [] f = open("captcha.png", "rb") data = f.read() f.close() findIdx = data.rfind(pngHeader) while findIdx != -1 : pngDataList.append(data[findIdx:]) data = data[:findIdx] findIdx = data.rfind(pngHeader) pngDataList = pngDataList[::-1] # extract files for i, item in enumerate(pngDataList) : f = open(str(i + 1) + ".png", "wb") f.write(item) f.close() # setting png MD5 hash m = {} m[GetMD5("62.png")] = "Q" m[GetMD5("17.png")] = "S" m[GetMD5("80.png")] = "8" m[GetMD5("4.png")] = "O" m[GetMD5("9.png")] = "G" m[GetMD5("31.png")] = "C" m[GetMD5("166.png")] = "3" m[GetMD5("61.png")] = "6" m[GetMD5("50.png")] = "X" m[GetMD5("177.png")] = "9" m[GetMD5("10.png")] = "g" m[GetMD5("58.png")] = "s" m[GetMD5("124.png")] = "e" m[GetMD5("437.png")] = "2" m[GetMD5("76.png")] = "x" m[GetMD5("386.png")] = "5" m[GetMD5("139.png")] = "W" m[GetMD5("172.png")] = "a" m[GetMD5("12.png")] = "A" m[GetMD5("60.png")] = "c" m[GetMD5("11.png")] = "o" m[GetMD5("2.png")] = "V" m[GetMD5("7.png")] = "0" m[GetMD5("425.png")] = "p" m[GetMD5("42.png")] = "d" m[GetMD5("44.png")] = "b" m[GetMD5("3.png")] = "B" m[GetMD5("32.png")] = "D" m[GetMD5("109.png")] = "q" m[GetMD5("6.png")] = "w" m[GetMD5("81.png")] = "Y" m[GetMD5("506.png")] = "y" m[GetMD5("8.png")] = "K" m[GetMD5("92.png")] = "Z" m[GetMD5("5.png")] = "R" m[GetMD5("59.png")] = "4" m[GetMD5("41.png")] = "7" m[GetMD5("79.png")] = "v" m[GetMD5("178.png")] = "P" m[GetMD5("43.png")] = "M" m[GetMD5("170.png")] = "k" m[GetMD5("379.png")] = "z" m[GetMD5("16.png")] = "N" m[GetMD5("162.png")] = "m" m[GetMD5("18.png")] = "U" m[GetMD5("88.png")] = "J" m[GetMD5("19.png")] = "h" m[GetMD5("116.png")] = "f" m[GetMD5("373.png")] = "/" m[GetMD5("484.png")] = "u" m[GetMD5("68.png")] = "n" m[GetMD5("128.png")] = "t" m[GetMD5("20.png")] = "E" m[GetMD5("57.png")] = "r" m[GetMD5("71.png")] = "1" m[GetMD5("77.png")] = "j" m[GetMD5("143.png")] = "+" m[GetMD5("641.png")] = "F" m[GetMD5("146.png")] = "T" m[GetMD5("122.png")] = "H" m[GetMD5("1.png")] = "i" m[GetMD5("1892.png")] = "=" m[GetMD5("461.png")] = "L" m[GetMD5("35.png")] = "I" # i -> I m[GetMD5("371.png")] = "l" # l -> L # make string from files result = "" for pngData in pngDataList : result += m[md5.md5(pngData).hexdigest()] f = open("result.png", "wb") f.write(base64.decodestring(result)) f.close()
댓글
댓글 쓰기