簡介:在漏洞盒子挖洞已經有一段時間了,雖說還不是大佬,但技術也有所進步,安全行業就是這樣,只有自己動手去做,才能將理論的知識變為個人的經驗,本篇文章打算分享一下我在挖union型SQL注入漏洞程序中的一些個人理解,如有不足也請大佬不吝指教,
0x00:什么是SQL注入
SQL注入,相信大多數人一開始接觸安全,聽說的第一種漏洞型別就會是SQL注入,眾所周知,其本質就是將用戶輸入的資料當成了SQL陳述句來執行,
開發過網站的朋友應該都清楚,大多數的小型企業或個人的站點大都采用了LAMP結構,即Linux + Apache + MySQL + PHP,當然還有一些其它常見的技術如下表:
| 作業系統 | Web服務器 | 資料庫 | 編程語言 |
|---|---|---|---|
| Linux | Apache | MySQL | PHP |
| Windows Server | Nginx | Oracle | JSP |
| Tomcat | SQL Server | ASP | |
| Python |
總的來說,絕大多數網站都采用了動態Web開發技術,而動態Web開發離不開資料庫,如果沒有處理好這兩者之間的關系,那么SQL注入就會隨之而來了,
舉例來說,當我們想要通過引數id來獲取相對應的新聞時,整個程序簡單來說就是用戶通過URL請求新聞-->后臺通過用戶請求去資料庫查詢相對應的新聞-->將查詢到的新聞回傳給用戶,在第二步查詢相對應的新聞時,后臺會執行SQL陳述句來查詢,就像SELECT * FROM news WHERE id='',id的值是用戶來控制的,當id=1時,就會回傳id=1的新聞,id=2時回傳id=2的新聞,以此類推,就可以動態的控制web界面了,
這時,當用戶輸入的id值不正確時,后臺就無法獲取相對應的新聞,前端就會沒有資料顯示,可當用戶輸入的資料為1'; DROP TABLE news-- a時,恐怖的事情就發生了,資料庫中的news表被洗掉了,這就說明這個引數存在SQL注入,
回到剛才用戶輸入的資料,拼接到后臺查詢資料時,整個SQL陳述句就變成了SELECT * FROM news WHERE id='1'; DROP TABLE news-- a',分析這條陳述句可知,用戶輸入的單引號閉合了id的值,分號閉合了SELECT陳述句,然后又新建了一條DROP陳述句洗掉了表news,最后的-- a注釋掉了id值后的那個單引號,SQL注入就這么產生了,
當一個站點存在SQL注入時,用戶的輸入就可以傳入資料庫執行,理論上這樣可以獲得資料庫的全部資料,也就是常說的脫庫了,獲得資料的方法也多種多樣,可以通過頁面直接回傳想要查詢的資料,也可以通過sleep延時函式猜測資料,都不行的話我們還可以使用DNS決議日志來獲得資料,其中,最簡單的一種方法就是union型的SQL注入了,
union型SQL注入只是SQL注入的其中一種,也是最簡單的一種,對于這種漏洞的防范也特別簡單,可這種漏洞在互聯網中仍不計其數...這也可見全國乃至全球對于網路安全知識普及的不足,接下來,我會從三個方面來講講這種漏洞,分別是為什么會產生、怎么利用以及怎么防范,
0x01:為什么會產生union型SQL注入
union型SQL注入,看名字就能知道,使用這種方法可以直接在頁面中回傳我們要查詢的資料,方法也很簡單,即使用UNION聯合查詢即可,
但使用UNION聯合查詢時還要滿足一個條件,那就是我們構造的SELECT陳述句的欄位數要和當前表的欄位數相同才能聯合查詢,即首先我們要確定當前表的欄位數,order by x是資料庫中的一個排序陳述句,order by 1即通過第一個欄位進行排序,這時我們就可以構造SELECT * FROM news WHERE id='1' order by x-- a'來猜測當前表的欄位數,x值遞增,當頁面回傳資料例外時,即無當前欄位時,用當前的x值減一即可得到當前表的欄位數了,
知道了當前表的欄位數,就可以進行UNION聯合查詢了,但聯合查詢時,頁面只會顯示查詢到資料的第一條,也就是UNION前的SELECT陳述句的結果,想要顯示我們自己聯合查詢的結果時,還必須使前一條陳述句失效,這里我們構造and 1=2使前一句SELECT陳述句失效,回到剛才的案例,假設當前表的欄位數為3,我們就可以構造SELECT * FROM news WHERE id='1' and 1=2 UNION SELECT 1,2,3-- a'來查詢當前頁面的顯錯點了,通過下圖的案例可知,當前的顯錯點為第一欄位和第三欄位,

