jxa 入门_持久JXA

jxa 入门

A poor man’s Powershell for macOS

适用于macOS的穷人的Powershell

介绍 (Introduction)

Over the last year or so, I have been diving into macOS tradecraft. Through my research, an area of particular interest is the use of JavaScript for Automation (JXA) on macOS. My goal was to fulfill an operational need to decrease dependency on Python and further my understanding of macOS tradecraft that I can hopefully build on. This post serves as an overview of the benefits of JXA for macOS tradecraft development, highlights a well-known persistence method, and a few lesser-known JXA execution methods.

在过去的大约一年中,我一直在研究macOS tradecraft。 通过我的研究,特别感兴趣的领域是在macOS上使用JavaScript for Automation(JXA)。 我的目标是满足操作需求,以减少对Python的依赖,并进一步理解我希望可以建立的macOS tradecraft。 这篇文章概述了JXA对macOS Tradecraft开发的好处,重点介绍了一种众所周知的持久性方法和一些鲜为人知的JXA执行方法。

JXA的简史 (A Brief History of JXA)

MacOS Yosemite (10.10) introduced JXA. Its implementation allows users to control applications and the operating system using the JavaScript language. It can be invoked via osascript, a compiled script (.scpt), or a compiled Application (.app). Additionally, it can be leveraged in OSAKit from within other macho binaries without spawning the osascript binary.

MacOS Yosemite(10.10)引入了JXA。 它的实现允许用户使用JavaScript语言控制应用程序和操作系统。 可以通过osascript ,已编译脚本( .scpt )或已编译应用程序( .app )调用它。 另外,可以在OSAKit中从其他猛男二进制文件中利用它,而不会产生osascript二进制文件。

为什么选择JXA? (Why JXA?)

The preferred method for post-exploitation macOS tradecraft is scripting languages over binaries. They allow attackers to avoid leveraging unsigned code and avoid going through the code signing cert process with Apple. Compiled binaries are subject to more scrutiny due to the built-in protections on macOS (Gatekeeper, Notarization, and XProtect).

漏洞利用后的macOS Tradecraft的首选方法是在二进制文件上编写脚本语言。 它们使攻击者可以避免利用未签名的代码,并避免与Apple一起进行代码签名证书过程。 由于macOS上的内置保护(Gatekeeper,Notarization和XProtect),编译后的二进制文件将受到更多审查。

As mentioned previously, Python was the favorite for macOS post-exploitation tradecraft. Python was great for macOS tradecraft as it was easy to develop with and installed by default of macOS. However, the following note from the macOS Catalina (10.15) release indicates Apple is slowly migrating away from having Python and other scripting languages included by default.

如前所述,Python是macOS开发后交易工具的最爱。 Python非常适合macOS tradecraft,因为它很容易使用macOS开发并默认安装。 但是,以下来自macOS Catalina(10.15)发行版的注释表明Apple逐渐从默认包含Python和其他脚本语言迁移。

Upon looking for future areas of tradecraft development, another option that arose was AppleScript. AppleScript has the same benefits of JXA but is quirky and, in my opinion, harder to develop with than JXA. It’s quirky because it attempts to use “natural language.” The best description I heard was it is trying to script through a series of conversations with Siri.

在寻找未来的Craft.io品开发领域时,出现了另一个选择是AppleScript 。 AppleScript具有与JXA相同的优点,但是它很古怪,而且在我看来,与JXA一起开发更难。 这很奇怪,因为它尝试使用“自然语言”。 我听到的最好的描述是它试图通过与Siri的一系列对话来编写脚本。

Based on those considerations, I turned towards JXA. JXA has similarities with early Powershell versions. It is not as robust as Powershell but allows for a convenient method to interact with macOS. JXA has a built-in Objective-C bridge that enables you to access the file system and Cocoa frameworks, such as Foundation and AppKit, which allows us to call Apple APIs without building binaries. Similar to Powershell commands, you can even obfuscate your commands using a simple JavaScript obfuscator to slow down defenders.

