web扫描控件破解
某招聘平台前端页面上有个“扫码登录”按钮,描控点下去会弹出一个二维码。破解我最初以为那就是描控一张普通图片,抓包一看,破解请求返回的描控是一段JavaScript,里面藏着一个叫`webScan`的破解对象。这东西就是描控今天要聊的主角——web扫描控件。
它本质上是破解个浏览器插件容器。银行、描控政务、破解医疗系统里常见,描控用来调用本地摄像头或高拍仪,破解把身份证、描控银行卡、破解票据扫成图片回传给网页。描控技术路线无非两种:ActiveX(IE时代的老古董)和NPAPI(Chrome 45之后也废了)。现在活着的,基本是厂商自己封装的EXE加本地WebSocket通信。
我拿到的是一个医疗行业的控件。安装后释放三个文件:一个驱动、一个后台服务、一个浏览器扩展。扩展负责注入页面,后台服务监听`127.0.0.1:某端口`,驱动跟硬件打交道。页面上的JS调用`window.webScan.capture()`,实际是往本地端口发HTTP请求。这个设计有个致命问题——本地端口没有鉴权。
我写了个Python脚本,循环请求`http://127.0.0.1:端口/scan`,每次返回一张base64图片。这意味着任何本地程序,甚至同一台机器上的其他浏览器标签页,都能无声无息地调起摄像头。用户以为只有点按钮才会扫描,实际上后台一直在被轮询。
更离谱的是跨域配置。那个本地服务返回的`Access-Control-Allow-Origin`是`*`。我建了个恶意网页,里面用fetch请求本地端口,居然成功了。用户只要在装有该控件的电脑上打开我的页面,我就能远程控制他的扫描仪。当然,浏览器混合内容策略会拦一部分,但HTTP页面完全不受影响。
破解的第一步是找端口。控件安装后在注册表`HKEY_LOCAL_MACHINE\SOFTWARE\某厂商\webScan`下写了端口号。没权限读注册表?那就扫。本地端口范围通常从`61000`开始,写个多线程扫描,两秒出结果。我试过三台机器,端口分别是`61234`、`61500`、`61888`,规律是厂商预留了1000个端口,实际只用第一个可用的。
拿到端口后,读接口文档?不存在的。我直接抓控件自己的通信包。用Wireshark抓loopback,看到它发的是JSON:`{ "action":"capture","device":"idcard","quality":90}`。响应是`{ "code":0,"image":"base64..."}`。没有token,没有签名,没有时间戳。重放攻击毫无难度。
有人会说,本地服务总得校验来源吧?我翻了那个EXE的字符串,发现它只检查`Referer`头里是否包含`localhost`或`127.0.0.1`。改一下请求头就绕过了。这种防护约等于没有。
修复方案其实很简单:每次调用生成一次性token,通过页面注入的扩展传递给本地服务;本地服务校验token并绑定会话;同时限制`Origin`白名单。但厂商不愿意改,因为会破坏现有集成。很多医院的信息科图省事,直接让控件以管理员权限运行,端口对所有网卡开放。我在某地卫健委的内网里见过,扫描控件监听`0.0.0.0:61234`,整个局域网都能调。
写这篇文章不是教人攻击。我想说的是,那些藏在浏览器角落里的控件,往往是整个系统最薄弱的环节。你花三个月加固了Web应用,SQL注入、XSS、CSRF全防住了,结果一个本地端口就把所有防线撕开了。下次看到“请安装扫描控件”的提示,先别急着点下一步。打开任务管理器,看看它到底在监听什么。