macOS Apps - Inspecting, debugging and Fuzzing

从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家)

支持 HackTricks 的其他方式:

WhiteIntel 是一个由 暗网 提供支持的搜索引擎,提供免费功能,用于检查公司或其客户是否受到 窃取恶意软件侵害

WhiteIntel 的主要目标是打击由信息窃取恶意软件导致的账户劫持和勒索软件攻击。

您可以访问他们的网站并免费尝试他们的引擎:


静态分析

otool

otool -L /bin/ls #List dynamically linked libraries
otool -tv /bin/ps #Decompile application

objdump

{% 代码 溢出="换行" %}

objdump -m --dylibs-used /bin/ls #List dynamically linked libraries
objdump -m -h /bin/ls # Get headers information
objdump -m --syms /bin/ls # Check if the symbol table exists to get function names
objdump -m --full-contents /bin/ls # Dump every section
objdump -d /bin/ls # Dissasemble the binary
objdump --disassemble-symbols=_hello --x86-asm-syntax=intel toolsdemo #Disassemble a function using intel flavour

jtool2

该工具可用作 codesignotoolobjdump替代品,并提供一些额外功能。在此下载或使用 brew 安装。

# Install
brew install --cask jtool2

jtool2 -l /bin/ls # Get commands (headers)
jtool2 -L /bin/ls # Get libraries
jtool2 -S /bin/ls # Get symbol info
jtool2 -d /bin/ls # Dump binary
jtool2 -D /bin/ls # Decompile binary

# Get signature information
ARCH=x86_64 jtool2 --sig /System/Applications/Automator.app/Contents/MacOS/Automator

# Get MIG information
jtool2 -d __DATA.__const myipc_server | grep MIG

Codesign / ldid

Codesign 可在 macOS 中找到,而 ldid 可在 iOS 中找到

# Get signer
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"

# Check if the app’s contents have been modified
codesign --verify --verbose /Applications/Safari.app

# Get entitlements from the binary
codesign -d --entitlements :- /System/Applications/Automator.app # Check the TCC perms

# Check if the signature is valid
spctl --assess --verbose /Applications/Safari.app

# Sign a binary
codesign -s <cert-name-keychain> toolsdemo

# Get signature info
ldid -h <binary>

# Get entitlements
ldid -e <binary>

# Change entilements
## /tmp/entl.xml is a XML file with the new entitlements to add
ldid -S/tmp/entl.xml <binary>

SuspiciousPackage

SuspiciousPackage 是一个有用的工具,用于检查 .pkg 文件(安装程序),在安装之前查看其中的内容。 这些安装程序包含 preinstallpostinstall bash 脚本,恶意软件作者通常会滥用这些脚本来持久化 恶意软件

hdiutil

这个工具允许挂载苹果磁盘映像(.dmg)文件以在运行任何内容之前检查它们:

hdiutil attach ~/Downloads/Firefox\ 58.0.2.dmg

它将被挂载在 /Volumes

Objective-C

元数据

请注意,用 Objective-C 编写的程序在编译为 Mach-O 二进制文件 时会保留它们的类声明。这些类声明包括以下内容的名称和类型:

  • 类方法

  • 类实例变量

您可以使用 class-dump 获取这些信息:

class-dump Kindle.app

函数调用

当在使用 Objective-C 的二进制文件中调用函数时,编译后的代码不会直接调用该函数,而是会调用 objc_msgSend。这将调用最终的函数:

此函数期望的参数包括:

  • 第一个参数(self)是“指向接收消息的类的实例的指针”。简单来说,它是方法被调用的对象。如果方法是类方法,这将是类对象的一个实例(整体),而对于实例方法,self将指向作为对象的类的实例化实例。

  • 第二个参数(op)是“处理消息的方法的选择器”。更简单地说,这只是方法的名称

  • 剩余的参数是方法所需的任何(op)。

查看如何使用 lldb 在 ARM64 中轻松获取此信息

