SQL注入

為什么會存在SQL注入

通俗來講艇拍,sql作為一種解釋型語言,在運(yùn)行時是由一個運(yùn)行時組件解釋語言代碼并執(zhí)行其中包含的指令的語言宠纯⌒断Γ基于這種執(zhí)行方式,產(chǎn)生了一系列叫做代碼注入(code injection)的漏洞 婆瓜。它的數(shù)據(jù)其實(shí)是由程序員編寫的代碼和用戶提交的數(shù)據(jù)共同組成的快集。程序員在web開發(fā)時贡羔,沒有過濾敏感字符,綁定變量个初,導(dǎo)致攻擊者可以通過sql靈活多變的語法乖寒,構(gòu)造精心巧妙的語句,不擇手段院溺,達(dá)成目的楣嘁,或者通過系統(tǒng)報錯,返回對自己有用的信息珍逸。

經(jīng)常我們在面試中會遇到"sql中#和$的區(qū)別"逐虚,都會提到注入問題:
(1)#將傳入的數(shù)據(jù)都當(dāng)成一個字符串,會對自動傳入的數(shù)據(jù)加一個雙引號谆膳。如:order by #user_id#叭爱,如果傳入的值是id,則解析成的sql為order by "id"漱病。
(2)$將傳入的數(shù)據(jù)直接顯示生成在sql中买雾。如:order by $user_id$,如果傳入的值是id缨称,則解析成的sql為order by id凝果。
(3)#方式在很大程度上能夠防止sql注入。
(4)$方式無法防止sql注入睦尽。

SQL注入演示

以PHP+MySQL為例器净,以一個Web網(wǎng)站中最基本的用戶系統(tǒng)來做實(shí)例演示。
1.創(chuàng)建一個名為demo的數(shù)據(jù)庫:

CREATE DATABASE  `demo` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

2.創(chuàng)建一個名為user的數(shù)據(jù)表当凡,并插入1條演示數(shù)據(jù):

CREATE TABLE  `demo`.`user` (
`uid` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT  '用戶uid',
`username` VARCHAR( 20 ) NOT NULL COMMENT  '用戶名',
`password` VARCHAR( 32 ) NOT NULL COMMENT  '用戶密碼'
) ENGINE = INNODB;
INSERT INTO `demo`.`user` (`uid`, `username`, `password`) VALUES ('1', 'plhwin', MD5('123456'));

實(shí)例一

傳入username參數(shù)山害,在頁面打印出這個user的詳細(xì)信息,編寫 userinfo.php 程序代碼:

<?php
header('Content-type:text/html; charset=UTF-8');
$username = isset($_GET['username']) ? $_GET['username'] : '';
$userinfo = array();
if($username){
    //使用mysqli驅(qū)動連接demo數(shù)據(jù)庫
    $mysqli = new mysqli("localhost", "root", "root", 'demo');
    $sql = "SELECT uid,username FROM user WHERE username='{$username}'";
    //mysqli multi_query 支持執(zhí)行多條MySQL語句
    $query = $mysqli->multi_query($sql);
    if($query){
        do {
            $result = $mysqli->store_result();
            while($row = $result->fetch_assoc()){
                $userinfo[] = $row;
            }
            if(!$mysqli->more_results()){
                break;
            }
        } while ($mysqli->next_result());
    }
}
echo '<pre>',print_r($userinfo, 1),'</pre>';

上面這個程序要實(shí)現(xiàn)的功能是根據(jù)瀏覽器傳入的用戶名參數(shù)沿量,在頁面上打印出這個用戶的詳細(xì)信息浪慌,采用了mysqli的驅(qū)動,以便能使用到 multi_query 方法來支持同時執(zhí)行多條SQL語句朴则,這樣能更好的說明SQL注入攻擊的危害性权纤。

假設(shè)我們可以通過 http://localhost/test/userinfo.php?username=plhwin這個URL來訪問到具體某個會員的詳情,正常情況下乌妒,如果瀏覽器里傳入的username是合法的汹想,那么SQL語句會執(zhí)行:

SELECT uid,username FROM user WHERE username='plhwin'

如果在瀏覽器里把傳入的username參數(shù)變?yōu)?"plhwin';SHOW TABLES-- hack",也就是當(dāng)URL變?yōu)?code>http://localhost/test/userinfo.php?username=plhwin';SHOW TABLES-- hack的時候撤蚊,此時我們程序?qū)嶋H執(zhí)行的SQL語句變成了:

