有趣的程式碼攻防戰

weixin_33762321發表於2018-08-29

有趣的程式碼攻防戰

寫在前面

今天這篇文章,是一篇關於程式碼安全的內容。大部分內容可能對於現在來說都已經很小兒科了。但是我在瞭解這方面的內容時,著實還是被這些前輩們腦洞大開的手段所折服。 所以今天就特地盤點了一些比較出名的漏洞問題。

漏洞大盤點

程式碼漏洞

不安全的程式碼-注入式攻擊

注入式(Inject)攻擊是一類非常常見的攻擊方式,其基本特徵是程式允許攻擊者將不可信的動態內容注入到程式中,並將其執行,這就可能完全改變最初預計的執行過程,產生惡意效果。

1、XSS

1.1、反射型 XSS(非永續性跨站攻擊)

一般是利用網站某些頁面會直接輸出請求引數的特性,通過在 url 的請求引數包含惡意指令碼,導致使用者開啟該 url 的時候,執行惡意指令碼。

例:http://localhost:8080/test.jsp?abc= <script>alert(“123”) </script>

使用者在訪問這個頁面的時候,就會觸發彈窗。

當然,一般的 XSS 攻擊不會這麼簡單的就讓你彈個窗,甚至可能彈出你的cookie資訊。

1.2、儲存型 XSS(永續性跨站攻擊)

該種型別的攻擊一般是通過表單輸入(比如釋出文章、回覆評論等功能中)插入一些惡意指令碼,並且儲存到資料庫,待其他使用者載入對應的頁面的時候,該段指令碼就會被載入並執行。

與反射型 XSS 相比,該類的攻擊更具有危害性,因為它影響的不只是一個使用者,而是大量使用者,而且該種型別還可進行蠕蟲傳播;就如之前的貼吧和微博事件,使用者訪問了含有惡意指令碼的頁面,使用者的cookie資訊被盜取了,並且立刻使用使用者的賬戶去發表新的帖子或微博同時注入惡意指令碼,使得該惡意指令碼不斷被傳播下去。

1.3、DOM Based XSS(基於 Dom 的跨站點指令碼)

基於 DOM 的跨站點指令碼與前面兩種型別有什麼區別呢?其實它注入的方式是基於前面兩種型別的方式的,只不過是注入的指令碼是通過改變DOM來實施的。

採用該種方式有一個好處就是從原始碼中不易被發現而已。

如何去防護 XSS

基於上面漏洞產生的原因,我們若要想防禦該種攻擊,就需要從源頭抓起(使用者輸入),制定一套合理且安全的 XSS 過濾規則。 以下介紹一些過濾方法

對 HTML 標籤及一些特殊符號進行轉義

該種方法是一種非常簡單的過濾方法,僅僅是通過轉義的方式將一些 HTML 標籤和屬性轉義,比如 < 轉義成 &lt ;, 這樣像的指令碼就執行不了。當然簡單的過濾方式也就代表很容易就會被繞過。 另外如果需要使用含有富文字的功能時,使用這樣的過濾就會使富文字失去作用。

使用白名單、黑名單的方式進行過濾

白名單、黑名單顧名思義是要定義哪些東西是可通過的,哪些東西不可通過。比如常見<b>、<p>; 、<等等標籤,不可通過的比如 javascript、<a>、<script>、<iframe>、onload 等等一些屬性,將其進行轉義。 當然使用該種方法也有自身的缺點,你並不可能窮舉出所有元素,也可能會某些元素在黑名單內,但在某些情況它是需要使用的,這就需要我們在設計 XSS 過濾器的時候權衡好,取最合理最適合需求的設計。

有趣的程式碼攻防戰

2、SQL隱碼攻擊

首先,就是最常見的SQL隱碼攻擊。一個典型的場景就是Web系統的使用者登入功能,根據使用者輸入的使用者名稱和密碼,我們需要去後端資料庫核實資訊。

假設應用邏輯是,後端程式利用介面輸入動態生成類似下面的 SQL,然後讓 JDBC 執行。 Select * from use_info where username = “input_usr_name” and password = “input_pwd”

但是,如果我輸入的 input_pwd 是類似下面的文字,“ or “”=”

那麼,拼接出的 SQL 字串就變成了下面的條件,OR 的存在導致輸入什麼名字都是複合條件的。 Select * from use_info where username = “input_usr_name” and password = “” or “” = “” 這個例子,各位小夥伴們應該很容易能夠理解到它的攻擊性。上面例子中,程式期望使用者輸入一個數值,但實際輸入的則是SQL語句片段。

根據這個套路,我們就可以注入很多很騷的SQL片段了,比如刪庫,跑路之類的~

3、作業系統命令注入

作業系統命令注入。

比如:Java 語言提供了類似Runtime.exec(…)的API,可以用來執行特定命令,假設我們構建了一個應用,以輸入文字作為引數,執行下面的命令: ls –la input_file_name

但是如果使用者輸入是:

input_file_name;rm –rf/* 那將是毀滅性的打擊,但是程式語言本身是做了很多的限制,這些操作未必可以真的能夠完成攻擊,但是這種隱患終究還是存在的。

預防注入式攻擊

在 Java 應用進行資料庫訪問時,如果不用完全動態的SQL,而是利用PreparedStatement,可以有效防範 SQL 注入。不管是SQL隱碼攻擊,還是OS命令注入,程式利用字串拼接生成執行邏輯都是個可能的風險點!

在資料庫層面,如果對查詢、修改等許可權進行了合理限制,就可以在一定程度上避免被注入刪除等高破壞性的程式碼。

暴力攻擊

臭名昭著-DoS攻擊

拒絕服務(DoS)攻擊,可以說是名聲很響的暴力攻擊方式。

最常見的DoS攻擊有對計算機網路的頻寬攻擊和連通性攻擊。頻寬攻擊指以極大的通訊量衝擊網路,使得所有可用網路資源都被消耗殆盡,最後導致合法的使用者請求無法通過。連通性攻擊指用大量的連線請求衝擊計算機,使得所有可用的作業系統資源都被消耗殆盡,最終計算機無法再處理合法使用者的請求。

雜湊碰撞攻擊

雜湊碰撞是一種有趣的攻擊方式。對方可以輕易消耗系統有限的CPU和執行緒資源。從這個角度思考,類似加密、解密、圖形處理等計算密集型任務,都要防範被惡意濫用,以免攻擊者通過直接呼叫或者間接觸發方式,消耗系統資源。

比如在Java中,有一個有趣的攻擊方式:

攻擊者可以事先構造大量相同雜湊值的資料,然後以Json資料的形式傳送給伺服器端,伺服器端在將其構建成為 Java 物件過程中,通常以Hastable或HashMap等形式儲存,雜湊碰撞將導致雜湊表發生嚴重退化,演算法複雜度可能上升一個數量級(HashMap1.8之後在紅黑樹結構的優化,也是應對此問題的優化),進而耗費大量CPU資源。衝突多了,就會極大的降低get的效能,造成極嚴重的卡頓,甚至伺服器崩掉~

有趣的程式碼攻防戰

Android-WebView

addJavascriptInterface介面引起遠端程式碼執行漏洞

此問題在4.2以後的版本被修復了

我們Native和Js互相通訊,可能會這麼寫我們本地的Java程式碼:

webView.addJavascriptInterface(new JSObject(), "mJSObject");
複製程式碼

這段程式碼是不是挺正常的?的確挺正常吶。如果我們用民主富強文明和諧的眼光去看,的確沒問題。不過如果我們懷著一顆搞破壞的心呢? 我們既然能拿到這個Java物件,那麼對於我們來說,我們可以使用反射為所欲為了。(這個問題,烏雲曾給出過明確的漏洞描述)

function execute(cmdArgs){
    for (var obj in window) {
        if ("getClass" in window[obj]) {
            alert(obj);
            return  window[obj].getClass().forName("java.lang.Runtime")
                 .getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
        }
    }
}
複製程式碼

不需多解釋吧,這是當前很著名的WebView漏洞問題。

  • 1,WebView新增了JavaScript物件,並且當前應用具有讀寫SDCard的許可權。
  • 2,JS中可以遍歷window物件,找到存在“getClass”方法的物件的物件,然後再通過反射的機制,得到Runtime物件,然後呼叫靜態方法來執行一些命令,比如訪問檔案的命令.
  • 3,再從執行命令後返回的輸入流中得到字串,就可以得到檔案的資訊了。(理論上SD卡的所有內容都可以拿到了)

網路傳輸

防不勝防 - 中間人攻擊

中間人攻擊原理大概是使用者在正常上網的時候,同網段的惡意使用者對其進行欺騙。惡意使用者向區域網廣播:我是路由器,然後正常使用者(電腦無防禦)收到以後認為惡意使用者就是路由器,然後向惡意使用者傳送資料包,惡意使用者可以截獲資料包,再向路由器傳送正常使用者的資料包,路由器將返回的資料包在給惡意使用者,惡意使用者在給正常使用者,惡意使用者就形成了中間人的效果,可以向返回的資料包注入html程式碼,達到劫持使用者網站的效果,不過現在大部分的網站都是https且雙向認證,比較難獲取到使用者傳送資料包中的賬號密碼。

CSRF攻擊

CSRF,全名:Cross site Request Forgery(跨站域請求偽造)。一般的攻擊方式是,通過請求偽造盜取使用者的cookie資訊,進而進行操作。

  • 1、首先使用者A請求登陸了伺服器B,這時伺服器 B 響應了使用者A,並且會返回唯一標識的該使用者的 cookie 資訊。
  • 2、使用者A在未退出伺服器B時(即仍與伺服器 B保持會話狀態),訪問了帶有惡意指令碼的伺服器 C,伺服器 C 響應給使用者 A 一個惡意頁面,並且通過惡意指令碼偽裝使用者 A 向伺服器 B 傳送請求,此時伺服器 B 誤以為是使用者 A 請求,故響應並返回了使用者 A 的 cookie 資訊。
  • 3、伺服器 C 收到使用者 A 與 伺服器 B 的cookie資訊後,儲存起來,並利用該資訊偽裝成使用者 A 去訪問伺服器 B,再進行相應的破壞~

尾聲

這部分內容,其實並非是對深層技術的討論。只是最近無意中看到這部分的內容,感覺很有趣就收集起來寫了這篇文章,算是忙碌的工作之中娛樂一下吧~

這裡是一幫應屆生共同維護的公眾號,內容是我們在從應屆生過渡到開發這一路所踩過的坑,以及我們一步步學習的記錄,如果感興趣的朋友可以關注一下,一同加油,一同努力~!~!

個人公眾號:IT面試填坑小分隊

相關文章