這個是 4 月份之前的漏洞的,不知道新版本有沒有修復這個問題,但最新一個 VIP 會員反饋遇到刷積分的問題,可能是 QQ 互聯絡結刷積分導致的,所以這裡就把烏雲上面的 discuz x3.1 任務刷積分漏洞的方法拿過來跟大家分享下。

在完成任務時 (home.php?mod=draw&do=view&id=xx),任務先前的狀態缺少判斷
完成任務的連結形如:home.php?mod=draw&do=view&id=xx
這個地址最終在 source/class/class_task.php 中被處理

約第 370 行:

  1. function draw($id) {
  2.         global $_G;
  3.         if(!($this->task = C::t('common_task')->fetch_by_uid($_G['uid'], $id))) {
  4.                 showmessage('task_nonexistence');
  5.         } elseif($this->task['status'] != 0) {
  6.                 showmessage('task_not_underway');
  7.         } elseif($this->task['tasklimits'] && $this->task['achievers'] >= $this->task['tasklimits']) {
  8.                 return -1;
  9.         }
  10. ......

之後就是獲得任務獎勵了
總覺得上面這一段少了些什麼判斷?我們對比下其他程式碼

約第 473 行:

  1. function giveup($id) {
  2.         global $_G;
  3.         if($_GET['formhash'] != FORMHASH) {
  4.                 showmessage('undefined_action');
  5.         } elseif(!($this->task = C::t('common_task')->fetch_by_uid($_G['uid'], $id))) {
  6.                 showmessage('task_nonexistence');
  7.         } elseif($this->task['status'] != '0') {
  8.                 showmessage('task_not_underway');
  9.         }

這一段是放棄任務的判斷,我們看到如果 $this->task['status'] != '0', 就是說任務沒有開始的時候,是不能放棄任務的。

但是,在上面那段獲取任務獎勵的程式碼中,並沒有判斷任務是否開始,造成了無需領取任務,就可以無限次數獲取獎勵。

此漏洞還可以用於強行獲取由於使用者組不符,沒有許可權領取的任務的獎勵。

漏洞詳細利用,請見漏洞證明。

漏洞證明:
1 、新建一個任務,就選擇紅包類任務吧

2 、此時千萬不要申請任務,而是進入任務詳細頁面 (完成之後就不能刷了)
home.php?mod=task&do=view&id=2
這樣就能看到任務詳情了,任務的獎勵是 威望+1 。
我們把地址改為領取任務獎勵
home.php?mod=task&do=draw&id=2
開啟這個地址,獲得了 威望+1 。

不斷重新整理這個頁面,即可不斷獲得獎勵。

修復方案:

在 source/class/class_task.php 中的 draw 函式部分,加入任務是否領取的判斷
即加上

  1. ......
  2. elseif($this->task['status'] != '0') {
  3.         showmessage('task_not_underway');
  4. }

這樣,再次使用漏洞時,就會提示:不是進行中的任務