猫鼠游戏,一个刷票老千看在线投票项目的防范与取舍
在线网络投票,本来就是一场流量的狂欢。在漂亮的数据背后,除了螳螂的镰臂与黄雀的利喙外,更伴随着不少见不得光的“寄生虫”和“腐食者”。
沙发上的老 K 从容地点上一支烟,抬起头缓缓吐出几个烟圈,旁边的我可以清晰地看到他蠕动的喉结,然后就听他说出了上面的那句话。
1.初见老 K
我与老 K 的相识源于一场“某省十大创业明星”的网络投票。我的好友小林是参赛者之一。说来搞笑,小林也是莫名其妙在投票即将结束的前 2 天时接收到了参赛邀请。提交参赛资料之后小林手机便收到一波刷票公司的短信轰炸,内容大体是“*元保证刷前*几名”之类。小林便这样认识了老 K,最终,小林成功获得了这场投票活动的冠军。中间帮助小林判断对方的可信度,我也因此得以结识老 K。
老 K 和我都生活在 J 市。由于我们公司也要做一个在线投票平台,所以希望和老 K 聊聊,从而加强我们系统的防刷能力。老 K 是一个挺谨慎的人,多次沟通后,在最终得知我的真实目的后,他并没有多抵触,答应了我的请求。我们相约在一个茶馆的包间内,我终于见到了他。他与我想象中的形象反差极大,一身干练的西服,短发,看不出程序员的痕迹(哈哈)。
2.与老 K 的对谈
👶寒暄过后,我向他提出了我的疑问:“你和我们说这些刷票手段,就不怕会影响你以后刷不到票吗?”
👤“这个我并不担心。”老 K 磕了下烟灰说道:“其实目前的大部分在线网络投票没有办法做到绝对的防作弊。有的时候是主办方平台程序员的水平有限,但更多时候是主办方出于增加活动的可裂变性进而获得更大的活动收益的目的,为了扩大投票活动的参与人群,减少复杂操作,往往会在防范机制与用户体验之间做诸多取舍。”
👤老 K 顿了顿,接着说道:“举个最简单的例子,你在你朋友圈看到一个投票活动,但是你必须像 12306 抢票一样通过对方的图灵测试,你乐意多瞅一眼吗?”。
👶我似乎明白了,“你说到了在线网络投票的本质:大部分的活动举办方办这些形形色色的投票活动,只是基于为了扩大自己产品知名度这样的一些目的。防刷手段越全面,用户体验基本也会变越差,活动的传播性也会变差。所以作弊者往往是有空子钻的。”
👤“基本是这样的。”他略带嘲讽地笑了一下:“最可笑的是,还有一些平台方办一些不知所云的活动,拉人参赛,然后自己私下收钱帮别人刷,他们更简单,直接改个数字就好了。”
实话,我有些惊讶。老 K 打断了我的沉思,给我讲起了一些刷票的手段。我拿出小本本做起了笔记。
3.老 K 的手段
在线网络投票作弊,就是要突破对方设定的限制,用低成本的方式重复投票。
3.1 cookie 限制
这是一种聊胜于无的限制。一般的防守方都会加这样的限制,可过滤小白,防止重复投票。但是也会有一些防守方仅有 cookie 限制(无语,心是真大!)。
cookie 特别容易丢失和被删除,而且同一台设备上安装的不同浏览器都会被分配 cookie,如下图。而这一切服务端无法控制。
老 K 只需要在一台设备的不同浏览器测试是否可以重复投票,即可判断是否存在此漏洞。
而现实更加残酷,一旦被验证存在这样的漏洞,根本不需要浏览器,只需要重复模拟获取 cookie 的过程,使用获取到的 cookie 重放投票的请求即可。
以百度为例子,如下图,一般在某个请求的 Response Headers 中会直接返回 cookie。
由此可见,cookie 限制,对于稍有常识的攻击者来说,如入无人之境。但是对于正常用户来说,也是无感的,并不会产生不良的操作体验。所以一般的防守方都会加入这样的限制。
3.2 IP 限制
IP 是很难伪造的。但是如果防守方通过 IP 进行对用户的标记,就是练七伤拳,先伤己,再伤人。多个用户在同一个局域网下使用手机是普遍的情况。
有些防守方会设置一个阈值,限制每个 IP 在一定时间内投票的次数。但是这个值很难把握,如果遇到校园网用户,那么阈值该设置多大,这是个问题。
服务端使用 IP 进行作弊限制,可以做到用户无感知。但是遇到 IP 限制,老 K 表示一点也不慌,使用 IP 代理解决就可以。无非是花点钱,IP 代理的成本也并没有很高,都在可接受范围之内。
目前我们使用的网络环境很多都是 IPV4+CIDR(无类域间路由),用有限的 IP 地址接入更多的设备,这种环境下,IP 限制在投票防作弊上起到的作用实在是有限。未来使用 IPV6 后或许作用会更好。
3.3 签名与验签限制
请求发起端和服务端对请求参数采用同一种约定的处理算法(例如:参数键值排序后 MD5 处理),请求发起前使用约定算法生成签名,并在请求发起时作为参数传输。服务端在收到请求后使用同样的算法计算签名,并和请求端传的签名进行比较验证,若双方签名不一致则请求非法。
对于这种情形,老 K 表示 js 代码的逆向难度并不是很大,他也将为此付出一定的时间成本。如下图,对某网页进行逆向并成功获取到签名算法。
签名与验签是对于程序而言的,和用户无关,所以也可以做到用户无感知。由于攻击方需要进行工程逆向,所以防守方采用这样的方案,基本可以过滤很大一部分攻击者了。而防守方也必须注意,源码一定要记得混淆(TAT),如果网页端 js 源码不混淆,攻击方会虔诚地阅读 js 源码。
3.4 验证码限制
有些防守方会采取验证码进行限制,验证一般会有下面这些种类
图形验证码(识别文本类、计算结果类)
手机验证码
邮箱验证码
滑块验证
如果需要突破这种防范,老 K 会使用一些第三方的服务,基于 AI 或者邮箱和手机一类的资源,配合刷票脚本实现。
验证码限制的弊端可想而知,一定程度地破坏了用户的体验。当然,攻击方的成本也被拉高。
3.5 逻辑漏洞
程序既然是人写的,就会存在逻辑漏洞。老 K 举了一个例子。
某活动在微信公众号内进行,用户授权后,系统获取用户的 openid,投票系统使用 openid 对用户进行唯一性标注,以此达到防刷的目的。但是经过抓包分析后发现,该活动的限制流程存在严重的逻辑漏洞。
如上图,乍一看好像并没有什么问题。注意黄色标注部分。
后台下发 cookie 时,前端发起了一个请求,这个请求没有签名限制,并且 openid 是否真实注册在用户信息表并未被后台检验。攻击者可以随意捏造一个 openid,进而获得合法的 cookie。
当后台 count 统计时,首先根据当前 cookie 对应的 openid 获取系统内部 userId,然后根据获取到的 userId 在投票记录表 count 统计,得到当前 userId 的投票次数。由于攻击者没有经过真实注册,根据攻击者提供的 openid 并不能找到对应 userId,所以联表 count 统计结果为 0。
在这种情况下,通过不存在的 openid 获取合法 cookie 后,攻击者不但可以伪造身份,更可以使用这个 cookie 无限次数投票。
“类似这种的逻辑漏洞,我见的太多了。”老 K 有点得意地和我说道。
4.拜别老 K
老 K 给我讲的那些东西虽然谈不上多高深,但是也让我很受启发。确实,要完全杜绝作弊刷票并不现实,但是防守方却可以通过一定的技术手段增加攻击方的突破难度,或者通过增加攻击方刷票的成本,在一定程度上防范刷票。对于防范网络刷票,我也渐渐有了我自己的想法。
我问老 K“随着技术的发展,刷票这个行业会消亡吗?”老 K 说出了下面的话。
这就是一场猫与鼠的游戏,取舍之间,总有这个行业生存的缝隙。
时间过得很快,老 K 起身作别。我和同事目送他离去,看着他渐远的身影。同事悄悄和我说道:“这个行业就是违反规则的成本太低了,抓几个就全老实了。”
版权声明: 本文为 InfoQ 作者【ucsheep】的原创文章。
原文链接:【http://xie.infoq.cn/article/bfd2821f2a196db44c04fdbfa】。未经作者许可,禁止转载。
评论 (21 条评论)