Web安全防護(二)

點擊劫持

點擊劫持,也稱UI覆蓋攻擊

1.1 iframe覆蓋攻擊

黑客創建一個網頁,用iframe包含了目標網站,並且把它隱藏起來。做一個僞裝的頁面或圖片蓋上去,且按鈕與目標網站一致,誘導用戶去點擊。僞裝的按鈕背後可能就會執行了危險操作。

<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
<head>
    <title>點擊劫持 POC</title>
      <style>
        iframe {
              width: 1440px;
              height: 900px;
              position: absolute;
              top: -0px;
              left: -0px;
              z-index: 2;
              -moz-opacity: 0;
              opacity: 0;
              filter: alpha(opacity=0);
           }
        button {
              position: absolute;
              top: 270px;
              left: 1150px;
              z-index: 1;
              width: 90px;
              height:40px;
           }
      </style>
</head>
<body>
<button>美女圖片</button>
<img src="http://pic1.win4000.com/wallpaper/2018-03-
19/5aaf2bf0122d2.jpg">
<iframe src="http://i.youku.com/u/UMjA0NTg4Njcy"
        scrolling="no"></iframe>
</body>
</html>

防護方案:

使用一個HTTP頭-X-Frame-Options。它可以設置frame的加載權限。它有三個可選的值:

  • DENY:瀏覽器會拒絕當前頁面加載任何frame頁面
  • SAMEORIGIN:frame頁面的地址只能爲同源域名下的頁面
  • ALLOW-FROM uri:允許frame加載的頁面地址

nginx配置:

add_header X-Frame-Options SAMEORIGIN;

1.2 圖片覆蓋攻擊

圖片覆蓋攻擊,攻擊者使用一張或多張圖片,利用圖片的style或者能夠控制的CSS,將圖片覆蓋在網頁上,形成點擊劫持。

<a href="http://tieba.baidu.com/f?kw=%C3%C0%C5%AE">
  <img src="XXXXXX"
style="position:absolute;top:90px;left:320px;" />
</a>

你以爲你點了圖片,其實你點了其他的鏈接。

防護方案:

在防禦圖片覆蓋攻擊時,需要檢查用戶提交的HTML代碼中,img標籤的style屬性是否可能導致浮出。

URL跳轉漏洞

URL跳轉漏洞(URL重定向漏洞),跳轉漏洞一般用於釣魚攻擊

攻擊原理:

URL跳轉漏洞本質上是利用Web應用中帶有重定向功能的業務,將用戶從一個網站重定向到另一個網站。

示例:http://www.
aaa.com?returnUrl=http://www.evil.com,www.aaa.com 有一個功能會取到returnUrl後的路徑,然後跳轉。這種功能就會被黑客利用,跳轉到他想跳轉的其他頁面上去。

一般容易出現的漏洞的點:

  • 登錄跳轉、第三方授權
  • 分享
  • 收藏

URL跳轉漏洞校驗繞過

  1. 域名字符串校驗
//獲取參數
String url = request.getParameter("returnUrl");
//判斷是否包含域名
if (url.indexOf("www.abc.com ") !=-1){ 
  response.sendRedirect(url);
}

黑客可以註冊一個包含abc.com的域名來繞過,如:
http://www.abc.com?returnUrl=http://www.abc.com.evil.com
2. 利用URL的各種特性符號

http://www.aaa.com?returnUrl=http://www.evil.com?www.aaa.com
http://www.aaa.com?returnUrl=http://www.evil.comwww.aaa.com
http://www.aaa.com?returnUrl=http://[email protected]
http://www.aaa.com?returnUrl=http://www.evil.com#www.aaa.com

防護方案

  1. 代碼固定跳轉地址,不讓用戶隨意輸
  2. 跳轉目標地址採用映射機制,如 1代表aaa.com,2代表bbb.com這樣,用戶只能輸1和2才能過校驗
  3. 合理充分的校驗機制,校驗跳轉的目標地址,非己方的地址跳轉時可以提示用戶,類似知乎做的那種。

