cs的插件在日常的工作中相对来说并不常用,因为cs基本只能当炮灰马上线的工具,主要是用cs过内存特征也太费劲了(菜狗难受),我相信在每一个渗透狗的心中,每个能给cs木马过内存特征过卡巴的大佬都是渗透狗的大爹。所以基本上更多的操作自己也不会选择使用cs,所以只是总结一下算是查漏补缺吧
废话结束,正文开始
sleep按作者的说法是java平台下实现的的perl脚本语言。
java \-jar sleep.jar #打开console
官方的语法在这里(http://sleep.dashnine.org/manual/),有过python或其他语言基础的写的时候看一下再看下其他师傅写的脚本基本上没啥问题,稍微提几个注意的点
在console中用x可以计算表达式(x 3+4),用?可以得到表达式判断结果
Sleep需要的语句之间需要有空格
Sleep 的变量可以是java对象的引用
使用前无需声明变量。当变量不存在时,Sleep 使用 $null(空标量)赋值
@号创建数组,%号创建字典,Sleep支持多维数组
$null 等于数字 0。作为字符串 $null 等于空字符串 ""。作为对象,$null 与 Java 值 null 相同。
Perl支持8进制、16进制、2进制(0b),但Sleep只支持8进制(0开头)和16进制(0x开头)
字符串变量组合用双引号和$xx $ ,eg.$flavor = "mint chocolate chip"; println("I love $flavor $+ !!!");
数字用计算符号比较(==,>,<,..),字符串用eq、ne等等比较,is用来比较引用
函数用sub声明
循环支持while、for、foreach
可以使用throw抛出异常,也可以使用try catch处理异常,&getStackTrace 函数返回异常发生时的调用堆栈,&warn 函数将错误消息传达给 Sleep。可以用assert关键字断言
使用inline定义内联子例程的宏,可以使用 &pushl 在内联函数中创建一个新的本地作用域。然后,您可以放心地在本地范围内声明变量。在内联子例程完成之前,您必须使用 &popl 处理局部作用域。
inline swap
{
pushl($a \=> $1, $b \=> $2);
local('$temp');
$temp \= $b;
$b \= $a;
$a \= $temp;
popl();
}
\[{ println("Hello $1 $+ !"); } : "World!"\];
或使用lamba表达式
$closure \= lambda({
println("\\$x is $x");
}, $x \=> 33);
\[$closure\];
$closure\['$x'\] \= "test!";
\[$closure\];
println("Accessing a value: " . $closure\['$x'\]);
Sleep支持正则匹配
^String 等同于 [Class forName: "java.lang.String"]
Sleep 可以从 Java 类路径中当前不存在的 jar 文件中动态导入包
Sleep 可以将闭包转换为响应某些接口的匿名 Java 对象。这个对象是一个代理实例。解释器在将它们传递给 Java 时自动将闭包编组到代理实例。此功能目前仅适用于接口。对代理实例的 Java 方法调用会导致对闭包的调用。参数 $0 设置为方法名称。来自 Java 的参数被转换为标量 $1、$2 等。这一特性将在后续插件编写过程中频繁使用
Sleep实现了文件IO、文件系统IO、网络IO和consoleIO、ThreadsIO
一些cs插件开发的文章开头通用这里都介绍过了,看过的师傅可以直接往后划,看过之后对cs接口实现的功能有一个大概的印象,具体到调用函数时直接搜索函数名称查下参数就好
cs函数的实现本质是对java代理实例的调用,第一个参数$0默认为方法名称,我们传入的参数$1,$2....是java方法所需的参数。
bind Ctrl+H {
show\_message("Hello World!");
}
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"); }
}
}
set EVENT\_SBAR\_LEFT {
return "\[" . tstamp(ticks()) . "\] " . mynick();
}
set EVENT\_SBAR\_RIGHT {
return "\[lag: $1 $+ \]";
}
on ready {
show\_message("Ready for action!");
}
on \* {
local('$handle $event $args');
$event \= shift(@\_);
$args \= join(" ", @\_);
$handle \= openf(">>eventspy.txt");
writeb($handle, "\[ $+ $event $+ \] $args");
closef($handle);
}
使用data_query函数可以查看数据类型,使用data_key列出来自Cobalt Strike的数据模型的可查询键
,这边可以看下官方实例就可以看出cs的target数据模型就是Sleep字典数组
listeners :函数获取所有的listener,
listener_local:返回当前server的listener
listener_create_ext:启动listener
openPayloadHelper :打开一个对话框,列出所有可用的侦听器
stager:导出绑定了cs payload的stager
artifact_stager:可以导出绑定了cs payload的ps脚本、EXE、或dll
stager_bind_tcp:绑定tcp的stager
beacon_stage_tcp:向stager_bind_tcp传递payload
artifact_general:接收shellcode并产生payload
stager_bind_pipe :stager仅支持x86
beacon_stage_pipe:向 stager_bind_pipe传递payload
payload:将payload导出为可运行二进制文件
Cobalt Strike 为每个 Beacon 分配一个会话 ID。这个 ID 是一个随机数。Cobalt Strike 将任务和元数据与每个 Beacon ID 相关联
beacons查询所有当前 Beacon 会话的元数据
beacon_info查询特定 Beacon 会话的元数据
alias 设置别名
beacon_initial 事件在 Beacon 第一次报告元数据时触发
beacon_initial_empty 与首次呼叫 home 的 DNS Beacon交互
btask:向用户确认操作
beacon_host_script:托管大型脚本
bdllspawn 函数生成一个临时进程,将我们的漏洞利用 DLL 注入其中,并将我们导出的payload作为参数传递
beacon_remote_exec_method_register:尝试远程执行命令
bupload_raw函数将工件数据上传到目标。此函数使用**\target\ADMIN$\filename.exe**通过仅限管理员的共享直接将 EXE 写入远程目标
brun运行**wmic /node:"target" process call create "\target\ADMIN$\filename.exe"**以在远程目标上执行文件
bpowerpick:生成一个进程,注入 Unmanaged PowerShell并执行
beacon\_checkin beacon准入确认发往console时触发
beacon\_error beacon错误发布到console时触发
beacon\_indicator
beacon\_initial beacon第一次报告元数据时触发
beacon\_initial\_empty 与首次呼叫 home 的 DNS Beacon交互时触发
beacon\_input beacon传入信息发布到console时触发
beacon\_mode 更改beacon模式时触发
beacon\_output 输出发布到console时触发
beacon\_output\_alt 当(备用)输出发布到 Beacon 的控制台时触发
beacon\_output\_jobs当job输出发送到 Beacon 的控制台时触发。
beacon\_output\_ls 当 ls 输出发送到 Beacon 的控制台时触发
beacon\_output\_ps当 ps 输出发送到 Beacon 的控制台时触发
beacon\_tasked 当task输出到console时触发
beacons 当server发送有关我们所有信标的最新信息时触发。这大约每秒发生一次
disconnect cs客户端与cs服务端断开时触发
event\_action当用户在事件日志中执行操作时触发
event\_beacon\_initial当初始信标消息发布到事件日志时触发
event\_join当用户连接到server时触发
event\_newsite当新站点消息发布到事件日志时触发
event\_notify当来自server的消息发布到事件日志时触发
event\_nouser当前 Cobalt Strike 客户端尝试与未连接到server的用户交互时触发
event\_private当private消息发布到事件日志时触发
event\_public当public消息发布到事件日志时触发
heartbeat\_\* 每隔\*时间触发一次
keylogger\_hit当通过克隆站点击键记录器向 Web 服务器报告新结果时触发
keystrokes当 Cobalt Strike 收到击键时触发
profiler\_hit当有新的结果报告给 System Profiler 时触发
ready当此 Cobalt Strike 客户端连接到server并准备好行动时触发
screenshots当 Cobalt Strike 收到屏幕截图时触发
sendmail\_\*发送钓鱼邮件过程中触发
ssh\_\*同beacon,但session为ssh
web\_hit 服务器有web访问时触发
hasbootstraphint 是否有引导函数
is64 是否是64位平台
isactive 是否活动
isadmin是否为管理员
isssh 是否是
show\_message向用户提示消息
show\_error提示用户错误。
dialog创建一个对话框
drow\_file 文件输入对话框
drow\_text 文本输入对话框
drow\_combobox 选择栏对话框
dialog\_show 显示对话框
dbutton\_action 关闭对话框并调用对话框回调函数
更多函数见
最后简单看一个实例,调用某程序上传到目标上并执行某命令,算是比较常见的需求了
https://github.com/422926799/csplugin/blob/master/%E5%8F%96%E8%AF%81/qz.cna
sub recentqueryfunc{
$path \= script\_resource("openfilehistory.exe");
bupload($3\['bid'\], $path);
bshell($3\['bid'\], "openfilehistory.exe $3\['username'\]");
}
sub recentquery{
$dialog \= dialog("最近使用痕迹查询", %(username \=> "Administrator", bid \=> $id), &recentqueryfunc);
dialog\_description($dialog, "要查询的用户名输入");
drow\_text($dialog, "username", "USERNAME:");
dbutton\_action($dialog, "run");
dialog\_show($dialog);
}
popup beacon\_bottom {
menu "windows取证"{
$bid \= $1;
item "最近使用痕迹"{
foreach $id ($bid){
recentquery($id)
}
}
}
}
这里的bid就是我们的beacon id,原因是cs hook了不同的对象弹出并提供了参数变量
具体看这个表格
Hook
Where
Arguments
aggressor
Cobalt Strike Menu
attacks
Attacks Menu
beacon
[session]
$1 = selected beacon IDs (array)
beacon_top
[session]
$1 = selected beacon IDs (array)
beacon_bottom
[session]
$1 = selected beacon IDs (array)
credentials
Credential Browser
$1 = selected credential rows (array of hashes)
filebrowser
[file in file browser]
$1 = beacon ID, $2 = folder, $3 = selected files (array)
help
Help Menu
listeners
Listeners table
$1 = selected listener names (array)
pgraph
[pivot graph]
processbrowser
Process Browser
$1 = Beacon ID, $2 = selected processes (array)
processbrowser_multi
Multi-Session Process Browser
$1 = selected processes (array)
reporting
Reporting Menu
ssh
[SSH session]
$1 = selected session IDs (array)
targets
[host]
$1 = selected hosts (array)
targets_other
[host]
$1 = selected hosts (array)
view
View Menu
可以看到通过recentquery弹出对话框输入要查询的用户名后,调用回调函数recentqueryfunc,回调函数参数如下
$1
是对对话框的引用。$2
是按钮名称。$3
是一个字典,将每一行的名称映射到它的值,所以在$3变量的字典中找到bid键的值,将文件上传到beacon上并执行