chall.py
#!/usr/bin/python3
import os
flag = open('flag.txt', 'r').read().strip().encode()
class XOR:
def __init__(self):
self.key = os.urandom(4)
def encrypt(self, data: bytes) -> bytes:
xored = b''
for i in range(len(data)):
xored += bytes([data[i] ^ self.key[i % len(self.key)]])
return xored
def decrypt(self, data: bytes) -> bytes:
return self.encrypt(data)
def main():
global flag
crypto = XOR()
print ('Flag:', crypto.encrypt(flag).hex())
if __name__ == '__main__':
main()
output.txt
Flag: 134af6e1297bc4a96f6a87fe046684e8047084ee046d84c5282dd7ef292dc9
밑의 chall.py 코드를 살펴보면
xored += bytes([data[i] ^ self.key[i % len(self.key)]])
len(self.key)는 os.urandom(4)로 작성했기 때문에 4로 항상 동일하다
따라서 self.key[i % len(self.key)]] 는 i가 4보다 작으면 i값 그대로 리턴해주고 4보다 크면 i-4를 리턴해준다
이때 self.key[]는 self.key[0], self.key[1], self.key[2], self.key[3] 이렇게 4개만 있다
-> 그래서 플래그 길이만큼 10진수 4개가 반복해서 플래그 인덱스 i와 xor되어서 이를 바이트로 차례대로 저장한다
그리고 이를 16진수로 바꾼게 제공받은 output.txt이다
플래그 중 일부분인 HTB{ 라는 플래그 형식을 알고있고 4글자라는 것을 이용해 self.key를 찾아낼 수 있다
output으로 제공받은 16진수에서 2글자 당 평문 글자 하나를 암호화한다
이를 이용해서 키를 구하는 코드를 작성해보면 다음과 같다
a = ['H', 'T', 'B', '{']
b = ['13', '4a', 'f6', 'e1']
key = []
for i in range(4):
a[i] = hex(ord(a[i]))[2:]
key.append(int(hex(int(a[i],16)^int(b[i], 16))[2:], 16))
print(key)
그럼 키는 [91, 30, 180, 154] 라는 것을 알 수 있다
이제 이 키를 이용해서 제공받은 16진수 플래그를 2글자씩 끊어서 xor해주면 평문인 플래그가 나올 것이다
sol.py
#a = ['H', 'T', 'B', '{']
#b = ['13', '4a', 'f6', 'e1']
#
#key = []
#for i in range(4):
# a[i] = hex(ord(a[i]))[2:]
# key.append(int(hex(int(a[i],16)^int(b[i], 16))[2:], 16))
#
#print(key)
key = [91, 30, 180, 154]
flag = '134af6e1297bc4a96f6a87fe046684e8047084ee046d84c5282dd7ef292dc9'
arr = []
for i in range(0, len(flag), 2):
arr.append(int(flag[i] + flag[i+1], 16))
msg = b""
for i in range(len(arr)):
msg += bytes([arr[i] ^ key[i % 4]])
print(msg)
'wargame > hack the box' 카테고리의 다른 글
HTB Lost Modulus writeup (0) | 2023.03.30 |
---|---|
HTB RSAisEasy writeup (0) | 2023.03.30 |
HTB BabyEncryption writeup (0) | 2022.10.23 |