CTF & Wargame(REVERSING)

[dreamhack] level1 Recover

KWAKBUMJUN 2025. 3. 6. 18:56

바이너리를 실행해보니 "fopen() error"라는 문구만 출력된다. ida로 확인해봐야할 것 같다.

 

문제를 읽어보니, flag.png 파일에 flag가 들어있고 해당 파일을 암호화한 파일인 encrypted 파일을 복호화하여 flag.png로 복구시켜야 하는 문제 같다. 

 

IDA 분석

main 함수 디컴파일 코드

flag.png 열음

실패하면 fopen() error 출력

 

encrypted 파일 열음

실패하면 fopen() error 출력

 

flag.png를 성공적으로 읽었다면 

ptr ^= v6[v5 % 4];

ptr += 19;

fwrite(&ptr, 1uLL, 1uLL, s);
++v5;

연산을 수행하여 flag.png를 암호화하고 encrypted 파일에 암호화함

 

문제 해결 방안

<핵심 연산>

v5 = 0;

while ( fread(&ptr, 1uLL, 1uLL, stream) == 1 )
  {
    ptr ^= v6[v5 % 4];
    ptr += 19;
    fwrite(&ptr, 1uLL, 1uLL, s);
    ++v5;
  }

encrypted 파일을 복호화하고 flag.png에 저장

또한 복호화를 위해선 v6의 값을 찾아야 한다. 

v6 = [0xDE, 0xAD, 0xBE, 0xEF]

위의 값은 ida에서 찾을 수 있다.

복호화 코드

def decrypt_file():
    v6 = [0xDE, 0xAD, 0xBE, 0xEF]

    try:
        # 암호화된 파일 열기
        with open("encrypted", "rb") as encrypted_file:
            # 원본 파일로 저장할 파일 열기
            with open("decrypted_flag1.png", "wb") as decrypted_file:
                v5 = 0  # 인덱스 카운터

                # 파일의 각 바이트 읽기
                byte = encrypted_file.read(1)
                while byte:
                    # 바이트를 정수로 변환
                    encrypted_byte = ord(byte)

                    # 복호화: 19를 빼고 v6[v5 % 4]와 XOR
                    decrypted_byte = (encrypted_byte - 19) & 0xFF  # 언더플로우 방지
                    decrypted_byte ^= v6[v5 % 4]

                    # 복호화된 바이트 쓰기
                    decrypted_file.write(bytes([decrypted_byte]))

                    # 다음 바이트 읽기
                    byte = encrypted_file.read(1)
                    v5 += 1

        print("복호화 완료! decrypted_flag1.png 파일을 확인하세요.")

    except Exception as e:
        print(f"오류 발생: {e}")

if __name__ == "__main__":
    # 키를 자동으로 찾고 복호화
    decrypt_file()