🌊

[TryHackMe] W1seGuy-writeup

に公開
  • easy

pythonで書かれたソースコードが渡されています。

source.py
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")
    
    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)

flag1

ncatで ip 1337で接続すると暗号文が表示されます。
鍵を特定したらflagが貰えそうです。
鍵はランダムな英数字の62で5文字使用しています。

与えられているプログラムを見ると
setup関数flagTHM{xxxxxxx}形式だとわかります。
setup関数はXORでflagを暗号化し、その結果を16進数形式でエンコードする関数です。
なのでこれを複合する鍵を作成していきます

chatGPTすごい
import binascii
import string

def decode_hex_encoded(hex_encoded, key):
    xored_bytes = binascii.unhexlify(hex_encoded)
    return ''.join(chr(b ^ ord(key[i % len(key)])) for i, b in enumerate(xored_bytes))


def brute_force_optimized(hex_encoded):
    characters = string.ascii_letters + string.digits
    known_plaintext = "THM{"
    xored_bytes = binascii.unhexlify(hex_encoded)
    
    # 既知の平文 "THM{" を使って最初の4文字の鍵を推定
    partial_key = ''.join(chr(xored_bytes[i] ^ ord(known_plaintext[i])) for i in range(len(known_plaintext)))

    # 最後の1文字を総当たりで試す
    for char in characters:
        key = partial_key + char
        flag = decode_hex_encoded(hex_encoded, key)
        if flag.startswith("THM{") and flag.endswith("}"):
            print("Key found:", key)
            print("Decoded flag:", flag)
            return True
    return False
    
if __name__ == "__main__":
    hex_encoded = input().strip()

THM{p1alntExtAtt4ckcAnr3alLyhUrty0urxOr}

flag2

先ほど出力されたkeyを入力すると2つ目のflagが入手できます。

THM{BrUt3_ForC1nG_XOR_cAn_B3_FuN_nO?}

Discussion