見出し画像

Pico-CTF Keygenme-py

今回はPico-CTF のKeygenme-pyのwriteupです

リバースエンジニアリングの内容でPythonのソースコードが与えられます.めちゃくちゃに長いのでとりあえず実行すると,4つのメニューが表示され選択することが可能になります.

Menu:
(a) Estimate Astral Projection Mana Burn
(b) [LOCKED] Estimate Astral Slingshot Approach Vector
(c) Enter License Key
(d) Exit Arcane Calculator
What would you like to do, FRASER (a/b/c/d)?

ここから(c)を選択するとライセンスキーを求められるのでこのライセンスキーがFLAGだと思います.
そこで,ライセンスキーの処理をしている部分を探すと

def check_key(keys, username_trial):

  global key_full_template_trial
    if len(key) != len(key_full_template_trial):
        return False
    else:
        # Check static base key part --v
        i = 0
        for c in key_part_static1_trial:
            if key[i] != c:
                return False
            i += 1
        # TODO : test performance on toolbox container
        # Check dynamic part --v
        if key[i] != hashlib.sha256(username_trial).hexdigest()[4]:
            return False
        else:
            i += 1
        if key[i] != hashlib.sha256(username_trial).hexdigest()[5]:
            return False
        else:
            i += 1
        if key[i] != hashlib.sha256(username_trial).hexdigest()[3]:
            return False
        else:
            i += 1
        if key[i] != hashlib.sha256(username_trial).hexdigest()[6]:
            return False
        else:
            i += 1
        if key[i] != hashlib.sha256(username_trial).hexdigest()[2]:
            return False
        else:
            i += 1
        if key[i] != hashlib.sha256(username_trial).hexdigest()[7]:
            return False
        else:
            i += 1
        if key[i] != hashlib.sha256(username_trial).hexdigest()[1]:
            return False
        else:
            i += 1
        if key[i] != hashlib.sha256(username_trial).hexdigest()[8]:
            return False


        return True

動作的には入力したライセンスキー(key)とグローバル変数として与えられているusername_trial(”FRASER”)を比較していく感じなんですけど,,,
username_trial のほうはそのまま比較ではなくハッシュ関数(sha256)を使ってハッシュ化しているところが今回のミソなんですかね
すなわちkeyに入ってくる文字を一つずつFRASERをハッシュ化した文字列の指定された箇所(4,5,3,6,2,7,1,8)と比較し一致するかを処理していることがわかる.よって,FRASERをハッシュ化し指定された箇所を出力することによりFLAGを得ることができる!!
ちなみにハッシュ化したものは

92d7ac3c9a0cf9d527a5906540d6c59c80bf8d7ad5bb1885f5f79b5b24a6d387

となる.


やっていることが分かったので解くためのプログラムを書いてみる!!

import hashlib
Username_trial = b"FRASER"
user_key = "picoCTF{1n_7h3_|<3y_of_"
positions = [4,5,3,6,2,7,1,8]
for i in positions:
    user_key += hashlib.sha256(Username_trial).hexdigest()[i]
    print(user_key)
user_key += '}'
print(user_key)
  

これで解くことができた!!

参考サイト
「分かりそうで」で「分からない」でも「分かった」気になれるIT用語辞典 SHA-256 [2023/8/22]
Robo Station [Python3][b]接頭辞をstr型の変数につける方法[2023/8/22]


この記事が気に入ったらサポートをしてみませんか?