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()
|
||
|
```
|