近日,参加金融行业某私测项目,随意选择某个业务办理,需要向客户发送短信验证码:
响应报文中包含大段加密数据:
全站并非全参数加密,加密必可疑!尝试篡改密文,页面提示“实名认证异常”:
猜测该密文涉及用户信息,且通过前端 JS 解密,验证之。
手工分析
要分析前端,自然得打开浏览器的开发者工具。习惯性按下 F12 键,无反应,显然页面禁用 F12,没有调试环境,所有后续工作均无法开展,我得创造环境。
1.1 创造前端调试环境
虽然禁用 F12,但未禁用 shift-F5,它也能启用开发者工具,或者,页面也未禁用右键,我从元素审查菜单项同样进入开发者工具。前端采用 webpack 打包,通过开发者工具的 {} 简单美化:
刚执行前端代码,页面卡死,应该存在反调试逻辑:
多次单步执行,发现 setTimeout(e, 100) 语句:
业务上几乎不可能用到 100 毫秒的定时器,猜测用于反调试。全局搜索(ctrl-shift-f)该语句,发现只存在于 businessReservation.js 中:
尝试删除该语句,看能否禁掉反调试。由于 JS 已被浏览器加载至内存,即便通过开发者工具删掉该语句,浏览器照样会执行它,所以,必须得在浏览器拿到 JS 前就将其删除,也就是说,得让服务端重新下发该 JS,拦截响应包,删除该语句后放行至浏览器。具体而言,JS 作为静态资源,优先从本地缓存中获取而非服务端,必须强制刷新页面(ctrl-shift-r),拦截返回 businessReservation.js 的响应包,搜索关键字 setTimeout(e, 100),无果:
考虑到关键字 setTimeout(e, 100) 是经浏览器美化(代码格式化)之后的,尝试去掉逗号后面的空格,用关键字 setTimeout(e,100) 再次搜索,命中:
将 setTimeout(e, 100) 改为空语句 ;:
放行修改后的 JS 至客户端,之后,前端代码可正常执行,也可随意下断点:
这下算是创建出了前端调试的环境。
1.2 解密 Data
现在我得想法找出解密函数。与 Data 同时返回至客户端的字段还有 ResultCode:
全局搜索 ResultCode,发现只出现在 businessReservation.js 中: