迎關注@程序員檸檬橙 回復「1024」獲取海量編程學習資源!
這兩天和一位大廠的朋友聊天,說起他們今年技術崗晉級答辯要增加代碼走讀環節,那該如何寫出好看又好用的代碼?
代碼是程序員改變世界的工具,每個程序員都會寫代碼,但不一定能寫出好代碼。
如今的大型商業軟件系統代碼量巨大,早已不是憑借一人之力可以完成,當然有些天才選手除外,比如Linux之父 Linus Torvalds 一人寫了初代Linux內核,微信之父張小龍一人寫了Foxmail郵箱,求伯君一人完成WPS1.0。
大部分程序員的工作是流水線形式的軟件開發,每人負責開發大系統中的一個小模塊,要么怎么會說大廠擰螺絲呢,這時候編碼規范在團隊開發中就顯得尤為重要,遵循代碼規范開發,更容易寫出可讀性高、易維護的代碼。
團隊剛引入編碼規范,為了適應規范可能需要額外的時間,如果規范的要求和成員平常的編碼習慣不同,還可能會影響了開發效率,但和日后的收益比起來,這些陣痛都是暫時的。
統一使用一種風格編碼,帶來的后期收益是巨大的,這時即使看一份不是你寫的程序代碼,有統一的代碼結構、變量命名、甚至注釋風格,也非常容易理解。
打個比方來說,學 C++ 一定要看《Effective C++》,這本書就是 C++ 大師公開的最佳實踐,講了編寫出優秀C++代碼的55個建議。代碼規范從某種程度上來說,是編程習慣的最佳實踐,好的編碼規范,讓我們以最少踩坑、最少溝通成本的完成軟件開發。
規范因團隊和組織而異,我所有待過的幾個公司,都有不同的代碼規范,當然有些小公司直接參考了業界的規范,好的代碼規范值得我們學習,比如 Google 的開源項目代碼規范。
Google代碼規范項目前包含了 C++\Object-C\Python\Shell\Javascript 這 5 種編程語言風格指南,可以先來看下目錄。
關于C++的規范,也截取部分出來,整體來看是比較細致,且有實踐指導意義,比如對于頭文件定義的約束:
所有頭文件要能自給自足,用戶和重構工具不需要為特別場合而包含額外頭文件
頭文件自包含
再比如,很多人不是很了解 C++ 的前置聲明,我曾經就在知乎回答過類似的問題。這個規范不但解釋了何為前置聲明,還告訴你哪些情況下要用它,哪些情況下使用前置聲明會帶來的問題。
下圖截取自 Python 編碼規范:
Objective-C 部分編碼規范:
shell 部分編碼規范:
javascript 部分編碼規范:
如你所見,谷歌的這份編碼規范還是非常有參考價值的,分享給需要的同學,助你碼到成功!
這份 Google 開源項目代碼規范 PDF 版本,關注@程序員檸檬橙 后私信回復「002」即可下載
新年新氣象,感謝各位讀者朋友,一年以來對@程序員檸檬橙 的關注和支持!
發了年終獎,給大家發 3000 塊錢開工紅包,無套路,拼手氣!目前參與的人還不多,趕緊來吧!新年給自己一個驚喜~
領取方式:關注@程序員檸檬橙 后,私信發送關鍵詞【888】參與即可
也可點擊文末「了解更多」直達領取頁面!
祝大家新年牛氣沖天,轉發文章牛氣好運分享給更多小伙伴~
我是@程序員檸檬橙 關注我,學習更多編程知識!如果覺得文章不錯,點贊轉發支持一下吧!
今天介紹一種走私技術,HTML Smuggling,這不是一種特別新的攻擊方法,但是它確實在越來越多的攻擊場景中出現,其中就包括網絡釣魚。接下來我們就來了解一下HTML走私的來龍去脈以及它在釣魚中是怎樣被利用的吧。
什么是HTML走私?HTML走私是指,瀏覽器根據HTML文件的內容在主機上創建惡意文件,而不是直接轉發/下載惡意軟件的一種技術。HTML走私可以通過在HTML頁面中將惡意文件隱藏為編碼后的“string”來繞過外圍安全性檢查和在線檢測。
大多數周邊/在線安全檢測方法都是通過匹配文件中的某些特定模式。但在HTML走私的情況下,惡意文件被嵌在瀏覽器中,所以檢測這樣隱藏的代碼是困難的。而且由于代碼中的混淆,甚至檢測HTML走私這種情況本身也很困難。
在去年也就是2020年的網絡釣魚調查中,我遇到了兩種本質上不同的HTML走私方式。這兩種方案都將數據存儲在HTML文件中,并且提供了無需向服務器發送額外請求就可以“下載”數據的方法。此外,這兩種方案都是基于HTML5的下載屬性(雖然不是強制性的但是有好處)。
先介紹第一種方案,基于JavaScript Blob,也是我經??吹降姆桨?。Blob對象表示一個不可變、原始數據的類文件對象。它的數據可以按照文本或二進制的格式進行讀取,也可以轉換為ReadableStream來讀取。借助Blob,我們可以將我們的惡意文件存儲在HTML代碼中,然后將其置入瀏覽器中,而不是直接向Web服務器發送文件上傳請求。
我們可以通過下面兩個鏈接來創建我們的HTML頁面:
https://gist.github.com/darmie/e39373ee0a0f62715f3d2381bc1f0974
https://developer.mozilla.org/en-US/docs/Web/API/Blob
要存儲文件,首先,需要將文件編碼為base64,可以在PowerShell中使用一下代碼來實現:
$base64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes($FileName))
然后替換下面html文件中<>所指的值。fileName變量表示你希望在默認情況下下載文件的名稱。base64_encoded_file變量存儲base64編碼后的文件。
<html>
<body>
<script>
var fileName = <>
var base64_encoded_file = <>
function _base64ToArrayBuffer(base64,mimeType) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array( len );
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return URL.createObjectURL(new Blob([bytes], {type: mimeType}))
}
var url = _base64ToArrayBuffer(base64_encoded_file,'octet/stream')
const link = document.createElement('a');
document.body.appendChild(link);
link.href = url;
link.download = fileName;
link.innerText = 'Download';
</script>
</body>
</html>
現在只要我們點擊上面的鏈接,就會開始下載步驟。
實現HTML走私的另一種方案是使用DataURL。這種解決方案就不需要使用JavaScript了。使用DataURL進行HTML走私的目標就是將較小的文件嵌入HTML文件中。
雖然上面強調了小文件,但是實際上,限制也不是很嚴格。DataURL的最大長度由瀏覽器中的最大URL長度決定。比如,在Opera中,這個大小是65535個字符,雖然這個字節數對于轉移1080p的電影來說是遠遠不夠的,但是用來反彈shell已經足夠了。
這種方法比第一種基于JS Blob的要簡單得多。先看一下語法:
data::前綴;
[<mediatype>]:可選項,是一個MIME類型的字符串,比如我們最常見的image/jpeg表示JPEG圖像,如果缺省,默認值為text/plain;charset=US-ASCII;
[;base64]:可選項,如果數據是base64編碼的,那么就用;base64標記
,:將數據與控制信息分開;
<data>:數據本身。
<html>
<body>
<a href="data:text/x-powershell;base64,aXBjb25maWcNCmhvc3RuYW1l"
download="test.ps1">
Download
</a>
</body>
</html>
這是一個簡單的HTML例子,加載該頁面的時候會顯示一個download按鈕。我們點擊下載,瀏覽器就會將test.ps1文件保存到我們的電腦上。而寫入的內容自然就是aXBjb25maWcNCmhvc3RuYW1lbase64解碼后的內容。
發現了一個比較有意思的事情。當講將<a>標簽中的download去掉后,也就是變成了下面的樣子:
<html>
<body>
<a href="data:text/x-powershell;base64,aXBjb25maWcNCmhvc3RuYW1l" >
Download
</a>
</body>
</html>
我們重新在Chrome瀏覽器中打開并嘗試下載,這個時候發現,這個按鈕已經失效了,點擊不會有任何反應。但是用Firefox打開,依舊可以下載文件,只不過firefox會創建一個隨機的文件名,并且保存的文件不會有后綴:
綜上,我們可以將DataURL和JS Blob相結合來添加一個函數,當然我們可以不適用任何腳本,但是和上面的例子中的問題一樣,顯然會更到更多的限制。
HTML走私是釣魚攻擊一個很好的補充。在HTML走私的幫助下,攻擊者可以逃避一些檢測和記錄機制。在這種方式下,文件被“注入”到HTML文檔中,而絕大多數的安全解決方案根本不會去檢測。
當然HTML走私也有一些缺點。首先,它需要用戶交互,雖然瀏覽器會自動處理惡意文件,但是下載到用戶主機還是需要用戶同意,除非配置了未經用戶確認的自動下載。而且即使文件被下載了,還是需要將其執行。
上面介紹了兩種常見的HTML走私方法,回到文章的主題,如何利用HTML走私來進行釣魚呢?這里介紹兩種比較常見的方法。首先,第一種是讓電子郵件包含一個指向外部網頁的鏈接,而該指向的網頁使用了HTML走私技術。這是比較常見的郵件釣魚方式。另一種方法是,在電子郵件中添加一個HTML附件,該HTML文件走私了惡意代碼,這種情況下,用戶打開的就是本地的HTML文件,不需要訪問外部站點。
在這兩種情況下,好處是惡意內容很難被檢測到,因為惡意代碼隱藏在HTML內容中。通過這種方式,可以繞過很多道安全防御。
首先,我們來看一下正常的文件下載步驟是怎樣的。在下圖的例子中,用戶訪問一個網站,然后下載一個exe文件:
1 . 首先,用戶打開一個正常的網站。這個網站可以是用戶自己輸入的,也可以從包含鏈接的釣魚郵件中獲得。
2 . 瀏覽器向網站發送HTTP請求。如果存在代理,那么這個流量就會走代理。
3 . 代理會檢查瀏覽器請求的URL。因為許多的代理都有檢查域信譽的能力,如果代理認為請求的域是惡意的,那么Proxy不會進行后續的請求,通信將在這一步就停止;反之,代理會將請求轉發給Web服務器。
4 . Web服務器返回請求的資源給代理,在本例中,Web服務器返回的就是一個普通的HTML頁面。
5 . 代理檢查Web服務器的響應。在這一步會進行各種過濾。代理可以阻止用戶下載一些類型的文件。此外,代理可以有一個內置的沙箱來測試文件是否安全,而HTML文件通常不會再沙箱中進行測試就被允許通過代理轉發給用戶。
6 . 頁面通過代理轉發給瀏覽器。此時判斷文件可信度的角色就變成了用戶,用戶可以決定瀏覽器中顯示的某個文件是否安全,如果用戶信任,就可以進行文件下載,在本例中,該文件是一個exe文件。
7 . 瀏覽器向Web服務器發送文件下載請求。
8 . 代理的處理和之前相同,這一步沒什么區別。
9 . Web服務器將請求的exe文件發送給代理。
10 . 當代理獲得該exe文件時候,它會對其進行綜合性評估。如果設置了網絡中禁止下載exe文件,那么顯然,exe下載請求在這一步就結束了,文件將無法到達用戶的機器。代理還會檢查文件是否是已知的惡意文件。此外,它還可以決定是不是要將文件放到沙箱中進行測試。這里有一個關鍵點,當代理知道這個文件是一個可執行文件時候,它可以決定是不是要繼續轉發。而且,網絡分路器(Network Taps)可以檢測到這個exe文件,如果它們認為該文件是惡意的,也可以阻止用戶下載該文件。
11 . 如果一切順利,那么文件就到達了它的最終目的地——用戶的電腦。
在上面的步驟中,最重要的一步就是第10步。這一步有普通文件下載和HTML走私下載的最大區別。在正常下載的情況下,exe文件易于檢測和評估(比如檢查散列,沙箱執行檢查,收集頭文件信息來判斷等等)。而在HTML走私的情況下,文件不會以一種未編碼的方式在網絡上傳播,它總是會被嵌入到另一個HTML文件中。
首先,先介紹一種很常見的走私技巧。在這種情況下,攻擊者會將事先準備好的鏈接放入電子郵件中。該鏈接會指向包含走私文件的外部鏈接。在這種情況下,惡意的內容不會通過電子郵件的網關,而是以隱藏的形式,通過代理被用戶訪問。
1 . 有一個帶著外部鏈接的e-mail向目標用戶發送。
2 . 郵件網關對郵件進行檢查。在這一步有很多種檢查方法,但在本例的場景下,我們就認為郵件網關并不會阻攔該郵件,因為這里沒有包含什么惡意文件。
3 . 用戶點擊郵件中的鏈接。
4 . 默認瀏覽器啟動。
5 . 瀏覽器向存儲(或是生成)HTML文檔的外部站點發送HTTP請求。
6 . 代理會進行一些必要的檢查,但是如果該URL并沒有被加入黑名單,那么該請求就會被轉發到該站點所對應的服務器。
7 . 服務器返回HTML頁面以及隱藏在其中的exe文件。exe文件是以字符串的形式存儲在文檔中,此時它已經變成了HTML內容的一部分。
8 . 代理會檢查響應內容。在本例中,響應只是一個HTML文件,代理不會去攔截HTML文件。而且,HTML文件在絕大多數情況下不會被轉發到沙箱中執行檢查。因而,隱藏在HTML文檔中的惡意內容幾乎不會在這里被檢測到。當然通過其他的檢測技術,它們也可能能識別到HTML走私技術(但是這里指的也只是HTML走私這件事本身,而不是隱藏在HTML中的惡意文件)?,F在我們就認為代理沒有識別出這個情況,將響應HTML頁面轉發給瀏覽器。
9 . 瀏覽器重新拼接嵌入在HTML頁面中的字符串,然后啟動下載進程。
10 . 最后惡意exe文件被存儲到用戶的電腦上。
我們可以看到,在這種情況下,e-mail的安全檢查機制并不能起到太大的作用。因為電子郵件本身不是惡意的,其中的鏈接可以是合法的鏈接。
代理當然可以查看HTML文件,但是很少有安全性檢測方案會對HTML文件進行徹底地處理。大多數情況下,這些文件都是被允許通過代理的。IDS解決方案還傾向于依賴檢測文件擴展名或是magic bytes(主要是通過分析文件的第一個字節來判斷文件的類型),因此文件中的編碼字符串很難被它們捕獲。但是其實我們可以創建一個模式匹配解決方案來檢測一些隱藏在HTML中的東西。這在后面會提到。
這種方法是指包含走私的HTML文件被附加到了電子郵件中。
1 . 郵件網關收到一份帶有HTML附件的電子郵件。
2 . 郵件網關會對電子郵件中附帶的HTML進行檢查。如果檢查未通過,那么郵件網關會阻擊電子郵件的后續轉發或者選擇刪除附件。但是,現在還沒有聽說過什么電子郵件安全解決方案能夠通過靜態分析或者動態分析來檢測HTML走私(即使是在HTML走私的是惡意代碼。)
3 . 用戶打開HTML附件。
4 . 瀏覽器打開并加載HTML文檔。
5 . 瀏覽器處理HTML文件的內容,處理被走私的文件并將其提供給用戶下載。
6 . 文件被保存到計算機上。當然,在這一步,要么需要用戶的批準,要么需要瀏覽器設置了自動下載,就是未經確認的下載。
這種方法相比上一種的好處就在于,它不需要通過任何代理。而且,網絡上的IDS/IPS安全檢查通常不會去檢查電子郵件,所以,如果攻擊者能夠成功欺騙電子郵件網關,那么在網絡上就沒有其他的難處了。
在這一小節中我們來探討一下如何防御與檢測HTML走私。
在發生了HTML走私的情況下,我們可以有兩種檢測方式,我們要么就關注HTML走私技術本身,要么可以嘗試捕獲隱藏在HTML文檔中的惡意代碼。
這里介紹幾種防御方法。
雖然對于HTML走私沒有什么萬能的防御辦法。禁用JavaScript看起來是一種可行的方案,畢竟一種HTML走私技術就是基于JavaScript Blob的,但是,在企業環境中禁用JS肯定會帶來很多問題。當然,如果在你遇到的顯示場景中,禁用JS是可行的,那么也可以嘗試這種方法,那么在這個時候,你只需要用模式匹配去識別DataURL是不是存在HTML走私情況就好。
HTML走私的一種類型是使用HTML文件作為附件。不幸的是,這在很多場景中都是常見的,實際上,現在有很多帶有HTML附件的合法的、與業務相關的電子郵件在增加。另一方面,不法分子也利用HTML附件來進行釣魚。
如果你能在不影響業務的情況下阻止帶有HTML附件的郵件,那么對于利用郵件中帶有的HTML來進行釣魚的路就被堵住了。那此時我們只需要關注郵件中附帶的鏈接了。
我們可以看到,前面這兩種防御方法都無法同時覆蓋所有的HTML走私情況。在最好的情況下,我們可以使用這兩種方案來防住部分HTML走私;在最壞的情況下,我們甚至都不能使用這些防御解決方案,因為這些方案在大多數現在企業環境中是不適用的。
Microsoft Defender Application Guard是Windows提供的一種安全解決方案,主要用于隔離各種試圖使用來自不可信源資源的應用程序,后面簡稱MDAG。MDAG有兩種不同的形式。第一種是Application Guard for Edge,它主要是用來隔離企業定義的不受信任(或不特別受信任)的站點,在企業的員工瀏覽Internet時保護公司。Application Guard通過在一個啟用了Hyper-V的隔離容器中打開站點來實現這一點。而且,它還與Firefox和Chrome瀏覽器兼容。
另一個版本是Application Guard for Office。它能夠保護可信資源不受不可信資源的攻擊。它也是通過在一個容器中打開不受信任的Word、Excel、PowerPoint文檔來實現。當然,這也和HTML走私無關,所以就不繼續討論了。
我們已經知道,Application Guard for Edge主要是通過在隔離的虛擬環境中打開不受信任的鏈接來保護我們的系統。如此一來,一個未知的URL,或者說是一個惡意的URL就不會對主機造成危害了。下載的惡意文件會被隔離存儲在隔離的環境中,而不會直接與宿主機接觸。
如果一個鏈接在電子郵件中到達,并且給定的URL并不在Application Guard的白名單中,那么它就會在一個隔離的Edge中被打開。因為對于該URL的訪問是在隔離的環境中進行的,那么每個文件下載行為也都是在這個隔離的環境中進行的,因此被走私的惡意文件不會對主機造成真實傷害。
當然,這個解決方案也并不是十全十美的。它也有一些缺點:
1 . 為了使Edge能發揮作用,你需要使用白名單和untrust來標記一切網站。這在大公司中,意味著相關的管理員需要承受巨大的負載。因為用戶會不斷地進行異常請求。
2 . 雖然Application Guard能夠防住以鏈接形式附在電子郵件中的HTML走私請求,但是它無法防御以電子郵件附件形式傳遞的HTML走私。這些附件到達用戶主機后,會作為本地文件在瀏覽器中打開,因此,這些文件不會被當作不受信任的域來處理,不會在隔離的Edge容器中打開這些HTML文件,也就不會觸發Application Guard。因此通過電子郵件附件進行的HTML走私在這種情況下依然可以成功。
3 . 會影響用戶訪問站點的速度,因為需要啟動容器。
如果HTML文件中沒有利用JS來走私,而是僅僅使用了DataURL,在這種情況下,我們可以使用模式匹配(比如匹配data:)來判斷是不是發生了HTML走私。我們可以實用IDS或是簡單的YARA工具來檢測,比如github上的開源工具LaikaBOSS就是一款可用的檢測工具。
KaikaBOSS對于下載的文件(HTML文件),甚至是電子郵件附帶的文件,都非常有效。它可以檢測大量的數據,伸縮性很好,所以即使在大型環境中,也同樣可以派上用場。
如果使用了JavaScript,那么可能代碼是被混淆過的,此時模式匹配可能就不太有效果了。我們只能用其他的方法來檢測混淆的代碼。
在使用了HTML走私的場景下,被下載的文件是在瀏覽器中創建的,而在一般的下載場景中,我們可以看到,是需要我們向Web服務器發起請求,然后Web服務器傳送給我們的,而且還會經過代理,經由代理檢查文件的安全性。因此我們還可以通過關注普通文件下載和基于HTML文件創建下載文件之間的區別來鑒別HTML走私。因此我們可以通過查看代理日志、觀察是否有瀏覽器進行在主機上創建文件等方式來查看是不是發生了HTML走私。
這種方式的缺點在于:
1 . 許多流量在默認情況下不會通過代理。比如,一些公司會配置它們的網絡,使其內部網站無法通過代理訪問。這個時候,如果通過瀏覽器生成了一個文件,但是沒有代理日志。這種情況經常發生,不應該基于這種情況創建警報。
2 . 在一些情況下,用戶可以繞過代理,也不會產生代理日志。
3 . 可以在瀏覽器中打開本地文件,然后保存為新文件,這也是瀏覽器創建的文件,同樣沒有代理日志。
如果用戶是在上面的情況下進行合法行為,我們都不應該進行攔截,因此難點就在于我們很難區分這是不是一種走私情況。
您可以將HTML文件發送到沙箱,然后使用沙箱中的瀏覽器打開它。不是通過互聯網訪問的HTML文件除了一些臨時文件之外,不應該在機器上創建任何文件。理論上,如果在沒有網絡訪問的情況下,HTML文件在沙箱中創建了文件,那么沙箱應該要發出一個警報來提醒用戶。
但是,經驗表明,HTML文件通常不會放到沙箱中打開。它們可以通過靜態分析進行檢查(如LaikaBoss),也可以動態分析進行檢查,但是動態分析將花費更多的時間,并且會顯著降低網絡速度。
但是沙箱這個解決方案在大多數的情況下不是特別友好,因為在轉發給用戶之前打開每個HTML文件負載也挺大的。而且,如果惡意文件是需要用戶點擊下載的,那么這種方式也行不通,只有在頁面配置了自動下載的情況下,我們才能通過沙箱來檢測。所以總體來說,這也不是一個特別好的方法。
另一種方式是使用取證分析中可能會使用的技術——Zone.Identifier來區分是不是發生了HTML走私。
由HTML走私創建的文件的Zone.Identifier是這樣的(在新版Edge、Chrome和Firefox測試過):
[ZoneTransfer]
ZoneId=3
HostUrl=about:internet
而正常下載的文件的Zone.Identifier則是(這在不同的瀏覽器之間存在區別):
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://www.sans.org/security-resources/posters/windows-forensic-analysis/170/download
HostUrl=https://www.sans.org/security-resources/posters/windows-forensic-analysis/170/download
這種方法的局限就在于,它只能在Windows(NTFS)上這樣做。因此這種方式也不是完全可靠的。
Chrome會存儲下載文件的來源,如果源是JavaScript Blob或是DataURL,那么這些信息就會作為源顯示。
當我們打開一個本地的HTML被走私文件:
當然上面的信息不會告訴我們該被走私的惡意文件是從哪里下載的。
當我們訪問遠程的走私HTML文件時,我們就可以看到相應的惡意文件下載URL了,但是也僅僅是在走私文件是使用了JS Blob時能看到,在使用DataURL時則不會顯示遠程鏈接:
這種情況相比前面的幾種方法看起來更加實用。在遠程訪問,并使用了JS Blob的情況下,我們甚至能看到惡意文件的真實來源,如果攻擊者使用了DataURL,我們還可以利用這個信息重新生成文件,這在一些場景下可能也是有用的。
總體來說,目前想要完全檢測和防御HTML走私是一件比較困難的事情。當然,上面介紹的方法也只是相對簡單地介紹了HTML走私下的釣魚事情,在現實攻擊場景中,可能會遇到更復雜的情況。
udaText是一個用Lazarus編寫的跨平臺文本編輯器,存在200多種語法詞法分析,為你提供多重插入和多選,查找/替換reg。CudaText Mac支持許多編碼,可定制的熱鍵,大大的提升了你的工作效率!有需要的朋友,歡迎前來下載!本軟件測試環境11.4系統!下載地址:https://www.macv.com/mac/2941.html
Macv.com
在下載完軟件后打開,雙擊.pkg文件,點擊繼續,根據提示進行安裝
Macv.com
CudaText是一個用Lazarus編寫的跨平臺文本編輯器。
它是完全開源的,它起步非??欤ㄔ贗ntel Intel Core i3 3Hz上有~30個插件,0.5秒)。它可以通過Python附加組件(插件,鏈接器,代碼樹解析器,外部工具)進行擴展。
Macv.com
Macv.com
Macv.com
Macv.com
*請認真填寫需求信息,我們會在24小時內與您取得聯系。