Session攻擊

通過竊取用戶SessionId,使用SessionId登錄進目標賬戶的攻擊方法。如果SessionId是保存在Cookie中的,則這種攻擊可以稱爲Cookie劫持。

3.1 Session劫持

攻擊原理:

  1. 目標用戶登錄網站
  2. 登錄成功後,用戶的SessionId服務器會認爲是已登錄的,可以做一些他權限內的操作
  3. 攻擊者通過某種攻擊手段捕獲Session ID
  4. 攻擊者通過捕獲到的Session ID訪問站點即可獲得目標用戶合法會話。

獲取SessionId的方式有多種:

  1. 暴力破解:不斷嘗試各種Session ID
  2. 預測:如果Session ID使用非隨機的方式產生,那麼就有可能計算出來
  3. 竊取:使用網絡嗅探、本地木馬竊取、XSS攻擊等方法

防禦方法:

  1. Cookie HttpOnly
  2. Cookie Secure,是設置Cookie時,可以設置的一個屬性,設置了之後只有https訪問時,瀏覽器纔會發送該cookie。這樣攻擊者從網絡上竊聽到,也是拿到一個加密的cookie
response.setHeader("SET-
HEADER","user="+request.getParameter("cookie")+";HttpOnly;Sec
ure");

3.2 會話固定

會話固定是讓用戶使用黑客預先設置的sessionID進行登錄,這樣同樣黑客能拿到用戶SessionId。

攻擊步驟:

  1. 攻擊者通過某種手段重置用戶的SessinoID,然後監聽用戶會話狀態
  2. 目標用戶攜帶攻擊者設定的Session ID登錄站點
  3. 攻擊者通過Session ID獲得合法會話

攻擊者如果讓目標使用黑客的Session ID呢?如果是保存在Cookie中是比較難做的,但如果是SessionID保存在URL中,則攻擊者只要誘導用戶打開這個URL即可。

防禦方法:

  1. 用戶登錄的時候就進行重置SessionID
// 會話失效
session.invalidate();
// 會話重建
session=request.getSession(true);
  1. SessionID閒置過久時,進行重置
  2. 設置HttpOnly

3.3 Session保持攻擊

一般情況下,Session是有生命週期的,當用戶長時間未活動,或者用戶點擊退出後,服務器將銷燬Session。但如果攻擊者拿到了一個用戶的Session,它可以通過不停的發起訪問請求,讓Session一直存活。

<script>
 //要保持session的url
 var url =
"http://bbs.yuanjing.com/wap/index.php?/sid=LOXSAJH4M";
 //定時任務
 window.setInterval("keeyId()",6000);
 function keepsid(){
 
 document.getElementById("iframe1").src=url+"&time"+Math.rand
om();
}
</script>
<iframe id="iframe1" src=""/></iframe>

攻擊者設置可以爲Session Cookie增加一個Expire事件,使得原本瀏覽器關閉就會失效的Cookie持久化地保存在本地。

防護方案:

  1. 可以設置一個固定的時間,如3天后就強制過期,但是也影響了正常用戶
  2. 比如用戶的IP、UserAgent信息發生編號,就可以強制銷燬當前的Session,並要求用戶重新登錄

注入攻擊

注入攻擊是Web安全領域中一種最常見的攻擊方式。XSS本質上也是一種針對HTML的注入攻擊。注入攻擊的本質,是把用戶輸入的數據當做了代碼執行。這裏有兩個關鍵條件,第一個是用戶能控制輸入,第二個是原本程序要執行的代碼拼接了用戶輸入的數據。解決注入攻擊的核心思想:數據與代碼分離原則

4.1 SQL注入

本應該輸入正常的數據,而黑客卻輸入一些sql語句。如果應用程序比較脆弱的話,則可能應用程序會被攻擊。

最簡單的示例就是一個:查詢某個用戶

String query = "select * from accounts where name ='"+request.getParameter("name")+"';

用戶如果輸張三李四是沒問題的,如果輸入 李四 or 1=1 那麼它會查到所有用戶數據。

容易導致SQL注入的弱點:

  1. 應用程序中使用字符串連接方式或聯合查詢方式組合SQL語句
  2. 應用程序連接數據庫時使用權限過大的賬戶(很多開發人員喜歡直接用管理員賬戶)
  3. 未校驗用戶輸入的字符串

攻擊步驟:

  1. SQL盲注

所謂盲注,就是在服務器沒有返回錯誤信息的情況下完成的注入攻擊。最常見的盲注驗證方法是構造簡單的條件語句,根據返回的頁面是否變化來判斷是否存在漏洞。

示例:下面是一個根據userId查詢用戶的功能:

1) 我先輸入

