banner
lca

lca

真正的不自由,是在自己的心中设下牢笼。

autodecode aes解密の侵入実戦を記録する

最近いくつかのサイトをテストしました。最初にログインフォームがあり、パケットキャプチャを行ったところ、ユーザー名とパスワードが暗号化されていました。フォーマットは以下の通りです:

Pasted image 20241129200536

フロントエンドでよく使われる暗号化は aes で、aes のキーを rsa で暗号化し、その後 aes を使ってデータを暗号化して送信するケースもありました。

上の図は aes を直接使用した暗号化の例です。

ブラウザを使って暗号化された js ファイルを見つけることができます。一般的にはソースコード / ソースの中で js ディレクトリを見つけます。このサイトは比較的簡単で、crypto-js.js ファイルを直接使用しており、開くと aes のキーと暗号化方式がすぐに確認できます。

Pasted image 20241129200734

上の図から、キーが与えられ、モードは ECB、パディングは Pkcs7 であることがわかります。これらの情報があれば、データを解読することができます。

burpsuite のautodecoderプラグインを使用して、今回の解読もこのプラグインを使いました。

Pasted image 20241129201305

autoDecoder には 4 つのタブがあります。

Pasted image 20241129201504

最初の options タブは、いくつかの設定です。

  • モジュール制御:burp のどのモジュールで autodecoder の暗号化 / 復号化を実行するか
  • 暗号化 / 復号化オプション:自前のアルゴリズムを使うか、インターフェースを使うかを制御します。

Pasted image 20241129201749

後のオプションは最初のオプションに関連しています。たとえば、インターフェースを使った暗号化 / 復号化を選択した場合、データヘッダーを処理するまたはリクエスト応答の異なる暗号化/復号化オプションを設定できます。

  • 暗号化 / 復号化設定:暗号化ドメインを必ず記入する必要があります。そうしないと autodecoder タブに表示されません。他はデフォルトで構いません。
  • 設定が完了したら、必ず保存してください。

2 番目のタブは autodecoder に自前のアルゴリズムによる暗号化 / 復号化があります。

Pasted image 20241129202124

3 番目のタブはインターフェースによる暗号化 / 復号化です。

インターフェースを設定する必要があります。インターフェースは作者が提供したものを参考にできます。リクエストパラメータをカスタマイズする必要がある場合は、ほとんどの場合インターフェースによる暗号化 / 復号化が必要です。

Pasted image 20241129202150

今回遭遇したように、2 つのパラメータが存在する場合、自前のアルゴリズムによる暗号化 / 復号化では要件を満たすことができません。

Pasted image 20241129200536

自前のアルゴリズムによる暗号化 / 復号化には正規表現パターンマッチングがあり、1 つの暗号化された文字列(name)のみをマッチさせることができ、pwd パラメータの暗号化された文字列を抽出することができません。

4 番目のタブはリクエスト応答の置き換えです。

権限昇格の脆弱性をテストするために使用でき、burp の Autorize プラグインと似ていると感じますが、使用したことはありません。

Pasted image 20241129202217

autodecoder プラグインについて簡単に紹介しました。

作者のスクリプトを少し変更して、現在テストしているサイトに適応させました。

from flask import Flask, request
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import base64
from urllib.parse import parse_qs,quote
import hashlib

def aes_encrypt(key, data):
    cipher = AES.new(key, AES.MODE_ECB)
    padded_data = pad(data.encode(), AES.block_size)
    cipher_text = cipher.encrypt(padded_data)
    return base64.b64encode(cipher_text).decode()

def aes_decrypt(key, data):
    cipher = AES.new(key, AES.MODE_ECB)
    decrypted_data = cipher.decrypt(base64.b64decode(data))
    unpadded_data = unpad(decrypted_data, AES.block_size)
    return unpadded_data.decode()

app = Flask(__name__)

@app.route('/encode', methods=["POST"])
def encrypt():
    key = b'ここにaesのkeyを書く'  # 16バイトのキー
    str1 = '123'
    param = request.form.get('dataBody')  # POSTパラメータを取得
    md5value = param + str1
    param1 =  quote(aes_encrypt(key,param))
    param2 = hashlib.md5(md5value.encode()).hexdigest()
    return f"Param={param1}&Autograph={param2}"
    '''
    data = json.loads(param)
    encrypted_id = aes_encrypt(key, data["id"])
    encry_param = param.replace(data["id"], encrypted_id)
    return base64.b64decode(encry_param.encode()).decode()
    '''

@app.route('/decode', methods=["POST"])
def decrypt():
    key = b'ここにaesのkeyを書く'
    param = request.form.get('dataBody')
    print('param: ',param)
    parsed_params = parse_qs(param)
    print(parsed_params)
    
    # 2つのパラメータを解読します。nameとpwdです。
    decrypted_name = aes_decrypt(key, parsed_params["name"][0])
    decrypted_value = aes_decrypt(key, parsed_params["pwd"][0])
    
    # 2つのパラメータを含むJSON応答を返します。
    return f"name={decrypted_name}&pwd={decrypted_value}"

if __name__ == '__main__':
    app.debug = True  # デバッグモードを設定します。運用時にはオフにすることを忘れないでください。
    app.run(host="0.0.0.0", port=8888)

スクリプトを書いたので、実行します。プログラムは 127.0.0.1:8888 でリスンします。

python3 aed_decode.py

まずはパケットをキャプチャしてテストしてみてください。成功裏に解読されたことが確認できます。

Pasted image 20241129203021

現在の設定は以下の通りです:

Pasted image 20241129203246

Pasted image 20241129203422

設定が完了したら、パケットをキャプチャすると、各リクエストが自動的に解読されるのが確認できます。autoDecoder タブで解読内容を見ることができます。

Pasted image 20241129203459

また、burp の intruder モジュールを利用してログインブルートフォース攻撃を開始することもできます。

ここでは、非対称暗号、対称暗号、署名、再送信禁止のテストシナリオを含むフロントエンド暗号化対抗練習のための靶場をお勧めします。AES、DES、RSA など、ペネトレーションテストの練習に使用されます。

靶場のアドレス:https://github.com/SwagXz/encrypt-labs/tree/main

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。