1.前沿
本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!
2.网址
aHR0cHM6Ly93d3cuZG91eWluLmNvbS91c2VyL01TNHdMakFCQUFBQUNWNUVtMTEwU2l1c0Vsd0tsSXBVZC1NUlNpOHJCWXlnME5mcFBycVpteWtIWTh3TFBROE80cHYzd1BMNkEtb3o=
3.加密参数定位
刷新网址,F12抓包,a_bogus的值长度180或176,每个人可能不一样
加密参数定位:
3.1 直接全局搜索搜索a_bogus,没有搜索到相关信息
3.2 xhr 断点定位
刷新网页,s.apply(this, r) ,this._url 中a_bogus已经产生
沿着堆栈向上追溯,发现1处(图片最后一行)断点位置M有abogus的值出现,而2处(图片第一行)及其向上追溯没有abogus的值出现,
而1处和2处断点中间经过 e.exports = function(e) 函数,在下图1处打上一个条件断点,确保拦截的是/aweme/v1/web/aweme/post/链接,断点走到M.send(h) 处 M还没有生成abogus
单步调试M.send(h),发现进入function e() 方法,上述追溯堆栈过程中经过function e方法,该方法内部是jsvmp混淆,现在单步调试又进入到该方法
所以u = function e() 函数很大概率是生成a_bogus的函数
4.验证
找到function e() 函数调用处,下断点
会发现断点一直断在这儿,外层有个大循环,这是指令集调用的地方,先下一个日志断点看一下
既然日志中有长为180的a_bogus的值产生,那么添加一个条件断点s.apply(b, u).length == 180;
此断点的目的:
1. 当a_bogus值产生的时候执行的是哪个目标函数
2 . 执行目标函数穿入什么参数
单步执行进入函数内部,执行function e函数a_bogus值产生
接下来就补环境了
5.补环境
a_bogus的值在这个函数生成了
u = function e() {
var r = e._v;
return (0,
e._u)(r[0], arguments, r[1], r[2], this)
}
直接将u函数导出
环境简单补一下即可运行出结果
require("./dy_env")
require("./dy_source")
function generate_abogus(param){
arguments = [
0,
1,
12,
param,
"",
"自己的User-Agent"
]
var r = window.dy_u._v;
return (0,
window.dy_u._u)(r[0], arguments, r[1], r[2], this)
}
param = "device_platform=webapp&aid=6383&channel=channel_pc_web&detail_list=1&source=6&main_billboard_count=5&update_version_code=170400&pc_client_type=1&version_code=170400&version_name=17.4.0&cookie_enabled=true&screen_width=1920&screen_height=1080&browser_language=zh-CN&browser_platform=MacIntel&browser_name=Chrome&browser_version=125.0.0.0&browser_online=true&engine_name=Blink&engine_version=125.0.0.0&os_name=Mac+OS&os_version=10.15.7&cpu_core_num=8&device_memory=8&platform=PC&downlink=10&effective_type=4g&round_trip_time=100&webid=7377586381898499625&verifyFp=verify_lx430xgm_gAkmep7q_tihS_4HtF_BQtL_8T5FgORxYFr7&fp=verify_lx430xgm_gAkmep7q_tihS_4HtF_BQtL_8T5FgORxYFr7&msToken=KT6fLqz9WW6oHu9MBnLl4JdiVBpQjPoBKshtduvsD-8H1dte9RHZQJNF3CbE2pLu5abPxaaF76w4CZJCav5NB4gAfTQKIjIVjb4I6ZxIdeW-v86C3OzYa3oko3DdFA%3D%3D&msToken=KT6fLqz9WW6oHu9MBnLl4JdiVBpQjPoBKshtduvsD-8H1dte9RHZQJNF3CbE2pLu5abPxaaF76w4CZJCav5NB4gAfTQKIjIVjb4I6ZxIdeW-v86C3OzYa3oko3DdFA%3D%3D"
abogus = generate_abogus(param)
console.log(abogus)
补环境环境代码
debugger;
;
catvm = {}
catvm.memory = {log: []};
catvm.proxy = function (obj) {
// Proxy 可以多层代理,即 a = new proxy(a); a = new proxy(a);第二次代理
// 后代理的检测不到先代理的
return new Proxy(obj, {
set(target, property, value) {
console.table([{"类型":"set-->","调用者":target,"调用属性":property,"设置值":value}]);
catvm.memory.log.push({"类型":"set-->","调用者":target,"调用属性":property,"设置值":value});
// console.log("set", target, property, value);
return Reflect.set(...arguments); //这是一种反射语句,这种不会产生死循环问题
},
get(target, property, receiver) {
console.table([{"类型":"get<--","调用者":target,"调用属性":property,"获取值":target[property]}]);
catvm.memory.log.push({"类型":"get<--","调用者":target,"调用属性":property,"获取值":target[property]});
// console.log("get", target, property, target[property]);
return target[property]; // target中访问属性不会再被proxy拦截,所以不会死循环
}
});
}
window = global;
delete global;
delete Buffer;
requestAnimationFrame = function requestAnimationFrame() {
}
_sdkGlueVersionMap = {
"sdkGlueVersion": "1.0.0.51",
"bdmsVersion": "1.0.1.5",
"captchaVersion": "4.0.2"
}
XMLHttpRequest = function XMLHttpRequest() {
}
onwheelx = {
"_Ax": "0X21"
}
fetch = function fetch() {
}
window.innerWidth = 1011
window.innerHeight = 959
window.outerWidth = 1920
window.outerHeight = 1020
window.screenX = -291
window.screenY = -1080
window.pageYOffset = 51
screen = {
availHeight: 1080,
availLeft: -291,
availTop: -1080,
availWidth: 1920,
colorDepth: 24,
height: 1080,
}
navigator = class navigator{}
navigator.platform = 'MacIntel'
navigator.userAgent = '替换自己的'
document = class document{}
window = catvm.proxy(window)
navigator = catvm.proxy(navigator)
document = catvm.proxy(document)
execjs 调用js代码执行
import requests
import execjs
import urllib.parse
import requests
headers = {
"accept": "application/json, text/plain, */*",
"accept-language": "zh-CN,zh;q=0.9",
"cache-control": "no-cache",
"pragma": "no-cache",
"priority": "u=1, i",
"referer": "https://www.douyin.com/user/MS4wLjABAAAACV5Em110SiusElwKlIpUd-MRSi8rBYyg0NfpPrqZmykHY8wLPQ8O4pv3wPL6A-oz",
"sec-ch-ua": "\"Google Chrome\";v=\"125\", \"Chromium\";v=\"125\", \"Not.A/Brand\";v=\"24\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "替换自己的User-Agent:"
}
cookies = {
"ttwid": "1%7CFuS7O1DVWyn5UIo3ydIi57ht6It810NUkgCmPZznPls%7C1717728208%7C6e3f9cf095b3bcd8630cc9b9f409131ac795bbe0a1138e98d8304b9885cb600d",
"s_v_web_id": "verify_lx430xgm_gAkmep7q_tihS_4HtF_BQtL_8T5FgORxYFr7",
"home_can_add_dy_2_desktop": "%220%22",
"dy_swidth": "1920",
"dy_sheight": "1080",
"strategyABtestKey": "%221717728210.174%22",
"csrf_session_id": "86cf6cecc3d7cf90b465554039a49779",
"passport_csrf_token": "54461560cd594f59d56df1e7113dc12f",
"passport_csrf_token_default": "54461560cd594f59d56df1e7113dc12f",
"bd_ticket_guard_client_web_domain": "2",
"download_guide": "%223%2F20240607%2F0%22",
"FORCE_LOGIN": "%7B%22videoConsumedRemainSeconds%22%3A180%2C%22isForcePopClose%22%3A1%7D",
"douyin.com": "",
"device_web_cpu_core": "8",
"device_web_memory_size": "8",
"volume_info": "%7B%22isUserMute%22%3Afalse%2C%22isMute%22%3Atrue%2C%22volume%22%3A0.5%7D",
"xgplayer_user_id": "993969320736",
"xg_device_score": "7.601412568506403",
"stream_player_status_params": "%22%7B%5C%22is_auto_play%5C%22%3A0%2C%5C%22is_full_screen%5C%22%3A0%2C%5C%22is_full_webscreen%5C%22%3A0%2C%5C%22is_mute%5C%22%3A1%2C%5C%22is_speed%5C%22%3A1%2C%5C%22is_visible%5C%22%3A0%7D%22",
"__ac_nonce": "06662d4860084322b89ba",
"__ac_signature": "_02B4Z6wo00f01qijScAAAIDB-lxp2bLgdX6og01AAMxW3b",
"WallpaperGuide": "%7B%22showTime%22%3A1717749819938%2C%22closeTime%22%3A0%2C%22showCount%22%3A1%2C%22cursor1%22%3A0%2C%22cursor2%22%3A0%7D",
"stream_recommend_feed_params": "%22%7B%5C%22cookie_enabled%5C%22%3Atrue%2C%5C%22screen_width%5C%22%3A1920%2C%5C%22screen_height%5C%22%3A1080%2C%5C%22browser_online%5C%22%3Atrue%2C%5C%22cpu_core_num%5C%22%3A8%2C%5C%22device_memory%5C%22%3A8%2C%5C%22downlink%5C%22%3A10%2C%5C%22effective_type%5C%22%3A%5C%224g%5C%22%2C%5C%22round_trip_time%5C%22%3A100%7D%22",
"msToken": "jQtJ1W978TmplB58GQng0JS5lvPOOtjwu7qpZxiz7LDTZkDc5t9hQeeDRPj_WHt6I-lh9QPLNWPmevu_YHaR1mOZTN1JGk3uzloPNXungYDi6biGexnc5rCpJFDHtw==",
"bd_ticket_guard_client_data": "eyJiZC10aWNrZXQtZ3VhcmQtdmVyc2lvbiI6MiwiYmQtdGlja2V0LWd1YXJkLWl0ZXJhdGlvbi12ZXJzaW9uIjoxLCJiZC10aWNrZXQtZ3VhcmQtcmVlLXB1YmxpYy1rZXkiOiJCQkV3dk5XYWNleWUwVVIyMTlYeERKNmh5TE1mYUdyQkhRQ0U0bzIwL0xhL0Q5bG5SM1kzWE5OZ2NaT0dJbEt4d1RwWmJzVlNpOWQwUEd5S1VtMTFLa1E9IiwiYmQtdGlja2V0LWd1YXJkLXdlYi12ZXJzaW9uIjoxfQ%3D%3D",
"IsDouyinActive": "true"
}
url = "https://www.douyin.com/aweme/v1/web/aweme/post/"
params = {
"device_platform": "webapp",
"aid": "6383",
"channel": "channel_pc_web",
"sec_user_id": "MS4wLjABAAAACV5Em110SiusElwKlIpUd-MRSi8rBYyg0NfpPrqZmykHY8wLPQ8O4pv3wPL6A-oz",
"max_cursor": "0",
"locate_query": "false",
"show_live_replay_strategy": "1",
"need_time_list": "1",
"time_list_query": "0",
"whale_cut_token": "",
"cut_version": "1",
"count": "18",
"publish_video_strategy_type": "2",
"update_version_code": "170400",
"pc_client_type": "1",
"version_code": "290100",
"version_name": "29.1.0",
"cookie_enabled": "true",
"screen_width": "1920",
"screen_height": "1080",
"browser_language": "zh-CN",
"browser_platform": "MacIntel",
"browser_name": "Chrome",
"browser_version": "125.0.0.0",
"browser_online": "true",
"engine_name": "Blink",
"engine_version": "125.0.0.0",
"os_name": "Mac OS",
"os_version": "10.15.7",
"cpu_core_num": "8",
"device_memory": "8",
"platform": "PC",
"downlink": "10",
"effective_type": "4g",
"round_trip_time": "100",
"webid": "7377586381898499625",
"verifyFp": "verify_lx430xgm_gAkmep7q_tihS_4HtF_BQtL_8T5FgORxYFr7",
"fp": "verify_lx430xgm_gAkmep7q_tihS_4HtF_BQtL_8T5FgORxYFr7"
}
param = urllib.parse.urlencode(params)
a_bogus = execjs.compile(open('dy.js').read()).call('generate_abogus', param)
print(len(a_bogus),a_bogus)
params['a_bogus'] = a_bogus
response = requests.get(url, headers=headers, cookies=cookies, params=params)
print(response.text)
效果图
运行没有结果或者结果不可用排查因素:
1. arguments中的值和浏览器值保持一致,注意:arguments是一个数组而不是字典
2.补环境navigator中userAgent和headers中的应该保持一致
3.发送请求时params参数应该序列化,且不包含a_bogus
4.a_bogus产生需要更新到params中去