SELECT uid,username FROM user WHERE username='plhwin';SHOW TABLES-- hack'

--會注釋后面的內(nèi)容
此時可以在瀏覽器里看到頁面的輸出,數(shù)據(jù)庫的user表古掏,此時將參數(shù)換成plhwin';DROP TABLE user-- hack,那將產(chǎn)生災(zāi)難性的嚴(yán)重結(jié)果侦啸。

Array
(
    [0] => Array
        (
            [uid] => 1
            [username] => plhwin
        )
    [1] => Array
        (
            [Tables_in_demo] => user
        )
)

SQL注入攻擊的總體思路

1.尋找到SQL注入的位置

2.判斷服務(wù)器類型和后臺數(shù)據(jù)庫類型

3.針對不通的服務(wù)器和數(shù)據(jù)庫特點(diǎn)進(jìn)行SQL注入攻擊

主要講一下如何尋找SQL注入點(diǎn)
尋找注入點(diǎn)常用的方法就是通過 不斷調(diào)整參數(shù)來測試服務(wù)器的響應(yīng)槽唾,進(jìn)而暴露出與數(shù)據(jù)庫結(jié)構(gòu)有關(guān)的問題丧枪。傳入SQL語句可控參數(shù)分為兩類

  • 數(shù)字類型,參數(shù)不用被引號括起來庞萍,如?id=1
  • 其他類型拧烦,參數(shù)要被引號擴(kuò)起來,如?name="phone"

數(shù)字類型

