常見的網站攻擊手段及預防措施


XSS

XSS攻擊的全稱是跨站腳本攻擊(Cross Site Scripting),為了不和層疊樣式表 (Cascading Style Sheets,CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為XSS,是WEB應用程序中最常見到的攻擊手段之一。跨站腳本攻擊指的是攻擊者在網頁中嵌入惡意腳本程序, 當用戶打開該網頁時,腳本程序便開始在客戶端的瀏覽器上執行,以盜取客戶端cookie、 盜取用戶名密碼、下載執行病毒木馬程序等等。

有一種場景,用戶在表單上輸入一段數據后,提交給服務端進行持久化,其他頁面上需要從服務端將數據取出來展示。還是使用之前那個表單nick,用戶輸入昵稱之后,服務端會將nick保存,並在新的頁面展現給用戶,當普通用戶正常輸入hollis,頁面會顯示用戶的 nick為hollis:

<body> hollis </body>

但是,如果用戶輸入的不是一段正常的nick字符串,而是<script>alert("haha")</script>, 服務端會將這段腳本保存起來,當有用戶查看該頁面時,頁面會出現如下代碼:

<body> <script> alert("haha") </script> </body>

xss1

XSS該如何防御

XSS之所以會發生,是因為用戶輸入的數據變成了代碼。因此,我們需要對用戶輸入的數據進行HTML轉義處理,將其中的“尖括號”、“單引號”、“引號” 之類的特殊字符進行轉義編碼。

xss

如今很多開源的開發框架本身默認就提供HTML代碼轉義的功能,如流行的jstl、Struts等等,不需要開發人員再進行過多的開發。使用jstl標簽進行HTML轉義,將變量輸出,代碼 如下:

<c:out value="${nick}" escapeXml="true"></c:out>

只需要將escapeXml設置為true, jstl就會將變量中的HTML代碼進行轉義輸出。

CSRF

CSRF攻擊的全稱是跨站請求偽造(cross site request forgery), 是一種對網站的惡意利用,盡管聽起來跟XSS跨站腳本攻擊有點相似,但事實上CSRF與XSS差別很大,XSS利用的是站點內的信任用戶,而CSRF則是通過偽裝來自受信任用戶的請求來利用受信任的網站。你可以這么理解CSRF攻擊:攻擊者盜用了你的身份,以你的名義向第三方網站發送惡意請求。CRSF能做的事情包括利用你的身份發郵件、發短信、進行交易轉賬等等,甚至盜取你的賬號。

csrf

假設某銀行網站A,他以GET請求來發起轉賬操作,轉賬的地址為www.xxx.com/transfer.do?accountNum=10001&money=10000,accountNum參數表示轉賬的目的賬戶,money參數表示轉賬金額。 而某大型論壇B上,一個惡意用戶上傳了一張圖片,而圖片的地址欄中填的並不是圖片的地址,而是前面所說的轉賬地址:

<img src="http://www.xxx.com/transfer.do?accountNum=10001&money=10000">

當你登陸網站A后,沒有及時登出,這個時候你訪問了論壇B,不幸的事情發生了,你會發現你的賬戶里面少了10000塊……

為什么會這樣呢,在你登陸銀行A的時候,你的瀏覽器端會生成銀行A的cookie,而當你訪問論壇B的時候,頁面上的標簽需要瀏覽器發起一個新的HTTP請求,以獲得圖片資源, 當瀏覽器發起請求的時候,請求的卻是銀行A的轉賬地址www.xxx.com/transfer.do?accoun tNum=10001&money=10000,並且會帶上銀行A的cookie信息,結果銀行的服務器收到這個請求后,會認為是你發起的一次轉賬操作,因此你的賬戶里邊便少了10000塊。

CSRF的防御

cookie設置為HttpOnly

CSRF攻擊很大程度上是利用了瀏覽器的cookie,為了防止站內的XSS漏洞盜取cookie,需要在cookie中設置”HttpOnly”屬性,這樣通過程序(如JavascriptS腳本、Applet等)就無法讀取到cookie信息,避免了攻擊者偽造cookie的情況出現。

增加token

CSRF攻擊之所以能夠成功,是因為攻擊者可以偽造用戶的請求,該請求中所有的用戶驗證信息都存在於cookie中,因此攻擊者可以在不知道用戶驗證信息的情況下直接利用用戶的cookie來通過安全驗證。由此可知,抵御CSRF攻擊的關鍵在於:在請求中放入攻擊者所不能偽造的信息,並且該信息不存在於cookie之中。鑒於此,系統開發人員可以在HTTP請求中以參數的形式加入一個隨機產生的token,並在服務端進行token校驗,如果請求中沒有token或者token內容不正確,則認為是CSRF攻擊而拒絕該請求。

通過Referer識別

根據HTTP協議,在HTTP頭中有一個字段叫Referer,它記錄了該HTTP請求的來源地址。在通常情況下,訪問一個安全受限頁面的請求都來自於同一個網站。比如某銀行的轉賬是通過用戶訪問http://www.xxx.com/transfer.do頁面完成,用戶必須先登錄www.xxx.com,然后通過點擊頁面上的提交按鈕來觸發轉賬事件。當用戶提交請求時,該轉賬請求的Referer值就會是提交按鈕所在頁面的URL(本例為www.xxx.com/transfer.do)。如果攻擊者要對銀行網站實施CSRF攻擊,他只能在其他的網站構造請求,當用戶通過其他網站發送請求到銀行時,該請求的Referer的值是其他網站的地址,而不是銀行轉賬頁面的地址。因此,要防御CSRF攻擊,銀行網站只需要對於每一個轉賬請求驗證其Referer值,如果是以www.xxx.com域名開頭的地址,則說明該請求是來自銀行網站自己的請求,是合法的。如果 Referer是其他網站的話,就有可能是CSRF攻擊,則拒絕該請求。

SQL注入攻擊

所謂SQL注入,就是通過把SQL命令偽裝成正常的HTTP請求參數,傳遞到服務端,欺騙服務器最終執行惡意的SQL命令,達到入侵目的。攻擊者可以利用SQL注入漏洞,查詢非授權信息, 修改數據庫服務器的數據,改變表結構,甚至是獲取服務器root權限。總而言之,SQL注入漏洞的危害極大,攻擊者采用的SQL指令,決定攻擊的威力。當前涉及到大批量數據泄露的攻擊事件,大部分都是通過利用SQL注入來實施的。

假設有個網站的登錄頁面,如下所示:

sql

假設用戶輸入nick為zhangsan,密碼為password1,則驗證通過,顯示用戶登錄:

login1

否則,顯示用戶沒有登錄:

login2

SQL注入攻擊原理

Connection conn = getConnection(); String sql = "select * from hhuser where nick = '" + nickname + "'" + " and passwords = '" + password + "'"; Statement st = (Statement) conn.createStatement(); ResultSet rs = st.executeQuery(sql); List<UserInfo> userInfoList = new ArrayList<UserInfo>(); while (rs.next()) { UserInfo userinfo = new UserInfo(); userinfo.setUserid(rs.getLong("userid")); userinfo.setPasswords(rs.getString("passwords")); userinfo.setNick(rs.getString("nick")); userinfo.setAge(rs.getInt("age")); userinfo.setAddress(rs.getString("address")); userInfoList.add(userinfo); }

當用戶輸入nick為zhangsan,密碼為' or '1'='1的時候,意想不到的事情出現了,頁面顯示為login狀態:

login1

以上便是一次簡單的、典型的SQL注入攻擊。當然,SQL注入的危害不僅 如此,假設用戶輸入用戶名zhangsan,在密碼框輸入' ;drop table aaa;-- 會發生什么呢?

SQL注入攻擊防御

使用預編譯語句

預編譯語句PreparedStatement是java.sql中的一個接口,繼承自Statement接口。通過 Statement對象執行SQL語句時,需要將SQL語句發送給DBMS,由DBMS先進行編譯后再執行。而預編譯語句和Statement不同,在創建PreparedStatement對象時就指定了SQL語句,該語句立即發送給DBMS進行編譯,當該編譯語句需要被執行時,DBMS直接運行編譯后的SQL語句,而不需要像其他SQL語句那樣首先將其編譯。 前面介紹過,引發SQL注入的根本原因是惡意用戶將SQL指令偽裝成參數傳遞到后端數據庫執行, 作為一種更為安全的動態字符串的構建方法,預編譯語句使用參數占位符來替代需要動態傳入的參數,這樣攻擊者無法改變SQL語句的結構,SQL語句的語義不會發生改變,即便用戶傳入類似於前面' or '1'='1這樣的字符串,數據庫也會將其作為普通的字符串來處理。

使用ORM框架

由上文可見,防止SQL注入的關鍵在於對一些關鍵字符進行轉義,而常見的一些ORM框架,如 ibatis、hibernate等,都支持對相應的關鍵字或者特殊符號進行轉義,可以通過簡單的配置, 很好的預防SQL注入漏洞,降低了普通的開發人員進行安全編程的門檻。 Ibatis的insert語句配置:

<insert id="insert" parameterClass="userDO"> insert into users(gmt_create,gmt_modified,userid,user_nick,address,age,sex) values(now(),now(),#userId#,#userNick#,#address#,#age#,#sex#) </insert>

通過#符號配置的變量,ibatis能夠對輸入變量的一些關鍵字進行轉義,防止SQL注入攻擊。

避免密碼明文存放

對存儲的密碼進行單向Hash,如使用MD5對密碼進行摘要,而非直接存儲明文密碼,這樣的好處就是萬一用戶信息泄露,即圈內所說的被“拖庫”,黑客無法直接獲取用戶密碼,而只能得到一串跟密碼相差十萬八千里的Hash碼。

處理好相應的異常

后台的系統異常,很可能包含了一些如服務器版本、數據庫版本、編程語言等等的信息,甚至是數據庫連接的地址及用戶名密碼,攻擊者可以按圖索驥,找到對應版本的服務器漏洞或者數據庫漏洞進行攻擊,因此,必須要處理好后台的系統異常,重定向到相應的錯誤處理頁面,而 不是任由其直接輸出到頁面上。

文件上傳漏洞

在上網的過程中,我們經常會將一些如圖片、壓縮包之類的文件上傳到遠端服務器進行保存, 文件上傳攻擊指的是惡意攻擊者利用一些站點沒有對文件的類型做很好的校驗這樣的漏洞, 上傳了可執行的文件或者腳本,並且通過腳本獲得服務器上相應的權利,或者是通過誘導外 部用戶訪問或者下載上傳的病毒或者木馬文件,達到攻擊目的。

為了防范用戶上傳惡意的可執行文件和腳本,以及將文件上傳服務器當做免費的文件存儲服務器使用,需要對上傳的文件類型進行白名單(非黑名單,這點非常重要)校驗,並且限制上傳文件的大小,上傳的文件,需要進行重新命名,使攻擊者無法猜測到上傳文件的訪問路徑。

對於上傳的文件來說,不能簡單的通過后綴名稱來判斷文件的類型,因為惡意攻擊可以將可執行文件的后綴名稱改成圖片或者其他的后綴類型,誘導用戶執行。因此,判斷文件類型需要使用更安全的方式。很多類型的文件,起始的幾個字節內容是固定的,因此,根據這幾個字節的內容,就可以確定文件類型,這幾個字節也被稱為魔數(magic number)。

DDoS攻擊

DDoS(Distributed Denial of Service),即分布式拒絕服務攻擊,是目前最為強大、最難以防御的攻擊方式之一。要理解DDos,得先從DoS說起。

最基本的DoS攻擊就是利用合理的客戶端請求來占用過多的服務器資源,從而使合法用戶無法得到服務器的響應。DDoS攻擊手段是在傳統的DoS攻擊基礎之上產生的一類攻擊方式,傳統的DoS攻擊一般是采用一對一方式的,當攻擊目標CPU速度、內存或者網絡帶寬等等各項性能指標不高的情況下,它的效果是明顯的,但隨着計算機與網絡技術的發展,計算機的處理能力顯著增加,內存不斷增大,同時也出現了千兆級別的網絡,這使得DoS攻擊逐漸失去效果。這時候分布式拒絕服務攻擊手段(DDoS)便應運而生了。你理解了DoS攻擊以后, DDoS的原理就非常簡單了,它指的是攻擊者借助公共網絡,將數量龐大的計算機設備聯合起來作為 攻擊平台,對一個或多個目標發動攻擊,從而達到癱瘓目標主機的目的。通常,在攻擊開始前,攻擊者會提前控制大量的用戶計算機,稱之為“肉雞”,並通過指令使大量的肉雞在同一時刻對某個主機進行訪問,從而達到癱瘓目標主機的目的。

DDoS的攻擊有很多種類型,如依賴蠻力的ICMP Flood、UDP Flood等等,隨着硬件性能的 提升,需要的機器規模越來越大,組織大規模的攻擊越來越困難,現在已經不常見,還有就是依賴協議特征以及具體的軟件漏洞進行的攻擊,如Slowloris攻擊,Hash碰撞攻擊等等,這類攻擊主要利用協議以及軟件漏洞發起攻擊,需要在特定環境下才會出現,更多的攻擊者采用的是前面兩種的混合方式,即利用了協議、系統的缺陷,又具備了海量的流量, 如SYN Flood、DNS Query Flood等等。

DNS Query Flood

DNS Query Flood實際上是UDP Flood攻擊的一種變形,由於DNS服務在互聯網中不可替代的作用,一旦DNS服務器癱瘓,影響甚大。

DNS Query Flood攻擊采用的方法是向被攻擊的服務器發送海量的域名解析請求,通常,請求解析的域名是隨機生成,大部分根本就不存在,並且通過偽造端口和客戶端IP,防止查詢請求被ACL過濾。被攻擊的DNS服務器在接收到域名解析請求后,首先會在服務器上查找是否有對應的緩存, 由於域名是隨機生成的,幾乎不可能有相應的緩存信息,當沒有緩存,並且該域名無法直接由該DNS服務器進行解析的時候,DNS服務器會向其上層DNS服務器遞歸查詢域名信息,直到全球互聯網的13台根DNS服務器。大量不存在的域名解析請求,給服務器帶來了很大的負載,當解析請求超過一定量的時候,就會造成DNS服務器解析域名超時,這樣攻擊者便達成了攻擊目的。

CC攻擊

CC(Challenge Collapsar)攻擊屬於DDos的一種,是基於應用層HTTP協議 發起的DDos攻擊,也被稱為HTTP Flood。

CC攻擊的原理是這樣的,攻擊者通過控制的大量“肉雞”或者利用從互聯網上搜尋的大量匿名的HTTP代理,模擬正常用戶給網站發起請求直到該網站拒絕服務為止。大部分網站會通過CDN以及分布式緩存來加快服務端響應,提升網站的吞吐量,而這些精心構造的HTTP請求往往有意避開這些緩存,需要進行多次DB查詢操作或者是一次請求返回大量的數據,加速系統 資源消耗,從而拖垮后端的業務處理系統,甚至連相關存儲以及日志收集系統也無法幸免。

 

 

轉自:http://www.hollischuang.com/archives/2101


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM