常見網絡攻擊

中間人攻擊(Man-in-the-Middle (MITM) attack)

中間人攻擊是一種常見的攻擊手段,攻擊者與通訊雙方分別創建鏈接,將雙方想要交換的數據進行記錄、篡改甚至丟棄。因爲Http是明文傳輸,所以很容易遭受到中間人攻擊。html

一個通俗的例子

  • 假設 Tom 想和 Jerry 交換一些祕密信息,然而 Tom 又不想跑到 Jerry 家裏,因而 Tom 叫來了郵遞員,給了郵遞員一封信。信的內容是但願 Jerry 給 Tom 一個盒子(這個盒子有兩把鑰匙)和其中一把鑰匙(另外一把在 Jerry 手裏)。
  • 郵遞員在拿到 Tom 給的信件之後,把 Tom 的信拆開看了一遍,瞭解到 Tom 但願 Jerry 給 Tom 一個有鎖的盒子,又用另外一個信封裝了回去,並交給了 Jerry。
  • Jerry 在收到 Tom 的信(實際已經被郵遞員拆閱過了)以後,給了郵遞員一個有鎖的盒子和其中一把鑰匙。
  • 郵遞員想知道他們的通訊內容,因而他把 Jerry 給 Tom 的盒子換成了他本身的盒子,並附上了本身盒子中的一把鑰匙,並在以後將本身的盒子交給了 Tom。
  • Tom 在收到盒子以後,覺得這個盒子是 Jerry 給他的,因而就把祕密的信件放進了盒子裏,並把鑰匙留下了,以後又交給了郵遞員。
  • 郵遞員在拿到盒子以後,用本身的另外一把鑰匙打開盒子,看了裏面的信件。以後將信件調換以後放進了 Jerry 給的盒子,交給了 Jerry。
  • Jerry 在拿到郵遞員給他的盒子以後,並不知道這個盒子裏的信件其實已經被郵遞員調換過了,因此 Jerry 認爲盒子裏的信件是來自 Tom 且未被修改過的。以後 Jerry 把回信放進了盒子裏,又交給了郵遞員。
  • 郵遞員再次調換盒子裏的信件,交給了 Tom。

這是一個典型的中間人攻擊的過程,在Http中,Tom是客戶端,Jerry是服務端,而郵遞員就是客戶端跟服務端之間的實體(包括代理服務器,路由器、反向代理服務器等),兩把鑰匙分別是公鑰和私鑰。通訊雙方並不知道且很難發覺本身其實在和中間人攻擊而非對方。在通訊過程當中,Tom和Jerry並無驗證對方的身份,這就致使了郵遞員能夠任意查看、修改或者丟棄雙方的通訊內容。sql

Http如何防範中間人攻擊

非對稱加密

用私鑰對某個文件/某段消息的散列值進行簽名就像一我的親手在信件最後簽上本身的名字同樣,證實這份文件/這段消息確實來自本身的擁有者(由於公鑰是公開的,私鑰只有擁有者知道,因此若是能用其公開的公鑰解開數字簽名,那就證實這條消息確實來自於私鑰的擁有者),這就能夠確保消息是來自他所聲稱的那個實體。瀏覽器

不過有個問題,若是中間人在會話創建階段把雙方交換的真實公鑰替換成本身的公鑰,那麼中間人仍是能夠篡改消息的內容而雙方不知情。爲了解決這個問題,須要找一個第三方來爲雙方確認身份。即數字證書跟CA(數字證書認證機構)。安全

數字證書就是申請人將一些必要的信息(包括公鑰、姓名、電子郵件、有效期)等提供給CA,CA在經過各類手段確認申請人確實是他所聲稱的人以後,用本身的私鑰對申請人所提供信息計算散列值進行加密,造成數字簽名,附在證書最後,再將數字證書頒發給申請人,申請人就可使用CA的證書想別人證實本身的身份了。對方收到數字證書以後,只須要用CA的公鑰解密證書最後的簽名獲得加密以前的散列值,同計算數字證書中的信息的散列值,將二者進行對比,只要散列值一致,就證實這張數字證書是有效切且未被篡改。服務器