基于这些考虑,我转向了JXA。 JXA与早期Powershell版本具有相似之处。 它不如Powershell强大,但允许使用便捷的方法与macOS进行交互。 JXA具有内置的Objective-C桥,使您能够访问文件系统和Cocoa框架,例如Foundation和AppKit,这使我们能够在不构建二进制文件的情况下调用Apple API。 与Powershell命令类似,您甚至可以使用简单JavaScript 模糊处理程序来模糊化命令,从而降低防御程序的速度。

There are a few projects that leverage JXA for macOS tradecraft. HealthInspector and Orchard from its-a-feature leverage JXA for host situational awareness and Active Directory enumeration, respectively. Additionally, the Apfell JXA agent which facilitates Command and Control (C2).

有一些项目将JXA用于macOS tradecraft。 HealthInspectorOrchard利用其功能来分别利用JXA进行主机态势感知和Active Directory枚举。 此外, Apfell JXA代理可简化命令和控制(C2)。

持久JXA (Persistent JXA)

To further develop my understanding of established macOS tradecraft, I developed the PersistentJXA project.

为了进一步了解已建立的macOS Tradecraft,我开发了PersistentJXA项目。

This section goes through a couple of usage examples as well as the related detections.

本节介绍了几个用法示例以及相关的检测。

持久性的Bash配置文件 (Bash Profiles for Persistence)

背景 (Background)

An older persistence method on macOS is the use of bash profiles. As a brief background, the ~/.bash_profile is a shell script that contains shell commands and is executed in the user’s context when a new shell opens. Attackers can abuse this by adding malicious commands to the profile to maintain persistence.

在macOS上,较旧的持久性方法是使用bash配置文件。 作为简要背景 ,〜/ .bash_profile是一个包含脚本命令的shell脚本,并在打开新的shell时在用户上下文中执行。 攻击者可以通过向配置文件添加恶意命令来保持持久性,从而滥用此功能。

The benefit of this persistence mechanism is that if an organization allows end-users to modify bash profiles, mitigation, and even detection becomes difficult due to the number of false positives. In my testing, I have found it easier to detect the actions the profile performs than the modification of the bash profile itself.

这种持久性机制的好处在于,如果组织允许最终用户修改bash配置文件,则由于误报的数量,缓解,甚至检测变得困难。 在测试中,我发现检测配置文件执行的操作比修改bash配置文件本身更容易。

The implementation within PersistentJXA checks to determine if osascript is running; if not, it executes our persistence action (assumed osascript) upon opening a new terminal window. Since macOS Catalina, zshell is the default shell. If the script detects the host as macOS Catalina, then ~/.zshenv is used instead.

PersistentJXA中的实现检查以确定osascript是否正在运行; 如果没有,它将在打开新的终端窗口时执行我们的持久性动作(假定为osascript )。 从macOS Catalina开始, zshell是默认的shell。 如果脚本将主机检测为macOS Catalina,则使用~/.zshenv

用法 (Usage)

The Apfell JXA agent can leverage all of the scripts within the PersistentJXA project. To gain access to the function, use the jsimport command.

Apfell JXA代理可以利用PersistentJXA项目中的所有脚本。 要访问该功能,请使用jsimport命令。

Image for post
Importing Bash Profile Persistence Script
导入Bash配置文件持久性脚本

After importing, we can use the jsimport_call command to run the imported function.

导入后,我们可以使用jsimport_call命令运行导入的函数。

Image for post
Calling Script and Setting Persistence Action
调用脚本并设置持久性操作

The PersistentJXA implementation of bash profile persistence creates two shell scripts in a created hidden directory. The apple.sh script provides the osascript monitoring action and the update.sh contains the user-specified persistence action.

bash概要文件持久性的PersistentJXA实现在创建的隐藏目录中创建两个Shell脚本。 apple.sh脚本提供osascript监视操作,而update.sh包含用户指定的持久性操作。

侦测 (Detection)

Again the modification of the ~/.bash_profile can be tracked but is not scalable. However, other elements of the persistence method can be detected.

同样,可以跟踪~/.bash_profile的修改,但不能扩展。 但是,可以检测到持久性方法的其他元素。

