加加米点击普通网站可刷积分的介绍及其修复方法(图解)
在不少积分或任务系统中,都存在一个经典的设计:用户需要停留或等待一段时间后才能完成操作并获得奖励。这个机制本意是增加用户参与的真实性,但有时候,它也可能成为系统安全的薄弱环节。今天我们就来深入聊聊,在“加加米”这类系统中,一个关于等待时间验证的漏洞是如何被利用的,以及从技术层面该如何进行加固。
简单来说,问题的核心在于,前端用于倒计时的Ja vaScript逻辑,可以被有经验的用户轻易绕过。这就好比一扇门只装了最简易的插销,从内部一拧就开。
漏洞原理与利用方法
系统的原始逻辑是这样的:当用户访问目标页面时,前端会启动一个倒计时(例如20秒),并动态更新页面上的显示。只有当倒计时归零后,“领取”按钮才会出现并变得可点击,此时提交请求到服务器,才能成功获得积分。
那么,怎么绕过这20秒的等待呢?关键在于,这个倒计时和最终的“可提交”状态,完全由前端Ja vaScript控制。攻击者可以利用像Fiddler这类网络抓包软件,拦截并修改浏览器与服务器之间传输的Ja vaScript文件。
具体来看,系统原本的 `click.js` 文件核心函数如下:
function init(s_time, d_delay, p_id, t_countr) {
delay = s_time;
counter = t_countr;
original = s_time;
def_delay = d_delay;
pid = p_id;
main_go();
}
function main_go() {
if (test_go) {
if (counter >= 1) {
$('#secSpan').html('还剩' + counter-- + '秒');
timerID = setTimeout('main_go()', 1000);
} else {
$('.fr').html('领取
');
}
}
}
这段代码清晰展示了其工作流程:初始化参数,然后每秒执行一次 `main_go` 函数更新倒计时显示,直到计数器 `counter` 为0时才注入可点击的按钮。想要绕过等待,思路就非常直接了——修改这段JS逻辑,让它跳过等待,直接执行领取操作。
经过修改后的JS代码变成了这样:
function init(s_time, d_delay, p_id, t_countr) {
pid = p_id;
ajaxTimeRequest(); // 关键修改:不再等待,直接发起领取请求
$("#barframe").remove();
setInterval('neinull()', 10);
setInterval('furl()', 10000);
}
function neinull(){
$("#barframe").remove();
}
function furl(){
$("#barframe").remove();
ajaxTimeRequest();
}
可以看到,原本用于初始化计时器的逻辑被彻底替换。修改后的 `init` 函数一执行,立刻就会调用 `ajaxTimeRequest()` 函数来提交领取请求,完全无视了 `s_time`(等待时间)和 `t_countr`(计数器)这两个参数。这样一来,用户无需等待,甚至无需看到页面内容,积分就已经到手了。


安全加固方案
显然,把核心的安全校验完全放在前端是行不通的,因为前端的一切对用户都是透明的、可篡改的。真正的防线必须建立在服务端。那么,一个有效的修复方案是怎样的?
回顾漏洞利用过程,攻击者修改JS跳过了前端的20秒等待。但如果我们能让服务端也参与这个“20秒”的验证呢?这就是修复的关键思路。
仔细看页面初始化的代码:
$(function(){
init(20, 20, '175efqi51i8xVbyf5ipzpWnCdGJZR3ULtrUOhF+jLNqz/pM', 20);
// ... 其他代码
});
这里,`init` 函数的第三个参数是一个加密字符串。这个字符串,完全可以设计成一种包含时间信息的“令牌”。
一个可行的方案是:当用户首次进入等待页面时,服务端生成一个令牌。这个令牌使用服务器当前的时间戳(例如Linux时间戳)经过特定算法(如HMAC-SHA256)加密生成,然后随着页面一起下发到前端。在 `init` 函数中,这个加密令牌被作为参数传入。
当用户最终点击“领取”按钮(或如漏洞中被直接调用)时,前端需要将这个加密令牌原样提交回服务端。服务端收到请求后,首先解密令牌,提取出其中蕴含的时间戳,然后与服务器当前时间进行比对。
判断逻辑很明确:只有当“当前服务器时间”减去“令牌中记录的时间”大于或等于规定的等待时间(如20秒)时,服务端才判定这次领取操作是合法的,并发放积分。否则,直接拒绝请求,并可以记录一次异常尝试。
这样一来,即使攻击者修改了前端JS,瞬间提交请求,他提交的令牌中记录的还是20秒前的时间戳。服务端一校验,发现时间差几乎为0,远远小于20秒,请求自然会被驳回。这就从根本上堵住了绕过等待时间的漏洞。
总而言之,在涉及积分、奖励、防刷等核心业务逻辑时,必须遵循一个原则:前端负责体验,后端负责规则。任何关键的校验和决策,都必须在不可篡改的服务端完成。这次关于“时间等待”的攻防,就是一个非常典型的案例。
