본문 바로가기

Dreamhack/CryptoPS

[Dreamhack][CryptoPS] [GCHD2022] 암호의 기초1

728x90

1.문제 분석

  • xor연산으로 암호화된 문장 복호화
  • key를 먼저 찾아야 하는 문제

2. 기본 아이디어

  1. 키의 길이와 플래그의 형식의 길이가 일치한다. length(apollob) = 7
  2. 아스키값의 무차별 대입으로 key를 구할 수 있다.
  3. key를 통해 FLAG를 구할 수 있다.

3.문제 풀이

 

이 문제는 flag가 들어있는 enc 파일과 prob.py 파일이 주어진다.

 

prob.py 파일은 다음과 같다.

 

key="???????"

flag="apollob{??????????????????????????????????}"

def encrypt(plain):
    res=""
    for _ in range(len(plain)):
        res+=chr(ord(key[_%7])^ord(plain[_]))
    return res

open("enc","wb").write(encrypt(flag).encode("base64")

 

우선 위 파일에서 알 수 있는 사실은

 

key의 길이가 7이라는 것이다. 단순히 ?의 개수로도 볼 수 있지만,

 

key의 인덱스를 7로 나눠준다는 점에서 확실히 알 수 있다.

 

또한 결과 값을 base64로 인코딩해서 enc파일에 넣어준 것을 볼 수 있다.

 

flag는 다음과 같다.

 

flag

 

이 문제를 풀기 위해서는 다음과 같은 단계를 진행하면 된다.

 

[1]. flag를 base64 디코딩 해준다.

[2]. flag의 형식은 apollob{??????????????????}이다.

[3]. 그렇다면 사이즈가 7인 Key를 통해 apollob 또한 다른 문자로 암호화 될 것이다.

[4]. ASCII(0~127)중 하나씩 대입해본다.

[5]. keys[0~6] ^ apollob = flag[0~6]임을 만족하는 key들을 찾는다.

 

이제 익스플로잇 코드를 짜보자.

 

import base64
import string

flag = open("enc", "rb").readline()

base = base64.b64decode(flag)
print(base)

flag = base.decode("ascii")
key = "???????"

def encrypt(plain):
    res=""
    for _ in range(len(plain)):
        res+=chr(ord(key[_%7])^ord(plain[_]))
    return res

plain = "apollob"
lst = list()

#flag key[0] ^ plain(a) = flag[0]
for i in range(len(plain)):
    for j in range(128):
         if j ^ ord(flag[i]) == ord(plain[i]):
             lst.append(chr(j))

def decrypt(enc):
    res =""
    for _ in range(len(enc)):
        res += chr(ord(lst[_%7])^ord(enc[_]))
    return res

print(decrypt(flag))

 

위 코드를 해석하자면

 

ascii 형태로 복호화된 base64 flag값을 ascii값과 xor 연산해 plain값의 ascii와 비교해서,

 

일치한다면 list에 추가해준다.

 

만들어진 key값을 통해 decrypt함수에 넣어 결과를 출력해주면 된다.

 

flag

728x90