Skip to main content

W1seGuy

A writeup for the room W1seGuy on TryHackMe.

A w1se guy 0nce said, the answer is usually as plain as day.

Get those flags!

Analyzing the code

The code provided in the room executes a simple encryption algorithm.

A first flag is read from an external file and then encrypted using a key. The operation is performed by XORing between the flag and the key, repeating the key if it is shorter than the flag.

The encoded flag is then printed in hexadecimal format. This means that each byte of the flag is represented by two hexadecimal characters.

The machine then asks for the key and, if it is correct, returns a second flag.

Exploiting the bad encryption

The key is 5 characters long, as can be seen in the code due to the k=5 parameter.

The flag on the other hand is 40 characters long, because the encoded flag is 80 hexadecimal characters long.

The first four characters of the plaintext are known as 'THM{'. These can be used to retrieve the first four characters of the key by XORing them with the encoded flag.

The XOR operation is commutative and reversible, so x = y ^ z is equivalent to y = x ^ z.

Since the length of the key is a perfect divisor of the length of the flag, the last character of the key is also known as the last character of the flag '}'.

The final script

The following script can be used to retrieve the key and the final flag:

from pwn import remote

conn = remote("10.10.226.191", 1337)

conn.recvuntil(b"flag 1: ")

# The given flag is encrypted and encoded in hex
flag1_encoded = conn.recvline().decode().strip()

# First we decode the flag from hex
flag1_decoded = bytes.fromhex(flag1_encoded).decode()

# Find the key by exploiting known characters in the flag
key = ""
key += chr(ord(flag1_decoded[0]) ^ ord("T"))
key += chr(ord(flag1_decoded[1]) ^ ord("H"))
key += chr(ord(flag1_decoded[2]) ^ ord("M"))
key += chr(ord(flag1_decoded[3]) ^ ord("{"))
key += chr(ord(flag1_decoded[-1]) ^ ord("}"))

# Decrypt the flag with the key found
flag1 = ""
for j, f in enumerate(flag1_decoded):
flag1 += chr(ord(f) ^ ord(key[j % 5]))

print(f"Flag 1: {flag1}...")

# Send the correct key to get the second flag
conn.sendlineafter(b"What is the encryption key? ", key.encode())
conn.recvuntil(b"flag 2: ")
flag2 = conn.recvline().decode().strip()

print(f"Flag 2: {flag2}...")

conn.close()