通訊過程當中的安全性自下而上就是這樣保證的:網絡

  • 雙方通訊的內容的安全性是靠私鑰加密,公鑰解密來保證的,這一安全性由非對稱加密的特性,即由私鑰加密的信息只能使用對應的公鑰才能解開來保證。因爲私鑰不會傳遞,只由擁有者知道,因此安全性就由公鑰的正確性來保證。
  • 公鑰由雙方在通訊初始化提供,但這時很容易被中間人替換掉,爲了保證公鑰的正確性,因此在發送公鑰的時候也會提供對應的數字證書,用於驗證這個公鑰是對方的而不是中間人的。那麼安全性就是由數字證書的正確性來保證了。
  • 數字證書是由上級CA簽發給我的/組織的,上級CA用本身的私鑰給我的證書進行簽名,保證證書中的公鑰不被篡改,而接受者須要用上級CA證書中的公鑰來解密我的數字證書中的數字簽名來驗證證書中的公鑰是否正確。那麼安全性就是由上級CA證書的正確性保證了。
  • 可是上級CA證書也是由其上級CA簽發的,這種信任關係一直到根證書。根證書沒有上級CA爲其簽名,而是自簽名,也就是他自身爲自身簽名,保證正確性。因此跟證書就是這個信任練最關鍵的部分。若是根證書泄露的話,其簽名的全部證書及使用其簽名的證書索簽名的證書的安全性將不復存在。如今,安全性就是靠系統根證書的私鑰不被泄露或者其公鑰不被篡改來保證的。
  • 根證書不該該經過網絡分發,由於經過網路分發的話,可能被中間人攻擊。通常根證書都經過操做系統或瀏覽器分發,在操做系統中會內置不少根證書,可是最初的操做系統也不能經過網絡分發,由於中間人能夠修改系統中的根證書。因此要確保安全只能靠最原始的方法,當面交流。硬件廠商會和證書籤發機構合做,在電腦、手機等設備出廠的時候在其操做系統中內置簽發機構的根證書,再將這些設備分發出去,這樣,這些設備的用戶就能夠安全地進行信息交換了。因此,安全性就依賴於這些設備在分發到消費者手中以前不會被惡意修改來保證了。

SSLTrip和HSTS

HTTP協議最初的時候是明文的,由於安全問題因此如今不少網站都在逐漸過渡到HTTPS,然而對於大部分使用者來講,他們並不知道HTTP和HTTPS的以前的區別,在瀏覽器輸入地址的時候都是直接輸入www.example.com而非https://www.example.com,在大部分狀況下,若是一個網站使用了HTTPS,服務器會將這個請求使用301或者302狀態碼以及一個Location頭部鍵將請求從80端口重定向至使用HTTPS的443端口,可是,若是中間人劫持了使用者的網絡請求,那麼中間人能夠阻止客戶端與服務器創建HTTPS鏈接,而是一直使用不安全的HTTP鏈接,而中間人和服務器創建正常的HTTP鏈接,讓客戶端覺得本身和真實服務器通訊。這種攻擊手法稱做SSLTripmybatis

爲了而解決這個問題,IETF(互聯網工程任務小組)引入了一個策略,叫作HSTS(HTTP Strict Transport Security,HTTP嚴格傳輸安全)。HSTS的做用是強制客戶端與服務端創建安全的HTTPS鏈接,而非不安全的HTTP鏈接。若是一個站點啓用了HSTS策略,那麼客戶端在第一次與該站點創建鏈接以後,在爲來一段時間內(由一個HTTP頭部控制,這個頭部爲:Strict-Transport-Security),客戶端與該站點的全部鏈接都會直接使用HTTPS,即便客戶端訪問的是HTTP,也會直接在客戶端重定向到HTTPS鏈接。框架

若是站點沒有啓用HSTS,用戶能夠忽略證書無效(域名對不上、自簽名、不在有效期)的警告,繼續創建鏈接,而若是站點啓用了 HSTS,那麼用戶即便想冒風險,瀏覽器也不會繼續訪問。分佈式

HSTS 能夠很大程度上防止 SSLTrip 攻擊,不過這樣仍是有個問題,那就是要啓用 HSTS,瀏覽器至少要和服務器創建一次 HTTPS 鏈接,若是中間人一直阻止瀏覽器與服務器創建 HTTPS 鏈接,那麼 HSTS 就失效了。解決這個問題有個辦法,那就是將 HSTS 站點列表內置到瀏覽器中,這樣只要瀏覽器離線判斷該站點啓用了 HSTS,就會跳過原先的 HTTP 重定向,直接發起 HTTPS 請求。網站

本內容摘自:
HTTPS中間人攻擊及其防範

拒絕服務攻擊(DDoS)

DDoS的攻擊方式有不少種,最基本的DDoS攻擊就是利用合理的服務請求來佔用過多的服務資源,從而使合法用戶沒法獲得服務的響應。

被DDoS攻擊時的現象

  • 被攻擊主機有大量等待的TCP鏈接
  • 網絡中充斥着大量的無用的數據包,源地址爲假
  • 製造高流量無用數據,形成網絡擁塞,是受害主機沒法正常和外界通信
  • 利用受害主機提供的服務或傳輸協議上的缺陷,反覆高速的發出特定的服務請求,是受害主機沒法及時處理全部正常請求
  • 嚴重時會形成系統死機

clipboard.png

DDoS攻擊實例--SYN Flood攻擊

SYN-Flood是目前最流行的攻擊手段。

SYN-Flood利用TCP/IP協議的固有漏洞。面向鏈接的TCP三次握手是SYN-Flood存在的基礎。
clipboard.png

