WebGoat學習——SQL注入(SQL Injection)


SQL注入(SQL Injection)

      所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串,欺騙服務器執行惡意的SQL命令。攻擊者通過web請求提交帶有影響正常SQL執行的參數(arlen’ OR ‘1’=’1),服務端在執行SQL時參數的特殊性影響了原本的意思(select * from table where user=’arlen\’ OR \’1\’=\’1’;),執行了非預期的操作(select * from table where user=’arlen’ OR ‘1’='1’),從而是攻擊者獲取到了其他用戶的信息或者對服務造成了攻擊。

      SQL注入操作簡單,危害嚴重,現在也有比較成熟的防范措施,但是往往因為開發人員操作不當(例如:忘記過濾參數、不當的錯誤處理、配置失誤)而產生風險,如果未被發現SQL注入漏洞並不影響任何系統功能,往往也不被察覺,一旦攻擊者發現SQL漏洞,后果就比較嚴重。

SQL注入技術原理

    在大多數web接口傳入的參數最終都會反映到數據庫表中的某一字段,例如用戶登錄的例子:

      后端代碼通過如下方法實現:

<?php
$con = mysql_connect("localhost", "xxx", "xxx");
if (!$con)
{
      die('Could not connect: '.mysql_error());
}

$db_selected = mysql_select_db("xxx", $con);
if (!$db_selected) 
{
     die('select db test failed: '.mysql_error());
}

$user = $_REQUEST["user"];
$pwd = $_REQUEST["password"];

$sql = "select count(*) as count from user_info where user = '$user' AND password = '$pwd';";

$sql_query = mysql_query($sql, $con);
if (!$sql_query)
{
    die(' mysql_query failed: '.mysql_error());
}

$num = 0;
if (!$data = mysql_fetch_object($sql_query))
{
    die('mysql_fetch_object failed: '.mysql_error());
}
else
{
    $num = $data->count;
}

if (0 >= $num)
{
     echo "user[$user] login failed!";
}
else
{
    echo "user[$user] login succ!";
 }

?>

      在后端實現是通過下面SQL來判斷用戶和密碼是否匹配:

SELECT COUNT (*) as count FROM user_info WHERE user='arlen' AND password='123456';

如果服務器沒有做過濾操作,可以令user=arlen’ or ‘1’='1來進行登錄,即便完全不知道用戶arlen對應的密碼一樣可以校驗通過,php拼裝的SQL語句為:

SELECT COUNT (*) as count FROM user_info WHERE user='arlen' or '1' = '1' AND password='123456';

      這樣只要user_info表中有數據就能通過login的校驗。

      SQL注入的原理就是在正常station 字段中注入特征字符,能組合成新的SQL 語句。SQL注入學習成本低,攻擊性高,容易防范,但往往因為工作上的失誤或者測試的不足而留下漏洞。

SQL注入防御

      SQL注入原理簡單易學,但防范起來卻略為復雜,本質就是防止用戶輸入的不安全參數放映到具體的SQL語句上,例如:

1. web參數過濾,只允許約定的字符出現,比如數字、字母,100%解決問題,但過於暴力;

2. 對需要拼裝SQL語句的參數做過濾,例如PHP自帶的mysql_real_escape_string()函數,修改上述代碼如下:

if (!$db_selected) 
{
     die('</br>select db test failed: '.mysql_error());
}

$user = mysql_real_escape_string($_REQUEST["user"]);
$pwd = mysql_real_escape_string($_REQUEST["password"]);


$sql = "select count(*) as count from user_info where user = '$user' AND password = '$pwd';";

echo $sql;

$sql_query = mysql_query($sql, $con);

這樣實際執行的SQL為:

select count(*) as count from user_info where user = 'arlen\' or \'1\' = \'1' AND password = '1234567';

3. 小心拼寫SQL語句,一定要注意拼接SQL字段各個字段的來源,如果是外部傳入的,根據不信任原則,一定要嚴格校驗過濾;

4. 設置Mysql權限,只給訪問數據庫的web應用功能所需的最低權限帳戶,這種只能降低損失,並不能避免注入;

5. 避免將數據庫的錯誤信息直接返回,對於Mysql錯誤,程序一定要識別后再做返回,避免將錯誤描述直接返回給前端。

6. 小心、細心,SQL注入最常出現在開發人員粗心時;

7. 借助SQL注入掃描工具。

SQL注入其他資料

百度百科:http://baike.baidu.com/view/3896.htm

SQL注入危害:http://www.cnblogs.com/hkncd/archive/2012/03/31/2426274.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM