聲明
出品|先知社區(qū)(ID:Jw5t)
以下內(nèi)容,來(lái)自先知社區(qū)的Jw5t作者原創(chuàng),由于傳播,利用此文所提供的信息而造成的任何直接或間接的后果和損失,均由使用者本人負(fù)責(zé),長(zhǎng)白山攻防實(shí)驗(yàn)室以及文章作者不承擔(dān)任何責(zé)任。
前言
隨著云函數(shù)概念越來(lái)越火熱,最近幾次攻防演練經(jīng)常能看見(jiàn)云函數(shù)掃描器以及云函數(shù)隱藏C2服務(wù)器,網(wǎng)上只有使用云函數(shù)攻擊的技術(shù),而基本沒(méi)有防御的技術(shù),于是我想著就總結(jié)一下,如有差錯(cuò),歡迎斧正
環(huán)境復(fù)現(xiàn)
關(guān)于環(huán)境的搭建,前人之述備矣
https://xz.aliyun.com/t/10764
我這里補(bǔ)充一些版本更新過(guò)后可能會(huì)出現(xiàn)的一些坑
對(duì)于騰訊云函數(shù),如果你的python選擇了比較新的python3.7,它是不帶request庫(kù)的,需要你自己安裝(python3.6自帶這個(gè)庫(kù))所以建議用3.6版本的python
現(xiàn)在安裝庫(kù)可以不用自己上傳zip包了,可以直接在終端使用pip下載
騰訊云只有新版本在線(xiàn)編輯器才能使用終端指令,而且會(huì)特別慢特別卡
安裝完成后訪(fǎng)問(wèn)80顯示404是正?,F(xiàn)象,訪(fǎng)問(wèn)后騰訊云出現(xiàn)日志記錄就代表成功了
全部安裝完成后cs中的兩個(gè)上線(xiàn)地址 必須去掉http://和:80,比如service-
xxxxxxxx-xxxxxxxxxx.sh.apigw.tencentcs.com這樣的格式,否則不會(huì)成功
流量分析
現(xiàn)在我的環(huán)境已經(jīng)配置好了,我們先從流量方面分析,cs的流量可以簡(jiǎn)單的分為三個(gè)階段
stage下載
beacon的心跳包階段
執(zhí)行C2服務(wù)器的命令并將結(jié)果回傳階段
如果是unstage則只有倆個(gè)(因?yàn)閡nstage相當(dāng)于stage+payload,所以u(píng)nstage的大小比stage大很多,stage才17KB多,unstage直接上了200)
beacon的心跳包階段
執(zhí)行C2服務(wù)器的命令并將結(jié)果回傳階段
stage下載
當(dāng)你執(zhí)行bean文件時(shí)(我用的是這個(gè)stager,可以遠(yuǎn)程下載一個(gè)payload)
它會(huì)注入到當(dāng)前被執(zhí)行服務(wù)器內(nèi)存,然后執(zhí)行C2的命令

beacon的心跳包階段
beacon按照在profile里面的配置以get方法向c2發(fā)起心跳請(qǐng)求,同時(shí)將宿主機(jī)的信息經(jīng)過(guò)公私鑰加密后再通過(guò)配置文件的加密混淆方式加密再發(fā)出
執(zhí)行C2服務(wù)器的命令并將結(jié)果回傳階段
C2服務(wù)器不會(huì)主動(dòng)請(qǐng)求客戶(hù)端,當(dāng)客戶(hù)端向C2服務(wù)端發(fā)送心跳包的時(shí)候,C2會(huì)把命令放入http心跳請(qǐng)求返回包中,然后當(dāng)beacon端處理完成后,通過(guò)post方法回傳數(shù)據(jù)。
stage下載
請(qǐng)求包

這個(gè)地方有一個(gè)特點(diǎn),就是 符合一個(gè)checksum8規(guī)則,即:路徑的ascii之和與256取余計(jì)算值等于92。
返回包

相對(duì)應(yīng)的profile文件

