声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请在公众号【K哥爬虫】联系作者立即删除!
逆向目标
- 目标:安某客滑动验证码逆向分析
- 主页:
aHR0cHM6Ly93d3cuYW5qdWtlLmNvbS9jYXB0Y2hhLXZlcmlmeS8/Y2FsbGJhY2s9c2hpZWxkJmZyb209YW50aXNwYW0=
抓包分析
首页请求,有个初始化函数,其中有个 sessionId
后续会用到。
然后有个 getInfoTp
的请求,Form Data
里有个 dInfo
是加密参数,返回值里 info
也是加密的,包含了图片信息,返回值 responseId
在后续的请求也会用到。
滑动之后,有个 checkInfoTp
请求,Form Data
里有个 data
是加密参数,包含了轨迹信息,返回值 message
可以看到是否校验成功。
整体流程就是:请求首页获取 sessionId
,请求 getInfoTp
获取图片信息和 responseId
,请求 checkInfoTp
校验是否成功,中间涉及到 dInfo
和 data
两个加密参数,以及 getInfoTp
返回得到的 info
的解密。
dInfo 生成
先来看 getInfoTp
请求的 dInfo
参数,直接搜索可定位,刷新断下,大致就可以看出是 AES 加密,传入了 sessionId
和一个 _taN()
函数的返回值:
_taN()
函数是一些 URL,UA 之类的信息,可以写死:
往里跟就可以看到 AES 算法了:
这里简简单单扣一下,java script 代码如下:
/* ==================================
# @Time : 2021-12-14
# @Author : 微信公众号:K哥爬虫
# @FileName: ajk.js
# @Software: PyCharm
# ================================== */
var CryptoJS = require('crypto-js')
function AESEncrypt(_cRV, _2undefinedp) {
_2undefinedp = _2undefinedp.split("").reduce(function(_PUi, _JrX, _JP9) {
return _JP9 % 2 == 0 ? _PUi + "" : _PUi + _JrX;
}, "");
_2undefinedp = CryptoJS.enc.Utf8.parse(_2undefinedp);
_cRV = "string" == typeof _cRV ? _cRV : JSON.stringify(_cRV);
_cRV = CryptoJS.AES.encrypt(_cRV, _2undefinedp, {
iv: _2undefinedp,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encodeURIComponent(_cRV.toString())
}
function u() {
return {
"sdkv": "3.0.1",
"busurl": "https://www.脱敏处理.com/captcha-verify/?callback=shield&from=antispam",
"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
"clienttype": "1"
}
}
function getDInfo(sessionId){
return AESEncrypt(u(), sessionId)
}
// 测试样例
var sessionId = "a8b339ec0c26459598786fee1cce8dc2"
console.log(getDInfo(sessionId))
这段逻辑也可以用 Python 来实现,关键代码如下(脱敏处理,不能直接运行):
# ==================================
# --*-- coding: utf-8 --*--
# @Time : 2021-12-14
# @Author : 微信公众号:K哥爬虫
# @FileName: ajk.py
# @Software: PyCharm
# ==================================
import json
import base64
import requests
from lxml import etree
from loguru import logger
from urllib.parse import quote_plus
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
class AESAlgorithm:
@staticmethod
def encrypt(aes_key_iv, text):
""" 对明文进行加密 """
cipher = AES.new(key=bytes(aes_key_iv, encoding='utf-8'), mode=AES.MODE_CBC, iv=bytes(aes_key_iv, encoding='utf-8'))
result = base64.b64encode(cipher.encrypt(pad(text.encode('utf-8'), 16))).decode('utf-8')
result = quote_plus(result)
return result
@staticmethod
def decrypt(aes_key_iv, text):
""" 对密文进行解密 """
cipher = AES.new(key=bytes(aes_key_iv, encoding='utf-8'), mode=AES.MODE_CBC, iv=bytes(aes_key_iv, encoding='utf-8'))
result = unpad(cipher.decrypt(base64.b64decode(text)), 16).decode('utf-8')
return result
class AJKSlide:
def __init__(self, index_url, user_agent):
self.