題目鏈接:
http://www.shiyanbar.com/ctf/30
分析:
打開題目提供網頁 , 發現是一個登陸頁面 , 而且提供了源碼 :
根據源碼可得知 , 使用了ACCESS數據庫
(通過搜索 : Microsoft.jet.OLEDB.4.0 可得知)
直接找到關鍵代碼 :
關鍵代碼 :
1. 如何處理用戶輸入
2. 如何構建SQL語句
如下圖 :
sql = "select * from bdmin where name='" & name & "'"
這里我們可以利用聯合查詢構造SQL查詢返回值達到滿足代碼邏輯的效果
由于我們審計代碼可以得到 , 這里對用戶輸入并沒有任何檢查 , 直接拿來構造SQL語句
所以理論上我們就可以在這里執行任何的SQL語句 , 只要這里連接的數據庫的這個用戶的權限有多大 , 我們的權限就有多大
注 : 有的題目中 , 會留一個PHP可以讀取文件的后門 , 這也是和這道題的效果是差不多的 , 只要PHP在服務器上的權限有多大 , 我們拿到后門后權限就有多大
然后我們就可以開始進行構造和攻擊 :
這種UNION聯合查詢的攻擊的主要是利用前一部分查詢失敗后會顯示后一部分查詢的結果這個原理
因此我們要利用的話 , 就需要構造參數讓前一部分的查詢失效 , 然后我們后一部分有用的信息就可能會被顯示出來
構造輸入如下 :
Username : 0' union select 1,1,1 from bdmin %00
Username : 0' union select 1,1,1 from bdmin
Password : 1
下面我們來解釋一下為什么需要這么構造 :
- Username中 :
這里第一字符0就是為了讓前一部分的查詢失效 , 隨便寫就行- 第一個單引號是為了閉合代碼中SQL語句的前一個引號
- union select 1,1,1 from bdmin 這里 select 1,1,1 from bdmin就是構造一個返回值為 1,1,1 的結果
- 最后的 %00 是由于ACCESS數據庫沒有注釋這一說 , 因此使用00截斷對SQL進行結束
- Password中 :
- 這里的密碼要和上面我們構造的1,1,1進行對應
本地構造演示 :
這樣就可以任意構造我們想要的返回值
輸入我們構造好的用戶名和密碼即可拿到flag
發現在輸入的時候又有問題了 , 這里在前端對用戶名的長度做出了限制 , 直接使用Chrome的調試工具進行調試 , 將input標簽的maxlenght屬性去掉即可
或者也可以不使用他的網頁 , 直接發送POST請求 (利用Chrome插件 : PostMan / 利用Python腳本 / 利用BurpSuite .... )
**后記 : **
寫完之后發現一個錯誤 , 這里不能直接使用Chrome發送Post請求 , 因為我們這個SQL語句最后需要注釋掉原本SQL語句后面的引號 , 因此使用了%00 , 但是在瀏覽器發送數據的時候 , 首先會將數據URL編碼 , 然后再進行發送 , 因此我們需要使用Burp發送 : 如下圖 :
答案:
Great! Key:BeautIful111
知識點: