本文将详细介绍如何对数美点选验证进行逆向分析,包括抓包分析、代码混淆处理、请求参数解析等步骤。通过这个过程,我们将揭示验证流程中的核心请求,提取验证图片及文字信息,最终通过代码构造出正确的坐标数据进行验证。
目标网站与抓包分析
目标网站为:
bash
aHR0cHM6Ly9zZWN1cmUuZWxvbmcuY29tL3Bhc3Nwb3J0L2xvZ2luX2NuLmh0bWw/bmV4dHVybD1odHRwczovL3d3dy5lbG9uZy5jb20v
目标是分析数美点选验证流程中的关键请求,并逆向其参数生成过程。以下是需要重点分析的三个核心请求:
https://captcha1.fengkongcloud.cn/ca/v2/fverify
https://captcha1.fengkongcloud.cn/ca/v1/register
https://captcha1.fengkongcloud.cn/ca/v1/conf
解决动态JS无法调试问题
在进行抓包分析之前,需要解决动态JS文件加载的问题。该文件URL每次都会变化,导致断点无法稳定设置。可以使用Charles或mitmproxy拦截并替换动态JS URL,使其加载固定的本地JS文件。
Charles替换方法
使用Charles捕获目标请求,右键保存响应内容。
启用Charles的Map Local功能,将动态JS URL映射到本地保存的文件。
mitmproxy脚本替换方法
以下是mitmproxy的拦截脚本示例:
python
from mitmproxy import http
from mitmproxy.http import Request, Response
def request(flow):
if flow.request.pretty_url.startswith("https://secure.elong.com/passport/login_cn.html?nexturl=https://www.elong.com/"):
with open("res.html", mode="rb") as f:
content = f.read()
flow.response = Response.make(
200,
content,
{"Content-Type": "text/html"}
)
def response(flow: http.HTTPFlow):
pass
代码混淆处理
首先抓取conf请求指向的api.js文件。该文件代码混淆严重,例如:
javascript
var _0x19e1cf = _0x136e2f[_0x2ae8e9(0x2fd)];
可以通过解混淆脚本处理:
python
import subprocess
import re
def Decode(hex_rg):
res = subprocess.check_output(f"node main.js {hex_rg}", shell=True)
return res.decode("utf-8").strip()
def run():
with open("f1.js", mode="r", encoding="utf-8") as fr, open("f2.js", mode="w", encoding="utf-8") as fw:
for line in fr:
matches = re.findall(r"(_0x\w+\((.*?)\))", line)
for func_string, hex_str in matches:
decoded_str = Decode(hex_str)
line = line.replace(func_string, f'"{decoded_str}"')
fw.write(line)
if __name__ == '__main__':
run()
conf请求分析
分析conf请求中的核心参数:
appId: default
organization: xQsKB7v2qSFLFxnvmjdO
callback: sm_1705412287345
sdkver: 1.1.3
model: select
captchaUuid: 20240116213802Zwas5htESARemRJWfW
rversion: 1.0.4
lang: zh-cn
channel: DEFAULT
生成captchaUuid
captchaUuid由当前时间和17个随机字符组成:
python
import random
import datetime
def gen_captcha_uuid():
total_string = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"
part = "".join(random.choice(total_string) for i in range(17))
ctime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
captcha_uuid = f"{ctime}{part}"
return captcha_uuid
fverify请求分析
fverify请求包含多个加密参数,需要解密分析其生成过程。以下是需要分析的参数:
en
dy
xy
tb
mu
oc
mp
nu
qd
ww
kq
jo
分析加密函数
通过混淆处理后的代码,找到加密函数getEncryptContent:
javascript
getEncryptContent: function(data, key) {
var cipher = CryptoJS.DES.encrypt(data, key);
return cipher.toString(CryptoJS.enc.Base64);
}
利用Python实现该加密函数:
python
from Crypto.Cipher import DES
import base64
def des_encrypt(data, key):
pad_func = lambda text: text + '\0' * (DES.block_size - len(text) % DES.block_size)
cipher = DES.new(key.encode('utf-8'), DES.MODE_ECB)
encrypted_data = cipher.encrypt(pad_func(data).encode('utf-8'))
return base64.b64encode(encrypted_data).decode('utf-8')
if __name__ == '__main__':
data = 'default'
key = '9cc268c1'
encrypted = des_encrypt(data, key)
print(encrypted) # Output: WYfkIZp7GoA=
完整示例代码
import random
import datetime
from Crypto.Cipher import DES
import base64
def gen_captcha_uuid():
total_string = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"
part = "".join(random.choice(total_string) for i in range(17))
ctime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
captcha_uuid = f"{ctime}{part}"
return captcha_uuid
def des_encrypt(data, key):
pad_func = lambda text: text + '\0' * (DES.block_size - len(text) % DES.block_size)
cipher = DES.new(key.encode('utf-8'), DES.MODE_ECB)
encrypted_data = cipher.encrypt(pad_func(data).encode('utf-8'))
return base64.b64encode(encrypted_data).decode('utf-8')
def get_encrypted_params():
params = {
'mp': des_encrypt('default', '9cc268c1'),
'oc': des_encrypt('DEFAULT', 'c2659527'),
'xy': des_encrypt('zh-cn', 'b1807581'),
'jo': des_encrypt('10', '6d005958')
}
return params
if __name__ == '__main__':
captcha_uuid = gen_captcha_uuid()
encrypted_params = get_encrypted_params()
print(f'captchaUuid: {captcha_uuid}')
print(f'encryptedParams: {encrypted_params}')
更多内容联系1436423940