1.什么是Web漏洞
WEB漏洞通常是指網站程序上的漏洞,可能是由於代碼編寫者在編寫代碼時考慮不周全等原因而造成的漏洞。如果網站存在WEB漏洞並被黑客攻擊者利用,攻擊者可以輕易控制整個網站,並可進一步提前獲取網站服務器權限,控制整個服務器。
2. 常見的web安全漏洞
2.1 SQL注入漏洞
2.1.1 SQL注入典型案例事件
1、SONY索尼事件
2011年4月,著名的匿名者組織Anonymous注入SONY一個網站,一星期后才被發現7千萬的用戶個人信息,其中包括姓名、地址、E-mail、出生日期、用戶名、密碼以及購買記錄的數據信息,隨后的一些其他服務器也被相繼攻破。
2、CSDN數據泄露門
2011年底,國內各大網站被爆出“密碼泄露門”,最先公布的是著名技術網站CSDN600萬賬戶和密碼泄露事件,網站由於存在SQL注入漏洞被利用並下載用戶數據庫,同時令人不解的是,網站對用戶的信息儲存竟然是明文。
2.1.2 什么是SQL注入
SQL注入攻擊(SQL Injection),簡稱注入攻擊、SQL注入,被廣泛用於非法獲取網站控制權,是發生在應用程序的數據庫層上的安全漏洞。在設計程序中,忽略了對輸入字符串中夾帶的SQL指令的檢查,被數據庫誤認為是正常的SQL指令而運行,從而使數據庫受到攻擊。可能導致數據被竊取、更改、刪除,以及進一步導致網站被嵌入惡意代碼、被植入后門程序等危害。
SQL注入是一種代碼注入技術,可能會破壞數據庫。SQL注入是通過網頁輸入將惡意代碼放置在SQL語句中。
目前SQL注入大致分為普通注入和盲注。
-
普通注入:根據后台數據庫提示有價值的錯誤信息進行注入
-
盲注:有經驗的管理員在給出錯誤頁面時,沒有提供詳細的錯誤信息。測試者需要運用腳本通過僅有的判斷信息(比如時間差)對表中的每一個字段進行探測,從而實現注入的技術(盲注的難度較大,但注入測試中經常會遇到) 。
2.1.3 SQL注入的位置
SQL注入主要就是與數據庫打交道,所以程序中與涉及到與數據庫交換數據的地方都有可能出現SQL注入的問題,具體有哪些呢?
-
表單提交,主要是POST請求,也包括GET請求;
-
URL參數提交,主要為GET請求參數;
-
Cookie參數提交;
-
HTTP請求頭部的一些可修改的值,比如Referer、User_Agent等;
2.1.4 SQL注入的思路
攻擊者通過構造不同的SQL語句來實現對數據庫的操作,這里有兩個關鍵條件:
-
參數用戶可控(如?id=1 就是根據不同的id能查看不同的內容)
-
用戶的參數帶入數據庫查詢(這里就是用來判斷是否有SQL注入)
注入的判斷方法常用的有:
1.使用英文的單引號’ :主要用來查看是否報錯,以及錯誤信息是否是語法錯誤,還能看出使用的數據庫類型
2.使用and、or操作
-
- 對於數字型的:若?id =1 and 1=1(正常) ?id=1 and 1=2(異常),則可能存在SQL注入
- 對於其他類型:若?name =xxx’ and 1=1(正常) ?name=xxx’ and 1=2(異常),則可能存在SQL注入
- 對於搜索型的:若?name =xxx%’ and 1=1(正常) ?name=xxx%’ and 1=2(異常),則可能存在SQL注入
3.加減法:對於數字型
-
- 加減法:?id=1+1或者?id=3-1 如果兩個頁面的數據與?id=2一樣,證明可能存在SQL異常
4.對於登錄框,常用注釋方法,常用的注釋有#、-- 、/*...*/三種
(1) 知道用戶名,如我們填寫的用戶名:admin’# 密碼:123456 構造的語句就是:
select * from user where username = 'admin'# ' and password = '123456'
(2) 不知道用戶名,如我們填寫的用戶名:’or 1=1# 密碼:123456 構造的語句就是:
select * from user where username = '' or 1=1#’ and password = '123456'
注入思路:
1.判斷注入點
如果存在如下方式,那么可能就會存在SQL注入漏洞
(1) ?id=1 正常
(2) ?id=1 and 1=1 正常且與(1)一致
(3) ?id=1 and 1=2 不正常
2.查詢數據庫類型
(1) ?id=1 and length(user())>0
(2) ?id=1 and version()>0
(3) ?id=1 and (select count(*) from information_schema.TABLES)>0
3.判斷字段數
使用order by number(其中number表示第幾列)
(1) ?id=1 and 1=1 order by 1
(2) ?id=1 and 1=1 order by 2
(3) ?id=1 and 1=1 order by 3
如果order by 3時不正常了,證明表中只有2列,即只有兩個字段
4.判斷回顯點(回顯點是頁面展示與數據庫交換數據的地方,這樣可以用來展示我們測試的內容),使用union(條件就是只要兩個查詢的字段數一致就可以)
(1) ?id=1 and 1=2 union select 1
(2) ?id=1 and 1=2 union select 1,2
如果在前端頁面顯示了2,則表示回顯點是2,那么就會在2處顯示我們的內容(如果在頁面顯示了相應的數字的話,該處就是回顯點,就可以將2更換成我們想要猜測的相關內容)。access數據庫的話必須加表名,表名我們可以自己猜,admin,user等來試試:union select 1,2 from table_name
5.查詢相關內容
(1) 查詢當前數據庫名稱:?id=1 and 1=2 union select 1,databases()
(2) 查詢數據庫的版本:?id=1 and 1=2 union select 1,version()
(3) 查詢當前數據庫的表:?id=1 and 1=2 union select 1,table_name from information_schema.tables where table_schema=database() limit 0,1 查看數據庫下的表,可使用limit 0,1;limit 1,1的方式不斷猜測下去(因為回顯點只展示一個值,所以只能一個一個猜測)我們可以使用group_concat()函數將所有展示出來,但是這個要先確定展示的內容有沒有長度的限制,如果有就需要使用limit
(4) 查詢當前數據庫的表:?id=1 and 1=2 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
(5) 查詢表下的字段:?id=1 and 1=2 union select 1,column_name from information_schema.columns where table_schema=database() and table_name='admin' limit 0,1 同樣也可以使用group_concat(column_name)來展示
(6) 查看表內容:?id=1 and 1=2 union select 1,username from admin limit 0,1 查詢表admin中第一行的username
(7) 查看表內容:?id=1 and 1=2 union select 1,password from admin limit 0,1 查詢表admin中第一行的password,需要注意的是information_schema這個系統表是MySQL5.0以后的。
2.1.5 SQL注入常用技巧
猜數據庫類型
-
使用英文的引號’,查看錯誤信息
從上面我們可以知道,如果程序的開發沒有過濾使用英文的引號’的錯誤信息的話,我們可以從錯誤提示中獲取到具體使用到的數據庫。
(1) 如MySQL中的錯誤信息如下:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1
(2) postegres中的錯誤信息如下:
unterminated quoted string at or near "'"
(3) mssql中的錯誤信息如下:
Microsoft JET Database Engine
(4) Oracle中的錯誤信息如下:
ORA-01756:quoted string not properly terminated
ORA-00933:SQLcommand not properly ended
2.通過數據庫特有的特征
(1) mssql數據庫特有的表sysobjects
?id=1 and (select count(*) from sysobjects)>0 正常
(2) access數據庫
?id=1 and (select count(*) from sysobjects)>0
?id=1 and (select count(*) from msysobjects)>0
兩個都異常就是access數據庫,因為access數據庫無sysobjects表,雖然有msysobjects表,但是沒有訪問權限,所以也會異常
(3) MySQL特有函數
?id=1 and length(user())>0
?id=1 and version()>0
?id=1 and (select count(*) from information_schema.TABLES)>0
(4) Oracle特有用戶表sys.user_tables
?id=1 and (select count(*) from sys.user_tables)>0
“;”是子句查詢標識符,Oracle不支持多行查詢,因此如果返回錯誤,則說明很可能是Oracle數據庫。
猜表名
(1) ?id=1 and exists(select * from 表名)
猜列名
(1) ?id=1 and exists(select 字段 from 表名)
猜列內容長度
(1) ?id=1 and (select top 1 len(字段) from 表名) = 1
(2) ?id=1 and (select length(字段) from 表名 limit 1) = 1
其中,要根據上面判斷的數據庫類型使用不同的方式。
猜列具體內容
(1) ?id=1 and (select top 1 asc(mid(字段,1,1)) from 表名) = 97
(2) ?id=1 and (select ASCII(mid(字段,1,1)) from 表名 limit 1) = 97
其中,也需要根據上面判斷的數據庫類型來使用不同的函數,ASCII為MySQL中將字符轉換成ASCII碼,mid為字符串的截斷函數,第一個參數為字段名稱,第二個參數為開始的列數,第三個為截取的長度。
2.1.6 SQL注入常見的防范方法
(1)所有的查詢語句都使用數據庫提供的參數化查詢接口,參數化的語句使用參數而不是將用戶輸入變量嵌入到SQL語句中。當前幾乎所有的數據庫系統都提供了參數化SQL語句執行接口,使用此接口可以非常有效的防止SQL注入攻擊。
(2)對進入數據庫的特殊字符(’”<>&*;等)進行轉義處理,或編碼轉換。
(3)確認每種數據的類型,比如數字型的數據就必須是數字,數據庫中的存儲字段必須對應為int型。
(4)數據長度應該嚴格規定,能在一定程度上防止比較長的SQL注入語句無法正確執行。
(5)網站每個數據層的編碼統一,建議全部使用UTF-8編碼,上下層編碼不一致有可能導致一些過濾模型被繞過。
(6)嚴格限制網站用戶的數據庫的操作權限,給此用戶提供僅僅能夠滿足其工作的權限,從而最大限度的減少注入攻擊對數據庫的危害。
(7)避免網站顯示SQL錯誤信息,比如類型錯誤、字段不匹配等,防止攻擊者利用這些錯誤信息進行一些判斷。
(8)在網站發布之前建議使用一些專業的SQL注入檢測工具進行檢測,及時修補這些SQL注入漏洞。
遺留:各種不同數據庫類型的攻擊實戰、SQL注入工具的使用
2.2 跨站腳本漏洞XSS
2.2.1 XSS定義
跨站腳本攻擊(Cross-site scripting,通常簡稱為XSS,因為和層疊樣式表的擴展名CSS重名了,故取名為XSS)。通常指的是利用網頁開發時留下的漏洞,通過巧妙的方法注入惡意指令代碼到網頁,使用戶加載並執行攻擊者惡意制造的網頁程序。這些惡意網頁程序通常是JavaScript,但實際上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。
簡單的說,SQL注入是將用戶輸入的數據當作SQL語句,放到數據庫中去執行,而XSS是將用戶輸入的數據當作HTML或者JavaScript腳本,放到頁面上去執行。
實際上,“跨站腳本攻擊”這個名字本身也另有來歷,僅僅是因為當時第一次演示這個漏洞的黑客是通過“跨站”的方式植入腳本進行攻擊的。 由於現代瀏覽器的“同源策略”已經讓運行在瀏覽器中的javascript代碼很難對外站進行訪問了, 所以這個漏洞的名稱可能存在一定的誤導性,讓很多初學者看了很多次都不能理解這個漏洞的原理。
2.2.2 XSS原理
XSS攻擊主要是依靠一切可能的手段,將瀏覽器中可以執行的腳本(javascript)植入到頁面代碼中,從而對用戶客戶端實施攻擊;從本質上講,就是想盡一切手段在別人的代碼環境中執行自己的代碼。
那么這里就有兩個關鍵的條件:
-
如何把代碼植入到對方的系統中去?也就是說用戶要能在頁面控制輸入;
-
植入進去的代碼能不能被對方的系統執行?也就是說原本要執行的代碼拼接了用戶輸入的數據。
2.2.3 XSS危害
2.2.3.1 什么是惡意腳本
實際上,能在受害者的瀏覽器中運行的JavaScript並不是都是有害的,因為JavaScript是在一個嚴格受限的環境中運行的(對用戶文件和操作系統有嚴格的訪問限制),然而當我們考慮如下幾個方面時,我們就會對惡意腳本有一個清晰的認識。
-
JavaScript可以訪問一些用戶的敏感信息,比如cookies。
-
JavaScript可以通過XMLHttpRequest和其他的一些機制向任意終端發送包含任意內容的HTTP請求。
-
JavaScript可以通過DOM操作方法任意修改當前頁面的HTML內容。
如果把上面這幾點集合起來,那可以造成很嚴重的安全攻擊了。
2.2.3.2 XSS危害
那么如果攻擊者擁有了可以執行任意JavaScript腳本的能力后,究竟會有哪些危害呢?
-
盜取Cookie:攻擊者可以通過document.cookie獲取與網站相關的Cookie信息。並且可以把Cookie信息發回攻擊者自己的服務器,然后分析出敏感信息,比如session id。
-
記錄按鍵信息:攻擊者可以通過addEventListener注冊鍵盤偵聽事件,然后把用戶所有的按鍵信息發回他自己的服務器。這就有可能會記錄下密碼、信用卡號等敏感信息。
-
釣魚:攻擊者可以通過DOM操作在頁面中插入一個偽造的登陸表單,並把form元素的action屬性指向他自己的服務器,誘使用戶提交敏感信息。
-
篡改頁面:攻擊者可以通過DOM操作方法直接篡改頁面內容
-
控制數據:包括讀取、篡改、添加、刪除企業敏感數據的能力
-
將XSS配合SQL、CSRF等漏洞,控制受害者機器向其它網站發起攻擊
總的來說,就是攻擊者利用XSS攻擊成功后,攻擊者可能得到(包括但不限於)更高的權限,那么攻擊者就可以使用這些權限做任何他想做的事。
2.2.4 XSS分類
2.2.4.1 非持久型跨站
非持久型XSS (也叫做反射型XSS),是指用戶發出請求時,xss代碼出現在url中,作為輸入提交到服務器端,服務器端解析后響應,xss代碼隨響應內容一起傳回給瀏覽器,最后瀏覽器解析執行xss代碼。這個過程像一次反射,故叫反射型xss。
反射型XSS主要是對一個頁面的URL中的某個參數做文章,把精心構造的惡意腳本包裝到URL參數中, 再將這個URL散布到網上,騙取用戶訪問這個URL,從而對其進行攻擊。
散布的方式通常伴有一些美女圖片、游戲外掛或是其他的一些強誘惑力的內容,而其真實目的則是為了騙取用戶訪問這個URL。
此類 XSS 通常出現在網站的搜索欄、用戶登錄口等地方,常用來竊取客戶端 Cookies 或進行釣魚欺騙。
其大致流程如下:
(1) 攻擊者構造了一個包含惡意字符串的URL並把它發給受害者。
(2) 誘使受害者發起這個URL請求。
(3) 網站在響應中引入這個惡意字符串。
(4) 受害者瀏覽器執行響應中的惡意腳本,將受害者的cookies信息發給攻擊者服務器。
那么反射型XSS是如何實施的呢?
從上面我們可以看出,實際上反射型XSS需要受害者向服務器發送一個包含惡意代碼的請求,這樣看起來沒有人會這樣做,但實際上至少有兩種常見的方法可以讓受害者發起一次針對自己的反射型XSS攻擊。
(1) 如果用戶是具體的個人,攻擊者可以發送惡意URL給受害者(如:通過email或者即時消息)然后誘使受害者訪問該URL。
(2) 如果用戶是一個群體,攻擊者可以發布一個惡意的URL鏈接(如:在他的網站上或社交網絡上)然后等待訪問者點擊該URL。
2.2.4.2 持久型跨站
這是危害最直接的跨站類型,跨站代碼存儲於服務端(比如數據庫中)。常見情況是某用戶在論壇發貼,如果論壇沒有過濾用戶輸入的Javascript代碼數據,就會導致其他瀏覽此貼的用戶的瀏覽器會執行發貼人所嵌入的Javascript代碼。
其大致流程如下:
(1) 攻擊者利用網站的一個表單(如發帖框),將惡意字符串插入到網站數據庫中。
(2) 受害者想訪問貼吧內容,所以向網站請求頁面。
(3) 網站在響應中將已經引入惡意字符串數據發給受害者。
(4) 受害者瀏覽器執行響應中的惡意腳本,並把受害者的cookies發給攻擊者服務器。
2.2.5 XSS驗證
XSS驗證常用的語句:
<script>alert(‘1’)</script> <script>document.cookie</script> <iframe src=http://baidu.com> <meta http-equiv="refresh" content="5;url=http://www.baidu.com">
實例網址:http://59.63.200.79:8004/Feedback.asp
2.2.6. XSS防范
(1)與SQL注入防護的建議一樣,假定所有輸入都是可疑的,必須對所有輸入中的script、iframe等字樣進行嚴格的檢查。這里的輸入不僅僅是用戶可以直接交互的輸入接口,也包括HTTP請求中的Cookie中的變量,HTTP請求頭部中的變量等。
(2)不僅要驗證數據的類型,還要驗證其格式、長度、范圍和內容。
(3)不要僅僅在客戶端做數據的驗證與過濾,關鍵的過濾步驟在服務端進行。
(4)對輸出的數據也要檢查,數據庫里的值有可能會在一個大網站的多處都有輸出,即使在輸入做了編碼等操作,在各處的輸出點時也要進行安全檢查。
(5)在發布應用程序之前測試所有已知的威脅。