1 ' and 1=1 #


發現能查詢到數據

2)再輸入

1 ' and 1=2 # 發現查不出數據,證明注入成功。

  1. 猜解數據庫

3)繼續輸入利用order by猜列數

1' order by 1 #
成功,然後輸入 1' order by 2 # ,依次遞增,直到提示
Unknown column '3' in 'order clause'

成功得到該表的列數。

4)知道列數之後,使用union select 聯合查詢獲取更多的信息,union 查詢的使用前提是關聯查詢的兩個查詢列數要一致

1 ' union select database(),user() #

查詢到數據庫名和當前查詢的用戶名

5)繼續查詢當前數據庫版本、操作系統

1 ' union select version(),@@version_compile_os#

6)根據數據庫名,查詢裏面的表

1 ' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa' #

7)猜users表的字段,根據經驗試試是不是user和password

1' union select user,password from users#

成功爆出了某網站的用戶名和密碼

  1. ORM注入

1) Mybatis:
${}:單純替代,純粹的將參數傳進去,沒有做任何的轉義操作和預編譯。
#{}: Mybatis會通過預編譯機制生成PreparedStatement參數,然後再安全的給參數賦值

${}是存在注入風險的。

2) Hibernate

usernameString//前臺輸入的用戶名
passwordString//前臺輸入的密碼
//hql語句
String queryString = "from User t where t.username= " +
usernameString + " and t.password="+ passwordString;
//執行查詢
List result = session.createQuery(queryString).list();

通過hql拼接的方式不安全。建議用參數綁定:

usernameString//前臺輸入的用戶名
passwordString//前臺輸入的密碼
//hql語句
String queryString = "from User t where t.username:
usernameString and t.password: passwordString";
//執行查詢
List result = session.createQuery(queryString)
          .setString("usernameString ",
usernameString )
          .setString("passwordString",
passwordString)
          .list(); 

3)JDBC:使用預處理執行SQL語句,對所有傳入SQL語句中的變量做綁定,這樣用戶拼接進來的變量無論內容是什麼,都會被當做替代符號"?"所替代的值。

示例:

String sql = "select * from users where userid = " + userid;

如果用戶輸入userid是"1;delete users;"會被編譯成2條sql,那麼users表會被非法刪除。

但是如果是預編譯的方式,那麼會編譯成一條sql,查詢userid爲'"1;delete users;"的用戶,查詢結果會是不存在,不會存在危險。

4.2 XML注入

XML注入是將用戶錄入的信息作爲XML節點。
示例:

//userData是準備保存的XML數據,接受了name和email兩個用戶提交的數據
String userData = "<USER >"+
 "<name>"+
 request.getParameter("name")+
 "</name>"+
 "<email>"+
 request.getParameter("email")+
 "</email>"
  "</USER>"
//保存XML數據
userDao.save(userData);

如果用戶輸入的時候name輸入張三,email輸入:

[email protected]</email></USER><USER><name>user2</name>
<email>[email protected]