pageIntroduction to ARM64v8

x64:

参数

寄存器

(对于) objc_msgSend

第1个参数

rdi

self:方法被调用的对象

第2个参数

rsi

op:方法的名称

第3个参数

rdx

方法的第一个参数

第4个参数

rcx

方法的第二个参数

第5个参数

r8

方法的第三个参数

第6个参数

r9

方法的第四个参数

第7个+ 参数

rsp+ (在堆栈上)

方法的第五个+ 参数

Swift

对于 Swift 二进制文件,由于存在 Objective-C 兼容性,有时可以使用 class-dump 提取声明,但并非总是有效。

使用 jtool -lotool -l 命令行可以找到以 __swift5 前缀开头的多个部分:

jtool2 -l /Applications/Stocks.app/Contents/MacOS/Stocks
LC 00: LC_SEGMENT_64              Mem: 0x000000000-0x100000000    __PAGEZERO
LC 01: LC_SEGMENT_64              Mem: 0x100000000-0x100028000    __TEXT
[...]
Mem: 0x100026630-0x100026d54        __TEXT.__swift5_typeref
Mem: 0x100026d60-0x100027061        __TEXT.__swift5_reflstr
Mem: 0x100027064-0x1000274cc        __TEXT.__swift5_fieldmd
Mem: 0x1000274cc-0x100027608        __TEXT.__swift5_capture
[...]

您可以在此博客文章中找到有关这些部分存储的信息

此外,Swift 二进制文件可能具有符号(例如,库需要存储符号以便调用其函数)。**这些符号通常以一种难以理解的方式包含有关函数名称和属性的信息,因此它们非常有用,而且有“**解码器”**可以获取原始名称:

# Ghidra plugin
https://github.com/ghidraninja/ghidra_scripts/blob/master/swift_demangler.py

# Swift cli
swift demangle

打包的二进制文件

  • 检查高熵

  • 检查字符串(如果几乎没有可理解的字符串,则为打包)

  • MacOS的UPX打包程序会生成一个名为"__XHDR"的部分

动态分析