這個顯錯點又是什么意思呢?比如當前表中共有三個欄位,一個是標題(title)、一個是時間(time)、一個是內容(data),而我們前端不需要顯示時間,只需要展示標題和內容即可,那么從資料庫獲得的資料中,也只有標題欄位和內容欄位會展示在頁面上,這兩個點就是顯錯點,
通過這里的顯錯點,用戶就可以獲得資料庫中的所有資料了,當用戶輸入的資料為1' and 1=2 UNION SELECT 1,2,database()-- a時,即SQL陳述句為SELECT * FROM news WHERE id='1' and 1=2 UNION SELECT 1,2,database()-- a'時,就可以直接得到資料庫的庫名,

0x02:怎么利用union型SQL注入
1.判斷是否存在注入
構造and 1=1/and 1=2查看頁面是否有例外,若有例外,即有可能存在注入,另外還可通過該陳述句判斷該站點是否有WAF,若有WAF的話會有攔截警告,當然,WAF也是可以繞過的,,,
2.查詢當前表的欄位數
構造order by x,當頁面回傳例外時,利用x減一即可得到當前表的欄位數,
3.查詢顯錯點
構造and 1=2 union select 1,2,3,若頁面顯示了我們構造的1,2,3,則對應的欄位即為顯錯點,
4.查詢資料庫庫名
構造and 1=2 union select 1,2,database(),即可在顯錯點顯示當前資料庫庫名,
一般挖漏洞的話到此步驟就可以提交了,切記千萬不可非法獲得資料,挖洞有風險,同志需謹慎!
5.查詢資料庫中的表名
構造and 1=2 union select 1,2,table_name from information_schema.tables where table_schema=database() limit 0,1,即可在顯錯點顯示當前庫中的表名,因為顯錯點一次只能顯示一條資料,這時可以通過limit陳述句選擇不同的表名進行查看,
6.查詢選擇表中的欄位名
構造and 1=2 union select 1,2,column_name from information_schema.columns where table_schema=database() and table_name='XXX' limit 0,1,即可在顯錯點顯示欄位名,這里也是通過limit陳述句選擇不同的欄位名進行查看,
7.查詢資料庫中的資料
構造and 1=2 union select 1,2,XXX from XXX limit 0,1,即可獲得資料庫中的資料了,
0x03:怎么防范union型SQL注入
針對union型SQL注入,我們可以對用戶輸入的資料進行一次篩查,設定黑名單,攔截注入常用的一些關鍵詞,比如and、order by、union、select、from等,
除了設定黑名單外,還有一種比較靠譜的方法,即使用預編譯陳述句,而不是動態的生成SQL陳述句,這樣可以有效的避免用戶輸入的資料連接到資料庫執行,就是實作起來比較復雜,需要設定大量的預編譯陳述句,
另外還有一種目前最靠譜的方法,實作起來還簡單,就是上硬體防火墻,,,就是有點小貴,
0x04:互聯網中的一些案例


依據網路安全法,本文旨在分享個人學習經驗,內容禁止用于違法犯罪行為!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/3730.html
標籤:其他
下一篇:buuctf-rsa
