자료를 다운로드 받으면 다음의 사진을 얻을 수 있다.

머리식히는 문제다 그림판으로 열어서 hxD의 빈공간을 페인트로 칠해보자

사진을 열면 다음과 같은 자료를 얻을 수 있다.

사진에 특별한점은 안보이니 hxD를 사용하여 열어보자 가장 하단에 .zip의 시그니처가 숨어있는 것을 알 수 있다.

zip파일을 열면 usethis라는 파일을 구할 수 있다. 그안에는 소스포지로 연결되어 steghide.exe를 사용하라는 툴 링크를 받을 수 있다. 툴을 사용하여 key를 뽑으려고하면 passphrase를 요구하는데, 아까전 사진의 마지막 문자열 Delta_Forace\m/을 기억하여 extract 하자

자료를 다운로드 받은면 다음과 같은 빈 사진을 얻을 수 있다.

사진을 HxD로 얻으면 다음과 같이 여러개의 사진이 합쳐져있음을 알 수 있다..

사진속에 숨겨진건 bmp, gif, png, jpg 4가지 종류이다. 시그니처와 푸터를 이용해서 다음의 코드로 추출했다.

def search_next(value:list) -> tuple :
    res = float('inf')
    for v in value:
        if(v==-1) :
            continue
        elif(v<res) :
            res=v
    return (res,value.index(res))

def search_bmp_next(value:list) -> tuple :
    res = value[3]
    new_value = value[:3]
    end,t = search_next(new_value)
    return (res,end,t)
        

if __name__=="__main__" :

    target_file = "MrFusion.gif"

    ext = [".jpg",".png",".gif",".bmp"]
    start = [b"\xff\xd8",b'\x89PNG',b'GIF89',b'\x42\x4D']
    end = [b"\xff\xd9",b'IEND\xaeB`\x82',b'\x00;']

    target_list = list()
    
    with open(target_file,"rb") as f:
        data = f.read()

    s_index=0
    cnt=1

    new_data = data
    
    while(True) :

        new_data = new_data[s_index:]
        
        tar_start = [-1]*len(ext)
        for i in range(len(start)) :
            tar_start[i] = new_data.find(start[i])
            
        if(max(tar_start)==-1) :
             break

        start_index,tar_type = search_next(tar_start)

        if(tar_type==3) :
            tmp_data=new_data
            
            tmp_start = [-1]*len(ext)
            for i in range(len(start)) :
                tmp_start[i] = tmp_data.find(start[i])
                    
            tmp_start_index,end_index,tmp_tar_type = search_bmp_next(tmp_start)
        else :
            end_index=new_data.find(end[tar_type])+len(end[tar_type])

        print(start_index,end_index)
        with open("./target/"+str(cnt)+ext[tar_type],"wb") as f:
            f.write(new_data[start_index:end_index]) 
            
        cnt+=1
        s_index=end_index
        
    print(str(cnt-1)+" extracted")

다만 중간에 5번째 gif가 시그니처를 2번만났는지 직접 추출했다. 

Key를 얻을 수 있었다.

사진을 다운로드 받아보면 block-hole이 보인다. 

문제의 포멧은 base64다. 그러므로 base64형식으로 인코딩된 문자열이 있는지 먼저 string을 통해서 탐색해 보았다. 

위쪽 base64값처럼 보이는 것이 있다. "UQklUQ1RGe1M1IDAwMTQrODF9" 이 값 말이다. 

다만 이값은 base64로 정상적으로 decoding되지 않았다. 누가봐도 base64 인코딩같은데... 잠시 문제로 돌아오자.

문제는 BITCTF{로 시작하는 문자열이 base64인코딩되어잇다고 한다. base64는 해시와 다르게 비슷한 문자열을 인코딩했을때 패턴이 나온다.

이와 같이 말이다. 그러므로 BITCTF{를 인코딩한 값과 유사한 값을 찾으면 될 것이다. 

아; 찾을 것도 없이 우리가 찾은 문자열의 맨 앞 U는 그냥 헥스문자였나보다 Decoding 하자

아싸

자료를 다운로드 받으면 깨진 QR Code를 얻을 수 있다.

포토샵으로 살짜쿵 복원해주자

완벽하다. 반전까지 시켰다. 이제 QR Code를 읽으면

완벽하다

 

사진을 다운로드 받아보면 머리잔이 있다.

진짜 머리잔이다ㅋㅋㅋ 뒤에 보면 이상한 패턴이 있다.

반복되는 것을 검정 1로 투명0으로 해석해보자

1010011

0110100

1001110

1000011

1001000

0110000

이렇게 된다. 이를 문자열로 변환해보자

a=["1010011",
"0110100",
"1001110",
"1000011",
"1001000",
"0110000"]

for v in a :
    print(chr(int(v,2)),end="")

출력은 다음과 같다.

 

오! 산초! Key의 format은 md5라고 하였으니, 이를 md5화하자

a=["1010011",
"0110100",
"1001110",
"1000011",
"1001000",
"0110000"]

for v in a :
    print(chr(int(v,2)),end="")

val = b"S4NCH0"
import hashlib
print("")
print("key : "+hashlib.md5(val).hexdigest())

완벽하다

 

+ Recent posts