關(guān)于常見的Web攻擊手段及解決手段

今天學(xué)習(xí)了一些常見的Web 攻擊手段,如 xss攻擊、CSRF 攻擊、SQ L 注入攻擊、DDos攻擊等。 xss攻擊、CSRF 攻擊、SQL 注入攻擊等這類攻擊手段相對來說比較容易防范,對癥下藥即可。對于企業(yè)來說,更多是需要從開發(fā)流程上來予以保障,以免因人為的疏忽而造成損失。而對于 DDos 攻擊來說,攻擊手段多樣,產(chǎn)生的影響及危害巨大,對它的防范也是一 個(gè)復(fù)雜的系統(tǒng)工程,需要持續(xù)性地組織防御演練,做好應(yīng)急預(yù)案,并保持有效的監(jiān)控。下面我將一一去介紹:

1.XSS(跨站腳本攻擊 Cross Site Scripting,為避免跟CSS重復(fù),命名XSS)

是指攻擊者在網(wǎng)頁中嵌入惡意腳本程序執(zhí)行,當(dāng)用戶打開網(wǎng)頁時(shí),執(zhí)行腳本程序,獲取用戶的cookie、用戶名和密碼,下載病毒,甚至獲取admin權(quán)限。是最常見的web攻擊手段之一。

他的原理是這樣的,比如在網(wǎng)頁中有一個(gè)表單,名稱為nick,用來向服務(wù)端提交網(wǎng)站用戶信息。
<input type= "text" name= "nick" value= "xiaomao ">
表單 nick 的內(nèi)容來 自用戶的輸入,當(dāng)用戶輸入的不是一 個(gè)正常的昵稱字符串,而是 "/><script>alert("haha ")</script><!- 時(shí),由于某種原因,如 nick 服務(wù)端校驗(yàn)不通過,服務(wù)端重定向回這個(gè)頁面,并且?guī)现坝脩糨斎氲?nick 參數(shù),此時(shí)頁面則變成下面的內(nèi)容:
<input type= "text" name= "nick" value= ""/><script>alert ("haha") </script> < !- " />

在輸入框 input 的后面帶上了一 段腳本程序,當(dāng)然,這段腳本程序只是彈出一 個(gè)消息框"haha",,并不會(huì)造成什么危害,攻擊的威力取決于用戶輸入了什么樣的腳本,只要稍微修改,便可使攻擊極具危害性。
image.png

攻擊者可以對該URL采用URLEncode, 如圖3-2所示,以迷惑用戶,讓它看起來像是一個(gè)正常的推廣鏈接,并且以郵件群發(fā)或者其他形式進(jìn)行推廣,一旦用戶點(diǎn)擊,腳本將在客戶端執(zhí)行,對用戶造成危害。


還有一 種場景,用戶在表單上輸入一段數(shù)據(jù)后,提交給服務(wù)端進(jìn)行持久化,其他頁面需要從服務(wù)端將數(shù)據(jù)取出來展示。

解決方案:
xss之所以會(huì)發(fā)生,是因?yàn)橛脩糨斎氲臄?shù)據(jù)變成了代碼。因此,我們需要對用戶輸入的數(shù),據(jù)進(jìn)行HTML轉(zhuǎn)義處理,將其中的 “尖括號(hào)”、“單引號(hào)”、“引號(hào)” 之類的特殊字符進(jìn)行轉(zhuǎn)義編碼.

進(jìn)行HTML轉(zhuǎn)移處理。把將括號(hào),單雙引號(hào)特殊字符轉(zhuǎn)義。

2.CRSF攻擊(cross site request forgery 跨站腳本請求偽造)

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

  1. CRSF攻擊原理



    如圖,在惡意站點(diǎn)B冒充用戶C去請求站點(diǎn)A,就可以做一些發(fā)送郵件,短信,支付,消息等操作。
    受害者在滿足了以下兩點(diǎn),登錄站點(diǎn)B,攻擊者就能發(fā)起CSRF攻擊了:
    ? 登錄受信任站點(diǎn)A,并在本地生成cookie;
    ? 在不登出站點(diǎn)A(清除站點(diǎn)A的cookie)的情況下,訪問惡意站點(diǎn)B

舉個(gè)例子:

假設(shè)某銀行網(wǎng)站A以GET請求來發(fā)起轉(zhuǎn)賬操作,轉(zhuǎn)賬的地址為www.xxx.com/transfer.do?accountNum=10001&money=10000, 參數(shù)accountNum表示轉(zhuǎn)賬的目的賬戶,參數(shù)money表示轉(zhuǎn)賬金額。
而某大型論壇B上,一個(gè)惡意用戶上傳了一張圖片,而圖片的地址欄中填的并不是圖片的地址,而是前面所說的轉(zhuǎn)賬地址:
<img src="http://www.xxx.com/transfer.do?accountNum=l0001&money=10000">
當(dāng)你登錄網(wǎng)站A后,沒有及時(shí)登出,這時(shí)你訪間了論壇B,不幸的事情發(fā)生了,你會(huì)發(fā)現(xiàn)你的賬戶里面少了10000塊……
為什么會(huì)這樣呢,在你登錄銀行A時(shí),你的瀏覽器端會(huì)生成銀行A的cookie,而當(dāng)你訪問論壇B的時(shí)候,頁面上的<img>標(biāo)簽需要瀏覽器發(fā)起一個(gè)新的HTTP請求,以獲得圖片資源, 瀏覽器發(fā)起請求時(shí),請求的卻是銀行A的轉(zhuǎn)賬地址www.xxx.com/transfer.do?accountNum=
I 000 I &money= I 0000, 并目會(huì)帶上銀行A的cookie信息,結(jié)果銀行的服務(wù)器收到這個(gè)請求后,會(huì)認(rèn)為是你發(fā)起的一次轉(zhuǎn)賬橾作,因此你的賬戶里邊便少了10000塊。
儼然,絕大多數(shù)網(wǎng)站都不會(huì)使用GET請求來進(jìn)行數(shù)據(jù)更新,因此,攻擊者也需要改變思路,與時(shí)俱進(jìn)。

假設(shè)銀行將其轉(zhuǎn)賬方式改成POST提交,而論壇B恰好又存在一個(gè)xss漏洞,惡意用戶在它的頁而上插入如下代碼:

image.png

如果你此時(shí)恰好登錄了銀行 A , 且沒有登出,當(dāng)你打開上述頁面后,腳本會(huì)將表單 aaa 提交,把 accountN um 和m oney 參數(shù)傳遞給銀行的轉(zhuǎn)賬地址 www .xxx.com /transfer.do, 同樣的,銀行以為是你發(fā)起的一 次轉(zhuǎn)賬,會(huì)從你的賬戶中扣除 10000 塊。
當(dāng)然,以上只是舉例,正常來說銀行的交易付款會(huì)有 USB key、驗(yàn)證碼、登錄密碼和支付密碼等一 系列屏障,流程比上述流程復(fù)雜得多,因此安全系數(shù)也高得多。

解決方案:
(1)將 cookie 設(shè)置為HttpOnly

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

在Java 的Servlet的API中設(shè)置cookie 為HttpOnly 的代碼如下:
response. setHeader ("Set-Cookie", "cookiename = cookievalue; HttpOnly");

(2) 增加token

CSRF 攻擊之所以能夠成功,是因?yàn)楣粽呖梢詡卧煊脩舻恼埱?,該請求中所有的用戶?yàn)證信息都存在于 cookie 中,因此攻擊者可以在不知道用戶驗(yàn)證信息的情況下直接利用用戶的cookie 來通過安全驗(yàn)證。由此可知,抵御 CSRF 攻擊的關(guān)鍵在于:在請求中放入攻擊者所不能偽造的信息,并且該信息不存在于 cookie 之中。鑒千此,系統(tǒng)開發(fā)人員可以在HTTP 請求中以參數(shù)的形式加入一 個(gè)隨機(jī)產(chǎn)生的token, 并在服務(wù)端進(jìn)行 token 校驗(yàn),如果請求中沒有 token 或者token 內(nèi)容不正確,則認(rèn)為是CSRF 攻擊而拒絕該請求。

在session中添加token的實(shí)現(xiàn)代碼:

(3)通過Referer識(shí)別(不常用)

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

取得HTTP請求Referer:
String referer = request.getHeader("Referer")

3.SOL注入攻擊(危害極大)

所謂SQL注入,就是通過把SQL命令偽裝成正常的HTTP請求參數(shù),傳遞到服務(wù)端,欺騙服務(wù)器最終執(zhí)行惡意的SQL命令,達(dá)到入侵目的。攻擊者可以利用SQL注入漏洞,查詢非授權(quán)信息,修改數(shù)據(jù)庫服務(wù)器的數(shù)據(jù),改變表結(jié)構(gòu),甚至是獲取服務(wù)器root權(quán)限。

比如在登錄的input中,把密碼設(shè)置成:

'or 1=1';

那么在執(zhí)行的時(shí)候就會(huì)變成:
select* from hhuser where nick='zhangsan'and passwords = '' or 'l'='l'
可以看到,這條語句一定能查詢出來的,不管密碼對不對,都滿足后面的Or 條件。

如果改成這樣呢?在密碼框輸入';drop table aaa;--
select * from hhuser where nick = 'zhangsan'and passwords =''; drop table aaa--'

就會(huì)造成更嚴(yán)重的后果,數(shù)據(jù)庫表被刪除了。

解決方案

1.使用預(yù)編譯語句