這一階段分析措施主要是看這個(gè)大流量包,流量包的大小差不多是在210kb左右,通過(guò)解析后可以看到回連地址、加密字段、公鑰等配置信息
對(duì)加解密有興趣的可以看看這個(gè)工具
https://github.com/WBGlIl/CS_Decryptset uri_x86 就是 32位的機(jī)子發(fā)送的
set uri_x64 就是64位的機(jī)子發(fā)送的
我的靶機(jī)是64位所以Get請(qǐng)求包是訪(fǎng)問(wèn)/bootstrap-2.min.js
此外,返回包里面還包括了云函數(shù)特有的幾個(gè)屬性
X-Request-Id: 請(qǐng)求的idX-Api-FuncName: 函數(shù)名,比如我在云函數(shù)里面設(shè)置的就是 test,這個(gè)是會(huì)被看出來(lái)的,所以建議紅隊(duì)偽裝一個(gè)業(yè)務(wù)名字X-Api-AppId: 對(duì)應(yīng)賬號(hào)但是不是賬號(hào),后面說(shuō)明X-Api-ServiceId: 服務(wù)idX-Api-HttpHost: 就是把a(bǔ)ppid 賬號(hào)id 還有騰訊云函數(shù)的域名放一起X-Api-Status: 200 返回值X-Api-UpstreamStatus: 200 返回值
但凡看到有這個(gè)格式,基本可以判斷是云函數(shù)了(但具體是不是業(yè)務(wù)需要和甲方業(yè)務(wù)組溝通)
心跳包階段

