逆向了联通官方测速系统的前端代码,发现四重作弊机制,难怪永远"达标"
各位 V 友好,最近闲着没事逆向了某省联通的官方宽带测速平台(就是装维上门给你”测速达标”签字那个),结果越看越上头。
分享一下发现,代码层面的东西,没有主观臆测。
TL;DR
联通测速系统的算法里埋了四个机制,叠加效果就是:不管你实际网速多少,测出来几乎必定”达标”。
0x01 先说合理的部分
公平起见,算法里有几个设计是业界通用的,没毛病:
- 多线程并发( 6 个连接同时下载)—— Speedtest 也这么干,单连接跑不满高带宽
- 预热丢弃(前 2 秒数据不算)—— TCP 慢启动,合理
- 累计平均(总量÷总时间)—— 比瞬时采样更稳定
这些没问题。问题在后面。
0x02 校正因子:所有结果 ×1.04
speed = downloadVal / elapsed * 1000 * 1.04 // 下载
speed = uploadedSize / elapsed * 1.048 // 上传
计算完实际速度后,下载乘 1.04 ,上传乘 1.048 。
官方可能会说”补偿 TCP/IP 协议开销”。但 TCP header 20 bytes + IP header 20 bytes ,在 MTU 1500 的帧里占比约 2.7%。HTTP header 在持续流式传输大文件时占比可忽略。
4~5% 的”校正”显然超出了协议开销的范畴。 而且方向只往上调,从不往下。
0x03 数据修剪:只砍低的,高的全留
测速过程中每 200ms 采样一次,20 秒下来大约 90 条有效记录。然后:
records.sort((a, b) => a - b);
records = records.slice(5 * minLostDataTime); // minLostDataTime=3, 砍掉最低 15 条
// 最高的呢?不动。
任何一本统计学教材都会告诉你,处理异常值要双边修剪或者用中位数。只砍低不砍高,这不叫数据清洗,这叫 cherry-picking 。
0x04 高位平均替换:波动大?用峰值覆盖
这段逻辑比较阴间:
topAvg = 取最高 10 条记录的平均值
totalAvg = 全部记录的平均值
if (totalAvg < topAvg * 0.96) {
// "平均值不够高" → 全部替换为峰值附近的随机数
records.forEach((val, i) => {
records[i] = topAvg * random(0.99, 1.0);
});
}
意思是:如果你的网速有波动(平均值低于峰值的 96%),那实际测量数据全部丢弃,替换为 峰值 × random(0.99, 1.0)。
现实中的网络环境哪有不波动的?所以这段代码大概率每次都会触发。效果就是:最终上报的数据全是接近峰值的假数据。
0x05 WiFi 补偿:没跑到?帮你补上
这是最炸裂的一段。
服务端下发了这么几个参数:
| 参数 | 值 | 含义 |
|---|---|---|
wifiLossRate |
0.6 | 最多补偿签约带宽的 60% |
wifiMaxLossValue |
600 | 单次最多加 600 Mb/s |
standardValue |
0.9 | 低于签约 90% 就触发 |
if (measured < bandwidth * 0.9 && measured > bandwidth * 0.1) {
gap = ceil((bandwidth * 0.9 - measured) / bandwidth * 100);
compensation = min(gap / 100, 0.6) * bandwidth;
compensation = min(compensation, 600);
speed += compensation * 1000 * 125; // 直接加到速度上
}
来,算一笔账:
签约 2000M ,实测 1200 Mb/s
gap = ⌈(1800 - 1200) / 2000 × 100⌉ = 30
compensation = min(0.3, 0.6) × 2000 = 600 Mb/s
上报 = 1200 + 600 = 1800 Mb/s → 达标 ✓
实际呢?只有 1200 。
注意,补偿参数是服务端控制的,也就是说运营商可以随时调整这个”作弊力度”。想让达标率高一点?把 wifiLossRate 调大就行了。
0x06 四重 buff 叠满
| 层级 | 机制 | 效果 |
|---|---|---|
| Layer 1 | ×1.04 校正因子 | 基础膨胀 4% |
| Layer 2 | 只删低值 | 拉高均值 |
| Layer 3 | 峰值替换 | 消灭波动,锁定高位 |
| Layer 4 | WiFi 补偿 +600M | 兜底,不达标也给你补到达标 |
这四层从下到上,覆盖了从”轻微美化”到”明目张胆造假”的完整光谱。你的宽带在这套系统面前,想不达标都难。
0x07 一些额外发现
- 测速参数全部由服务端动态下发,运营商可以远程调整”作弊力度”,前端只是执行
- 前端 JS 做了混淆,变量名全是
_0x585b('0x2c')这种,但混淆程度不高,字符串表基本明文 - 认证机制是
MD5("speedInternal-" + secret + timestamp)然后 Base64 ,写死的密钥
0x08 我的验证
用 Python 复现了完整测速流程,保留合理部分(多线程、预热),去掉四个作弊机制。
同一条 2000M 宽带:
| 官方系统 | 去掉修正 | |
|---|---|---|
| 下行 | “达标” | ~1400 Mb/s |
| 上行 | “达标” | ~365 Mb/s |
1400⁄2000 = 70%,实际并不达标。但在官方系统里,WiFi 补偿一加,峰值一替换,妥妥的”达标”。
最后
我不反对运营商考虑 WiFi 衰减的因素。但正确的做法是在报告里注明”有线/无线”测试环境和修正说明,而不是在算法里偷偷加数据,给用户一份失真的报告,然后让装维拿着这份报告让你签”速率达标确认单”。
校正因子可以商榷,但 WiFi 补偿和峰值替换就是纯粹的造假,没有任何技术合理性。
用户买的是带宽,不是一份永远达标的测速报告。
以上分析基于前端 JS 逆向,所有结论可从源码直接验证。代码已脱敏,有兴趣的同学可以自己抓包看看。
技术讨论欢迎,键政免入。
@lyz2754509784 每个地区的测试网址应该是隔离的,我看了一下你这个测速网址只有江苏的 IP 可以打开
太可怕了……
所以我都是用
https://h3.speed.cloudflare.com/
这个测速站。虽然测出来结果不会很好看,但是至少真实。我们办宽带是为了访问内容,所以从 CDN 入口反馈速度会比较接近真实打开网页的情况。 而国标的宽带标准,也只测到达运营商 BARS 的速度,其实非常的片面。
有没有逆向过江苏联通的测速网站 https://jsspeedtestwebv4.js165.com:8091/h5/broadband.html 装维上门测速应该也是用的这个,也就是所谓的测速正常…目前江苏联通宽带只有这个网站和全球网测的江苏南京联通节点是可以正常测到合同标称的宽带的,其余所有网站/节点上行都只有 2-3m ,有的软件可能有 5m ,包括微信发文件类的实际使用也限制在 500kb/s 左右…更离谱的是 iPhone14pro 用这个网站能跑出物理设备上限的速度来