CNA插件开发
简介
Cobalt Strike的Aggressor脚本(.cna文件)是用一种名为Sleep的脚本语言编写的。Sleep语言是一种简洁的、动态类型的、类似Perl和JavaScript的语言,它被设计用来方便地进行脚本编写和快速原型开发
Sleep语言入门
变量
Sleep使用 $
符号来定义变量。例如,$x = 5;
将变量 x
的值设置为5
数据类型
Sleep支持多种数据类型,这里主要讲两种,分别是数组(array)和哈希表(hash)
在 Sleep 中,你可以使用 @
符号来创建数组。Sleep 还提供了一些函数来操作数组,例如 push()
(将一个元素添加到数组的末尾)和 size()
(获取数组的大小)
哈希表(也称为字典或映射)是一种可以存储键值对的数据结构。在 Sleep 中,你可以使用 %
符号来创建哈希表
遍历操作
1.遍历数组:你可以使用 foreach
语句来遍历数组,如下所示,这个脚本会打印出数组中的每一个元素
2.遍历哈希表:使用 foreach
语句来遍历哈希表。需要注意的是,遍历哈希表时,每一个元素都是一个键值对,如下代码会打印出哈希表种的每一个键和值
函数定义
你可以使用 sub
关键字来定义函数,如下代码所示, 在command定义中,$1表示第一个参数;command
关键字用于定义一个新的命令,当你aggressor命令行输入MyAdd
加参数,命令的代码就会被执行
aggressor命令行
查看帮助
点击Script Console
打开脚本控制台
然后输入help查看命令帮助,我将这些命令及其对应的含义总结在以下表格中了
!
执行shell命令。! ls
将会在你的系统shell中执行ls
命令
?
获取关于特定命令的帮助信息。例如,? load
将会显示有关load
命令的帮助信息
e
执行一段Aggressor脚本。例如,e println('Hello, World!');
将会在命令行中打印出Hello, World!
help
获取命令行的帮助信息
history
查看命令历史
load
加载一个Aggressor脚本(.cna文件)
ls
列出当前已加载的Aggressor脚本
proff
关闭Aggressor的性能分析
profile
显示Aggressor的性能分析结果
pron
开启Aggressor的性能分析
reload
重新加载所有已经加载的Aggressor脚本
troff
关闭Aggressor的跟踪功能
tron
开启Aggressor的跟踪功能
unload
卸载一个已加载的Aggressor脚本
x
用于执行一个表达式并返回结果
加载脚本
在aggressor命令行执行load
命令加载cna文件,以下是一个简单的字符串输出脚本代码。输入myprint
,控制台输出“hello world”
除此之外,在CS的文件目录还有一个agscript
文件,它用于运行Aggressor脚本(.cna文件)。你可以使用agscript
来启动一个新的Cobalt Strike客户端,连接到一个Cobalt Strike团队服务器,并运行一个或多个Aggressor脚本,agscript
的基本用法如下:
<host>
、<port>
、<user>
和<pass>
用于指定要连接的Cobalt Strike团队服务器的详细信息。<script>
参数用于指定要运行的Aggressor脚本。你可以指定一个或多个脚本
例如,你可以使用以下命令来运行一个名为my_script.cna
的Aggressor脚本。这将会启动一个新的Cobalt Strike客户端,连接到运行在本地(127.0.0.1)的Cobalt Strike团队服务器,然后运行my_script.cna
脚本
设置输出字体颜色
在Aggressor脚本中,可以使用 \c
跟随一个数字来改变接下来的文本颜色,以下是\c
后跟随的数字与颜色的对应关系:
\c0
\c1
\c2
\c3
\c4
\c5
\c8
CNA常用操作
绑定快捷键
使用关键字bind来绑定快捷键,以此执行指定的功能,如下代码绑定了快捷键Ctrl+H
,当按了快捷键后会弹框提示“Hello World!”
菜单编写
1**.定义菜单**:使用popup
函数定义一个新的菜单,如下所示,这将定义一个名为my_menu
的新菜单
2.添加菜单项 :在 popup
块内部,使用 item
函数添加菜单项。如下所示,将在 my_menu
菜单中添加两个菜单项,名为 "Menu Item 1" 和 "Menu Item 2",当这些菜单项被点击时,会在控制台中打印相应的消息
3.添加菜单到菜单栏:使用 menubar
函数将你的菜单添加到 Cobalt Strike 的菜单栏中,这将在菜单栏中添加一个新的菜单,名为 "My Menu",当你点击这个菜单时,会显示你之前定义的 my_menu
菜单
如果你不想在菜单栏上创建新的菜单,而是想在默认的菜单上添加菜单项,例如你想在Help菜单添加菜单项,你可以这样做:
使用popup
函数并指定beacon_bottom
作为参数可以在右键单击 Beacon 会话时添加一个自定义的上下文菜单
还可以通过menu语句来创建多级菜单,menu语句中还能再嵌套一个menu语句
编写对话框
以下代码编写了一个对话框,用于实现数据交互
以下是编写对话框常用到的一些函数:
dialog
函数在 Aggressor 脚本中用于创建一个新的对话框,以用来显示消息,获取用户输入,或执行其他与用户交互的任务,基本语法如下(注意,虽然 dialog
函数创建了一个对话框,但它并不会立即显示这个对话框。要显示对话框,你需要使用 dialog_show
函数):
<标题>
是一个字符串,用于设置对话框的标题。<默认值>
是一个哈希表,用于设置对话框中各个字段的默认值。<回调函数>
是一个函数,当对话框被关闭时,这个函数将被调用,对话框中用户输入的值将作为参数传递给这个函数
drow_text
函数用于在对话框中添加一个文本输入框。其基本语法如下
这个函数接受三个参数:对话框(通过 dialog
函数创建),字段名(用于标识文本输入框),和提示文本(显示在文本输入框旁边的文本
dbutton_action
函数用于在对话框中添加一个动作按钮。当用户点击这个按钮时,会触发对话框的回调函数。这个函数接受两个参数:对话框(通过 dialog
函数创建)和按钮文本(显示在按钮上的文本)
dbutton_help
函数用于在对话框中添加一个帮助按钮。当用户点击这个按钮时,会在默认的网页浏览器中打开一个网页。其基本语法是
drow_combobox
函数用于在对话框中添加一个下拉列表(也称为组合框或combobox)。其基本语法如下:
$dialog
是对话框的引用,通常是通过dialog
函数创建的。$key
是一个字符串,用于标识这个下拉列表。当用户在下拉列表中选择一个选项时,这个选项的值会被存储在对话框的数据中,可以通过这个键来访问。$label
是一个字符串,用于显示在下拉列表旁边的标签。@options
是一个数组,包含了下拉列表中的所有选项。
数据模型
Cobalt Strike的数据模型提供了一组功能,通过这些功能,你可以查询和操作Cobalt Strike中存储的各种数据。这包括目标信息、凭证、下载的文件、键盘记录等。这些功能通过一系列的函数提供,你可以在Aggressor脚本中使用这些函数
以下是一些常用的数据接口:
targets:用于查询和操作Cobalt Strike中存储的目标信息。
archives:用于查询Cobalt Strike最近的活动信息。
beacons:用于查询和操作Cobalt Strike中的Beacon会话。Beacon是Cobalt Strike的一个轻量级恶意软件,可以在受感染的主机上运行,并与团队服务器通信。
credentials:用于查询和操作Cobalt Strike存储的凭证信息。这些凭证可能是攻击者从目标系统上获取的密码、哈希值或Kerberos票据。
downloads:用于查询和操作Cobalt Strike下载的文件。
keystrokes:用于查询Cobalt Strike记录的键盘输入。
screenshots:用于查询Cobalt Strike获取的屏幕截图。
sites:这用于查询和操作Cobalt Strike托管的资产,例如监听器和stagers。
servers:用于查询和操作Cobalt Strike的团队服务器。
如下是使用targets函数查询beacon数据的实例:
x targets()
:这个命令返回了一个数组,数组中的每个元素都是一个哈希表,代表了一个目标。哈希表中包含了目标的地址('address')、操作系统('os')、主机名('name')和版本('version')。x targets()[0]
:这个命令返回了数组中的第一个元素,也就是第一个目标的信息。x targets()[0]['address']
:这个命令返回了第一个目标的地址。
Beacon
目标主机上线后,C2会为其分配一个唯一的随机数ID,我们可使用beacon_ids()
来获取所有会话的ID
获取到会话ID后,可使用beacon_info()
来获取指定会话的所有数据
当然你还可以使用beacons()
来获取所有会话的所有信息
beacon_initial
是Cobalt Strike的Aggressor脚本中的一个预定义事件。当一个新的Beacon首次上线时,这个事件就会被触发,并返回一个会话ID($1
)
如下代码所示, 它会在新的Beacon首次上线时弹出一个消息框,显示Beacon的一些基本信息
binput
函数实际上是将字符串发送到Beacon的命令行, 其第一个参数是beacon的ID, 第二个参数是你想要输出至beacon命令行的字符串
bshell
函数用于在指定的beacon会话执行一个shell命令
常见示例
与BOF相关
涉及函数
script_resource(path)
:获取脚本资源的路径,当然不只限于bof(.obj)文件,还可以是exe、cna等等。要注意的是,脚本资源的路径要一定填写相对路径( 相对于cna文件)
openf
和readb
:打开文件并读取
bofpack
:将参数打包成一个字节流,然后传递给BOF中的go函数,其语法格式如下:
其中参数2是格式字符串,用于指定参数的类型,这个字符串可以包含以下字符:
i
:表示一个32位整数。I
:表示一个64位整数。d
:表示一个双精度浮点数。z
:表示一个以null结尾的字符串。Z
:表示一个以null结尾的宽字符串(即,每个字符由两个字节表示)。
beacon_inline_execute
:用于在指定的Beacon中执行一个BOF,该函数接收四个参数:
参数一:Beacon的ID,这是一个整数,表示你想要在哪个Beacon中执行BOF。
参数二:BOF的内容,这是一个字节流,通常是你从BOF文件中读取的内容。
参数三:BOF中的函数名,这是一个字符串,表示你想要执行的函数。
参数四:传递给BOF函数的参数,这是一个字节流,通常是你使用
bof_pack
函数创建的。
alias
:在Cobalt Strike的Aggressor脚本中,command
和alias
都是用来定义新的命令的,但它们的使用场景是不同的
command
函数定义的命令是在Cobalt Strike的脚本控制台中使用的,而alias
函数定义的命令是在Beacon的命令行中使用的
实例演示
如下实例演示添加计划任务
如下是bof的代码,此处我只给出了go函数的代码:
beacon命令行执行:boftask "test" "henry" "this is bof" "C:\\beacon.exe" ""
查看目标主机的计划任务列表可以发现,计划任务成功添加上了
反射dll执行
涉及函数
bdllspawn
是一种使用Cobalt Strike进行DLL注入的技术,它允许攻击者在新的或已存在的进程中注入并执行DLL。这种方法通常用于创建新的进程,并将恶意DLL加载到该进程中执行,但是创建新进程可能会引起安全软件的注意
bdllinject
允许攻击者将DLL注入到已存在的进程中。这意味着攻击者可以选择一个正常运行的、不会引起怀疑的进程,并将其用作恶意DLL执行的宿主,如果选择的宿主进程被安全软件密切监控,或者如果DLL注入导致进程行为异常,这种方法可能会增加被检测的风险。相比bdllspawn
,该函数无法在插件中实现传递参数给dll文件。
实例演示
如下Aggressor代码用于测试反射dll能否加载成功
beacon命令行测试Dll能否运行成功
推荐编辑器
VS Code是一个非常流行的、功能丰富的代码编辑器,支持通过插件扩展其功能,可以安装CobaltStrike的官方插件来方便CNA脚本的编写
参考链接
https://cloud.tencent.com/developer/article/1785567
https://www.bilibili.com/video/BV1pU4y1C7xh/?spm_id_from=333.337.search-card.all.click&vd_source=a6caf742912abf241ffbcb3c11933841
https://maka8ka.cc/post/cobaltstrike-bof%E5%8F%8A%E5%AF%B9%E5%BA%94%E7%9A%84cna%E8%84%9A%E6%9C%AC/
https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/agressor_script.htm
最后更新于