這是cs的心跳包,心跳包通過(guò)cookie傳輸機(jī)器信息(使用了公私鑰加密),先經(jīng)過(guò)一次base64編碼,再添加"SESSIONID=",最后添加 header "Cookie";
對(duì)于云函數(shù)配置下的cs配置文件(此處可以更改)
http-get?{set?uri?"/api/getit";client {header "Accept" "*/*";metadata {base64;prepend "SESSIONID=";header "Cookie";}}
X-Api-AppId 不是賬號(hào)啊ID,但是是對(duì)應(yīng)著賬號(hào)ID的,

X-Api-ServiceId 我在控制臺(tái)沒(méi)找到,應(yīng)該是對(duì)應(yīng)test云函數(shù)服務(wù)的id 的
命令執(zhí)行階段

執(zhí)行了兩次命令 一次是whoami 一次是pwd

流量包是這樣的,可以看出請(qǐng)求頭依舊會(huì)帶有很明顯的云函數(shù)特征,Host頭帶有請(qǐng)求云函數(shù)的api的url,header中帶有云函數(shù)的各種參數(shù)
profile文件分析
紅隊(duì)對(duì)cs魔改大部分是profile文件,這是一個(gè)比較常見(jiàn)的云函數(shù)的profile文件
set sample_name "t";set sleeptime "3000";set jitter "0";set maxdns "255";set?useragent?"Mozilla/5.0?(compatible;?MSIE?8.0;?Windows?NT?6.1;?Trident/5.0)";http-get {set uri "/api/x";client {header "Accept" "*/*";metadata {base64;prepend "SESSIONID=";header "Cookie";}}server {header "Content-Type" "application/ocsp-response";header "content-transfer-encoding" "binary";header "Server" "Nodejs";output {base64;print;}}}http-stager {set uri_x86 "/vue.min.js";set uri_x64 "/bootstrap-2.min.js";}http-post {set uri "/api/y";client {header "Accept" "*/*";id {base64;prepend "JSESSION=";header "Cookie";}output {base64;print;}}server {header "Content-Type" "application/ocsp-response";header "content-transfer-encoding" "binary";header "Connection" "keep-alive";output {base64;print;}}}
您可以通過(guò)配置文件配置 Beacon 的默認(rèn)值。有兩種類(lèi)型的選項(xiàng):全局選項(xiàng)和局部選項(xiàng)。全局選項(xiàng)更改全局的信標(biāo)設(shè)置。
本地選項(xiàng)是特定于事務(wù)的 (這句話(huà)的翻譯自cs的官方手冊(cè),原文是 Local options are transaction specific 在我看來(lái),在這里的意思是專(zhuān)注于方式的配置,比如對(duì)于http協(xié)議應(yīng)該如何配置,對(duì)于https又應(yīng)該選擇如何配置)
全局選項(xiàng)
如
1 set sleeptime
set sleeptime "3000";
是設(shè)置默認(rèn)的睡眠時(shí)間,注意此處是以毫秒為單位的
2 set jitter
set jitter "0";
這個(gè)是設(shè)置數(shù)據(jù)抖動(dòng)
官方給出的解釋是
Append random-length string (up to data_jitter value) to http-get and http-post server output.就是讓返回包的大小在一定范圍內(nèi)隨機(jī)抖動(dòng),單位是百分比
在一些文章中,會(huì)通過(guò)它c(diǎn)s流量包的默認(rèn)大小來(lái)溯源,建議修改
3 set maxdns
` set maxdns?是 通過(guò) DNS 上傳數(shù)據(jù)時(shí)主機(jī)名的最大長(zhǎng)度 (0-255)
詳情見(jiàn)于https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_dns-beacons.htm?Highlight=maxdns
4 set useragent
set useragent 這個(gè)顯而易見(jiàn) 設(shè)置UA
如果你對(duì)這個(gè)感興趣,可以參考
https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_profile-language.htm#_Toc65482842局部選項(xiàng)
首先它會(huì)有一個(gè)模板
# this is a commenthttp-get {set uri "/api/x";client {header "Accept" "*/*";metadata {base64;prepend "SESSIONID=";header "Cookie";}}server {header "Content-Type" "application/ocsp-response";header "content-transfer-encoding" "binary";header "Server" "Nodejs";output {base64;print;}}}
這是一個(gè)對(duì)get請(qǐng)求方式的局部選項(xiàng)配置
# 是代表注釋
set uri
set uri 分配客戶(hù)端和服務(wù)器在此事務(wù)期間將引用的 URI, set 語(yǔ)句需要出現(xiàn)在客戶(hù)端和服務(wù)器代碼塊之外,因?yàn)樗m用于它們兩者。
client
header 添加header
metadata { base64; prepend "SESSIONID="; header "Cookie";}是代表metadata先經(jīng)過(guò)一次base64編碼,再在編碼后的數(shù)據(jù)前面添加
"SESSIONID=",最后在修改過(guò)的數(shù)據(jù)后添加 header頭 "Cookie";
server
output { ? ?base64; ? ?print;}
輸出的metadata進(jìn)行base64編碼,再打印
分析與反制思路
所以 綜上所述 有幾個(gè)分析與反制的思路
判斷流量特征
如果是stage,會(huì)有一個(gè)payload下載階段,大小約為210kb,payload未解密之前間隔有大批量重復(fù)字符串(cs本身特征)
未經(jīng)魔改的云函數(shù)配置在stage下載階段訪(fǎng)問(wèn)/bootstrap-2.min.js (配置文件特征),同時(shí)返回包有很大一串加密數(shù)據(jù),且路徑的ascii之和與256取余計(jì)算值等于92(cs本身特征)
未經(jīng)魔改的云函數(shù)會(huì)訪(fǎng)問(wèn)/api/getit這樣類(lèi)似api的模式,可以重點(diǎn)關(guān)注(配置文件特征)
云函數(shù)的host是
service-173y3w0z-xxxxxxxxxx.sh.apigw.tencentcs.com這樣的格式,有點(diǎn)類(lèi)似域前置,host為白域名,可以著重注意host為apigw.tencentcs.com格式的流量,如果業(yè)務(wù)部門(mén)沒(méi)有這樣的業(yè)務(wù),特殊時(shí)期,可以直接封禁這個(gè)域名
apigw.tencentcs.com(云函數(shù)特征)
請(qǐng)求頭中會(huì)有云函數(shù)的特有特征,如
??? X-Request-Id: 請(qǐng)求的id? ? X-Api-FuncName: 函數(shù)名
? ? X-Api-AppId: 對(duì)應(yīng)賬號(hào)但是不是賬號(hào)
? ? X-Api-ServiceId: 服務(wù)id
? ?X-Api-HttpHost: 就是把a(bǔ)ppid 賬號(hào)id 還有騰訊云函數(shù)的域名放一起
? ? X-Api-Status: 200 返回值
? ? X-Api-UpstreamStatus: 200 返回值
抓包看流量,通信的IP是騰訊云的CDN服務(wù)器IP
反制手段
批量上線(xiàn)釣魚(yú)馬
從cs客戶(hù)端可以看出,上線(xiàn)后的ip過(guò)一會(huì)就會(huì)自動(dòng)變一次(云函數(shù)特性),一次性上線(xiàn)大量ip會(huì)讓紅隊(duì)直接無(wú)法分辨(直接放同一個(gè)虛擬機(jī)都行,因?yàn)槊看卧坪瘮?shù)的特性,所以每個(gè)心跳包都是一個(gè)新的請(qǐng)求,都會(huì)分配一個(gè)新ip)
消耗云函數(shù)額度
工具?https://github.com/a1phaboy/MenoyGone
云函數(shù)隱藏C2 和 cdn很像,都有同一個(gè)弱點(diǎn),就是訪(fǎng)問(wèn)是需要計(jì)費(fèi)的,所以可以使用腳本把紅隊(duì)的額度跑掉就好,這樣紅隊(duì)的所有馬都無(wú)法上線(xiàn)
虛假上線(xiàn)
重放心跳包進(jìn)行上線(xiàn),但是紅隊(duì)無(wú)法執(zhí)行任何命令
截圖舉報(bào)
收集好證據(jù),主要是 host名 X-Api-FuncName X-Api-AppId 這些帶有明顯云函數(shù)的特征的證據(jù),(X-Api-AppId這個(gè)很重要)說(shuō)明該人正在使用云函數(shù)對(duì)我司進(jìn)行惡意攻擊,請(qǐng)求對(duì)其暫時(shí)封禁.