《大型分佈式網站架構設計與實踐》——常見的Web攻擊手段

常見的Web攻擊手段

XSS攻擊

跨站腳本攻擊(Cross Site Scripting),指的是攻擊者在網頁中嵌入惡意腳本程序,當用戶打開該網頁時,腳本程序便開始在客戶端的瀏覽器上執行,以盜取客戶端cookie、用戶名密碼,下載執行病毒木馬程序,甚至是獲取客戶端admin權限等

<img fen_015>

防範: 對用戶輸入的數據進行HTML轉義處理

轉義前 轉義後
< &lt ;
> &gt ;
&amp ;
&quot ;

CSRF攻擊

跨站請求僞造(cross site request forgery),是一種對網站的惡意利用,XSS利用的是站點內的信任用戶,而CSRF則是通過僞裝來自受信任用戶的請求來利用受信任的網站,可以這麼理解CSRF攻擊:攻擊者盜用了你的身份,以你的名義向第三方網站發送惡意請求,CRSF能做的事情包括利用你的身份發郵件、發短信、進行交易轉賬等,甚至盜取你的賬號

攻擊原理如下圖所示

<img_018>

防範:

  • 將cookie設置爲HttpOnly

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

    在Java的Servlet的API中設置cookie爲HttpOnly的代碼如下

    response.setHeader("Set-Cookie", "cookiename=cookievalue;HttpOnly");
    
  • 增加token

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

    假設請求通過POST方式提交,則可以在相應的表單中增加一個隱藏域:

    <input type="hidden" name="_token" value="tokenvalue">
    

    token的值通過服務端生成,表單提交後token的值通過POST請求與參數一同帶到服務端,每次會話可以使用相同的token,會話過期,則token失效,攻擊者因無法獲取到token,也就無法僞造請求

    在session中添加token的實現代碼

    HttpSession session = request.getSession();
    Object token = session.getAttribute("_token");
    if(token == null || "".equals(token)){
        session.setAttribute("_token", UUID.randomUUID().toString());
    }
    
  • 通過Referer識別

    在HTTP頭中有一個字段叫Referer,它記錄了該HTTP請求的來源地址,在通常情況下, 訪問一個安全受限的頁面的請求都來自於同一個網站,如果攻擊者要對第三方網站實施CSRF攻擊,他只能在其他網站構造請求,當用戶通過其他網站發送請求到第三方網站時,只需要對請求驗證其Referer值即可

    取得HTTP請求Referer

    String referer = request.getHeader("Referer");
    

SQL注入攻擊

通過把SQL命令僞裝成正常的HTTP請求參數,傳遞到服務端,欺騙服務器最終執行惡意的SQL命令,達到入侵目的

防範:

  • 使用預編譯語句

    預編譯SQL語句中的特殊字符會被轉義

  • 避免免密碼明文存放

    不用明文存儲密碼,使用哈希加鹽法(Hash+Salt),能夠在一定程度上解決使用彩虹表的破解方法(逆向或碰撞串),所謂加鹽(Salt)就是在生成Hash時給予一個擾動,使Hash值與標準的Hash結果不同,如密碼是”hello”,加一個鹽,也就是隨機字符串”abcdefgids”,兩者合到一起,計算MD5,通過這種操作, 即便用戶用的是弱密碼,也能通過加鹽,使實際計算哈希的密碼值變成一個長字符串,一定程度上防禦了窮舉攻擊和彩虹表攻擊

  • 處理好相應的異常

    處理好後臺的系統異常,重定向到相應的錯誤處理頁面

文件上傳漏洞

文件上傳攻擊指的是惡意攻擊者利用一些站點沒有對文件的類型做很好的校驗,上傳了可執行的文件或者腳本,並且通過腳本獲得服務器上相應的權力,或者是通過誘導外部用戶訪問、下載上傳的病毒或木馬文件,達到攻擊的目的