這樣就惡意構造了一個xml,拼接起來一次保存了兩條數據。

防護方案:

對xml數據進行轉義:

String userData = "<USER>"+
  "
<name>"+StringUtil.xmlEncode(request.getParameter("name"))+"
</name>"+
  "
<email>"+StringUtil.xmlEncode(request.getParameter("email"))+
"</email>"+
  "</USER>";

4.3 代碼注入

web應用程序中如果有允許接收用戶輸入一段代碼並執行。那麼用戶可以根據這個功能寫一個遠程控制木馬,進行惡意攻擊。代碼注入往往是由一些不安全的函數或者方法引起的,其中的典型代表就是eval()

public static void main(String[] args) {
    //在Java中也可以實施代碼注入,比如利用Java的腳本引擎。
    ScriptEngineManager manager = new
ScriptEngineManager();
    //獲得JS引擎對象
    ScriptEngine engine =
manager.getEngineByName("JavaScript");
    try {
      //用戶錄入
      String param = "hello";
      String command = "print('"+param+"')";
      //調用JS中的eval方法
      engine.eval(command);
   } catch (ScriptException e) {
      e.printStackTrace();
   }
 }

攻擊示例:

hello'); var fImport = new JavaImporter(java.io.File);
with(fImport) { var f = new File('new'); f.createNewFile(); }

防護方案:

對抗代碼注入,需要禁止eval()等可以執行命令的函數,如果一定要用,則需要對用戶輸入的數據進行處理。如只能由開發人員定義代碼內容,用戶只能提交對應的id”1、2、3“等參數。

4.4 OS命令注入

OS命令注入(操作系統命令注入),僅當Web應用程序代碼包括操作系統調用,並且使用了用戶的輸入內容。

示例:
應用程序開發人員希望用戶能夠在Web應用程序中查看Ping命令的輸出。用戶正常輸入ip,那還好。

如果輸入:

127.0.0.1 && whoami
或者
127.0.0.1 && ps -ef
就能夠執行一些危險的操作。

防護方案:

最有效的方法就是不要再應用程序代碼中調用OS命令。如果非要這麼搞,那麼還是一樣需要對用戶輸入進行嚴格的驗證。

文件操作防護

5.1 文件上傳漏洞

互聯網當中,我們經常用到文件上傳功能,傳excel、傳圖片、傳視頻等等。文件上傳後,服務器的處理邏輯如果做的不夠安全,就會導致漏洞的產生。

文件上傳後導致的常見安全問題一般有:

  • 上傳文件是Web腳本語言,服務器的Web容器解釋並執行了用戶上傳的腳本
  • 上傳文件是病毒、木馬文件,然後誘使用戶或管理員下載執行
  • 上傳文件是釣魚圖片或爲包含了腳本的圖片,在某些版本的瀏覽器中會被作爲腳本執行,被用於釣魚和欺詐。

防護方案:

  1. 檢查上傳文件擴展名
  2. 上傳文件的目錄必須是http請求無法直接訪問到的。如果需要訪問,需要上傳到其他(和web服務器不同的)域名下,並設置該目錄爲不可執行目錄
  3. 上傳文件要保存的文件名和目錄名由系統根據時間生成,不允許用戶自定義
  4. 圖片上傳,要通過處理(縮略圖、水印等),無異常才能保存到服務器
  5. 上傳文件需要做日誌記錄

5.2 文件下載和目錄瀏覽漏洞

文件下載和目錄瀏覽漏洞是屬於程序設計和編碼上的不嚴謹導致的。處理用戶請求下載文件時,用戶提交文件路徑,就把服務器上對應的文件發送給用戶,這就造成了任意文件下載危險。如果用戶提交目錄,就把目錄下的文件列表發給用戶,會造成目錄遍歷安全威脅。良好的設計應該是:不允許用戶提交任意文件路徑進行下載,而是用戶單機下載按鈕默認傳遞ID到後臺程序。

