암호(수학) 등.. 공부한 거 잊을거 같아서 만든 블로그

Play Nice 본문

picoCTF

Play Nice

h34hg0 2022. 6. 22. 22:29

문제


Play Nice

모든 고대 암호들이 그렇게 나쁜 것은 아니었다... 플래그가 표준 형식이 아닙니다. nc mercury.picoctf.net 30568 playfair.py


풀이


문제를 풀기에 앞서, 이 문제는 플레이 페어 암호화 방식을 사용한다 다음 링크를 참고하기 바란다.

문제에서 준 파일인 playfair.py의 코드는 다음과 같다

 

#!/usr/bin/python3 -u
import signal

SQUARE_SIZE = 6


def generate_square(alphabet):
	assert len(alphabet) == pow(SQUARE_SIZE, 2)
	matrix = []
	for i, letter in enumerate(alphabet):
		if i % SQUARE_SIZE == 0:
			row = []
		row.append(letter)
		if i % SQUARE_SIZE == (SQUARE_SIZE - 1):
			matrix.append(row)
	return matrix

def get_index(letter, matrix):
	for row in range(SQUARE_SIZE):
		for col in range(SQUARE_SIZE):
			if matrix[row][col] == letter:
				return (row, col)
	print("letter not found in matrix.")
	exit()

def encrypt_pair(pair, matrix):
	p1 = get_index(pair[0], matrix)
	p2 = get_index(pair[1], matrix)

	if p1[0] == p2[0]:
		return matrix[p1[0]][(p1[1] + 1)  % SQUARE_SIZE] + matrix[p2[0]][(p2[1] + 1)  % SQUARE_SIZE]
	elif p1[1] == p2[1]:
		return matrix[(p1[0] + 1)  % SQUARE_SIZE][p1[1]] + matrix[(p2[0] + 1)  % SQUARE_SIZE][p2[1]]
	else:
		return matrix[p1[0]][p2[1]] + matrix[p2[0]][p1[1]]

def encrypt_string(s, matrix):
	result = ""
	if len(s) % 2 == 0:
		plain = s
	else:
		plain = s + "0fkdwu6rp8zvsnlj3iytxmeh72ca9bg5o41q"[0]
	for i in range(0, len(plain), 2):
		result += encrypt_pair(plain[i:i + 2], matrix)
	return result

alphabet = open("key").read().rstrip()
m = generate_square(alphabet)
msg = open("msg").read().rstrip()
enc_msg = encrypt_string(msg, m)
print("Here is the alphabet: {}\nHere is the encrypted message: {}".format(alphabet, enc_msg))
signal.alarm(18)
resp = input("What is the plaintext message? ").rstrip()
if resp and resp == msg:
	print("Congratulations! Here's the flag: {}".format(open("flag").read()))

# https://en.wikipedia.org/wiki/Playfair_cipher

 

 

키 테이블로 6x6행렬을 사용하는 것 외에는 플레이페어와 동일한 암호화 방식을 가진다.

 

nc mercury.picoctf.net 30568

연결을 해보면 두 문자열을 준다. 여기서 alphabet 문자열이 키테이블에 사용될 문자열이다.

 

key = "0fkdwu6rp8zvsnlj3iytxmeh72ca9bg5o41q"
m = "herfayo7oqxrz7jwxx15ie20p40u1i"

SQUARE_SIZE = 6

def get_index(letter, matrix):
	for row in range(SQUARE_SIZE):
		for col in range(SQUARE_SIZE):
			if matrix[row][col] == letter:
				return (row, col)
	print("letter not found in matrix.")
	exit()

def generate_square(alphabet):
	assert len(alphabet) == pow(SQUARE_SIZE, 2)
	matrix = []
	for i, letter in enumerate(alphabet):
		if i % SQUARE_SIZE == 0:
			row = []
		row.append(letter)
		if i % SQUARE_SIZE == (SQUARE_SIZE - 1):
			matrix.append(row)
	return matrix

def decrypt_pair(pair, matrix):
	p1 = get_index(pair[0], matrix)
	p2 = get_index(pair[1], matrix)

	if p1[0] == p2[0]:
		return matrix[p1[0]][(p1[1] - 1)  % SQUARE_SIZE] + matrix[p2[0]][(p2[1] - 1)  % SQUARE_SIZE]
	elif p1[1] == p2[1]:
		return matrix[(p1[0] - 1)  % SQUARE_SIZE][p1[1]] + matrix[(p2[0] - 1)  % SQUARE_SIZE][p2[1]]
	else:
		return matrix[p1[0]][p2[1]] + matrix[p2[0]][p1[1]]

def encrypt_string(s, matrix):
	result = ""
	if len(s) % 2 == 0:
		plain = s
	else:
		plain = s + "0fkdwu6rp8zvsnlj3iytxmeh72ca9bg5o41q"[0]
	for i in range(0, len(plain), 2):
		result += decrypt_pair(plain[i:i + 2], matrix)
	return result

matrix = generate_square(key)
flag = encrypt_string(m, matrix)
print(flag)

 

문제에서 제공한 코드를 약간의 변형을 거쳐서 복호화를 할 수 있도록 만들었다.

 

def decrypt_pair(pair, matrix):
	p1 = get_index(pair[0], matrix)
	p2 = get_index(pair[1], matrix)

	if p1[0] == p2[0]:
		return matrix[p1[0]][(p1[1] - 1)  % SQUARE_SIZE] + matrix[p2[0]][(p2[1] - 1)  % SQUARE_SIZE]
	elif p1[1] == p2[1]:
		return matrix[(p1[0] - 1)  % SQUARE_SIZE][p1[1]] + matrix[(p2[0] - 1)  % SQUARE_SIZE][p2[1]]
	else:
		return matrix[p1[0]][p2[1]] + matrix[p2[0]][p1[1]]

크게 바뀐 것은 없고, encrypto_pair 함수를 decrypto_pair 로 이름을 바꾸고 기존에 p[1] + 1 꼴로 된 부분을 p[1] - 1로 변경해서 암호화 하기 전의 위치로 돌아가게 바꿔줬다.

 

flag

프로그램을 실행해서 나온 문자열을 입력함으로 플래그가 007d0a696aaad7fb5ec21c7698e4f754 임을 알 수 있다..


 

'picoCTF' 카테고리의 다른 글

No Padding, No Problem  (0) 2022.06.22
Magikarp Ground Mission  (0) 2022.06.12
Tab, Tab, Attack  (0) 2022.06.12
Static ain't always noise  (0) 2022.06.12
Nice netcat...  (0) 2022.06.12