3.9 KiB
W1seGuy
This is a solver function for the W1seGuy
challenge of tryhackme.
We get the implementation of the server we can connect to through the downloaded file. A key is a random string of alphanumeric characters with a length of 5. We can take a look an see that there a key xored with the flag. To execute the xor function the key has to be at the length of the flag. This is achieved through the modulo over the length of the key. After the key has been xored the resulting bytestring is changed to a hex representation.
We need to find out the key to xor it with the result we are given by the server after we have been connected.
import random
import socketserver
import socket, os
import string
flag = open('flag.txt','r').read().strip()
def send_message(server, message):
enc = message.encode()
server.send(enc)
def setup(server, key):
flag = 'THM{thisisafakeflag}'
xored = ""
for i in range(0,len(flag)):
xored += chr(ord(flag[i]) ^ ord(key[i%len(key)]))
hex_encoded = xored.encode().hex()
return hex_encoded
def start(server):
res = ''.join(random.choices(string.ascii_letters + string.digits, k=5))
key = str(res)
hex_encoded = setup(server, key)
send_message(server, "This XOR encoded text has flag 1: " + hex_encoded + "\n")
print(hex_encoded)
send_message(server,"What is the encryption key? ")
key_answer = server.recv(4096).decode().strip()
try:
if key_answer == key:
send_message(server, "Congrats! That is the correct key! Here is flag 2: " + flag + "\n")
server.close()
else:
send_message(server, 'Close but no cigar' + "\n")
server.close()
except:
send_message(server, "Something went wrong. Please try again. :)\n")
server.close()
class RequestHandler(socketserver.BaseRequestHandler):
def handle(self):
start(self.request)
if __name__ == '__main__':
socketserver.ThreadingTCPServer.allow_reuse_address = True
server = socketserver.ThreadingTCPServer(('0.0.0.0', 1337), RequestHandler)
server.serve_forever()
Solution
We need 5 characters to rebuild the key and solve the flag.
We know the flag starts with the chars THM{
and ends with }
, in total 5
characters.
That is enough information. We connect to the server, get the hexed and xored
flag. It is reversed to its bytestring representation and xored with a random
key. When the string THM{
is found we've got 4 out of 5 characters of the
key. The fifth is found through iterating the alphanumeric string and xoring
the key with the flag again.
import sys
from pwn import *
import binascii
import string
import random
def solve():
p = remote(sys.argv[1], 1337)
r = p.recv().strip().split()
p.recv()
alpha = string.ascii_letters + string.digits
hex_encoded = r[7].decode()
print(f"Got flag 1: {hex_encoded}")
hex_decoded = binascii.unhexlify(hex_encoded).decode()
print(f"Unhexed Key is: {hex_decoded} with a length of {len(hex_decoded)}")
while True:
_res = ''
_key = str(''.join(random.choices(alpha, k=5)))
_key = _key * (len(hex_decoded) // 5 )
for i in range(0, len(hex_decoded)):
_res += chr(ord(hex_decoded[i]) ^ ord(_key[i%len(_key)]))
if _res.startswith("THM{"):
for char in alpha:
res = ''
key = _key[:4] + char
key = key * (len(hex_decoded) // 5)
for i in range(0, len(hex_decoded)):
res += chr(ord(hex_decoded[i]) ^ ord(key[i%len(key)]))
if res.endswith('}'):
print("Flag 1: " + res)
print("Key: " + key[:5])
p.send(key[:5].encode())
print(p.recv().decode())
return
if __name__ == "__main__":
solve()