構(gòu)造測試 預(yù)期結(jié)果 變種
' 觸發(fā)錯誤,返回數(shù)據(jù)庫錯誤
1+1 返回原來相同的結(jié)果 3-1
1+0 返回原來相同的結(jié)果
1 or 1=1 永真條件挂绰,返回所有記錄 1) or (1=1
1 or 1=2 空條件屎篱,返回原來相同的結(jié)果 1) or (1=2
1 and 1=2 永假條件,不返回記錄 1) and (1=2

其他類型

構(gòu)造測試 預(yù)期結(jié)果 變種
col 3 is right-aligned $1600
col 2 is centered $12
zebra stripes are neat $1
a' 觸發(fā)錯誤葵蒂,返回數(shù)據(jù)庫錯誤
a' or '1'='1 永真條件交播,返回所有記錄 a') or ('1'=1
a' or '1'='2 空條件,返回原來相同結(jié)果 a') or ('1'=2
a' and '1'='2 永假條件践付,不返回記錄 a') and ('1'='2

常見基本的方法有如下幾種:
1.加引號法,通過在瀏覽器地址欄中的頁面鏈接地址后面增加一個單引號秦士,進(jìn)而測試服務(wù)器的響應(yīng),來判斷是否存在注入點(diǎn)永高。
2.“1=1和1=2”法

后續(xù)待補(bǔ)充

如何預(yù)防SQL注入

1. PreparedStatement預(yù)編譯語句(簡單最有效)

采用預(yù)編譯語句集隧土,它內(nèi)置了處理SQL注入的能力,不同的程序語言命爬,都分別有使用預(yù)編譯語句的方法曹傀。
使用好處:

(1).代碼的可讀性和可維護(hù)性.
(2).PreparedStatement盡最大可能提高性能.
(3).最重要的一點(diǎn)是極大地提高了安全性.

還是以php為例:

<?php
header('Content-type:text/html; charset=UTF-8');
$username = isset($_GET['username']) ? $_GET['username'] : '';
$userinfo = array();
if($username){
    //使用mysqli驅(qū)動連接demo數(shù)據(jù)庫
    $mysqli = new mysqli("localhost", "root", "root", 'demo');
    //使用問號替代變量位置
    $sql = "SELECT uid,username FROM user WHERE username=?";
    $stmt = $mysqli->prepare($sql);
    //綁定變量
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $stmt->bind_result($uid, $username);
    while ($stmt->fetch()) {
        $row = array();
        $row['uid'] = $uid;
        $row['username'] = $username;
        $userinfo[] = $row;
    }
}
echo '<pre>',print_r($userinfo, 1),'</pre>';

我們程序里并沒有使用addslashes函數(shù),但是瀏覽器里運(yùn)行 http://localhost/test/userinfo2.php?username=plhwin' AND 1=1-- hack 里得不到任何結(jié)果饲宛,說明SQL漏洞在這個程序里并不存在皆愉。實(shí)際上,綁定變量使用預(yù)編譯語句是預(yù)防SQL注入的最佳方式艇抠,使用預(yù)編譯的SQL語句語義不會發(fā)生改變幕庐,在SQL語句中,變量用問號?表示家淤,黑客即使本事再大异剥,也無法改變SQL語句的結(jié)構(gòu),像上面例子中絮重,username變量傳遞的 plhwin' AND 1=1-- hack 參數(shù)冤寿,也只會當(dāng)作username字符串來解釋查詢,從根本上杜絕了SQL注入青伤。

2.用正則表達(dá)式過濾傳入的參數(shù)

如關(guān)鍵字過濾:

reg = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|"  + "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";
3.字符串過濾
4.js代碼預(yù)防注入(后臺仍然需要預(yù)防)
5.不要隨意開啟生產(chǎn)環(huán)境中Webserver的錯誤顯示督怜,同時不要信任任何用戶輸入的數(shù)據(jù),對請求服務(wù)器的數(shù)據(jù)需要進(jìn)行一定的規(guī)則和格式校驗(yàn)潮模。

附sql注入系列專題:sql注入專題
同時推薦testfire.net來模擬漏洞攻擊:demo.testfire.net


看不到我 / \ 看不到我~~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亮蛔,一起剝皮案震驚了整個濱河市痴施,隨后出現(xiàn)的幾起案子擎厢,更是在濱河造成了極大的恐慌究流,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件动遭,死亡現(xiàn)場離奇詭異芬探,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)厘惦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門偷仿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宵蕉,你說我怎么就攤上這事酝静。” “怎么了羡玛?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵别智,是天一觀的道長。 經(jīng)常有香客問我稼稿,道長薄榛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任让歼,我火速辦了婚禮敞恋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谋右。我一直安慰自己硬猫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布倚评。 她就那樣靜靜地躺著浦徊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪天梧。 梳的紋絲不亂的頭發(fā)上盔性,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音呢岗,去河邊找鬼冕香。 笑死,一個胖子當(dāng)著我的面吹牛后豫,可吹牛的內(nèi)容都是我干的悉尾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼挫酿,長吁一口氣:“原來是場噩夢啊……” “哼构眯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起早龟,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤惫霸,失蹤者是張志新(化名)和其女友劉穎猫缭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壹店,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猜丹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了硅卢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片射窒。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖将塑,靈堂內(nèi)的尸體忽然破棺而出脉顿,到底是詐尸還是另有隱情,我是刑警寧澤点寥,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布弊予,位于F島的核電站,受9級特大地震影響开财,放射性物質(zhì)發(fā)生泄漏汉柒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一责鳍、第九天 我趴在偏房一處隱蔽的房頂上張望碾褂。 院中可真熱鬧,春花似錦历葛、人聲如沸正塌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乓诽。三九已至,卻和暖如春咒程,著一層夾襖步出監(jiān)牢的瞬間鸠天,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工帐姻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留稠集,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓饥瓷,卻偏偏與公主長得像剥纷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子呢铆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Web安全簡史 在Web1.0時代晦鞋,人們更多是關(guān)注服務(wù)器端動態(tài)腳本語言的安全問題,比如將一個可執(zhí)行腳本(俗稱Web...
    潘良虎閱讀 3,930評論 3 72
  • Sql 注入基礎(chǔ)原理介紹一、實(shí)驗(yàn)說明1.1 實(shí)驗(yàn)內(nèi)容SQL注入攻擊通過構(gòu)建特殊的輸入作為參數(shù)傳入Web應(yīng)用程序悠垛,而...
    FreaxJJ閱讀 1,819評論 3 23
  • 姓名:于川皓 學(xué)號:16140210089 轉(zhuǎn)載自:https://baike.baidu.com/item/sq...
    道無涯_cc76閱讀 1,949評論 0 2
  • SQL注入 概念 危害 原理 實(shí)例 防御 基礎(chǔ) - ### SQL語句所用符號不同數(shù)據(jù)庫的sql注入與提權(quán)常見S...
    yddchsc君閱讀 1,317評論 1 10
  • SQL注入漏洞全接觸--入門篇 隨著B/S模式應(yīng)用開發(fā)的發(fā)展鼎文,使用這種模式編寫應(yīng)用程序的程序員也越來越多。但是由于...
    西邊人閱讀 701評論 0 0