osquery does not capture process events by default. For my testing, I made modifications to the Palantir osquery configuration found here and here. I then forwarded the osquery logs to Splunk.

osquery默认不捕获进程事件。 为了进行测试,我对此处此处找到的Palantir osquery配置进行了修改。 然后,我将osquery日志转发到Splunk。

osquery captures the chmod actions on the apple.sh and update.sh scripts within the created hidden directory ./security.

osquery在已创建的隐藏目录./security捕获apple.shupdate.sh脚本上的chmod操作。

Image for post
Process Events to Make Scripts executable within osquery
处理事件以使脚本在osquery中可执行

Additionally, osquery captures those scripts’ execution events upon opening a new terminal window in which osascript is not already running.

另外,osquery在打开尚未运行osascript的新终端窗口时捕获这些脚本的执行事件。

Image for post
Execution of apple.sh which contains the osascript monitoring function
包含osascript监视功能的apple.sh的执行

You may have noticed that the separate actions have the same Process Identifier (PID). Additional details on macOS process execution and why different commands can have the same PID is discussed here.

您可能已经注意到,单独的操作具有相同的进程标识符(PID)。 此处讨论了有关macOS进程执行的其他详细信息以及为什么不同的命令可以具有相同的PID。

Image for post
Execution for update.sh which contains the persistence action
包含持久性操作的update.sh的执行

Lastly, osquery captures the launching of the persistence action (Apfell JXA payload). Flagging on the osascript invocation would be the most straightforward detection approach and would still occur if the persistence action was placed directly in the bash profile.

最后,osquery捕获持久性动作(Apfell JXA有效负载)的启动。 对osascript调用进行标记将是最直接的检测方法,并且如果将持久性操作直接放置在bash概要文件中,则仍然会发生。

Image for post
JXA command to pull and execute Apfell payload
JXA命令来提取并执行Apfell有效负载
Image for post
Agent in Apfell running in the osascript PID 1200
在osascript PID 1200中运行的Apfell中的代理

崇高的持久性插件 (Sublime Plugin for Persistence)

背景 (Background)

Another persistence method is abusing sublime plugins. This method discovered by Chris Ross (xorrior) exploits the ability of end-users creating plugins for Sublime.

另一种持久性方法是滥用Sublime插件。 克里斯·罗斯( xorrior )发现的这种方法利用了最终用户为Sublime创建插件的能力。

The Sublime Text Editor provides the ability to create plugins that Sublime loads upon application execution. Adversaries can take advantage of this mechanism to plant malicious plugins to gain persistence. The abuse of Sublime Text Editor plugins requires a plugin at ~/Library/Application\ Support\ Text\ <2 or 3>\Packages. These plugins are typically python scripts. If a malicious plugin is placed in the Packages directory and is formatted to load our malicious dynamic library (dylib), then Sublime will execute our code upon initialization by the user under the context of Sublime plugin_host.

Sublime文本编辑器提供了创建在应用程序执行时Sublime加载的插件的功能。 攻击者可以利用这种机制来植入恶意插件以获得持久性。 要滥用Sublime Text Editor插件,需要使用~/Library/Application\ Support\ Text\ <2 or 3>\Packages的插件。 这些插件通常是python脚本。 如果将恶意插件放置在Packages目录中并经过格式化以加载我们的恶意动态库(dylib),则Sublime将在用户在Sublime plugin_host上下文下初始化时执行我们的代码。

用法 (Usage)

Image for post
Importing Sublime Plugin Persistence Script
导入Sublime插件持久性脚本

This persistence method requires uploading/creating a dylib on the target. After importing, we can use the jsimport_call command to run the imported function, specifying the targeted dylib location.

此持久性方法需要在目标上上传/创建dylib。 导入后,我们可以使用jsimport_call命令运行导入的函数,并指定目标dylib位置。

Image for post
Calling Script and Setting Persistence Action
调用脚本并设置持久性操作

The PersistentJXA implementation creates a fake plugin called PrettyText to load the dylib.

PersistentJXA实现创建了一个名为PrettyText的假插件来加载dylib。

Image for post
Confirmation of Successful Sublime Text Plugin Persistence Execution
确认成功的Sublime Text插件持久性执行