防護方案:

  1. 要下載的文件地址保存在數據庫中
  2. 文件路徑保存至數據庫,讓用戶提交文件對應ID下載文件
  3. 下載文件之前做權限判斷
  4. 文件放在web無法直接訪問的目錄下
  5. 記錄文件下載日誌
  6. 不允許提供目錄遍歷服務

訪問控制

6.1 功能權限漏洞

功能權限漏洞是指Web應用沒有做權限控制,或僅僅在菜單上做了權限控制,導致惡意用戶只要猜到了其他頁面的URL地址,就可以訪問到他權限外的頁面和數據。

防護方案:

針對任何URL,每次用戶訪問,都要判斷用戶是否有訪問此URL的權限。

6.2 數據權限漏洞

這種問題出現在未對用戶與數據級別之間建立關係,如用戶A和用戶B都有查詢訂單的權限,但是A只能查詢A的訂單,B只能查B的訂單。如果只校驗用戶是否有某個功能的權限,不校驗時候有這個數據的權限,就會出現越權問題。

防護方案:

根據用戶的ID做好數據級權限控制,比如針對CRUD操作進行身份驗證,且對用戶訪問的數據進行數據權限校驗,防止通過修改ID的方式查看別人的數據。

DDOS攻擊

7.1 DDOS攻擊

DDOS(Distributed Denial of Service)又稱爲分佈式拒絕服務,DDOS是利用合理的請求造成資源過載,導致服務不可用。常見的DDOS攻擊有SYN flood、UDP flood、ICMP flood等。其中SYN flood是一種最爲經典的DDOS攻擊,其發現於1996年,至今仍然保持着非常強大的生命力。SYN flood如此猖獗是因爲它利用了TCP協議設計中的缺陷,而TCP/IP是整個互聯網的基礎,想要修復這樣的缺陷機不是不可能的事情。

SYN flood攻擊原理:

SYN flood攻擊是根據TCP協議的三次握手過程進行的攻擊。在TCP服務器收到SYN請求包時,在發送ACK包回去之前,TCP服務器需要先分配一個數據區專門服務於這個快形成的TCP連接。

在常見的SYN flood攻擊中,攻擊者短時間內發送大量的SYN包給受害者服務器,服務器需要爲每個TCP SYN包分配一個數據區,只要這些SYN包具有不同的源地址。這將給受害者服務器造成很大的系統負擔,最終導致系統不能正常工作。

SYN flood防護方案:

syn cookie:

syn cookie是通過修改TCP三次握手協議,來專門防禦DDOS的一種手段。服務器收到客戶端的SYN包,並且返回一個ACK+SYN包時,不專門分配一個數據區,而是根據這個包計算出一個cookie值。然後再收到ACK包時,服務器根據這個cookie值檢查這個ACK包是否合法。如果合法,再分配專門的數據區進行處理未來的TCP連接。

7.2 CC攻擊

CC攻擊是DDOS攻擊的一種,可以看作是應用層面的DDOS攻擊。攻擊原理是:針對一些耗費資源較大的應用頁面不斷髮起請求,以達到消耗服務器資源的目的。

防護方案:

  1. 代碼要做好性能優化,合理的使用緩存,減輕數據庫負擔
  2. 網絡架構優化,善用負債均衡,避免用戶流量集中在單臺服務器,同時可以充分利用CDN和鏡像站點的分流作用,緩解主站的壓力。
  3. 使用頁面靜態化技術,利用客戶端瀏覽器的緩存功能或服務器的緩存功能,CDN節點的緩衝服務,均可以降低服務器的檢索壓力和計算壓力。
  4. 也可以使用一些對抗手段。如限制每個ip的請求頻率,超出頻率的ip加入黑名單

IP黑白名單的開發

可以使用OpenResty+Lua腳本實現。也可以使用KONG

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章