请注意,为了调试二进制文件,需要禁用SIPcsrutil disablecsrutil enable --without debug),或者将二进制文件复制到临时文件夹并使用codesign --remove-signature <binary-path>移除签名,或者允许对二进制文件进行调试(可以使用此脚本

请注意,为了对macOS上的系统二进制文件(如cloudconfigurationd)进行插桩必须禁用SIP(仅仅移除签名是不够的)。

统一日志

MacOS生成了大量日志,在运行应用程序时,尝试理解其正在执行的操作时,这些日志非常有用。

此外,有一些日志将包含标签<private>,用于隐藏一些用户计算机可识别信息。但是,可以安装证书来披露这些信息。请参考这里中的说明。

Hopper

左侧面板

在hopper的左侧面板中,可以看到二进制文件的符号(标签),过程和函数的列表(Proc)以及字符串(Str)。这些不是所有字符串,而是在Mac-O文件的几个部分中定义的字符串(如_cstring或objc_methname)。

中间面板

在中间面板中,您可以看到反汇编代码。您可以看到原始反汇编,图形反编译二进制,通过单击相应的图标:

右键单击代码对象,可以查看对该对象的引用/来自该对象的引用,甚至更改其名称(在反编译伪代码中不起作用):

此外,在中间下方,您可以编写Python命令

右侧面板

在右侧面板中,您可以查看一些有趣的信息,例如导航历史记录(以便了解如何到达当前情况),调用图,您可以看到所有调用此函数的函数以及此函数调用的所有函数,以及本地变量信息。

dtrace

它允许用户以极其低级别访问应用程序,并为用户提供了一种跟踪程序甚至更改其执行流的方法。Dtrace使用探针,这些探针分布在内核的各个位置,如系统调用的开始和结束。

DTrace使用**dtrace_probe_create函数为每个系统调用创建一个探针。这些探针可以在每个系统调用的入口和出口点触发**。与DTrace的交互通过/dev/dtrace进行,这仅对root用户可用。

要在不完全禁用SIP保护的情况下启用Dtrace,您可以在恢复模式下执行:csrutil enable --without dtrace

您还可以**dtracedtruss**您已编译的二进制文件。

可以使用以下命令获取dtrace的可用探针:

dtrace -l | head
ID   PROVIDER            MODULE                          FUNCTION NAME
1     dtrace                                                     BEGIN
2     dtrace                                                     END
3     dtrace                                                     ERROR
43    profile                                                     profile-97
44    profile                                                     profile-199

探针名称由四个部分组成:提供者、模块、函数和名称(fbt:mach_kernel:ptrace:entry)。如果未指定名称的某些部分,Dtrace 将将该部分视为通配符。

要配置 DTrace 以激活探针并指定触发时要执行的操作,我们需要使用 D 语言。

更详细的解释和更多示例可在https://illumos.org/books/dtrace/chp-intro.html找到

示例

运行 man -k dtrace 以列出可用的DTrace 脚本。示例:sudo dtruss -n binary

  • 在行中

#Count the number of syscalls of each running process
sudo dtrace -n 'syscall:::entry {@[execname] = count()}'
  • 脚本

syscall:::entry
/pid == $1/
{
}

#Log every syscall of a PID
sudo dtrace -s script.d 1234
syscall::open:entry
{
printf("%s(%s)", probefunc, copyinstr(arg0));
}
syscall::close:entry
{
printf("%s(%d)\n", probefunc, arg0);
}

#Log files opened and closed by a process
sudo dtrace -s b.d -c "cat /etc/hosts"
syscall:::entry
{
;
}
syscall:::return
{
printf("=%d\n", arg1);
}

#Log sys calls with values
sudo dtrace -s syscalls_info.d -c "cat /etc/hosts"

dtruss

dtruss -c ls #Get syscalls of ls
dtruss -c -p 1000 #get syscalls of PID 1000

ktrace

即使启用了SIP,您也可以使用此命令

ktrace trace -s -S -t c -c ls | grep "ls("

ProcessMonitor

ProcessMonitor 是一个非常有用的工具,用于检查进程执行的与进程相关的操作(例如,监视进程创建的新进程)。

SpriteTree

SpriteTree 是一个工具,用于显示进程之间的关系。 您需要使用类似 sudo eslogger fork exec rename create > cap.json 这样的命令监视您的 macOS(启动此命令需要 FDA)。然后您可以在此工具中加载 json 文件以查看所有关系:

FileMonitor

FileMonitor 允许监视文件事件(例如创建、修改和删除),提供有关这些事件的详细信息。

Crescendo

Crescendo 是一个具有类似于 Microsoft Sysinternal 的 Procmon 的外观和感觉的 GUI 工具。该工具允许启动和停止各种事件类型的记录,允许通过文件、进程、网络等类别对这些事件进行过滤,并提供将记录的事件保存为 json 格式的功能。

Apple Instruments

Apple Instruments 是 Xcode 的开发工具的一部分,用于监视应用程序性能,识别内存泄漏和跟踪文件系统活动。

fs_usage

允许跟踪进程执行的操作:

fs_usage -w -f filesys ls #This tracks filesystem actions of proccess names containing ls
fs_usage -w -f network curl #This tracks network actions

TaskExplorer

Taskexplorer 对于查看二进制文件使用的、正在使用的文件网络连接非常有用。 它还会针对virustotal检查二进制进程,并显示有关二进制文件的信息。

PT_DENY_ATTACH

这篇博文中,您可以找到一个示例,说明如何调试正在运行的守护程序,该守护程序使用**PT_DENY_ATTACH**来防止调试,即使 SIP 已禁用。

lldb

lldbmacOS二进制文件调试的事实标准工具。

lldb ./malware.bin
lldb -p 1122
lldb -n malware.bin
lldb -n malware.bin --waitfor

您可以在家目录下创建一个名为**.lldbinit**的文件,并添加以下行以设置使用lldb时的intel flavor:

settings set target.x86-disassembly-flavor intel

在 lldb 中,使用 process save-core 命令来转储一个进程

(lldb) 命令

描述

run (r)

开始执行,直到触发断点或进程终止。

continue (c)

继续调试进程的执行。

nexti (n / ni)

执行下一条指令。该命令会跳过函数调用。

stepi (s / si)

执行下一条指令。与 nexti 命令不同,该命令会进入函数调用。

finish (f)

执行当前函数中剩余的指令,返回并停止。

control + c

暂停执行。如果进程已经运行(r)或继续(c),这会导致进程停止在当前执行位置。

breakpoint (b)

b main #调用名为 main 的任何函数

b `main #二进制文件的主函数

b set -n main --shlib #指定二进制文件的主函数

b -[NSDictionary objectForKey:]

b -a 0x0000000100004bd9

br l #断点列表

br e/dis #启用/禁用断点

breakpoint delete

help

help breakpoint #获取断点命令的帮助

help memory write #获取写入内存的帮助

reg

reg read

reg read $rax

reg read $rax --format format

reg write $rip 0x100035cc0

x/s

将内存显示为以空字符结尾的字符串。

x/i

将内存显示为汇编指令。

x/b

将内存显示为字节。

print object (po)

这将打印参数引用的对象

po $raw

{

dnsChanger = {

"affiliate" = "";

"blacklist_dns" = ();

请注意,大多数 Apple 的 Objective-C API 或方法返回对象,因此应通过“print object”(po)命令显示。如果 po 不产生有意义的输出,请使用 x/b

memory

memory read 0x000.... memory read $x0+0xf2a memory write 0x100600000 -s 4 0x41414141 #在该地址写入 AAAA memory write -f s $rip+0x11f+7 "AAAA" #在地址写入 AAAA

disassembly

dis #反汇编当前函数

dis -n #反汇编函数

dis -n -b #反汇编函数

dis -c 6 #反汇编 6 行

dis -c 0x100003764 -e 0x100003768 #从一个地址到另一个地址

dis -p -c 4 #从当前地址开始反汇编

parray

parray 3 (char **)$x1 # 检查 x1 寄存器中的 3 个组件的数组

在调用 objc_sendMsg 函数时,rsi 寄存器保存方法的名称,作为以空字符结尾的(“C”)字符串。要通过 lldb 打印名称,执行以下命令:

(lldb) x/s $rsi: 0x1000f1576: "startMiningWithPort:password:coreCount:slowMemory:currency:"

(lldb) print (char*)$rsi: (char *) $1 = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"

(lldb) reg read $rsi: rsi = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"

反动态分析

VM 检测

  • 命令 sysctl hw.model主机为 MacOS 时返回 "Mac",在虚拟机上返回其他内容。

  • 通过调整 hw.logicalcpuhw.physicalcpu 的值,一些恶意软件尝试检测是否为虚拟机。

  • 一些恶意软件还可以根据 MAC 地址(00:50:56)判断主机是否为 VMware。

  • 也可以通过简单的代码来判断进程是否正在被调试:

  • if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //process being debugged }

  • 还可以使用 ptrace 系统调用以 PT_DENY_ATTACH 标志。这会阻止调试器附加和跟踪。

  • 可以检查是否正在导入 sysctlptrace 函数(但恶意软件可能会动态导入)。

  • 如在这篇文章中所述,“Defeating Anti-Debug Techniques: macOS ptrace variants”: “消息“进程 # 以状态 = 45 (0x0000002d) 退出”通常是调试目标正在使用 PT_DENY_ATTACH 的明显迹象

模糊测试

ReportCrash 分析崩溃进程并将崩溃报告保存到磁盘。崩溃报告包含的信息可以帮助开发人员诊断崩溃的原因。 对于在每个用户的launchd上下文中运行的应用程序和其他进程,ReportCrash 作为一个 LaunchAgent 运行,并将崩溃报告保存在用户的 ~/Library/Logs/DiagnosticReports/ 目录中。 对于守护进程、在系统launchd上下文中运行的其他进程和其他特权进程,ReportCrash 作为一个 LaunchDaemon 运行,并将崩溃报告保存在系统的 /Library/Logs/DiagnosticReports 目录中。

如果您担心崩溃报告被发送到苹果,您可以禁用它们。如果不担心,崩溃报告可以帮助找出服务器崩溃的原因

#To disable crash reporting:
launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

#To re-enable crash reporting:
launchctl load -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

休眠

在 MacOS 中进行模糊测试时,重要的是不让 Mac 进入睡眠状态:

SSH 断开连接

如果您通过 SSH 连接进行模糊测试,重要的是确保会话不会断开。因此,请更改 sshd_config 文件如下:

  • TCPKeepAlive Yes

  • ClientAliveInterval 0

  • ClientAliveCountMax 0

sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

内部处理程序

查看以下页面,了解如何找出哪个应用程序负责处理指定的方案或协议:

pagemacOS File Extension & URL scheme app handlers

枚举网络进程

这很有趣,可以找到管理网络数据的进程:

dtrace -n 'syscall::recv*:entry { printf("-> %s (pid=%d)", execname, pid); }' >> recv.log
#wait some time
sort -u recv.log > procs.txt
cat procs.txt

或者使用 netstatlsof

Libgmalloc

lldb -o "target create `which some-binary`" -o "settings set target.env-vars DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib" -o "run arg1 arg2" -o "bt" -o "reg read" -o "dis -s \$pc-32 -c 24 -m -F intel" -o "quit"

Fuzzers

适用于 CLI 工具

它可以与 macOS GUI 工具一起使用。请注意,一些 macOS 应用程序具有特定要求,如唯一文件名、正确的扩展名,需要从沙盒中读取文件 (~/Library/Containers/com.apple.Safari/Data)...

一些示例:

# iBooks
litefuzz -l -c "/System/Applications/Books.app/Contents/MacOS/Books FUZZ" -i files/epub -o crashes/ibooks -t /Users/test/Library/Containers/com.apple.iBooksX/Data/tmp -x 10 -n 100000 -ez

# -l : Local
# -c : cmdline with FUZZ word (if not stdin is used)
# -i : input directory or file
# -o : Dir to output crashes
# -t : Dir to output runtime fuzzing artifacts
# -x : Tmeout for the run (default is 1)
# -n : Num of fuzzing iterations (default is 1)
# -e : enable second round fuzzing where any crashes found are reused as inputs
# -z : enable malloc debug helpers

# Font Book
litefuzz -l -c "/System/Applications/Font Book.app/Contents/MacOS/Font Book FUZZ" -i input/fonts -o crashes/font-book -x 2 -n 500000 -ez

# smbutil (using pcap capture)
litefuzz -lk -c "smbutil view smb://localhost:4455" -a tcp://localhost:4455 -i input/mac-smb-resp -p -n 100000 -z

# screensharingd (using pcap capture)
litefuzz -s -a tcp://localhost:5900 -i input/screenshared-session --reportcrash screensharingd -p -n 100000

更多关于 MacOS 的模糊测试信息

参考资料

WhiteIntel 是一个由 暗网 提供支持的搜索引擎,提供免费功能,用于检查公司或其客户是否受到 窃取恶意软件威胁

WhiteIntel 的主要目标是打击由信息窃取恶意软件导致的账户劫持和勒索软件攻击。

您可以访问他们的网站并免费尝试他们的引擎:

从零开始学习 AWS 黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)!

支持 HackTricks 的其他方式:

最后更新于