侦测 (Detection)

From Truetree, we can follow the process execution from Finder to Sublime Text and ultimately to the Sublime Text plugin_host, which is PID 661.

Truetree中 ,我们可以跟踪从Finder到Sublime Text并最终到达Sublime Text plugin_host的过程执行,即PID 661

Image for post
TrueTree Excerpt of Sublime Plugin Execution
Sublime插件执行的TrueTree摘录

Additionally, we can monitor the creation of Sublime plugins within the packages folder, but your mileage will vary depending on use in the environment. Also, network connections under the plugin host process is a nontypical occurrence.

此外,我们可以在packages文件夹中监视Sublime插件的创建,但是您的工作量会因环境中的使用而异。 同样,插件宿主进程下的网络连接是非典型的。

Image for post
Venator Excerpt showing network connection for PID 661 Venator摘录显示PID 661的网络连接
Image for post
plugin_host PID 661 plugin_host PID 661中运行

Sublime Application Script for Persistence (Sublime Application Script for Persistence)

背景 (Background)

Another fun method is using the Sublime application script for persistence. This method, discovered by theevilbit, allows us to simply execute our JXA payload on Sublime startup without requiring a dylib on the target. Through the modification of the application script located at /Applications/Sublime\ Text.app/Contents/MacOS/sublime.py, we can have our payload executed when the target user starts Sublime.

另一个有趣的方法是使用Sublime应用程序脚本进行持久化。 该方法由theevilbit发现, 使我们可以在Sublime启动时简单地执行JXA有效负载,而无需在目标服务器上使用dylib。 通过修改位于/Applications/Sublime\ Text.app/Contents/MacOS/sublime.py的应用程序脚本,可以在目标用户启动Sublime时执行有效负载。

用法 (Usage)

Image for post
Importing Sublime Plugin Persistence Script
导入Sublime插件持久性脚本

Next, call the function and specify our persistence action.

接下来,调用该函数并指定我们的持久性动作。

Image for post
Calling Script and Setting Persistence Action
调用脚本并设置持久性操作
Image for post
Confirmation of Successful Sublime Text Plugin Persistence Execution
确认成功的Sublime Text插件持久性执行

侦测 (Detection)

This method follows a similar process tree as the plugin method except osascript is a child of Sublime Text. We can see the process execution from Finder to Sublime Text to osascript, PID 2212.

