leHACK 2025 : Writeup singularity

Writeup sur le challenge singularity 👍

Cette fois-ci on ne s'attaque pas à un fichier binaire mais à un script Python qui est le suivant :

import base64

def banner():
    BANNER = """CgogICAgICAgICAgICAgICAgICAuYW5kQUhIQWJubi4KICAgICAgICAgICAgICAgLmFBSEhIQUFV
    VUFBSEhIQW4uCiAgICAgICAgICAgICAgZEhQXn4iICAgICAgICAifl5USGIuCiAgICAgICAgLiAg
    IC5BSEYgICAgICAgICAgICAgICAgWUhBLiAgIC4KICAgICAgICB8ICAuQUhIYi4gICAgICAgICAg
    ICAgIC5kSEhBLiAgfAogICAgICAgIHwgIEhIQVVBQUhBYm4gICAgICBhZEFIQUFVQUhBICB8CiAg
    ICAgICAgSSAgSEZ+Il9fX19fICAgICAgICBfX19fIF1ISEggIEkgICAgCiAgICAgICBISEkgSEFQ
    SyIifl5ZVUhiICBkQUhISEhISEhISEggSUhICiAgICAgICBISEkgSEhIRCZndDsgLmFuZEhIICBI
    SFVVUF5+WUhISEggSUhIICAgICAgIFdlbGNvbWUgYmFjayB0byB0aGUgc2luZ3VsYXJpdHkgIQog
    ICAgICAgWVVJIF1ISFAgICAgICJ+WSAgUH4iICAgICBUSEhbIElVUAogICAgICAgICIgIGBISyAg
    ICAgICAgICAgICAgICAgICBdSEgnICAiICAgICAgICAgICAgICAgQ2FuIHlvdSBmaW5kIG15IHBh
    c3N3b3JkID8KICAgICAgICAgICAgVEhBbi4gIC5kLmFBQW4uYi4gIC5kSEhQCiAgICAgICAgICAg
    IF1ISEhIQUFVUCIgfn4gIllVQUFISEhIWwogICAgICAgICAgICBgSEhQXn4iICAuYW5ubi4gICJ+
    XllISCcKICAgICAgICAgICAgIFlIYiAgICB+IiAiIiAifiAgICBkSEYKICAgICAgICAgICAgICAi
    WUFiLi5hYmRISGJuZGJuZEFQIgogICAgICAgICAgICAgICBUSEhBQWIuICAuYWRBSEhGCiAgICAg
    ICAgICAgICAgICAiVUhISEhISEhISEhVIgogICAgICAgICAgICAgICAgICBdSEhVVUhISEhISFsK
    ICAgICAgICAgICAgICAgIC5hZEhIYiAiSEhISEhibi4KICAgICAgICAgLi5hbmRBQUhISEhISGIu
    QUhISEhISEhBQWJubi4uCiAgICAubmRBQUhISEhISFVVSEhISEhISEhISFVQXn4ifl5ZVUhISEFB
    Ym4uCiAgICAgICJ+XllVSEhQIiAgICJ+XllVSEhVUCIgICAgICAgICJeWVVQXiIKICAgICAgICAg
    ICAiIiAgICAgICAgICJ+fiIK"""
    print(base64.b64decode(BANNER).decode())

def check_password(password):
    singularity = lambda t: (ord(t[1])+t[0])^0x42 == bytes.fromhex(
      base64.b64decode('MDExMjMyN2IzNDdiMzgxODI1MjA3OGMyMjkxMTNmYzYzYzM3MzMzZDNiMTljMDE1MWQ=').decode()
    )[t[0]]
    return = all(map(singularity, enumerate(password)))

def main():
    banner()
    password = input("Enter the password> ")
    if check_password(password):
        print("You can validate with leHACK{{{}}}".format(password))
    else:
        print("Error: Wrong password")

if __name__ == '__main__':
    main()

Bien que le script semble assez basique à première vue, je n'ai pas réussi à le résoudre dans les temps, seulement le lendemain au réveil. A vrai dire, j'étais trop occupé à tenter de résoudre celui de kubain (medium)... Le cas présent c'est la fonction check_password() qui est intéressante car elle s'occupe de la comparaison avec l'entrée input().

L'idée étant de faire l'inverse. On prépare déjà notre structure (le plus simple) :

import base64

encoded = 'MDExMjMyN2IzNDdiMzgxODI1MjA3OGMyMjkxMTNmYzYzYzM3MzMzZDNiMTljMDE1MWQ='
hex_string = base64.b64decode(encoded).decode()
target_bytes = bytes.fromhex(hex_string)

Le 0x42 est une façon d'écrire le nombre 66 en héxadécimal, et le ^ permet d'y apporter une opération xor, une méthode mathématique pour le masquer. Du coup on va faire la même chose à l'inverse :

password = ''.join(
    chr((b ^ 0x42) - i) for i, b in enumerate(target_bytes)
)

Ce qui permet de récupérer le flag :

python3 singularity.flag.py | python3 singularity.py


                  .andAHHAbnn.
               .aAHHHAAUUAAHHHAn.
              dHP^~"        "~^THb.
        .   .AHF                YHA.   .
        |  .AHHb.              .dHHA.  |
        |  HHAUAAHAbn      adAHAAUAHA  |
        I  HF~"_____        ____ ]HHH  I
       HHI HAPK""~^YUHb  dAHHHHHHHHHH IHH
       HHI HHHD> .andHH  HHUUP^~YHHHH IHH       Welcome back to the singularity !
       YUI ]HHP     "~Y  P~"     THH[ IUP
        "  `HK                   ]HH'  "               Can you find my password ?
            THAn.  .d.aAAn.b.  .dHHP
            ]HHHHAAUP" ~~ "YUAAHHHH[
            `HHP^~"  .annn.  "~^YHH'
             YHb    ~" "" "~    dHF
              "YAb..abdHHbndbndAP"
               THHAAb.  .adAHHF
                "UHHHHHHHHHHU"
                  ]HHUUHHHHHH[
                .adHHb "HHHHHbn.
         ..andAAHHHHHHb.AHHHHHHHAAbnn..
    .ndAAHHHHHHUUHHHHHHHHHHUP^~"~^YUHHHAAbn.
      "~^YUHHP"   "~^YUHHUP"        "^YUP^"
           ""         "~~"

Enter the password> You can validate with leHACK{COn6r4tS_Y0u_Found_leFl@G}