在github發(fā)現(xiàn)了個代碼審計學(xué)習(xí)的資料哮幢,項目叫PHP-Audit-Labs,紅日安全做的志珍,跟著學(xué)習(xí)下做個記錄吧橙垢。
知識點:in_array(),在不知道列名的情況跑數(shù)據(jù)伦糯,make_set()柜某。
in_array():檢查數(shù)組中是否存在某個值,可以接受3個參數(shù)(a,b,c)敛纲。在b中尋找a喂击,如果存在則返回true,否則返回false载慈。第三個參數(shù)c默認為false惭等,如果指定為TRUE ,則 in_array() 函數(shù)會進行強檢查办铡,檢查a的類型是否和b中的相同辞做,則返回 TRUE,否則返回 FALSE寡具。
將他的代碼下到本地秤茅,我這使用phpstudy,用它給的sql語句在本地數(shù)據(jù)庫里運行一下童叠,再將數(shù)據(jù)庫賬號密碼改下框喳,訪問课幕,配置成功。
先黑盒測試五垮,待會在對照代碼測試乍惊。需要傳一個id。隨便傳一個id=1放仗,返回數(shù)據(jù)润绎,添加單引號,報錯诞挨。傳id=1' and '1'='1莉撇,也出錯。傳id=1 and 1=1惶傻,返回正常棍郎,傳id=1 and 1=2返回異常。存在數(shù)字型注入银室。
嘗試union查詢涂佃,發(fā)現(xiàn)union被過濾了。接著用updatexml(1,concat(0x7e,(select database()),0x7e),1)粮揉,發(fā)現(xiàn)concat被過濾了巡李。用burpsuite的intruder模塊fuzz測試下,大概過濾了or,union,concat,sub,join這些關(guān)鍵字。直接盲注吧扶认,用mid()代替substr()侨拦,id=2 and if(mid((select database()),1,1)='d',sleep(5),1)。
然后想起了or被過濾了辐宾,用不了information.schema狱从,也就是說跑不了表名和列名。emmmm接下來盲猜一下它的表(admin,user,users之類的)叠纹,猜到表名users季研,列名從頁面顯示中得到有(id,name,email,salary)。
如果實在不知道列名誉察,可以通過這個姿勢
select `4` from (select 1,2,3,4 union select * from users)a
正常查詢
發(fā)現(xiàn)列名變成了1与涡,2,3持偏,4
成功查到第3列
但是這里過濾了union驼卖,此處用不上這個姿勢。
接著對應(yīng)著代碼看鸿秆,先看index.php酌畜,大意是得到一個id,經(jīng)過stop_hack()處理卿叽,再用in_array()處理后查詢桥胞。
//index.php
<?php
include 'config.php';
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("連接失敗: ");
}
$sql = "SELECT COUNT(*) FROM users";
$whitelist = array();
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
$whitelist = range(1, $row['COUNT(*)']);
}
$id = stop_hack($_GET['id']);
$sql = "SELECT * FROM users WHERE id=$id";
if (!in_array($id, $whitelist)) {
die("id $id is not in whitelist.");
}
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
echo "<center><table border='1'>";
foreach ($row as $key => $value) {
echo "<tr><td><center>$key</center></td><br>";
echo "<td><center>$value</center></td></tr><br>";
}
echo "</table></center>";
}
else{
die($conn->error);
}
?>
在config.php中恳守,過濾了一些關(guān)鍵字。
//config.php
<?php
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "day1";
function stop_hack($value){
$pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval";
$back_list = explode("|",$pattern);
foreach($back_list as $hack){
if(preg_match("/$hack/i", $value))
die("$hack detected!");
}
return $value;
}
?>
再看下題解贩虾,發(fā)現(xiàn)它用make_set()替代了concat()催烘。搜了一下它的用法
id=4 and (select updatexml(1,make_set(3,'~',(select flag from flag)),1))
make_set(bits,str1,str2,,,,),將第一個參數(shù)轉(zhuǎn)化為二進制缎罢,在1處打印字符str旧噪,0處不打印淆九,詳情如下
1的二進制為0001,倒過來為1000匆瓜,打印a奔则。
2的二進制為0010蛮寂,倒過來為0100,打印b易茬。
7的二進制為0111酬蹋,倒過來為1110,打印a,b,c抽莱。
[圖片上傳中...(圖片.png-7b38da-1562846283165-0)]