CobaltStrike插件开发官方指南 Part1
翻译+实践 原文地址: https://www.cobaltstrike.com/agscript-script/index.html 0x01 简介 什么是agscript? (agscript为Aggressor Script的简写,直译攻击者脚本通篇读起来怪怪的,故保留。) agscript是CobaltStrike 3.0之后版本中内置的脚本语言,利用Aggresor编写脚本可轻松地武
翻译+实践
原文地址:
https://www.cobaltstrike.com/agscript-script/index.html
0x01 简介

什么是agscript?
(agscript为Aggressor Script的简写,直译攻击者脚本通篇读起来怪怪的,故保留。)
agscript是CobaltStrike 3.0之后版本中内置的脚本语言,利用Aggresor编写脚本可轻松地武装您的CobaltStrike客户端。
背景
agscript是Armitage的开源脚本引擎Cortana的精神继承者。 因为DARPA的Cyber Fast Track计划才使Cortana成了可能。 Cortana支持开发者通过Armitage的团队服务器扩展Armitage并控制Metasploit Framework及其功能。 当然,Cobalt Strike 3.0并不是以Armitage为基础的重写的。 这次大弧度的版本升级是为了重新审视Cobalt Strike,并围绕Cobalt Strike的功能进行重构。 产物就是agscript的诞生。
agscript是一种简单脚本语言,主要用于红队编写针对肉鸡的攻击脚本。 它有两个作用,一是可以用来对自己的肉鸡做持久性控制,二是可以用来扩展或修改Cobalt Strike客户端以满足您的个性化需求。
现状
agscript是以Cobalt Strike 3.0为基础的。 Cobalt Strike 3.0中绝大部分菜单/按钮事件都是由agscript引擎支撑。 Strategic Cyber LLC尚未为Cobalt Strike的大多数功能写API,也就是说,agscript目前仍处于起步阶段。 在未来,我们也期待看到agscript的发展壮大。这份文档也会随着时间的推移而变动。
如何加载脚本?
agscript内置于Cobalt Strike 客户端, 如果需要长期使用agscript, 请移步Cobalt Strike客户端 -> Script Manager and press Load功能。

脚本控制台
Cobalt Strike提供了交互式的脚本控制台。 通过控制台可跟踪,配置,调试以及管理脚本。可以通过View- > Script Console获得进入agscript控制台。
基础命令:
| 命令 | 参数 | 作用 |
|---|---|---|
| ? | "foo" 即 "foobar" | 测试Sleep predicate并打印结果 |
| e | println("foo"); | 测试Sleep statement |
| help | - | 列出所有命令 |
| load | /path/to/script.cna | 加载脚本 |
| ls | - | 列出已加载的脚本 |
| proff | script.cna | 禁用脚本的Sleep Profiler |
| profile | script.cna | 转储脚本的性能统计信息 |
| pron | script.cna | 启用脚本的Sleep Profiler |
| reload | script.cna | 重新加载脚本 |
| troff | script.cna | 禁用脚本的功能跟踪 |
| tron | script.cna | 启用脚本的功能跟踪 |
| unload | script.cna | 卸载脚本 |
| x | 2 + 2 | 执行表达式并返回结果 |

命令行使用Cobalt Strike
您也许会希望在在没有GUI的情况下启动Cobalt Strike,客户端压缩包中的agscript这个脚本文件能够满足您的需求,连接命令:
./agscript [host] [port] [user] [password]
上述命令可以使您快捷的连接到团队的服务器,当然,如果您希望加载agscript脚本还可以这样写参数:
./agscript [host] [port] [user] [password] [/path/to/script.cna]
上述命令可以连接团队服务器并运行您的脚本,下面给出一段demo代码:
on ready {
println("Hello World! I am synchronized!");
closeClient();
}

Sleep快速上手
agscript是基于Raphael Mudge的Sleep语言的二次开发的。原手册见:
http://sleep.dashnine.org/manual
(译者注:Sleep是一种基于java开发的脚本语言)
Sleep能做的agscript都能做,下面是一些注意事项:
Sleep的语法,运算符甚至俚语都与Perl极其类似,简单说一个他们的区别,Sleep需要的语句之间需要有空格,以下代码无效:
$x=1+2; # this will not parse!!
正确的语法是这样的:
$x = 1 + 2;
Sleep的变量有标量,字符串,各自类型的数字,Java对象引用,函数,数组以及字典等。 以下是Sleep中的常见的几种变量:
$x = "Hello World";
$y = 3;
$z = @(1, 2, 3, "four");
$a = %(a => "apple", b => "bat", c => "awesome language", d => 4);
使用@和%函数即可创建数组和字典,数组和字典不仅可以引用其他数组和字典,还可以可以引用自己。
Sleep的注释以#开头,直到结束。
Sleep会插入双引号的字符串,这意味着以\$符号开头的任何以空格分隔的标记都将替换为其值。 特殊变量$+将插字符串与另一个值连接起来。
println("\$a is: $a and \n\$x joined with \$y is: $x $+ $y");
运行结果为:
$a is: %(d => 4, b => 'bat', c => 'awesome language', a => 'apple') and
$x joined with $y is: Hello World3

这儿有一个和println类似的函数叫warn,不同的是warn输出的内容中包含了当前代码的文件名和行数,对于开发者来说,调试定位错误特别方便。

