Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- cryptography
- Cube Root Attack
- OverTheWire Bandit Level 1 → Level 2
- Montgomery Reduction
- rao
- 시스템해킹
- redirect
- arp
- shellcode
- dns
- 웹해킹
- CSRF
- 드림핵
- return address overflow
- overthewire
- pycrpytodome
- Franklin-Reiter Related Message Attack
- spoofing
- weak key
- Crypto
- Bandit Level 1 → Level 2
- RSA
- 암호학
- RSA Common Modulas Attack
- AES
- XSS
- Hastad
- picoCTF
- bandit
- dreamhack
Archives
- Today
- Total
암호(수학) 등.. 공부한 거 잊을거 같아서 만든 블로그
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행렬을 사용하는 것 외에는 플레이페어와 동일한 암호화 방식을 가진다.
연결을 해보면 두 문자열을 준다. 여기서 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로 변경해서 암호화 하기 전의 위치로 돌아가게 바꿔줬다.
프로그램을 실행해서 나온 문자열을 입력함으로 플래그가 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 |