防範:

  • 對上傳的文件類型進行白名單(非黑名單)校驗,並且限制上傳文件的大小,上傳的文件需要進行重命名,使攻擊者無法猜測到上傳文件的訪問路徑
  • 不能簡單地通過後綴名稱來判斷文件的類型,因爲惡意攻擊可以將可執行文件的後綴名改成圖片或者其他後綴類型。因爲很多類型的文件,起始的幾個字節內容是固定的,因此,根據這幾個字節的內容,就可以確定文件類型,這幾個字節也被稱爲魔數(magic number)

    1.通過魔數來判斷文件類型

    public enum FileType{
        JPEG("FFD8FF"),
        PNG("89504E47"),
        GIF("47494638"),
        TIFF("49492A00"),
        BMP("424D"),
        DWG("41433130"),
        PSD("38425053"),
        XML("3C3F786D6C"),
        HTML("68746D6C3E"),
        PDF("255044462D312E"),
        ZIP("504B0304"),
        RAR("52617221"),
        WAV("57415645"),
        AVI("41564920"),
    
        private String value = "";
        private FileType(String value){
            this.value = value;
        }
    
        public String getValue(){
            return value;
        }
    
        public void setValue(String value){
            this.value = value;
        }
    
    }
    
    /**
     *讀取文件頭
     *
     */
     private static String getFileHeader(String filePath) throws IOException {
         //這裏需要注意的是,每個文件的魔數的長度都不相同,因此需要使用startwith
         byte[] b = new byte[28];
         InputStream is = null;
         is = new FileInputStream(filePath);
         is.read(b, 0, 28);
         is.close();
    
         return bytes2hex(b);
     }
    
     /**
      *判斷文件類型
      */
      public static FileType getType(String filePath) throws IOException {
          String fileHead = getFileHeader(filePath);
          if(fileHead == null || fileHead.length() == 0){
              return null;
          }
          fileHead = fileHead.toUpperCase();
          FileType[] fileTypes = FileType.values();
          for(FileType type : fileTypes){
              if(fileHead.startsWith(type.getValue())){
                  return type;
              }
          }
          return null;
      }
    

    對於圖片類型的文件,可以在上傳後,對圖片進行相應的縮放,破壞惡意用戶上傳的二進制可執行文件的結構,來避免惡意代碼執行

    imagemagick是一套功能強大、穩定並且開源的針對圖片處理的開發工具包,能夠處理多種格式的圖片文件,可以利用imagemagick來對圖片進行縮放處理

DDoS攻擊

DDoS(Distributed Denial of Service)即分佈式拒絕服務攻擊,是目前最爲強大、最難以防禦的攻擊方式之一

最基本的DoS攻擊就是利用合理的客戶端請求來佔用過多的服務器資源,從而使合法用戶無法得到服務器的響應,DDoS攻擊手段是在傳統的DoS攻擊基礎之上產生的一類攻擊方式,傳統的DoS攻擊一般是採用一對一的方式,當攻擊目標的CPU速度、內存或者網絡帶寬等各項性能指標不高的情況下,它的效果是明顯的,但隨着計算機與網絡技術的發展,計算機的處理能力顯著增加,內存不斷增大,同時也出現了千兆級別的網絡,這使得DoS攻擊逐漸失去了效果

DDoS指的是攻擊者藉助公共網絡,將數量龐大的計算機設備聯合起來作爲攻擊平臺,對一個或多個目標發動攻擊,從而達到癱瘓目標主機的目的,通常在攻擊開始前,攻擊者會提前控制大量的用戶計算機,稱之爲”肉雞”,並通過指令使大量的肉雞在同一時刻對某個主機進行訪問,從而達到癱瘓目標主機的目的

常見的DDoS攻擊手段:

  • SYN Flood

    SYN Flood是互聯網最經典的攻擊方式之一,它利用了TCP協議三次握手過程

    <img fen_019>

    TCP協議爲實現可靠傳輸,在三次握手的過程中設置了一些異常處理機制,如果服務器沒有收到客戶端的ACK報文,服務端一般會進行重試,也就是再次發送SYN+ACK報文給客戶端,並且一直處於SYN_RECV狀態,將客戶端加入等待列表。重發一般會進行3~5次,大約每隔30秒左右會輪詢一遍等待隊列,重試所有客戶端;另一方面,服務器在發出SYN+ACK報文後,會預分配一部分資源給即將建立的TCP連接,這個資源在等待重試期間一直保留,更爲重要的是,服務器資源有限,可以維護的等待列表超過極限後就不再接收新的SYN報文,也就是拒絕建立新的TCP連接

    SYN Flood正是利用了TCP協議三次握手的過程來達到攻擊的目的,攻擊者僞造大量的IP地址給服務器發送SYN報文,但是由於僞造的IP地址幾乎不可能存在,也就不可能從客戶端得到任何迴應,服務端將維護一個非常大的半連接等待列表,並且不斷對這個列表中的IP地址進行遍歷和重試,佔用了大量的系統資源,更爲嚴重的是,由於服務器資源有限,大量的惡意客戶端信息佔滿了服務器的等待隊列,導致服務器不再接收新的SYN請求,正常用戶無法完成三次握手與服務器進行通信,這便是SYN 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查詢操作或者一次請求返回大量的數據,加速系統資源消耗,從而拖垮後端的業務處理系統,甚至連相關存儲與日誌收集系統也無法倖免

其他攻擊手段

其他比較常見的攻擊手段還有DNS域名劫持、CDN回源攻擊、服務器權限提升、緩衝區溢出,以及一些依賴於平臺或者具體軟件漏洞的攻擊等

發佈了84 篇原創文章 · 獲贊 135 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章