如上圖圖,在第一步中,客戶端向服務端提出鏈接請求。這時TCP SYN標誌置位。客戶端告訴服務端序列號區域合法,須要檢查。客戶端在TCP報頭的序列號區中插入本身的ISN。服務端收到該TCP分段後,在第二步以本身的ISN迴應(SYN標誌置位),同時確認收到客戶端的第一個TCP分段(ACK標誌置位)。在第三步中,客戶端確認收到服務端的ISN(ACK標誌置位)。到此爲止創建完整的TCP鏈接,開始全雙工模式的數據傳輸過程。

clipboard.png

假設一個用戶向服務器發送了SYN報文後忽然死機或掉線,那麼服務器在發出SYN+ACK應答報文後是沒法收到客戶端的ACK報文的(第三次握手沒法完成),這種狀況下服務器端通常會重試(再次發送SYN+ACK給客戶端)並等待一段時間後丟棄這個未完成的鏈接,這段時間的長度咱們稱爲SYN Timeout,通常來講這個時間是分鐘的數量級(大約爲30秒-2分鐘);一個用戶出現異常致使服務器的一個線程等待1分鐘並非什麼很大的問題,但若是有一個惡意的攻擊者大量模擬這種狀況,服務器端將爲了維護一個很是大的半鏈接列表而消耗很是多的資源—-數以萬計的半鏈接,即便是簡單的保存並遍歷也會消耗很是多的CPU時間和內存,況且還要不斷對這個列表中的IP進行SYN+ACK的重試。實際上若是服務器的TCP/IP棧不夠強大,最後的結果每每是堆棧溢出崩潰—即便服務器端的系統足夠強大,服務器端也將忙於處理攻擊者僞造的TCP鏈接請求而無暇理睬客戶的正常請求(畢竟客戶端的正常請求比率很是之小),此時從正常客戶的角度看來,服務器失去響應,這種狀況咱們稱作:服務器端受到了SYN Flood攻擊(SYN洪水攻擊)。

DDoS的防範

主機上的設置
幾乎全部的主機平臺都有抵禦DDoS的設置,基本的有幾種:

  • 關閉沒必要要的服務
  • 限制同時打開的SYN半鏈接數目
  • 縮短SYN半鏈接的time out時間
  • 及時更新系統補丁

網絡設備上的設置

  • 防火牆

    • 禁止對主機的非開放服務的訪問
    • 限制同時打開的SYN最大鏈接數
    • 限制特定IP地址的訪問
    • 啓用防火牆的防DDoS屬性
    • 嚴格限制對外開放的服務器的向外訪問

本內容摘自:
分佈式拒絕服務攻擊(DDoS)原理及防範

XSS攻擊

SQL注入攻擊

SQL注入是一種危害極大的攻擊形勢,雖然危害很大,可是防護卻遠沒有XSS那麼難。

緣由

SQL注入的漏洞存在,就是拼接SQL參數,也就是將用於輸入的查詢參數,直接拼接在SQL語句中,致使了SQL注入漏洞。

例子

String sql = "SELECT id,no FROM user WHERE id = " + id;

其中id是用戶輸入的參數,那麼若是用戶輸入2,那麼上面查到的是一條數據,若是用戶輸入的是"2 or 1 = 1"進行SQL注入攻擊,那麼即將user表的全部記錄都查找出來了。

SQL注入的防護

採用預編譯和綁定變量

String sql = "SELECT id,no FROM user WHERE id = ?";
    PreparedStatement ps = conn.preparedStatement(sql);
    ps.setInt(1,id);
    ps.executuQuery();

緣由:採用了PrepareStatement,就會將sql語句:"SELECT id,no FROM user WHERE id = ?"`預先編譯好,也就是SQL引擎預先進行語法分析,產生語法書,聲稱執行計劃,也就是說,後面你輸入的參數,不管輸入什麼,都不會影響該SQL語句的語法結構,後面輸入的參數,毫不會被做爲sql命令來執行,只會被當作字符串面值參數。

在實際項目中,通常都是採用各類框架,好比ibatis,hibernate,mybatis等,他們通常默認就是sql預編譯。對於ibatis/mybatis,若是使用#{name}形式的,那麼就是SQL預編譯,使用${name},就不是SQL預編譯。

mybatis中的#跟$:
#{}:解析爲一個JDBC預編譯語句的參數標識符,一個#{}被解析爲一個參數標識符。
${}:僅僅做爲一個純粹的String替換,在動態SQL解析階段進行變量替換。

eg:

-- id = 123
    SELECT id,no FROM user WHERE id = #{id} -- > '123'
    SELECT id,no FROM user WHERE id = ${id} -- >  123

本內容參考:
sql注入防護方法總結
Mybatis 中$與#的區別

相關文章
相關標籤/搜索