123 lines
3.9 KiB
Markdown
123 lines
3.9 KiB
Markdown
# W1seGuy
|
|
|
|
This is a solver function for the `W1seGuy` challenge of [tryhackme](https://tryhackme.com/r/room/w1seguy).
|
|
|
|
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.
|
|
|
|
```python
|
|
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.
|
|
|
|
```python
|
|
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()
|
|
```
|