Solution de bluesheet pour Serial Keyler

reverse linux x86/x64 keygenme

17 novembre 2023

Table des matières

Serial Keyler

50 points

Enoncé

On vous demande d’écrire un générateur d’entrées valides pour ce binaire, puis de le valider sur les entrées fournies par le service distant afin d’obtenir le flag.

Ma solution

J’utilise Ghidra pour le reverse. Le reverse est assez direct (modulo les erreurs de décompilation de Ghidra, facilement repérables et compréhensibles). On y voit une boucle, qui parcourt l’input dans le sens inverse, et qui réalise un XOR avec 0x1f.

C’est donc là notre keygen : Il prend le nom, le retourne, et XOR chaque caractère avec 0x1f.

Encore une fois on réalise un script Python pour automatiser la partie réseau, et on obtient le flag au bout de 55 tours.

# nom à l'envers XOR 1f

import socket

def generateKey(nom):
    ret = nom[::-1]
    ret = [chr(x ^ 0x1f) for x in ret]
    ret = "".join(ret)
    return ret.encode()

class Netcat:

    """ Python 'netcat like' module """

    def __init__(self, ip, port):

        self.buff = b""
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((ip, port))

    def read(self, length = 1024):

        """ Read 1024 bytes off the socket """

        return self.socket.recv(length)

    def read_until(self, data):

        """ Read data into the buffer until we have data """

        while not data in self.buff:
            self.buff += self.socket.recv(1024)

        pos = self.buff.find(data)
        rval = self.buff[:pos + len(data)]
        self.buff = self.buff[pos + len(data):]

        return rval

    def write(self, data):

        self.socket.send(data)

    def close(self):

        self.socket.close()

nc = Netcat('challenges2.france-cybersecurity-challenge.fr', 3001)

for i in range(55):
    name = nc.read_until(b'\n')
    name = name.split(b': ')[-1][:-1]
    print(name)
    key = generateKey(name)
    print(key)
    print('----- '+str(i))
    nc.write(key+b'\n')
    if i == 54:
        print(nc.read())