預(yù)編譯語句PreparedStatement是java.sql中的一個(gè)接口,繼承自Statement接口。通過Statement對象執(zhí)行SQL語句時(shí),需要將SQL語句發(fā)送給DBMS,由DBMS先進(jìn)行編譯后再執(zhí)行。而預(yù)編譯語句和Statement不同,在創(chuàng)建PreparedStatement對象時(shí)就指定了SQL語句,該語句立即發(fā)送給DBMS進(jìn)行編譯,當(dāng)該編譯語句需要被執(zhí)行時(shí),DBMS直接運(yùn)行編譯后的SQL語句,而不需要像其他SQL語句那樣先將其編譯。

引發(fā)SQL注入的根本原因是惡意用戶將SQL指令偽裝成參數(shù)傳遞到后端數(shù)據(jù)庫執(zhí)行。作為一種更為安全的動(dòng)態(tài)字符串的構(gòu)建方法,預(yù)編譯語句使用參數(shù)占位符來替代需要?jiǎng)討B(tài)傳入的參數(shù),這樣攻擊者無法改變SQL語句的結(jié)構(gòu),SQL語句的語義不會(huì)發(fā)生改變,即便用戶傳入類似千前面or'l'='l這樣的字符串,數(shù)據(jù)庫也會(huì)將其作為普通的字符串來處理。

2.使用ORM框架

常見的ORM框架IBATIS、Hibernate等都支持相應(yīng)的關(guān)鍵字或特殊符號(hào)轉(zhuǎn)義。
通過#符號(hào)配置的變量,iBATIS能夠?qū)斎胱兞康囊恍╆P(guān)鍵字進(jìn)行轉(zhuǎn)義,防止SQ L 注入攻擊。

3.避免免密碼明文存放

采用MD5加鹽加密后持久化密碼數(shù)據(jù)。

  1. 文件上傳的漏洞

文件上傳攻擊指的是惡意攻擊者利用一些站點(diǎn)沒有對文件的類型做很好的校驗(yàn),上傳了可執(zhí)行的文件或者腳本,并且通過腳本獲得服務(wù)器上相應(yīng)的權(quán)利,或者是通過誘導(dǎo)外部用戶訪問、下載上傳的病毒或木馬文件,達(dá)到攻擊的目的。

為了防范用戶上傳惡意的可執(zhí)行文件和腳本,以及將文件上傳服務(wù)器當(dāng)做免費(fèi)的文件存儲(chǔ)服務(wù)器使用,我們需要對上傳的文件類型進(jìn)行白名單(非黑名單,這點(diǎn)非常重要)校驗(yàn),并且限制上傳文件的大小,上傳的文件需要進(jìn)行重新命名,使攻擊者無法猜測到上傳文件的訪問路徑。

對千上傳的文件來說,不能簡單地通過后綴名稱來判斷文件的類型,因?yàn)閻阂夤艨梢詫⒖蓤?zhí)行文件的后綴名稱改成圖片或者其他后綴類型,誘導(dǎo)用戶執(zhí)行。因此,判斷文件類型需要使用更安全的方式。
很多類型的文件,起始的幾個(gè)寧節(jié)內(nèi)容是固定的,因此,根據(jù)這幾個(gè)字節(jié)的內(nèi)容,就可以確定文件類型,這幾個(gè)字節(jié)也被稱為魔數(shù)6(magic number)。

在后臺(tái)中,我們可以通過魔數(shù)來判斷文件的類型


不同類型的文件對應(yīng)不同的文件頭,F(xiàn)ileType中包含了常用的文件類型對應(yīng)的文件頭的十六進(jìn)制編碼。
讀取文件頭,判斷文件類型:
/**
*讀取文件頭
*/
privates七aticString getFileHeader(String filePath) throws IOException
//這里需要注意的是,每個(gè)文件的魔數(shù)的長度都不相同,因此需要使用startwith
byte db = new byte [ 2 8 ] ;
InputStrearn inputStream = null;
inputstream=new FileinputStream(filePath); inputStream.read(b, 0, 28);
inputstream.close();
return bytes2hex(b);

**
*判斷文件類型
*/
public static FileTypegetType(String filePath)throws IOException {

String fileHead = getFileHeader(filePath);
if (fileHead == null || fileHead.length () == 0) {
return null;
}


}
對一 個(gè)文件的前 28 個(gè)字節(jié)進(jìn)行讀取,并將讀取的內(nèi)容轉(zhuǎn)換成為十六進(jìn)制,與前面 FileType中枚舉的文件頭進(jìn)行對比,判斷文件的類型。

對于圖片類型的文件,可以在上傳后,對圖片進(jìn)行相應(yīng)的縮放,破壞惡意用戶上傳的二進(jìn)制可執(zhí)行文件的結(jié)構(gòu),來避免惡意代碼執(zhí)行。

解決方案

1.后臺(tái),可以使用imagemagick 開發(fā)工具包

2.前端可以使用前端框架進(jìn)行限制上傳的文件的格式和校驗(yàn)。

待續(xù): DDos攻擊
http://www.itdecent.cn/p/fd871bad94ad

整理不易,喜歡請點(diǎn)個(gè)贊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容