输入法漏洞通过 端口实现的
《输入法漏洞通过端口实现的输入》
2019年,某安全团队在测试一款国内主流输入法时发现,法漏它的洞通后台更新服务监听在UDP 3702端口上。这个端口原本属于WS-Discovery协议,过端用来在局域网里发现设备。口实输入法用它做什么?输入答案是:自动同步词库和配置。问题在于,法漏这个端口没有任何身份验证机制。洞通任何人往这个端口发一个特定格式的过端UDP包,就能让输入法进程执行任意代码。口实
这不是输入孤例。输入法走端口出事的法漏案例,我见过的洞通至少有七八起。核心逻辑很一致:输入法需要联网同步、过端云候选、口实皮肤下载、词库更新,这些功能都得开端口。但开发团队往往把精力放在前端UI和词库算法上,网络模块的安全审计被忽略。端口一旦暴露,就是一条直通系统底层的通道。
具体怎么实现的?拿一个典型场景来说。输入法安装后,会在本地起一个HTTP服务,监听127.0.0.1的某个高位端口,比如4万以上。这个服务负责和浏览器、Office等宿主程序通信,接收按键事件、返回候选词。设计初衷是好的——本地回环,外网碰不到。但很多输入法为了支持手机投屏、跨设备剪贴板同步,会把这个服务绑定到0.0.0.0,也就是所有网卡。同一个咖啡厅WiFi下,别人扫一下端口就能连上。
连上之后能干什么?我实际复现过一次。用Python写个socket客户端,连上某输入法的本地服务端口,发送一个构造好的JSON请求。请求里带一个callback字段,输入法会把它当作词库更新指令处理。如果这个字段里嵌了路径穿越字符,就能读写系统任意文件。更狠的是,有些输入法把eval或exec直接暴露在端口接口上,用来动态加载词库脚本。这等于把后门钥匙插在锁上。
为什么输入法偏爱用端口而不是其他IPC方式?因为跨平台。Windows上可以用命名管道,macOS有XPC,Linux有D-Bus。但输入法要同时跑在Windows、macOS、Linux、Android、iOS上,一套代码通吃,最省事的就是TCP/UDP socket。端口号写死,协议自定义,开发快。代价是安全边界模糊了——本地端口和网络端口在代码里没区别,一不小心就监听了外网。
还有一个细节:输入法的端口往往不固定。它会在启动时随机选一个空闲端口,然后把端口号写进一个临时文件或注册表项,供其他进程读取。这个“端口发现”机制本身也可能被劫持。攻击者可以抢先占住那个临时文件,写入自己的端口号,让输入法把流量导到恶意服务上。这叫端口重定向,配合DNS劫持或ARP欺骗,在公共WiFi下成功率不低。
我跟踪过某款输入法的更新日志,2021年它修了一个CVE,编号忘了,大意是“本地HTTP服务未校验Origin头,导致任意网页可读取用户词库”。修复方式是在请求里加了一个随机token。但token存在内存里,同一台机器上的其他进程可以通过读进程内存拿到。这种修补,治标不治本。根本问题在于:输入法把端口当成了可信通道,而端口从来不可信。
那怎么办?作为普通用户,能做的有限。检查输入法设置里有没有“允许局域网同步”之类的选项,关掉。防火墙规则里,把输入法进程的入站连接全禁掉,只留出站。如果是技术用户,用netstat -ano看看输入法到底监听了哪些端口,绑定的是0.0.0.0还是127.0.0.1。0.0.0.0的一律拉黑。开发者那边,别再用裸socket传指令了,至少加个HMAC签名,或者干脆改用操作系统提供的安全IPC机制。端口不是不能用,但得当成公网接口来对待——零信任,默认拒绝,最小权限。
输入法是个每天陪你打几千字的东西,它在你系统里的权限比大多数软件都高。它能看到你敲的每一个键,包括密码。一个监听在端口上的输入法,等于在你键盘和屏幕之间插了一个透明代理。这个代理要是被人控了,后果不用我多说。