CobaltStrike是一個(gè)知名的紅隊(duì)命令與控制框架,采用Beacon <-> TeamServer <-> Client
架構(gòu)。TeamServer存在受限路徑穿越寫文件與反序列化漏洞,可以被認(rèn)證后客戶端惡意利用。Client存在反序列化漏洞,可以被RogueCS攻擊。
山寨威脅建模
由于這個(gè)軟件的特殊性,我們需要想想什么才是漏洞:
-
直接攻擊TeamServer暴露的服務(wù)
-
通過Beacon攻擊TeamServer
-
通過Client攻擊TeamServer
-
通過TeamServer攻擊Client
-
TeamServer控制Beacon是功能,任何所謂TeamServer攻擊Beacon的操作都不能算漏洞
可以看出TeamServer是核心,先從它下手。
歷史漏洞
-
in-the-wild
利用TeamServer從Beacon下載文件時(shí),會(huì)將Beacon可控?cái)?shù)據(jù)中的IP字段作為目錄的特點(diǎn),實(shí)現(xiàn)路徑穿越寫計(jì)劃任務(wù)RCE。
-
CVE-2021-36798
利用TeamServer從Beacon加載截圖和鍵盤記錄時(shí),會(huì)根據(jù)Beacon可控?cái)?shù)據(jù)中的字節(jié)大小申請(qǐng)內(nèi)存的特點(diǎn),實(shí)現(xiàn)內(nèi)存耗盡DoS。
-
CVE-2022-23317
猜測(cè)是為了兼容proxy
的功能(路徑為http://
開頭),沒有對(duì)URL路徑做嚴(yán)謹(jǐn)?shù)男r?yàn)。動(dòng)態(tài)調(diào)試可以看出這會(huì)繞過profile相關(guān)配置,直接拿到公鑰等數(shù)據(jù):
虛假的DoS
BeaconC2.process_beacon_data
中存在一處利用條件比較苛刻的DoS。
...
int?var4?=?var3.readInt();
...
if?(var4?>?var3.available())?{
????return?false;
}
...
byte[]?var5?=?new?byte[var4];
受限路徑穿越
用來防止路徑穿越的核心是CommonUtils.SafeFile
方法,判斷解析前后的路徑是否還以限定前綴開頭。這其實(shí)可以讓我們向上穿越一級(jí)并得到前綴開頭的文件對(duì)象:
-
?CVE-2022-23457就是另一個(gè)例子
以ManageUser.process
為例,Client可以通過Host File
功能上傳文件到TeamServer并映射至Web服務(wù),這會(huì)先發(fā)出一個(gè)armitage.upload
進(jìn)行預(yù)處理,隨后由armitage.append
上傳文件數(shù)據(jù)。
這里Client與TeamServer基于序列化通過socket通信,SafeFile
的二參var1.arg(0)
客戶端可控,在UploadFile.result
拼接上前綴就可以實(shí)現(xiàn)受限路徑穿越寫文件。然而這并沒有什么卵用
this.conn.call("armitage.append",?CommonUtils.args(this.file.getName()
|
V
this.conn.call("armitage.append",?CommonUtils.args("../uploads"+this.file.getName()
想到zip解壓釋放軟鏈接那種套路,F(xiàn)ile確實(shí)可以透過軟鏈接寫入指向文件中,但這里似乎沒法實(shí)現(xiàn)直接將用于路徑穿越的軟鏈接本身存進(jìn)去。
反序列化
反序列化核心是TeamSocket.readObject
方法,實(shí)際使用的ObjectInputStream.readUnshared
。它在ManageUser.run
中被PostAuthentication.clientAuthenticated
通過多線程拉起。
client
來自SecureServerSocket.acceptAndAuthenticate
中接收的客戶端數(shù)據(jù),預(yù)檢密碼使用readUnsignedByte
讀入,在密碼比對(duì)正確時(shí)會(huì)進(jìn)入上述反序列化流程。
在客戶端Connect.dialogAction
發(fā)起連接時(shí)可以向TeamServer傳輸序列化對(duì)象,如果服務(wù)端存在gadgets環(huán)境就可被惡意利用。
this.tqueue.call("aggressor.authenticate",?CommonUtils.args(var3,?var6,?Aggressor.VERSION),?this);
|
V
Object?payload?=?getObject()?//?URLDNS,?7u21,?...
this.tqueue.call("aggressor.authenticate",?CommonUtils.args(var3,?var6,?payload),?this)
-
看代碼流程感覺作者是考慮到了的,所以將反序列化放到了認(rèn)證后
隨后ManageUser.process
會(huì)將登錄成功/失敗的消息序列化寫回客戶端,我們可以把SecureServerSocket.authenticate
改為任何密碼都校驗(yàn)成功(欺騙客戶端通過密碼預(yù)檢),再寫回惡意序列化對(duì)象(成為RogueCS),如果客戶端存在gadgets環(huán)境就可被利用。
...
if?(!this.authenticated?&&?"aggressor.authenticate".equals(var1.getCall())?&&?var1.size()?==?3)?{
...
????Object?payload?=?getObject()?//?URLDNS,?7u21,?...
????this.client.writeObject(var1.reply(payload))
...
利用條件
Client攻擊TeamServer的話,需要知道服務(wù)端的密碼(比如通過泄漏/反制得到HOME目錄下.aggressor.prop
配置文件),而通過TeamServer則可以攻擊任何前來連接的Client。
危害大小取決于運(yùn)行環(huán)境中g(shù)adgets的能力,我目前還沒在CS內(nèi)置的lib中找到有實(shí)質(zhì)危害的gadgets。對(duì)于原生JRE環(huán)境而言,可以通過DeserializationBomb
造成CPU型DoS:
Set<Object>?root?=?new?HashSet<>();
Set<Object>?s1?=?root;
Set<Object>?s2?=?new?HashSet<>();
for?(int?i?=?0;?i?<?100;?i++)?{
????Set<Object>?t1?=?new?HashSet<>();
????Set<Object>?t2?=?new?HashSet<>();
????t1.add("foo");?//?make?it?not?equal?to?t2
????s1.add(t1);
????s1.add(t2);
????s2.add(t1);
????s2.add(t2);
????s1?=?t1;
????s2?=?t2;
}
這個(gè)與之前OpenSSL的DoS效果類似,多核環(huán)境只會(huì)影響單核。相關(guān)上下文大都是局部變量,也不太可能通過反序列化造成內(nèi)存型DoS。所以一般也就能打個(gè)DNS自嗨,但如果以前調(diào)試漏洞在jre/lib/ext
之類的目錄引入過危險(xiǎn)依賴,或者有大聰明用了7u21就會(huì)導(dǎo)致RCE:
文章來源:http://www.zghlxwxcb.cn/news/detail-806927.html
CS內(nèi)置了commons-io
、sleep
等jar包,找到鏈也不是完全沒有可能,或者找到一種可控方式從當(dāng)前目錄加載類,就能結(jié)合受限路徑穿越變成RCE。萬一山雞變鳳凰了呢(doge文章來源地址http://www.zghlxwxcb.cn/news/detail-806927.html
到了這里,關(guān)于某C2雞肋漏洞分析:你的CS安全嗎?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!