來源前硫;http://bbs.ichunqiu.com/thread-9518-1-1.html?from=ch
作者:zusheng
時(shí)間:2016年8月3日 12:11:50
社區(qū):i春秋
前言
不管用什么語言編寫的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)營(yíng)且最具破壞性的漏洞之一败明,這里我想問隘马,我們真的了解SQL注入嗎?看完本篇文章希望能讓你更加深刻的認(rèn)識(shí)SQL注入肩刃。
目錄
第一節(jié) 注入攻擊原理及自己編寫注入點(diǎn)
1.1祟霍、什么是SQL?
1.2盈包、什么是SQL注入沸呐?
1.3、SQL注入是怎么樣產(chǎn)生的呢燥?
1.4崭添、編寫注入點(diǎn)
第二節(jié) 尋找及確認(rèn)SQL注入
2.1、推理測(cè)試法
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í)很簡(jiǎn)單就能解釋,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)構(gòu)造SQL語句字符串:
[PHP]純文本查看復(fù)制代碼
1
$query="SELECT * FROM users WHERE username = ".$_GET["ichunqiu"];
看上面代碼我們可以控制輸入?yún)?shù)ichunqiu,修改所要執(zhí)行SQL語句徘跪,達(dá)到攻擊的目的甘邀。
1.4、編寫注入點(diǎn)
為了照顧一下新人垮庐,這里先介紹一下涉及到的基礎(chǔ)知識(shí):
[SQL]純文本查看復(fù)制代碼
1
2
3SQLSELECT語法
SELECT列名稱FROM表名稱
符號(hào) * 取代列的名稱是選取所有列
[SQL]純文本查看復(fù)制代碼
1
2
3
4WHERE子句
如需有條件地從表中選取數(shù)據(jù)松邪,可將WHERE子句添加到SELECT語句。
語法
SELECT列名稱FROM表名稱WHERE列 運(yùn)算符 值
下面的運(yùn)算符可在 WHERE 子句中使用:
了解了以上基礎(chǔ)知識(shí)就讓我們來自己編寫注入點(diǎn)把哨查。
第一步:我們使用if語句來先判斷一下變量是否初始化
[PHP]純文本查看復(fù)制代碼
1
2
3
4
5
if(isset($_GET["ichunqiu"])){
}
?>
第二步:在if語句里面逗抑,我們連接數(shù)據(jù)庫。在PHP中寒亥,這個(gè)任務(wù)通過 mysql_connect() 函數(shù)完成邮府。
[PHP]純文本查看復(fù)制代碼
1
2
3
4mysql_connect(servername,username,password);
servername??????? 可選。規(guī)定要連接的服務(wù)器溉奕。默認(rèn)是"localhost:3306"褂傀。
username??????? 可選。規(guī)定登錄所使用的用戶名加勤。默認(rèn)值是擁有服務(wù)器進(jìn)程的用戶的名稱紊服。
password??????? 可選。規(guī)定登錄所用的密碼胸竞。默認(rèn)是""。
第三步:連接成功后参萄,我們需要選擇一個(gè)數(shù)據(jù)庫卫枝。
[PHP]純文本查看復(fù)制代碼
1
2
3mysql_select_db(database,connection)
database??????? 必需。規(guī)定要選擇的數(shù)據(jù)庫讹挎。
connection??????? 可選校赤。規(guī)定 MySQL 連接。如果未指定筒溃,則使用上一個(gè)連接马篮。
第四步:選擇完數(shù)據(jù)庫,我們需要執(zhí)行一條 MySQL 查詢怜奖。
[PHP]純文本查看復(fù)制代碼
1
2
3mysql_query(query,connection)
query??????? 必需浑测。規(guī)定要發(fā)送的 SQL 查詢。注釋:查詢字符串不應(yīng)以分號(hào)結(jié)束。
connection??????? 可選迁央。規(guī)定 SQL 連接標(biāo)識(shí)符掷匠。如果未規(guī)定,則使用上一個(gè)打開的連接岖圈。
第五步:執(zhí)行完查詢讹语,我們?cè)賹?duì)結(jié)果進(jìn)行處理
[AppleScript]純文本查看復(fù)制代碼
1
2
3
4
5
6
7mysql_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將執(zhí)行的SQL語句輸出逐抑,方便我們查看后臺(tái)執(zhí)行了什么語句鸠儿。
[PHP]純文本查看復(fù)制代碼
1
echo$querry
最終代碼如下:
[PHP]純文本查看復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26if(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"";
id
username
echo"";
".$result['id']."
".$result['username']."
echo"";
echo"";
mysql_close($con);
echo$querry;
}
?>
MySQL數(shù)據(jù)庫實(shí)驗(yàn)環(huán)境配置:
代碼層工作已經(jīng)做好,但是在數(shù)據(jù)庫里面厕氨,我們還沒有ichunqiu這個(gè)數(shù)據(jù)庫啊进每,接下來我就帶大家一步步創(chuàng)建數(shù)據(jù)庫,創(chuàng)建表命斧,創(chuàng)建列田晚,插入數(shù)據(jù)。
第一步:創(chuàng)建數(shù)據(jù)庫
第二步:創(chuàng)建表users和列id,username,password
第三步:我們插入幾條數(shù)據(jù)
同樣的道理国葬,大家多插幾條數(shù)據(jù)贤徒。到此我們整個(gè)任務(wù)就完成了。
最終成果如下:
第二節(jié) 尋找及確認(rèn)SQL注入
2.1汇四、推理測(cè)試法
尋找SQL注入漏洞有一種很簡(jiǎn)單的方法接奈,就是通過發(fā)送特殊的數(shù)據(jù)來觸發(fā)異常。
首先我們需要了解數(shù)據(jù)是通過什么方式進(jìn)行輸入通孽,這里我總結(jié)了三個(gè):
GET請(qǐng)求:該請(qǐng)求在URL中發(fā)送參數(shù)序宦。
POST請(qǐng)求:數(shù)據(jù)被包含在請(qǐng)求體中。
其他注入型數(shù)據(jù):HTTP請(qǐng)求的其他內(nèi)容也可能會(huì)觸發(fā)SQL注入漏洞背苦。
了解完數(shù)據(jù)的輸入方式互捌,我們接下來再學(xué)習(xí)數(shù)據(jù)庫錯(cuò)誤。這里我們以MySQL為例行剂,其它的請(qǐng)大家自行學(xué)習(xí)咯秕噪。
我們現(xiàn)在參數(shù)后面加個(gè)單引號(hào),如下圖:
sql語句最終變?yōu)?/p>
[SQL]純文本查看復(fù)制代碼
1
select*fromuserswhereid = 1'
執(zhí)行失敗厚宰,所以mysql_query()函數(shù)會(huì)返回一個(gè)布爾值腌巾,在下行代碼中mysql_fetch_array($sql)將執(zhí)行失敗,并且PHP會(huì)顯示一條警告信息,告訴我們mysql_fetch_array()的第一個(gè)參數(shù)必須是個(gè)資源壤躲,而代碼在實(shí)際運(yùn)行中城菊,給出的參數(shù)值卻是一個(gè)布爾值。
我們修改代碼在
[PHP]純文本查看復(fù)制代碼
1
2$sql= mysql_query($querry,$con);下一行加上
var_dump($sql);
可以發(fā)現(xiàn):
為了更好的了解MySQL錯(cuò)誤碉克,我們?cè)?/p>
[PHP]純文本查看復(fù)制代碼
1
$sql= mysql_query($querry,$con);
加上
[PHP]純文本查看復(fù)制代碼
1
2
3
4if(!$sql)
{
die('
error:'.mysql_error().'
');}
這樣當(dāng)應(yīng)用捕獲到數(shù)據(jù)庫錯(cuò)誤且SQL查詢失敗時(shí)凌唬,就會(huì)返回錯(cuò)誤信息:(我們?cè)趨?shù)中添加單引號(hào)返回的錯(cuò)誤信息)
[SQL]純文本查看復(fù)制代碼
1
error:You have an errorinyour SQL syntax;checkthe manual that correspondstoyour MySQL server versionfortherightsyntaxtouse near'''atline 1
然后借助這些錯(cuò)誤,我們這可以推斷應(yīng)該存在SQL注入漏麦。還有其他數(shù)據(jù)庫錯(cuò)誤信息客税,以及MySQL其他錯(cuò)誤信息,由于篇幅問題就不一一講解了撕贞。
2.2更耻、and大法和or大法
頁面不返回任何錯(cuò)誤信息,我們就可以借助本方法來推斷了捏膨,首先我們?cè)趨?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ù)返回。
好域蜗,講完and巨双,我們自來看看 or ,or就是或者霉祸,兩個(gè)都為假筑累,才會(huì)為假。我們先把id改為5丝蹭,可以發(fā)現(xiàn)id=5是沒有數(shù)據(jù)的疼阔。
可以發(fā)現(xiàn)我們加上or 1=1就成功返回了數(shù)據(jù),這是因?yàn)?=1為真半夷,不管前面是不是假,數(shù)據(jù)都會(huì)返回迅细,這樣就把表里面數(shù)據(jù)全部返回巫橄,我們沒看見,是因?yàn)榇a中并沒有迭代輸出茵典。這樣湘换,我們來修改一下代碼。
[PHP]純文本查看復(fù)制代碼
01
02
03
04
05
06
07
08
09
10
11
12echo"";
id
username
echo"";
//遍歷查詢結(jié)果
while($result= mysql_fetch_array($sql)) {
".$result[0] ."
".$result[1] ."
echo"";
}
然后你就可以發(fā)現(xiàn):
2.3、加法和減法
這里我們需要區(qū)分一下數(shù)字型和字符串型:
數(shù)字型:不需要使用單引號(hào)來表示
其他類型:使用單引號(hào)來表示
綜合上述彩倚,我們可以發(fā)現(xiàn)我們的例子是數(shù)字型的筹我,這樣我們就可以使用加法和減法來判斷了。
加法帆离,我們?cè)趨?shù)輸入1+1蔬蕊,看看返回的數(shù)據(jù)是不是id等于2的結(jié)果,這里注意一下+號(hào)在SQL語句是有特效含義的哥谷,所以我們要對(duì)其進(jìn)行url編碼岸夯,最后也就是%2b。
減法是同樣的道理们妥,不過我們不需要對(duì)-號(hào)進(jìn)行url編碼了猜扮。
結(jié)束語
感謝大家的支持吧,在此我也總結(jié)一下前面自己的不足监婶,由于篇幅很長(zhǎng)旅赢,寬度是到位了,但是并沒有深入惑惶,也不算詳細(xì)煮盼,所以本篇教程分為了三級(jí)即初級(jí)、中級(jí)集惋、高級(jí)孕似。六節(jié)來寫,既要深度也要寬度刮刑,當(dāng)然我也不是技術(shù)大牛喉祭,如文中有錯(cuò)誤請(qǐng)指出,我會(huì)加以改正雷绢,謝謝泛烙。
系列文章預(yù)告及導(dǎo)航
滲透攻防Web篇-SQL注入攻擊中級(jí)(狀態(tài):更新中)
第三節(jié) 利用SQL注入
第四節(jié) SQL盲注利用
滲透攻防Web篇-SQL注入攻擊高級(jí)(狀態(tài):更新中)
第五節(jié) 避開過濾方法總結(jié)
第六節(jié) 探討SQL注入防御技巧