web端常见风控及应对策略
引言
掌握Web端风控手段是逆向工程的基石。通过了解常见的防御策略及其实现,才能更深刻理解如何应对和解析安全挑战。
Web端风控手段,包括但不限于访问频率控制、输入验证、请求验证、行为分析、代码保护、内容保护等。
访问频率限制
基于访问频率对相应ip或账号进行限制,对于访问频繁的账号/ip,标记为异常流量并进行相应的处理。
通常可以通过上高质量代理、加账号、降低访问频率等方式解决。
输入验证
对用户的输入进行验证,不信任客户端提供的信息。主要用于防sql注入、xss攻击等一系列的恶意行为。不在研究范围内,不再多说。
请求验证
顾名思义,请求验证是用于确认客户端的请求的是否合法的验证流程,确保只有通过了验证的用户才能访问特定的资源或执行特定的操作。
从鉴权流程来看,常见的流程有两种:临时令牌和请求签名。而从鉴权手段来看,又分为设备指纹、账号认证及人机验证。
临时令牌
客户端发送授权请求,服务端鉴权通过后返回相应的短效token,有效期或者一定次数内携带此token请求就会返回正确的数据。
目前国内外绝大多数的WAF或者人机验证都是通过 验证请求->返回token->通过认证 的流程去进行风控。如国内某验的validate、某里的x5sec、国外akm的abck、px3的_px3等
请求签名
客户端的所有请求会经过中间件,中间件对某些安全等级高的接口进行额外的算法处理(通常对请求url、请求体等进行哈希计算),将计算后的签名加入到请求头/请求体/ck中进行请求,服务端计算此签名与请求内容是否匹配,进而返回响应结果。
由于签名算法大都需要校验URL、请求体等敏感内容,因此大厂的签名算法基本都为自研产品,少有使用第三方的签名算法(如国内的某数)进行风控。常见的签名算法有字节系xb/ab、pdd的anti_content、shopee的x-sap、shape的-abcdef等。
设备指纹
通常为读取设备的各种软硬件环境信息,加密后传给服务端,根据这些设备指纹对设备进行风控。
常见的设备指纹检测有:
DOM相关
主要是用户与浏览器的交互行为,如:
鼠标事件,移动轨迹的检测,结合相应区域的dom组件属性
按键事件,注册/登录页校验
打印机事件,很多风控产品都有检测,但是感觉没太大用
陀螺仪事件,主要用于h5/app内嵌页面的校验
触屏操作,同h5/app内嵌页面的校验
canvas指纹
webgl指纹(可与canvas协同检测)
显卡型号、厂商等
字体指纹与像素比
WebRTC api(流媒体相关)
input指纹
iframe指纹
div背景色指纹
其中较为重要的有两方面,一个是dom事件中的isTrusted,自动化/js调用为0、手动为1,为浏览器内置属性。算法可无视,自动化则需要反编译浏览器修改。另一个则是用户鼠标滑动的轨迹的检测,通过机器学习模型判定是否为真人轨迹。解决方法则有重放轨迹、自动化+修改js收录、训练模型对抗等。
BOM相关
主要是window相关属性,即浏览器的实例对象,常见的检测有:
各种window内置函数、属性的toString检测、原型链检测(检测hook与补环境,检测f12等)
各硬件的检测,常见且较为重要的有以下这些:
ua
浏览器扩展组件
语音合成声音指纹
设备总内存、可用内存,栈内存(也可用来检测f12)
屏幕相关
是否支持某个javascript api(Gamepad API、MediaDevices API等)
webdriver、selenium特征串相关
加载的js、css、html节点等静态元素
基于dom/iframe/storage/cookie/blob等的一系列写入、读取等操作
网络层指纹
tls指纹,目前海外主流风控几乎都在使用的检测技术,主要检测tls的加密套件列表、压缩方法、扩展字段等,代表性应用ja3/ja4等,可通过很多第三方库自定义tls各种配置绕过。
h2指纹,检测HTTP/2的设置帧(SETTINGS frame)参数、头部压缩方式、优先级处理、窗口大小等,akm和cf都有检测,可通过浏览器转发、定制cronet等绕过。
tcp/ip指纹,检测IP包的TTL值、窗口大小、DF标志、选项字段(如MSS、窗口缩放、时间戳)等,px盾有此项检测,可通过修改系统配置、编译内核网络请求库等绕过。
其它各种细节,比如datadome的请求头顺序检测 dd和akm的头完整性校验等。
账号认证
特指注册/登录阶段的认证,一方面加大获取账号的难度,另一方面限制个人账号的公开使用。
MFA认证
各大平台登录及敏感业务常用,除了账号密码外还需要手机点击确认、接收短信、发送验证码、生物指纹识别等二次认证。
强相关认证
注册账号时的强制手机号、实名或者微信等认证,借助运营商、第三方平台的风控与账号保护手段来提升获取自己平台账号的难度。
人机验证
“无感验证”以及各种验证码加密参数不再多说,主流技术就那么几种,有机会另起一篇,这里主要说说常见的交互验证码:
数英识别、空间推理、文字点选、图标点选、语义识图、语序点选、差异点选、字体识别
通过训练ocr、物品检测、物品分类或者孪生模型即可识别。
拼图验证、旋转验证、滑块验证、面积验证、小车验证(亚马逊)
针对不同验证通过opencv进行不同处理,如边缘匹配、遍历余弦值匹配、色彩提取等。
手势验证
京东h5登录、vaptcha、pdd海外手机号登录均会遇到,通过opencv来使用合适的对比度算法或者大量打标不规则数据集使用yolo训练模型均可识别。
其它验证
其实任何识别方法与上述验证的识别方案都大同小异,只是看对抗者想不想得到、愿不愿意做以及成本够不够。比如谷歌的4*4十六宫格,通过不规则数据集肯定能搞出来,只是打标及训练成本都会很高。
自己见过的一些其它的奇葩验证码包括:百度新出的拉绳(本质上和手势类似)、美团的颜色连线(opencv定点识别色彩)、拼多多的三维魔方(svg处理+ocr)、虾皮的动态数英(gif帧合并)、腾讯的aigc语义点选(clap微调或者钞能力gpt4 api)、hcaptcha的各种奇葩验证(大多数都是打标+opencv)......
行为分析
可以理解为“秋后算账”,根据账号的行为日志进行分析并风控。常见的有两种:
log上报
即为了建立用户画像,又可以风控,大厂最爱。
请求链路追踪
电商网站最爱,伴随着ck的链路埋点,包括且不限于账号、浏览页面、历史时间戳、停留时间等。比如某宝的exitShop/坚挺的aui/lid、链路相关的spm、页面相关的pisk/tfstk、某多多的时间戳埋点等。
在这方面,并夕夕可谓是翘楚,只要你不在我的平台买东西,就算你是真人,商品看多了照封不误。
代码保护
主要分为两部分,一方面是反调试,另一方面是代码混淆。
反调试
一般通过debugger、console、窗口检测、toString检测、调用栈检测、性能检测、内存爆破等来反调试
debugger
常见的两种:无限debugger和debugger前后时间差校验。
绕过由简至繁依次为右键从不在此暂停、hook debugger句柄、修改源码debugger语句并替换、重新编译浏览器去debugger。
console
console.log、error、table等等,打开f12后传入对象的toString方法会被调用两次,未打开只会调用一次,通过修改toString添加埋点即可检测是否开启f12。
绕过则需要找到检测部分修改埋点。
窗口检测
f12的打开通常会影响页面的可视区域尺寸,通过outerWidth和innerWidth的差值判断是否开启f12。双屏或者修改差值即可绕过。
toString检测
获取js某些函数的toString,计算哈希或者直接判断进行风控。hook Function toString后修改绕过。
调用栈检测
检测stack或者主动抛异常catch后检测异常内容判断是否格式化及行数是否正确。hook stack或者Error toString、message等属性或方法,分析修改后绕过。
性能检测
测算代码执行时间来推断是否开启f12,hook performance绕过。
内存爆破
为调试器分配大量的无用内存,导致f12崩溃。常见的爆破方法为大数组创建,hook Array、UintArray等修改绕过。
不知道原理的反调试
在某东商智的行业板块如下部分遇到过
下载表格的请求有一个user-mnp的请求,跟栈显示:
无法加载 webpack://xtl/src_next/static/js/util/common/all.js 的内容(Fetch through target failed: Unsupported URL scheme; Fallback: HTTP 错误:状态代码 404,net::ERR_UNKNOWN_URL_SCHEME)
但是全局搜可以进入js文件,断点后能成功断到相应位置但是依旧显示无法加载。日志断点也可正常打印:
怀疑是webpack的某种特殊设置,没有深究,通过chrome的本地替换可成功调试。
代码混淆
无论是混淆还是反混淆都离不开ast,个人感觉把蔡老板星球练习题过一遍就差不多了,不懂的看看通用插件学习思路。对于复杂的混淆(流程平坦化、vmp),想要反混淆则需要足够坚实的数据结构基础。
变量名丑化
同盾的Oo0o0O、js盾的蝌蚪文、常见的ob花指令
常量混淆
ob编码混淆/大数组混淆、jsfuck的(!![]+[])[+[]]、字符串的分割再合并、数字的加加减减、布尔值的真真假假......
webpack
严格来说不算反混淆,而是一种提升前端性能、模块维护性、兼容性等的技术,但是复杂的webpack很让人头疼。通常不用ast反混淆,而是找导出模块,缺什么模块copy什么模块,缺什么环境补什么环境。
流程平坦化
最知名的阿里x82y,把执行流程switch case化。
jsvmp
当前最主流的代码保护技术,最早接触到的应该是字节系,现在几乎风控厂商”人均vmp“,最有代表性的应该是腾讯的tdc。简单来说就是用js写一个虚拟机,把源代码指令化。
wasm
严格来说不算代码混淆,而是二进制文件,可以理解为安卓的so或者windows的dll文件。通过wasm2c转化c语言扣代码,或者补wasm初始化时传入的js方法及对应环境可以快速出值。
个人觉得以后的主流可能会是wasm的vmp化+初始化传入webpack的大对象,让补js和还原c都多一层难度。
内容保护
使用加密或是其它手段隐藏响应内容中的真实数据。
响应加密
加密response,解密后再渲染到页面。可通过DOM断点逆向追或者response success的回调正向追。(微信读书、虾皮验证码)
css偏移
略
字体反爬
略
图片代替文字
常见于小说网站,ocr识别后替换图片位置
蜜罐数据
分析风控原因,对症下药