前前言
本人的個(gè)人博客網(wǎng)址:www.QmSharing.space,所有的文章都可以在里面找到,歡迎各位大佬前來參觀并留下寶貴的建議,大家一起學(xué)習(xí)一起成長 :-)
前言
本系列的初衷和 Pwnable.kr 系列一樣, 是為了在最大程度保留游戲樂趣的前提下, 給卡殼的 Player 提供一定的提示, 幫助其完成該題并學(xué)習(xí)到分析的思路.
難度分析
本題雖然在難度評分上是屬于中等偏上的難度, 但如果你之前有做過 PHP 0815 的話, 難度會稍微降低一定(畢竟注入點(diǎn)好找了). 但本題難在考察了一種稍微特殊的 SQL 盲注, 需要 Player 有一定的知識面, 并有較好的 Payload 構(gòu)造和腳本編寫能力(當(dāng)然, 你想花個(gè)幾小時(shí)手工注入, 我也不攔著你 ;-) ).
分析
本題的目的是通過各種方式得到管理員的密碼, 然后提交正確的密碼. 通過對于題目名字的分析, 大概可以猜到這應(yīng)該是個(gè)注入題, 但本題只給了部分的核心代碼:
# 這個(gè)函數(shù)可以忽略, 就是連接數(shù)據(jù)庫用的
function addslash2_get_db() { }
function addslash2_sort($orderby, $dir)
{
# 連接數(shù)據(jù)庫用
if (false === ($db = addslash2_get_db())) {
return false;
}
static $whitelist = array(1, 3, 4, 5);
static $names = array(1 => 'Username', 3 => 'Apples', 4 => 'Bananas', 5 => 'Cherries');
# 這個(gè)變量指定排序方向, 這個(gè)白名單函數(shù)被隱藏了
$dir = GDO::getWhitelistedDirS($dir, 'DESC');
# 看起來像是用了白名單噢! 怎么辦!
if (!in_array($orderby, $whitelist)) {
return htmlDisplayError('Error 1010101: Not in whitelist.');
}
# 還有 escape, 好像很嚴(yán)格呢...
$orderby = $db->escape($orderby);
# 直接拼接 SQL 語句, 啊哈, 還限制了顯示個(gè)數(shù)
$query = "SELECT * FROM users ORDER BY $orderby $dir LIMIT 10";
# ... 顯示結(jié)果
}
如果簡單地審計(jì)一下, 好像輸入都被嚴(yán)格過濾過, 而且還是使用了白名單這種安全的方法. 不過, 這題給我的感覺好像是前面的題目的綜合(如果你和我一樣是按 PHP 分類順序做下來的話). 如果你做過 PHP 0815, 你會輕易地發(fā)現(xiàn), 這個(gè) in_array 的使用好像沒有設(shè)置為嚴(yán)格模式, 更要命的是, 它是和 int 類型進(jìn)行比較(這個(gè)問題可以參考我的 PHP 0815 的文章). 這樣的話, 我可以判斷出這是一個(gè)注入點(diǎn)(因?yàn)槲抑灰斎肴我獾陌酌麊螖?shù)字+一個(gè)非數(shù)字就能繞過 in_array, 比如 "1 -- "), 你輸入后會發(fā)現(xiàn)其實(shí)這個(gè)數(shù)據(jù)庫里有 21 行.
有些人可能做過 PHP 0815, 然后輕易地發(fā)現(xiàn)這個(gè)漏洞, 但他會說, 這個(gè) $orderby 還被 escape 過, 怎么還存在注入呢? 如果你做過 No Escape 這題, 你會知道 mysqli_real_escape_string 僅過濾個(gè)別特殊字符, 但這個(gè)函數(shù)無法防御數(shù)字型注入和類似這種 order by 注入, 因此你只要不用任何引號, 其他的注釋符號(-- 和 #)都是能正常使用的.
有人可能已經(jīng)發(fā)行了這個(gè)注入點(diǎn), 并且成功注入了, 但卻不知道下一步該怎么做? 這其實(shí)也是本題的一個(gè)難點(diǎn), 因?yàn)?order by 的特殊性(它基本只能放在語句末尾), 導(dǎo)致無法使用常用的 union select 大法, 而且很多的注入方法也會失效. 但也并不是無法注入的, 既然我們不能 "明注", 我們可以盲注啊. 這里提示一下, order by 能接 if 或 case 語句, 然后你就可以根據(jù)不同的結(jié)果, 控制顯示的結(jié)果從而猜解出答案. 再提示下去, 答案就出來了, 如果你還是不懂, 可以在留言提出你的問題, 我看到后會盡快解答.
答案
解答步驟和 Writeup 可以在我的 Github 中找到: JackoQm's Github: order_by_query
注: 本題還有小彩蛋, 還是挺有意思的, 不要過錯哦 : )