使用sub字符即可声明函数,传给函数的参数标记为$1,$2,一直到$n。函数可以接受无数个参数。 变量@_是一个包含所有参数的数组,$1,$2等变量的更改将改变@_的内容。
sub addTwoValues {
println($1 + $2);
}
addTwoValues("3", 55.0);
运行结果:
58.0

在Sleep语法中,函数是任何其他对象的首选类型,下面语法您可以会常见到:
$addf = &addTwoValues;
$addf变量引用了&addTwoValues函数,调用并传参可以这样写:
[$addf : "3", 55.0];
这括号的表示方法还可用于操作Java对象,需要了解更多建议您阅读上面提到的Sleep手册,以下语句是等效的:
[$addf : "3", 55.0];
[&addTwoValues : "3", 55.0];
[{ println($1 + $2); } : "3", 55.0];
addTwoValues("3", 55.0);

Sleep有三变量范围:全局变量,特殊变量,本地变量。Sleep手册中的介绍更为详细一些,这里不做赘述。 示例中看到local('$x $y $z')中的$x,$y和$z就是当前函数的本地变量,并且当函数返回时它们的值将重置。
更多Sleep相关的语法结构请参考官方手册。
交互式操作
agscript显示输出同样使用了Sleep的&println, &printAll, &writeb, 以及&warn这四个函数,这些函数均可在控制台输出内容。
大多数语言都可以注册快捷命令,agscript也不例外,使用command即可创建命令:
command foo {
println("Hello $1");
}
这段代码将会注册命令foo,脚本控制台会自动解析命令的参数,并按空格将它们拆分为参数,$1是第一个参数,$2是第二个参数,依此类推。用户可以使用“双引号”来创建带空格的参数。 如果这种解析对您可能会对输入执行造成破坏性的操作,请使用$0访问传递给命令的原始文本。

控制台文本颜色
如果你想给Cobalt Strike的控制台添加一些色彩,通过\c,\U和\o转义即可告诉Cobalt Strike如何格式化文本。 值得提醒的是这些转义仅在双引号字符串内有效。
\cX就是告诉Cobalt Strike你想输出什么颜色,X是颜色的值:

\U是告诉控制台添加下划线,\o则是重置这些花里胡哨的东西。

0x02 Cobalt Strike
Cobalt Strike客户端
agscript引擎是糅合到Cobalt Strike的功能之一,Cobalt Strike的绝大部分对话框和功能都是以独立模块的形式编写的,并面向agscript引擎开放了一些接口。
内置的脚本default.cna就定义了工具栏的按钮,弹出的菜单等等。
本章将向您展示这些功能的工作流程,并使您能够根据需要打造自己的Cobalt Strike客户端。

快捷键绑定
使用bind即可快速绑定关键字,这里加上我们要按Ctrl+H快捷输出一个Hello Word该怎么写?看代码:
bind Ctrl+H {
show_message("Hello World!");
}
快捷键可以是任何ASCII字符或特殊键,快捷方式可能会应用一个或多个修饰符,修饰符修饰符仅为以下几个特定按键:Ctrl,Shift,Alt,Meta。脚本可以指定修饰符+键。
弹出菜单
使用agscript可以添加或是重新定义CoblatStrike菜单,popup这个关键字即为Hook弹出菜单的语句。
看一个添加菜档的demo代码:
popup help {
item("&Homepage", { url_open("https://www.cobaltstrike.com/"); });
item("&Support", { url_open("https://www.cobaltstrike.com/support"); });
item("&Arsenal", { url_open("https://www.cobaltstrike.com/scripts?license=" . licenseKey()); });
separator();
item("&System Information", { openSystemInformationDialog(); });
separator();
item("&About", { openAboutDialog(); });
}

如上图所示,脚本新添件并定义了多个按钮事件,点击机制执行对应代码。
再看看如何添加子菜单:
popup pgraph {
menu "&Layout" {
item "&Circle" { graph_layout($1, "circle"); }
item "&Stack" { graph_layout($1, "stack"); }
menu "&Tree" {
item "&Bottom" { graph_layout($1, "tree-bottom"); }
item "&Left" { graph_layout($1, "tree-left"); }
item "&Right" { graph_layout($1, "tree-right"); }
item "&Top" { graph_layout($1, "tree-top"); }
}
separator();
item "&None" { graph_layout($1, "none"); }
}
}
如果你想覆盖已存在的菜单,使用&popup_clear函数清除其他已注册的菜单项,并代码新定义的菜单弹出选项。
自定义输出
agscript中的set关键字定义了如何格式化事件并将其输出呈现给客户端。 以下是set关键字的demo:
set EVENT_SBAR_LEFT {
return "[" . tstamp(ticks()) . "] " . mynick();
}
set EVENT_SBAR_RIGHT {
return "[lag: $1 $+ ]";
}
上面的代码定义了Cobalt Strike的事件日志(View -> Event Log)中状态栏的内容,此状态栏的左侧显示当前时间和您的昵称,右侧显示了Cobalt Strike客户端和团队服务器之间的消息往返时间。
Cobalt Strike中默认的各种设置都可以通过统一的方法来修改覆盖。
事件管理
使用on这个关键字可以为事件定义处理程序,当Cobalt Strike连接到团队服务器并准备代表您行动时,就绪事件将触发。demo:
on ready {
show_message("Ready for action!");
}
使用* meta-event可查看再Cobalt Strike中发生的所有事件。
on * {
local('$handle $event $args');
$event = shift(@_);
$args = join(" ", @_);
$handle = openf(">>eventspy.txt");
writeb($handle, "[ $+ $event $+ ] $args");
closef($handle);
}