该方法遵循与插件方法相似的过程树,只是osascript是Sublime Text的子级。 我们可以看到从Finder到Sublime Text到osascript ( PID 2212的过程执行。

Image for post
TrueTree excerpt showing execution of our payload
TrueTree摘录显示了我们的有效载荷的执行

Furthermore, osquery captures the launching of our payload.

此外,osquery捕获有效负载的启动。

Image for post
Process Events to Execute from osquery in Splunk
处理事件以从Splunk中的osquery执行
Image for post
Agent in Apfell running in the osascript PID 2212
在osascript PID 2212中运行的Apfell中的代理

If enabled, another artifact would be the file modification of the sublime.py script, which is not typically modified unless the entire Sublime package is under a change.

如果启用,另一个工件将是sublime.py脚本的文件修改,除非整个Sublime软件包都处于更改状态,否则通常不会进行修改。

自动化的持久性工作流程 (Automator Workflows for Persistence)

Through my research, I found that Automator can execute JXA as well. Automator allows for the completion of tasks through workflow files. The actions can interact with a variety of apps and parts of macOS. Perhaps unknown to some, there is a command-line tool for Automator. It is vastly reduced compared to its GUI counterpart but allows for the execution of workflow files.

通过研究,我发现Automator也可以执行JXA。 Automator允许通过工作流文件完成任务。 这些动作可以与各种应用程序和部分macOS进行交互。 也许某些人不知道,有一个Automator命令行工具。 与GUI相比,它大大减少了,但允许执行工作流文件。

We can create a workflow in the Automator GUI that will run our JXA payload and leverage the Automator command-line tool to execute. This method is merely replacing osascript command-line usage with Automator for a command-line detection perspective. Although simple, it is a useful option to bypass any of the alerts only looking at osascript.

我们可以在Automator GUI中创建一个工作流,该工作流将运行我们的JXA有效负载并利用Automator命令行工具执行。 此方法仅用Automator替换osascript命令行用法,以用于命令行检测。 尽管很简单,但是绕过仅查看osascript任何警报是一个有用的选项。

Within the PersistentJXA project is a workflow template, which is a modified version of the one created through the Automator GUI.

PersistentJXA项目中有一个工作流程模板,它是通过Automator GUI创建的工作模板的修改版本。

To create through the workflow through Automator, first, we select the workflow template.

要通过Automator创建工作流,首先,我们选择工作流模板。

Image for post
Workflow option within GUI for Automator
GUI中的Automator工作流选项

Next, we select the Run JavaScript action and paste our JXA payload.

接下来,我们选择“运行JavaScript”操作并粘贴我们的JXA有效负载。

Image for post
Inserting Apfell payload into Automator
将Apfell有效负载插入Automator

After creation, we can take out the created document.wflow file under <FileName>.workflow/Contents/, upload to the target, and invoke using the command line Automator binary.

创建后,我们可以在<FileName>.workflow/Contents/下取出创建的document.wflow文件,上传到目标,然后使用命令行Automator二进制文件进行调用。

Image for post
Agent in Apfell running in com.automator.runner.xpc PID 2569
在com.automator.runner.xpc中运行的Apfell中的代理PID 2569

侦测 (Detection)

Command-line detection for Automator binary is a simple alert as its usage is probably uncommon in environments.

Automator二进制文件的命令行检测是一个简单的警报,因为在环境中它的用法可能并不常见。

Image for post
osquery excerpt capturing Automator execution
osquery摘录捕获Automator执行

Another indicator with this method is due to the long-running processes resulting in the “cog” indicator. As noted in the post regarding folder actions, longer running processes result in an icon in the top menu bar indicating that something is processing, and if you click on it, you can see the workflow name.

此方法的另一个指标是由于长时间运行的过程导致出现“ cog”指标。 如有关文件夹操作的文章所述,长时间运行的进程会在顶部菜单栏中显示一个图标,指示正在处理某些内容,如果单击该图标,则可以看到工作流程名称。

Image for post
Spinning cog wheel highlighting long-running process
旋转齿轮突出了长时间运行的过程

As far as the process tree, the execution of Automator shows a child of the terminal app, but the com.automator.runner.xpc PID 2569 in which our payload is executing under is not a child of Automator PID 2658 yet appears to be a separate child of the terminal app. However, killing the Automator process kills the runner, which is what our payload is running in.

就进程树而言,Automator的执行显示了终端应用程序的子级,但是有效负载在其下执行的com.automator.runner.xpc PID 2569不是Automator PID 2658的子级,终端应用程序的单独子项。 但是,杀死Automator进程会杀死运行程序,这是我们的有效负载所运行的。

Image for post
TrueTree excerpt detailing the execution of the Automator workflow
TrueTree摘录,详细介绍了Automator工作流程的执行

结论 (Conclusion)

The purpose of this post was to display the benefits of JXA while highlighting some lesser-known persistence methods on macOS. By no means are the implementations within the PersistentJXA project perfect. I’m still new to macOS tradecraft and JXA development. If you have any thoughts on improvements/ additions, I am open to pull requests 😃. Regardless, I hope this post serves as a starting point for those interested in reviewing some macOS persistence methods and provides a starting point on some indicators to aid detections of malicious behavior.

这篇文章的目的是展示JXA的好处,同时重点介绍macOS上一些鲜为人知的持久性方法。 PersistentJXA项目中的实现绝不是完美的。 我仍然是macOS tradecraft和JXA开发的新手。 如果您对改进/增加有任何想法,我愿意提出要求requests。 无论如何,我希望这篇博文可以作为那些对审查某些macOS持久性方法感兴趣的人的起点,并为一些有助于检测恶意行为的指标提供起点。

参考资料/资源: (References / Resources:)

翻译自: https://posts.specterops.io/persistent-jxa-66e1c3cd1cf5

jxa 入门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值