文章目录
- 1. 写在前面
- 2. 风控分析
- 3. 破盾实战
【🏠作者主页】:吴秋霖
【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作!
【🌟作者推荐】:对爬虫领域以及JS逆向分析感兴趣的朋友可以关注《爬虫JS逆向实战》《深耕爬虫领域》
未来作者会持续更新所用到、学到、看到的技术知识!包括但不限于:各类验证码突防、爬虫APP与JS逆向分析、RPA自动化、分布式爬虫、Python领域等相关文章
作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!
1. 写在前面
Akamai可以说是反爬虫对抗领域中目前难度极高的防护产品。这家公司主要就是提供CDN的,其中CK加密技术的应用覆盖了境外很多航空网站,而做廉价票务监控的一些公司不得不考虑如何解决Akamai的防护。目前国内的话有瑞数,它们都是基于CK去做加密处理进行防护,但是跟Akamai跟RS是不一的
RS可以走补环境的方案,Akamai这个方案基本是不可行的!
通过请求网站拿到_abck、bm_sz,同时会得到一个外链JS,POST这个外链JS(携带sensor_data)会得到一个新的_abck,其中需要逆向的参数就是sensor_data
2. 风控分析
基本上更新也是频繁的!几天内小更新、一个月内会有大更新。一些网站还会有指纹校验,对IP地址的质量纯净度要求也是很高
JS加密的重点则是对一些行为事件、每一次的点击提交都会触发它的CK认证,且手机了大量的设备跟行为信息。所以说一般做Akamai服务的都是需要收集大量的真实指纹。所以,想要持续的破盾就需要持续的对抗
另外一个就是高并发跟TLS!并发一上去基本很容易就会挂掉。所以很多第三方的服务有些都是用的真实设备、指纹、环境,包括获取sensor_data的时候都是通过的浏览器去搞
3. 破盾实战
这里我们用Vueling境外的一个航空网站来进行实验,这个网站的Akamai防护算是比较高级别的,如下所示:
需要达到的目的就是将Cookie中的_abck参数由-1变为有效的0,而每个网站都不相同,有的防护等级高的网站则需要请求多次在触发某些事件以后才会给出有效的Cookie
分析的过程中注意比对环境,大数组!保持一致基本是没有问题的!环境监测点比较多,像UA、Window的属性、自动化…
首先我们需要请求拿到第一次的Cookie中的_abck、bm_sz参数,然后调用生成sensor_data参数的算法,如下所示:
session = requests.session()
session.impersonate = "chrome120"
session.verify = False
proxies = {
"http": "http://127.0.0.1:7890",
"https": "http://127.0.0.1:7890",
}
session.proxies = proxies
session.headers = {
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Content-Type": "application/json",
"Origin": "https://m.vueling.com",
"Pragma": "no-cache",
"Referer": "https://m.vueling.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"User-Agent": ""
}
url = "https://m.vueling.com"
response = session.get(url)
abck = session.cookies.get("_abck")
bm_sz = session.cookies.get("bm_sz")
sensor_data = get_sensor_data(abck, bm_sz)
response = session.post(
'https://tickets.vueling.com/ZeAjNN/o8pqU5/ke/mPLR/J6Xa4pZdI/uuEfbhrNYuJr/QRgwWis/A0x/RahwzGXw',
data=json.dumps({'data': sensor_data}),
)
logger.info(response.text)
def get_sensor_data(abck, bmsz):
with open("akm_vueling.js", encoding='utf-8') as f:
ctx = execjs.compile(f.read())
res = ctx.call("gen_sensor_data", abck, bmsz)
return res
url = "https://apimobile.vueling.com/Vueling.Mobile.AvailabilityService.WebAPI/api/V2/AvailabilityController/DoAirPriceSB"
payload = json.dumps({
"DeviceType": "WEB",
"UserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1",
"Udid": "9aa0-18c9-e0ca-d6b0-2704-75dd",
"AppVersion": "17.33.0",
"Domain": "https://m.vueling.com",
"DiscountType": 0,
"Paxs": [
{
"PaxType": "ADT",
"Quantity": "1"
},
{
"PaxType": "CHD",
"Quantity": "0"
},
{
"PaxType": "INF",
"Quantity": "0"
}
],
"CurrencyCode": "EUR",
"AirportDateTimeList": [
{
"ArrivalStation": "ALG",
"DepartureStation": "LCG",
"MarketDateDeparture": "2024-08-15"
}
],
"Language": "en-GB"
})
cookies = ""
for k, v in session.cookies.items():
cookies += f"{k}={v}; "
logger.info(f'cookies: {cookies}')
headers = {
'User-Agent': "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1",
'Accept': "application/json, text/plain, */*",
'Accept-Encoding': "gzip, deflate, br, zstd",
'Content-Type': "application/json",
'Pragma': "no-cache",
'Cache-Control': "no-cache",
'Origin': "https://m.vueling.com",
'Sec-Fetch-Site': "same-site",
'Sec-Fetch-Mode': "cors",
'Sec-Fetch-Dest': "empty",
'Referer': "https://m.vueling.com/",
'Accept-Language': "zh-CN,zh;q=0.9",
'Cookie': cookies
}
response = requests.post(url, data=payload, headers=headers, proxies=proxies, verify=False)
logger.info(f'请求状态: {response.status_code}')
logger.info(f'请求结果: {response.text}')
接下来,我们来测试一下破盾效果,首先拿到JS算法生成的sensor_data参数,如下所示:
携带sensor_data参数请求后得到最新Cookie,然后请求查询接口,如下所示: