目錄
什么是SQL注入
SQL注入產(chǎn)生的原因
SQL注入攻擊方式
如何進(jìn)行SQL注入
SQL注入三部曲
1.滲透攻防WEB篇-SQL注入攻擊初級(jí)
什么是SQL注入
結(jié)構(gòu)化查詢語言(Structured Query Language贮缕,縮寫:SQL)窃页,是一種特殊的編程語言,用于數(shù)據(jù)庫中的標(biāo)準(zhǔn)數(shù)據(jù)查詢語言怠李。1986年10月殿衰,美國國家標(biāo)準(zhǔn)學(xué)會(huì)對SQL進(jìn)行規(guī)范后朱庆,以此作為關(guān)系式數(shù)據(jù)庫管理系統(tǒng)的標(biāo)準(zhǔn)語言(ANSI X3. 135-1986),1987年得到國際標(biāo)準(zhǔn)組織的支持下成為國際標(biāo)準(zhǔn)闷祥。不過各種通行的[數(shù)據(jù)庫系統(tǒng)](http://www.ichunqiu.com/courses/277)在其實(shí)踐過程中都對SQL規(guī)范作了某些編改和擴(kuò)充娱颊。所以,實(shí)際上不同數(shù)據(jù)庫系統(tǒng)之間的SQL不能完全相互通用凯砍。
SQL注入(SQL Injection)是一種常見的web安全漏洞箱硕,攻擊者利用這個(gè)問題,可以訪問或修改數(shù)據(jù)悟衩,或者利用潛在的數(shù)據(jù)庫漏洞進(jìn)行攻擊剧罩。
SQL注入產(chǎn)生的原因
針對SQL注入的攻擊行為可描述為通過在用戶可控參數(shù)中注入SQL語法,破壞原有的SQL結(jié)構(gòu)座泳,達(dá)到編寫程序時(shí)意料之外結(jié)果的攻擊行為惠昔,其成因可以歸結(jié)為以下兩個(gè)元云疊加造成的:
1.程序編寫者在處理應(yīng)用程序和數(shù)據(jù)庫交互時(shí)幕与,使用字符串拼接的方式造成SQL語句
2.未對用戶可控參數(shù)進(jìn)行住夠的過濾便將參數(shù)內(nèi)容拼接進(jìn)入到SQL語句中
SQL注入攻擊方式
SQL注入的攻擊方式根據(jù)應(yīng)用程序處理數(shù)據(jù)庫返回內(nèi)容的不同,可以分為可顯注入镇防、報(bào)錯(cuò)注入和盲注:
1啦鸣、可顯注入:攻擊者可以直接在當(dāng)前界面內(nèi)容中獲取想要獲得的內(nèi)容
2、報(bào)錯(cuò)注入:數(shù)據(jù)庫查詢返回結(jié)果并沒有在頁面中顯示来氧,但是應(yīng)用程序?qū)?shù)據(jù)庫報(bào)錯(cuò)信息打印到了頁面中诫给,所以攻擊者可以構(gòu)造數(shù)據(jù)庫報(bào)錯(cuò)語句,從報(bào)錯(cuò)信息中獲取想要獲得的內(nèi)容
3啦扬、盲注:數(shù)據(jù)庫查詢結(jié)果無法從直觀頁面中獲取中狂,攻擊者通過使用數(shù)據(jù)庫邏輯或使數(shù)據(jù)庫庫執(zhí)行延時(shí)等方法獲取想要獲得的內(nèi)容
如何進(jìn)行SQL注入
SQL注入攻擊是非常令人討厭的安全漏洞,是所有的web開發(fā)人員考传,不管是什么平臺(tái)吃型,技術(shù),還是數(shù)據(jù)層僚楞,需要確信他們理解和防止的東西勤晚。不幸的是,開發(fā)人員往往不集中花點(diǎn)時(shí)間在這上面泉褐,以至他們的應(yīng)用赐写,更糟糕的是,他們的客戶極其容易受到攻擊膜赃。下面的三部曲從漏洞發(fā)現(xiàn)到漏洞確認(rèn)挺邀,再到漏洞利用,最后漏洞防御四個(gè)方面的技術(shù)做了詳細(xì)的講解跳座。
SQL注入三部曲
1.滲透攻防WEB篇-SQL注入攻擊初級(jí)
前言:
不管用什么語言編寫的Web應(yīng)用端铛,它們都用一個(gè)共同點(diǎn),具有交互性并且多數(shù)是數(shù)據(jù)庫驅(qū)動(dòng)疲眷。在網(wǎng)絡(luò)中禾蚕,數(shù)據(jù)庫驅(qū)動(dòng)的Web應(yīng)用隨處可見,由此而存在的SQL注入是影響企業(yè)運(yùn)營且最具破壞性的漏洞之一狂丝,這里我想問换淆,我們真的了解SQL注入嗎?看完本篇文章希望能讓你更加深刻的認(rèn)識(shí)SQL注入几颜。
注釋:
數(shù)據(jù)庫驅(qū)動(dòng)是不同數(shù)據(jù)庫開發(fā)商(比如oracle mysql等)為了某一種開發(fā)語言環(huán)境(比如java)能夠?qū)崿F(xiàn)統(tǒng)一的數(shù)據(jù)庫調(diào)用而開發(fā)的一個(gè)程序倍试,他的作用相當(dāng)于一個(gè)翻譯人員,將Java語言中對數(shù)據(jù)庫的調(diào)用語言通過這個(gè)翻譯翻譯成各個(gè)種類的數(shù)據(jù)庫自己的數(shù)據(jù)庫語言蛋哭,當(dāng)然這個(gè)翻譯(數(shù)據(jù)庫驅(qū)動(dòng))是由各個(gè)開發(fā)商針對統(tǒng)一的接口自定義開發(fā)的
目錄:
第一節(jié) 注入攻擊原理及自己編寫注入點(diǎn)
1.1县习、什么是SQL?
1.2、什么是SQL注入躁愿?
1.3哈蝇、SQL注入是怎么樣產(chǎn)生的?
1.4攘已、編寫注入點(diǎn)
第二節(jié) 尋找及確認(rèn)SQL注入
2.1、推理測試法
2.2怜跑、and大法和or大法
2.3样勃、加法和減法
第一節(jié)注入攻擊原理及自己編寫注入點(diǎn)
1.1什么是SQL?
SQL 是一門 ANSI 的標(biāo)準(zhǔn)計(jì)算機(jī)語言性芬,用來訪問和操作數(shù)據(jù)庫系統(tǒng)峡眶。SQL 語句用于取回和更新數(shù)據(jù)庫中的數(shù)據(jù)。SQL 可與數(shù)據(jù)庫程序協(xié)同工作植锉,比如 MS Access辫樱、DB2、Informix俊庇、MS SQL Server狮暑、Oracle、Sybase 以及其他數(shù)據(jù)庫系統(tǒng)
1.2什么是SQL注入辉饱?
看起來很復(fù)雜搬男,其實(shí)很簡單就能解釋,SQL注入就是一種通過操作輸入來修改后臺(tái)SQL語句達(dá)到代碼執(zhí)行進(jìn)行攻擊目的的技術(shù)彭沼。
1.3 SQL注入是怎樣產(chǎn)生的缔逛?
構(gòu)造動(dòng)態(tài)字符串是一種編程技術(shù),它允許開發(fā)人員在運(yùn)行過程中動(dòng)態(tài)構(gòu)造SQL語句姓惑。開發(fā)人員可以使用動(dòng)態(tài)SQL來創(chuàng)建通用褐奴、靈活的應(yīng)用。動(dòng)態(tài)SQL語句是在執(zhí)行過程中構(gòu)造的于毙,它根據(jù)不同的條件產(chǎn)生不同的SQL語句敦冬。當(dāng)開發(fā)人員在運(yùn)行過程中需要根據(jù)不同的查詢標(biāo)準(zhǔn)來決定提取什么字段(如SELECT語句),或者根據(jù)不同的條件來選擇不同的查詢表時(shí)望众,動(dòng)態(tài)構(gòu)造SQL語句會(huì)非常有用匪补。
在PHP中動(dòng)態(tài)SQL語句字符串:
$query = "SELECT * FROM users WHERE username = ".$_GET["id"];
看上面代碼我們可以控制輸入?yún)?shù)xway,修改所要執(zhí)行SQL語句烂翰,達(dá)到攻擊的目的夯缺。
1.4編寫注入點(diǎn)
基礎(chǔ)知識(shí):
SQL SELECT 語法
SELECT 列名稱 FROM 表名稱
符號(hào) * 取代列的名稱是選取所有列
WHERE 子句
如需有條件地從表中選取數(shù)據(jù),可將 WHERE 子句添加到 SELECT 語句甘耿。
語法
SELECT 列名稱 FROM 表名稱 WHERE 列 運(yùn)算符 值
下面的運(yùn)算符號(hào)可以在WHERE子句中使用操作符
= 等于
<> 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
BETWEEN 在某個(gè)范圍內(nèi)
LIKE 搜索某種模式
以上基礎(chǔ)主要是介紹數(shù)據(jù)庫的查詢簡單使用方式踊兜,之后我們在出入中會(huì)使用到
編寫注入點(diǎn):
第一步:我們使用if語句先判斷一下變量是否初始化
<?php
If(isset(_GET[“id”])){
}
?>
注釋:isset檢查變量是否設(shè)置
第二步:在if語句內(nèi),我們連接數(shù)據(jù)庫佳恬。
mysql_connect(servername,username,password);
注釋:php中mysql_connect函數(shù)用于連接數(shù)據(jù)庫
servername 可選捏境。規(guī)定要連接的服務(wù)器于游。默認(rèn)是 "localhost:3306"。
username 可選垫言。規(guī)定登錄所使用的用戶名贰剥。默認(rèn)值是擁有服務(wù)器進(jìn)程的用戶的名稱。
password 可選筷频。規(guī)定登錄所用的密碼蚌成。默認(rèn)是 ""。
第三步:選擇數(shù)據(jù)庫凛捏,選擇你要使用的數(shù)據(jù)庫
mysql_select_db(database,connection)
注釋:database 必須担忧,數(shù)據(jù)庫名
connection 可選。規(guī)定 SQL 連接標(biāo)識(shí)符坯癣。如果未規(guī)定瓶盛,則使用上一個(gè)打開的連接。
第四步:選擇完數(shù)據(jù)庫示罗,執(zhí)行一條mysql查詢語句惩猫。
mysql_query(query,connection)
注釋:query 必需。規(guī)定要發(fā)送的 SQL 查詢鹉勒。注釋:查詢字符串不應(yīng)以分號(hào)結(jié)束帆锋。
connection 可選。規(guī)定 SQL 連接標(biāo)識(shí)符禽额。如果未規(guī)定锯厢,則使用上一個(gè)打開的連接。
第五步:執(zhí)行完查詢脯倒,對結(jié)果進(jìn)行處理
mysql_fetch_array(data,array_type)
注釋:data 可選实辑。規(guī)定要使用的數(shù)據(jù)指針。該數(shù)據(jù)指針是 mysql_query() 函數(shù)產(chǎn)生的結(jié)果藻丢。
array_type 可選剪撬。規(guī)定返回哪種結(jié)果∮品矗可能的值:
MYSQL_ASSOC - 關(guān)聯(lián)數(shù)組
MYSQL_NUM - 數(shù)字?jǐn)?shù)組
MYSQL_BOTH - 默認(rèn)残黑。同時(shí)產(chǎn)生關(guān)聯(lián)和數(shù)字?jǐn)?shù)組
最后使用echo輸出查詢內(nèi)容
echo $querry
最后的頁面
<?php
if(isset($_GET["id"])){
$con = mysql_connect("127.0.0.1:3306","root","root");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("ichunqiu",$con);
$querry = "select * from users where id = " . $_GET['id'];
$sql = mysql_query($querry,$con);
$result = mysql_fetch_array($sql);
echo "<table class='itable' border='1' cellspacing='0' width='300px' height='150'>";
echo "<tr>";
echo "<td>id</td>";
echo "<td>username</td>";
echo "</tr>";
echo "<tr>";
echo "<td>".$result['id']."</td>";
echo "<td>".$result['username']."</td>";
echo "</tr>";
echo "</table>";
mysql_close($con);
echo $querry;
}
?>
注釋:以上代碼連接數(shù)據(jù)庫通過變量執(zhí)行查詢語句,通過mysql_fetch_array對查詢結(jié)果進(jìn)行分類斋否,然后提取在頁面的表單內(nèi)
數(shù)據(jù)庫配置
創(chuàng)建數(shù)據(jù)庫ichunqiu
表單users
列 id梨水,username,password
插入幾條數(shù)據(jù)
將上面網(wǎng)頁保存成test.php放在phpstudy下的www目錄下茵臭。
然后我們就開始下一階段的內(nèi)容
第二節(jié)尋找及確認(rèn)SQL注入
2.1推理測試法
尋找SQL注入漏洞有一種很簡單的方法疫诽,就是通過發(fā)送特殊的數(shù)據(jù)來觸發(fā)異常。
首先我們需要了解數(shù)據(jù)是通過什么方式進(jìn)行輸入,這里我總結(jié)了三個(gè):
GET請求:該請求在URL中發(fā)送參數(shù)奇徒。
POST請求:數(shù)據(jù)被包含在請求體中雏亚。
其他注入型數(shù)據(jù):如cookie注入,http頭注入等多種注入方式
了解完數(shù)據(jù)的輸入方式摩钙,我們接下來再學(xué)習(xí)數(shù)據(jù)庫錯(cuò)誤罢低。這里我們以MySQL為例,其它的請大家自行學(xué)習(xí)咯胖笛。
我們現(xiàn)在參數(shù)后面加個(gè)單引號(hào)奕短,如下圖:
執(zhí)行失敗,所以mysql_query()函數(shù)會(huì)返回一個(gè)布爾值匀钧,在下行代碼中mysql_fetch_array($sql)將執(zhí)行失敗,并且PHP會(huì)顯示一條警告信息谬返,告訴我們mysql_fetch_array()的第一個(gè)參數(shù)必須是個(gè)資源之斯,而代碼在實(shí)際運(yùn)行中,給出的參數(shù)值卻是一個(gè)布爾值遣铝。
我們修改代碼在:
$sql = mysql_query($querry,$con);下一行加上
var_dump($sql);
注釋:var_dump()方法是判斷一個(gè)變量的類型與長度,并輸出變量的數(shù)值,如果變量有值輸?shù)氖亲兞康闹挡⒒胤禂?shù)據(jù)類型.此函數(shù)顯示關(guān)于一個(gè)或多個(gè)表達(dá)式的結(jié)構(gòu)信息佑刷,包括表達(dá)式的類型與值。數(shù)組將遞歸展開值酿炸,通過縮進(jìn)顯示其結(jié)構(gòu)瘫絮。
為了更好的了解MySQL錯(cuò)誤,我們在
$sql = mysql_query($querry,$con);下面加上
if(!$sql)
{
die('<p>error:'.mysql_error().'</p>');
}
這樣當(dāng)應(yīng)用捕獲到數(shù)據(jù)庫錯(cuò)誤且SQL查詢失敗時(shí)填硕,就會(huì)返回錯(cuò)誤信息:(我們在參數(shù)中添加單引號(hào)返回的錯(cuò)誤信息)
error:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1
完成后刪除
2.2 and 和 or 判斷
頁面不返回任何錯(cuò)誤信息麦萤,我們就可以借助本方法來推斷了,首先我們在參數(shù)后面加上 and 1=1和and 1=2看看有什么不同扁眯。
原理:可以發(fā)現(xiàn)and 1=1 返回了數(shù)據(jù)壮莹,而and 1=2沒有,這是由于1=1是一個(gè)為真的條件姻檀,前面的結(jié)果是true命满,true and true 所以沒有任何問題,第二個(gè) 1=2 是個(gè)假條件绣版, true and false還是false胶台,所以并沒有數(shù)據(jù)返回。
注:主要是利用數(shù)據(jù)庫的聯(lián)合查詢的特性杂抽,使用and或or連接符將查詢關(guān)聯(lián)诈唬,并通過查詢的成功和失敗判斷插入字符是否被帶入數(shù)據(jù)庫進(jìn)行執(zhí)行,如果執(zhí)行了我們就判斷該點(diǎn)存在SQL注入默怨。
修改輸出格式:
<?php
if(isset($_GET["id"]))
{
$con = mysql_connect("127.0.0.1:3306","root","root");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("ichunqiu",$con);
$querry = "select * from users where id = ".$_GET['id'];
$sql = mysql_query($querry,$con);
# $result = mysql_fetch_array($sql); #注釋掉
echo "<table class='itable' border='1' cellspacing='0' width='300px' height='150'>";
echo "<tr>";
echo "<td>id</td>";
echo "<td>username</td>";
echo "</tr>";
while ($result = mysql_fetch_array($sql))
{
echo "<tr>";
echo "<td>" . $result[0] . "</td>";
echo "<td>" . $result[1] . "</td>";
echo "</tr>";
}
echo "</table>";
mysql_close($con);
echo $querry;
}
?>
執(zhí)行查詢結(jié)果
使用or 1=1 輸出全部結(jié)果
2.3 加法和減法
注入中數(shù)字型:使用加法減法判斷
其他類型:使用單引號(hào)判斷
我們使用代碼類型為注入類型為數(shù)字型.
我們使用+號(hào)時(shí)需要對加號(hào)進(jìn)行url編碼為%2b
編碼后執(zhí)行為id=1%2b1輸出結(jié)果為id=2時(shí)表示運(yùn)算在SQL中執(zhí)行讯榕,該點(diǎn)存在SQL注入。
減號(hào)也是相同原理,減號(hào)不用使用url進(jìn)行編碼