61 KiB
iOS渗透测试
使用Trickest轻松构建和自动化工作流,使用全球最先进的社区工具。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
从零开始学习AWS黑客技术,成为专家 htARTE(HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
- 如果您想在HackTricks中看到您的公司广告或下载PDF格式的HackTricks,请查看订阅计划!
- 获取官方PEASS & HackTricks周边产品
- 发现PEASS家族,我们的独家NFTs系列
- 加入 💬 Discord群 或 电报群 或在Twitter上关注我 🐦 @carlospolopm。
- 通过向HackTricks和HackTricks Cloud github仓库提交PR来分享您的黑客技巧。
iOS基础知识
{% content-ref url="ios-basics.md" %} ios-basics.md {% endcontent-ref %}
测试环境
在此页面,您可以找到关于iOS模拟器、模拟器和越狱的信息:
{% content-ref url="ios-testing-environment.md" %} ios-testing-environment.md {% endcontent-ref %}
初始分析
基本iOS测试操作
在测试过程中会建议执行多个操作(连接到设备、读取/写入/上传/下载文件、使用一些工具...)。因此,如果您不知道如何执行这些操作,请开始阅读页面:
{% content-ref url="basic-ios-testing-operations.md" %} basic-ios-testing-operations.md {% endcontent-ref %}
{% hint style="info" %}
在以下步骤中,应在设备上安装应用程序并已获取应用程序的IPA文件。
阅读基本iOS测试操作页面以了解如何执行此操作。
{% endhint %}
基本静态分析
建议使用工具MobSF对IPA文件执行自动静态分析。
识别二进制文件中存在的保护措施:
- PIE(位置无关可执行文件):启用后,应用程序每次启动时都会加载到随机内存地址,使其更难以预测其初始内存地址。
otool -hv <app-binary> | grep PIE # 应包含PIE标志
- 堆栈Canaries:为了验证堆栈的完整性,在调用函数之前在堆栈上放置一个“canary”值,并在函数结束时再次验证。
otool -I -v <app-binary> | grep stack_chk # 应包含符号:stack_chk_guard和stack_chk_fail
- ARC(自动引用计数):防止常见的内存损坏缺陷
otool -I -v <app-binary> | grep objc_release # 应包含_objc_release符号
- 加密二进制文件:二进制文件应该是加密的
otool -arch all -Vl <app-binary> | grep -A5 LC_ENCRYPT # cryptid应为1
识别敏感/不安全函数
- 弱哈希算法
# 在iOS设备上
otool -Iv <app> | grep -w "_CC_MD5"
otool -Iv <app> | grep -w "_CC_SHA1"
# 在Linux上
grep -iER "_CC_MD5"
grep -iER "_CC_SHA1"
- 不安全的随机函数
# 在iOS设备上
otool -Iv <app> | grep -w "_random"
otool -Iv <app> | grep -w "_srand"
otool -Iv <app> | grep -w "_rand"
# 在Linux上
grep -iER "_random"
grep -iER "_srand"
grep -iER "_rand"
- 不安全的‘Malloc’函数
# 在iOS设备上
otool -Iv <app> | grep -w "_malloc"
# 在Linux上
grep -iER "_malloc"
- 不安全和易受攻击的函数
# 在iOS设备上
otool -Iv <app> | grep -w "_gets"
otool -Iv <app> | grep -w "_memcpy"
otool -Iv <app> | grep -w "_strncpy"
otool -Iv <app> | grep -w "_strlen"
otool -Iv <app> | grep -w "_vsnprintf"
otool -Iv <app> | grep -w "_sscanf"
otool -Iv <app> | grep -w "_strtok"
otool -Iv <app> | grep -w "_alloca"
otool -Iv <app> | grep -w "_sprintf"
otool -Iv <app> | grep -w "_printf"
otool -Iv <app> | grep -w "_vsprintf"
# 在Linux上
grep -R "_gets"
grep -iER "_memcpy"
grep -iER "_strncpy"
grep -iER "_strlen"
grep -iER "_vsnprintf"
grep -iER "_sscanf"
grep -iER "_strtok"
grep -iER "_alloca"
grep -iER "_sprintf"
grep -iER "_printf"
grep -iER "_vsprintf"
基本动态分析
查看MobSF执行的动态分析。您需要浏览不同视图并与其交互,但它将挂接多个类并执行其他操作,并在完成后准备报告。
列出已安装的应用程序
使用命令frida-ps -Uai
来确定已安装应用程序的捆绑标识符:
$ frida-ps -Uai
PID Name Identifier
---- ------------------- -----------------------------------------
6847 Calendar com.apple.mobilecal
6815 Mail com.apple.mobilemail
- App Store com.apple.AppStore
- Apple Store com.apple.store.Jolly
- Calculator com.apple.calculator
- Camera com.apple.camera
- iGoat-Swift OWASP.iGoat-Swift
基本枚举和挂钩
学习如何枚举应用程序的组件以及如何使用 objection 轻松挂钩方法和类:
{% content-ref url="ios-hooking-with-objection.md" %} ios-hooking-with-objection.md {% endcontent-ref %}
IPA 结构
IPA 文件的结构本质上是一个压缩包。通过将其扩展名更改为 .zip
,可以对其进行解压以显示其内容。在这个结构中,Bundle代表一个完全打包好准备安装的应用程序。在其中,您会找到一个名为 <NAME>.app
的目录,其中包含应用程序的资源。
Info.plist
:此文件保存应用程序的特定配置详细信息。_CodeSignature/
:此目录包含一个包含签名的 plist 文件,确保捆绑包中所有文件的完整性。Assets.car
:存储像图标之类的资源文件的压缩存档。Frameworks/
:此文件夹包含应用程序的本机库,可能是.dylib
或.framework
文件的形式。PlugIns/
:这可能包括应用程序的扩展,称为.appex
文件,尽管它们并不总是存在。 *Core Data
:用于保存应用程序的永久数据以供离线使用,缓存临时数据,并在单个设备上为应用程序添加撤销功能。为了在单个 iCloud 帐户中跨多个设备同步数据,Core Data 会自动将您的模式镜像到 CloudKit 容器中。PkgInfo
:PkgInfo
文件是指定应用程序或捆绑包的类型和创建者代码的另一种方式。- en.lproj, fr.proj, Base.lproj:是包含这些特定语言资源的语言包,以及在不支持某种语言的情况下的默认资源。
- 安全性:
_CodeSignature/
目录通过数字签名验证所有捆绑文件的完整性,在应用程序的安全性方面起着关键作用。 - 资产管理:
Assets.car
文件使用压缩来高效管理图形资产,这对于优化应用程序性能并减小其整体大小至关重要。 - 框架和插件:这些目录突显了 iOS 应用程序的模块化,允许开发人员包含可重用的代码库(
Frameworks/
)并扩展应用程序功能(PlugIns/
)。 - 本地化:该结构支持多种语言,通过包含特定语言包的资源,有助于全球应用程序覆盖。
Info.plist
Info.plist 作为 iOS 应用程序的基石,以键-值对的形式封装关键配置数据。这个文件不仅对应用程序是必需的,对于打包在其中的应用程序扩展和框架也是必需的。它以 XML 或二进制格式结构化,并包含从应用程序权限到安全配置等关键信息。要详细探索可用键,可以参考Apple Developer Documentation。
对于希望以更易访问的格式处理此文件的人,可以通过 macOS 上的 plutil
(在版本 10.2 及更高版本中本地可用)或 Linux 上的 plistutil
轻松实现 XML 转换。转换的命令如下:
- 对于 macOS:
$ plutil -convert xml1 Info.plist
- 对于Linux:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
在Info.plist文件中可以泄露大量信息,其中一些显著条目包括应用程序权限字符串(UsageDescription
)、自定义URL schemes(CFBundleURLTypes
)以及App Transport Security的配置(NSAppTransportSecurity
)。这些条目以及其他条目,如导出/导入的自定义文档类型(UTExportedTypeDeclarations
/ UTImportedTypeDeclarations
),可以通过检查文件或使用简单的grep
命令轻松定位:
$ grep -i <keyword> Info.plist
数据路径
在iOS环境中,目录专门用于系统应用程序和用户安装的应用程序。系统应用程序位于/Applications
目录下,而用户安装的应用程序则放置在/private/var/containers/
目录下。这些应用程序被分配一个称为128位UUID的唯一标识符,由于目录名称的随机性,手动定位应用程序文件夹的任务变得具有挑战性。
为了便于发现用户安装的应用程序的安装目录,objection工具提供了一个有用的命令,即env
。该命令会显示有关所讨论应用程序的详细目录信息。以下是如何使用此命令的示例:
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # env
Name Path
----------------- -------------------------------------------------------------------------------------------
BundlePath /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
CachesDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library/Caches
DocumentDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Documents
LibraryDirectory /var/mobile/Containers/Data/Application/8C8E7EB0-BC9B-435B-8EF8-8F5560EB0693/Library
或者,可以使用find
命令在/private/var/containers
中搜索应用程序名称:
find /private/var/containers -name "Progname*"
命令如 ps
和 lsof
也可用于识别应用程序的进程和列出打开的文件,从而提供有关应用程序活动目录路径的见解:
ps -ef | grep -i <app-name>
lsof -p <pid> | grep -i "/containers" | head -n 1
Bundle directory:
- AppName.app
- 这是应用程序包,与IPA文件中看到的一样,其中包含基本的应用程序数据、静态内容以及应用程序的编译二进制文件。
- 此目录对用户可见,但用户无法对其进行写入。
- 此目录中的内容不会被备份。
- 此文件夹的内容用于验证代码签名。
Data directory:
- Documents/
- 包含所有用户生成的数据。应用程序最终用户启动此数据的创建。
- 对用户可见,用户可以对其进行写入。
- 此目录中的内容已备份。
- 应用程序可以通过设置
NSURLIsExcludedFromBackupKey
来禁用路径。 - Library/
- 包含所有非特定于用户的文件,如缓存、首选项、cookies和属性列表(plist)配置文件。
- iOS应用程序通常使用
Application Support
和Caches
子目录,但应用程序可以创建自定义子目录。 - Library/Caches/
- 包含半持久性缓存文件。
- 对用户不可见,用户无法对其进行写入。
- 此目录中的内容不会被备份。
- 当应用程序未运行且存储空间不足时,操作系统可能会自动删除此目录中的文件。
- Library/Application Support/
- 包含运行应用程序所需的持久性文件。
- 对用户不可见,用户无法对其进行写入。
- 此目录中的内容已备份。
- 应用程序可以通过设置
NSURLIsExcludedFromBackupKey
来禁用路径。 - Library/Preferences/
- 用于存储属性,这些属性可以在应用程序重新启动后持久存在。
- 信息以未加密的方式保存在应用程序沙盒中的名为[BUNDLE_ID].plist的plist文件中。
- 使用
NSUserDefaults
存储的所有键/值对都可以在此文件中找到。 - tmp/
- 使用此目录来写入不需要在应用程序启动之间持久存在的临时文件。
- 包含非持久性缓存文件。
- 对用户不可见。
- 此目录中的内容不会被备份。
- 当应用程序未运行且存储空间不足时,操作系统可能会自动删除此目录中的文件。
让我们更仔细地查看iGoat-Swift的应用程序包(.app)目录,位于Bundle目录内(/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app
):
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # ls
NSFileType Perms NSFileProtection ... Name
------------ ------- ------------------ ... --------------------------------------
Regular 420 None ... rutger.html
Regular 420 None ... mansi.html
Regular 420 None ... splash.html
Regular 420 None ... about.html
Regular 420 None ... LICENSE.txt
Regular 420 None ... Sentinel.txt
Regular 420 None ... README.txt
二进制反向工程
在 <application-name>.app
文件夹中,您会找到一个名为 <application-name>
的二进制文件。这是将被执行的文件。您可以使用工具 otool
对二进制文件进行基本检查:
otool -Vh DVIA-v2 #Check some compilation attributes
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 ARM64 ALL 0x00 EXECUTE 65 7112 NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK PIE
otool -L DVIA-v2 #Get third party libraries
DVIA-v2:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.1)
/usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current version 274.6.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
@rpath/Bolts.framework/Bolts (compatibility version 1.0.0, current version 1.0.0)
[...]
检查应用是否已加密
查看是否有以下输出:
otool -l <app-binary> | grep -A 4 LC_ENCRYPTION_INFO
反汇编二进制文件
反汇编文本部分:
otool -tV DVIA-v2
DVIA-v2:
(__TEXT,__text) section
+[DDLog initialize]:
0000000100004ab8 sub sp, sp, #0x60
0000000100004abc stp x29, x30, [sp, #0x50] ; Latency: 6
0000000100004ac0 add x29, sp, #0x50
0000000100004ac4 sub x8, x29, #0x10
0000000100004ac8 mov x9, #0x0
0000000100004acc adrp x10, 1098 ; 0x10044e000
0000000100004ad0 add x10, x10, #0x268
要打印示例应用程序的Objective-C段,可以使用:
otool -oV DVIA-v2
DVIA-v2:
Contents of (__DATA,__objc_classlist) section
00000001003dd5b8 0x1004423d0 _OBJC_CLASS_$_DDLog
isa 0x1004423a8 _OBJC_METACLASS_$_DDLog
superclass 0x0 _OBJC_CLASS_$_NSObject
cache 0x0 __objc_empty_cache
vtable 0x0
data 0x1003de748
flags 0x80
instanceStart 8
为了获得更紧凑的 Objective-C 代码,您可以使用 class-dump 工具:
class-dump some-app
//
// Generated by class-dump 3.5 (64 bit).
//
// class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
//
#pragma mark Named Structures
struct CGPoint {
double _field1;
double _field2;
};
struct CGRect {
struct CGPoint _field1;
struct CGSize _field2;
};
struct CGSize {
double _field1;
double _field2;
};
然而,最佳的反汇编二进制文件选项是:Hopper 和 IDA。
使用 Trickest 来轻松构建和自动化工作流程,利用世界上最先进的社区工具。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
数据存储
要了解 iOS 如何在设备中存储数据,请阅读此页面:
{% content-ref url="ios-basics.md" %} ios-basics.md {% endcontent-ref %}
{% hint style="warning" %}
应该在安装应用程序后立即检查以下存储信息的位置,在检查应用程序的所有功能后,甚至在从一个用户注销并登录到另一个用户后。
目标是查找应用程序(密码、令牌)、当前用户和先前登录用户的未受保护的敏感信息。
{% endhint %}
Plist
plist 文件是结构化的 XML 文件,包含键值对。这是一种存储持久数据的方式,因此有时您可能会在这些文件中找到敏感信息。建议在安装应用程序后和在大量使用应用程序后检查这些文件,以查看是否写入了新数据。
在 plist 文件中持久保存数据的最常见方式是通过使用 NSUserDefaults。此 plist 文件保存在应用程序沙盒中的 Library/Preferences/<appBundleID>.plist
NSUserDefaults
类提供了与默认系统进行交互的编程接口。默认系统允许应用程序根据用户偏好自定义其行为。由 NSUserDefaults
保存的数据可以在应用程序包中查看。此类将数据存储在 plist 文件中,但应该与少量数据一起使用。
这些数据无法直接通过受信任的计算机访问,但可以通过备份访问。
您可以使用 objection 的 ios nsuserdefaults get
转储使用 NSUserDefaults
保存的信息。
要查找应用程序使用的所有 plist,可以访问 /private/var/mobile/Containers/Data/Application/{APPID}
并运行:
find ./ -name "*.plist"
要将文件从**XML或二进制(bplist)**格式转换为XML,可以根据您的操作系统使用不同的方法:
对于 macOS 用户:
使用 plutil
命令。这是 macOS(10.2+)中的一个内置工具,专门用于此目的:
$ plutil -convert xml1 Info.plist
对于Linux用户:
首先安装libplist-utils
,然后使用plistutil
来转换您的文件:
$ apt install libplist-utils
$ plistutil -i Info.plist -o Info_xml.plist
在 Objection 会话中: 用于分析移动应用程序的特定命令允许您直接转换 plist 文件:
ios plist cat /private/var/mobile/Containers/Data/Application/<Application-UUID>/Library/Preferences/com.some.package.app.plist
Core Data
Core Data
是一个用于管理应用程序中对象模型层的框架。Core Data 可以使用 SQLite 作为其持久存储,但该框架本身并不是一个数据库。
CoreData 默认情况下不会加密其数据。然而,可以向 CoreData 添加额外的加密层。查看 GitHub 仓库 以获取更多详细信息。
您可以在路径 /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support
中找到应用程序的 SQLite Core Data 信息。
如果您可以打开 SQLite 并访问敏感信息,则表示您发现了一个配置错误。
{% code title="iGoat 中的代码" %}
-(void)storeDetails {
AppDelegate * appDelegate = (AppDelegate *)(UIApplication.sharedApplication.delegate);
NSManagedObjectContext *context =[appDelegate managedObjectContext];
User *user = [self fetchUser];
if (user) {
return;
}
user = [NSEntityDescription insertNewObjectForEntityForName:@"User"
inManagedObjectContext:context];
user.email = CoreDataEmail;
user.password = CoreDataPassword;
NSError *error;
if (![context save:&error]) {
NSLog(@"Error in saving data: %@", [error localizedDescription]);
}else{
NSLog(@"data stored in core data");
}
}
{% endcode %}
YapDatabase
YapDatabase是建立在SQLite之上的键/值存储。
由于Yap数据库是SQLite数据库,您可以使用上一节中提到的命令找到它们。
其他SQLite数据库
应用程序通常会创建自己的SQLite数据库。它们可能在其中存储敏感数据并将其保留为未加密。因此,检查应用程序目录中的每个数据库始终是一件有趣的事情。因此,请转到保存数据的应用程序目录(/private/var/mobile/Containers/Data/Application/{APPID}
)。
find ./ -name "*.sqlite" -or -name "*.db"
Firebase实时数据库
开发人员可以通过Firebase实时数据库在NoSQL云托管数据库中存储和同步数据。数据以JSON格式存储,并实时同步到所有连接的客户端。
您可以在此处找到如何检查配置错误的Firebase数据库:
{% content-ref url="../../network-services-pentesting/pentesting-web/buckets/firebase-database.md" %} firebase-database.md {% endcontent-ref %}
Realm数据库
Realm Objective-C 和 Realm Swift 提供了一个强大的数据存储替代方案,苹果没有提供。默认情况下,它们以未加密的方式存储数据,可以通过特定配置进行加密。
这些数据库位于:/private/var/mobile/Containers/Data/Application/{APPID}
。要查看这些文件,可以使用如下命令:
iPhone:/private/var/mobile/Containers/Data/Application/A079DF84-726C-4AEA-A194-805B97B3684A/Documents root# ls
default.realm default.realm.lock default.realm.management/ default.realm.note|
$ find ./ -name "*.realm*"
要查看这些数据库文件,建议使用Realm Studio工具。
要在Realm数据库中实现加密,可以使用以下代码片段:
// Open the encrypted Realm file where getKey() is a method to obtain a key from the Keychain or a server
let config = Realm.Configuration(encryptionKey: getKey())
do {
let realm = try Realm(configuration: config)
// Use the Realm as normal
} catch let error as NSError {
// If the encryption key is wrong, `error` will say that it's an invalid database
fatalError("Error opening realm: \(error)")
}
Couchbase Lite 数据库
Couchbase Lite 被描述为一款轻量级且嵌入式的数据库引擎,遵循面向文档(NoSQL)的方法。设计用于iOS和macOS,提供了无缝同步数据的能力。
要识别设备上可能存在的 Couchbase 数据库,应检查以下目录:
ls /private/var/mobile/Containers/Data/Application/{APPID}/Library/Application Support/
Cookies
iOS将应用程序的cookies存储在每个应用程序文件夹中的**Library/Cookies/cookies.binarycookies
中。然而,开发人员有时会决定将它们保存在钥匙串中,因为上述cookie文件可以在备份中访问**。
要检查cookies文件,您可以使用此python脚本或使用objection的**ios cookies get
**。
您还可以使用objection将这些文件转换为JSON格式并检查数据。
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios cookies get --json
[
{
"domain": "highaltitudehacks.com",
"expiresDate": "2051-09-15 07:46:43 +0000",
"isHTTPOnly": "false",
"isSecure": "false",
"name": "username",
"path": "/",
"value": "admin123",
"version": "0"
}
]
缓存
默认情况下,NSURLSession将数据,如HTTP请求和响应存储在Cache.db数据库中。如果令牌、用户名或任何其他敏感信息已被缓存,该数据库可能包含敏感数据。要查找缓存的信息,请打开应用的数据目录(/var/mobile/Containers/Data/Application/<UUID>
)并转到/Library/Caches/<Bundle Identifier>
。WebKit缓存也存储在Cache.db文件中。Objection可以使用命令sqlite connect Cache.db
打开并与数据库交互,因为它是一个普通的SQLite数据库。
建议禁用缓存这些数据,因为请求或响应中可能包含敏感信息。以下列表显示了实现此目的的不同方法:
- 建议在注销后删除缓存的响应。可以使用苹果提供的名为
removeAllCachedResponses
的方法来执行此操作。您可以按如下方式调用此方法:
URLCache.shared.removeAllCachedResponses()
此方法将从Cache.db文件中删除所有缓存的请求和响应。 2. 如果您不需要使用Cookie的优势,建议只使用URLSession的.ephemeral配置属性,这将禁用保存Cookie和缓存。
苹果文档:
一个临时会话配置对象类似于默认会话配置(请参阅default),不同之处在于相应的会话对象不会将缓存、凭据存储或任何会话相关数据存储到磁盘。相反,会话相关数据存储在RAM中。临时会话仅在您告诉它将URL的内容写入文件时才会将数据写入磁盘。
3. 通过将缓存策略设置为.notAllowed也可以禁用缓存。这将禁用以任何方式存储缓存,无论是在内存中还是在磁盘上。
快照
每当按下主屏幕按钮时,iOS都会拍摄当前屏幕的快照,以便能够更流畅地切换到应用程序。然而,如果当前屏幕中存在敏感数据,它将被保存在图像中(这将持续 跨 重启)。这些快照也可以通过双击主屏幕来访问,以在应用程序之间切换。
除非iPhone已越狱,攻击者需要访问****未锁定的设备才能查看这些屏幕截图。默认情况下,最后一个快照存储在应用程序的沙盒中的Library/Caches/Snapshots/
或Library/SplashBoard/Snapshots
文件夹中(受信任的计算机无法从iOS 7.0访问文件系统)。
防止这种不良行为的一种方法是在拍摄快照之前使用ApplicationDidEnterBackground()
函数放置空白屏幕或删除敏感数据。
以下是一个设置默认屏幕截图的示例修复方法。
Swift:
private var backgroundImage: UIImageView?
func applicationDidEnterBackground(_ application: UIApplication) {
let myBanner = UIImageView(image: #imageLiteral(resourceName: "overlayImage"))
myBanner.frame = UIScreen.main.bounds
backgroundImage = myBanner
window?.addSubview(myBanner)
}
func applicationWillEnterForeground(_ application: UIApplication) {
backgroundImage?.removeFromSuperview()
}
Objective-C:
@property (UIImageView *)backgroundImage;
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIImageView *myBanner = [[UIImageView alloc] initWithImage:@"overlayImage.png"];
self.backgroundImage = myBanner;
self.backgroundImage.bounds = UIScreen.mainScreen.bounds;
[self.window addSubview:myBanner];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self.backgroundImage removeFromSuperview];
}
这会在应用程序进入后台时将背景图像设置为overlayImage.png
。它可以防止敏感数据泄露,因为overlayImage.png
将始终覆盖当前视图。
Keychain
要访问和管理iOS钥匙串,可以使用像Keychain-Dumper这样的工具,适用于越狱设备。此外,Objection提供了ios keychain dump
命令,用于类似的目的。
存储凭据
NSURLCredential类非常适合直接将敏感信息存储在钥匙串中,无需使用NSUserDefault或其他包装器。要在登录后存储凭据,可以使用以下Swift代码:
NSURLCredential *credential;
credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistencePermanent];
[[NSURLCredentialStorage sharedCredentialStorage] setCredential:credential forProtectionSpace:self.loginProtectionSpace];
自定义键盘和键盘缓存
从iOS 8.0开始,用户可以安装自定义键盘扩展,可在设置 > 通用 > 键盘 > 键盘下进行管理。虽然这些键盘提供了扩展功能,但存在记录按键和将数据传输到外部服务器的风险,尽管用户会收到有关需要网络访问的键盘的通知。应用程序可以并且应该限制对自定义键盘用于输入敏感信息。
安全建议:
- 建议禁用第三方键盘以增强安全性。
- 注意默认iOS键盘的自动更正和自动建议功能,这些功能可能会将敏感信息存储在
Library/Keyboard/{locale}-dynamic-text.dat
或/private/var/mobile/Library/Keyboard/dynamic-text.dat
中的缓存文件中。应定期检查这些缓存文件以查找敏感数据。建议通过设置 > 通用 > 重置 > 重置键盘字典来清除缓存数据。 - 拦截网络流量可以揭示自定义键盘是否远程传输按键。
防止文本字段缓存
UITextInputTraits协议提供了管理自动更正和安全文本输入的属性,对于防止敏感信息缓存至关重要。例如,通过禁用自动更正和启用安全文本输入可以实现:
textObject.autocorrectionType = UITextAutocorrectionTypeNo;
textObject.secureTextEntry = YES;
此外,开发人员应确保文本字段,特别是用于输入诸如密码和个人识别码(PIN)等敏感信息的字段,通过将autocorrectionType
设置为UITextAutocorrectionTypeNo
和secureTextEntry
设置为YES
来禁用缓存。
UITextField *textField = [[UITextField alloc] initWithFrame:frame];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
日志
调试代码通常涉及使用日志。存在风险,因为日志可能包含敏感信息。在iOS 6及更早版本中,日志对所有应用程序都是可访问的,存在敏感数据泄漏的风险。现在,应用程序仅限于访问自己的日志。
尽管存在这些限制,拥有物理访问权限的攻击者仍可以利用这一点,通过将设备连接到计算机并读取日志。需要注意的是,即使在应用程序卸载后,日志仍然保留在磁盘上。
为了减轻风险,建议全面与应用程序进行交互,探索其所有功能和输入,以确保没有意外记录敏感信息。
在审查应用程序源代码以查找潜在泄漏时,查找预定义和自定义日志记录语句,使用关键字如NSLog
、NSAssert
、NSCAssert
、fprintf
用于内置函数,以及任何提及Logging
或Logfile
的自定义实现。
监控系统日志
应用程序记录各种可能敏感的信息。要监控这些日志,可以使用工具和命令,如:
idevice_id --list # To find the device ID
idevicesyslog -u <id> (| grep <app>) # To capture the device logs
以下步骤是有用的。此外,Xcode 提供了一种收集控制台日志的方法:
- 打开 Xcode。
- 连接 iOS 设备。
- 导航至 Window -> Devices and Simulators。
- 选择您的设备。
- 触发您正在调查的问题。
- 使用 Open Console 按钮在新窗口中查看日志。
对于更高级的日志记录,连接到设备 shell 并使用 socat 可以提供实时日志监控:
iPhone:~ root# socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
观察日志活动的命令非常宝贵,可用于诊断问题或识别日志中的潜在数据泄漏。
使用 Trickest 可轻松构建并通过全球最先进的社区工具自动化工作流程。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
备份
iOS 集成了自动备份功能,通过 iTunes(适用于 macOS Catalina 及以下版本)、Finder(从 macOS Catalina 开始)或 iCloud,便于创建设备数据副本。这些备份几乎包含所有设备数据,但不包括高度敏感的元素,如 Apple Pay 详细信息和 Touch ID 配置。
安全风险
备份中包含已安装应用及其数据会引发潜在数据泄漏问题,备份修改可能会改变应用功能的风险。建议不要在任何应用程序目录或其子目录中以明文形式存储敏感信息,以减轻这些风险。
从备份中排除文件
默认情况下,Documents/
和 Library/Application Support/
中的文件会被备份。开发人员可以使用 NSURL setResourceValue:forKey:error:
和 NSURLIsExcludedFromBackupKey
从备份中排除特定文件或目录。这一做法对于保护敏感数据不被包含在备份中至关重要。
漏洞测试
要评估应用的备份安全性,首先使用 Finder 创建备份,然后根据苹果官方文档的指导找到备份位置。分析备份中的敏感数据或配置,以确定是否可能影响应用行为。
可以使用命令行工具或应用程序如 iMazing 查找敏感信息。对于加密备份,可以通过检查备份根目录中的 "Manifest.plist" 文件中的 "IsEncrypted" 键来确认是否加密。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
...
<key>Date</key>
<date>2021-03-12T17:43:33Z</date>
<key>IsEncrypted</key>
<true/>
...
</plist>
处理加密备份时,DinoSec的GitHub存储库中提供的Python脚本,如backup_tool.py和backup_passwd.py可能会很有用,尽管可能需要调整以与最新的iTunes/Finder版本兼容。iOSbackup工具是访问受密码保护备份中文件的另一种选择。
修改应用程序行为
通过备份修改改变应用程序行为的示例可在Bither比特币钱包应用中找到,其中UI锁定PIN存储在pin_code键下的net.bither.plist
中。从plist中删除此键并恢复备份将删除PIN要求,提供无限制访问。
敏感数据的内存测试总结
处理存储在应用程序内存中的敏感信息时,限制此数据的暴露时间至关重要。调查内存内容有两种主要方法:创建内存转储和实时分析内存。这两种方法都有各自的挑战,包括在转储过程或分析过程中可能错过关键数据的风险。
检索和分析内存转储
对于越狱和非越狱设备,诸如objection和Fridump等工具允许转储应用程序进程内存。一旦转储完成,分析这些数据需要使用各种工具,具体取决于您正在搜索的信息的性质。
要从内存转储中提取字符串,可以使用strings
或rabin2 -zz
等命令:
# Extracting strings using strings command
$ strings memory > strings.txt
# Extracting strings using rabin2
$ rabin2 -ZZ memory > strings.txt
对于更详细的分析,包括搜索特定数据类型或模式,radare2 提供了广泛的搜索功能:
$ r2 <name_of_your_dump_file>
[0x00000000]> /?
...
运行时内存分析
r2frida 提供了一个强大的替代方案,可以实时检查应用程序的内存,而无需进行内存转储。该工具使得可以直接在运行应用程序的内存上执行搜索命令:
$ r2 frida://usb//<name_of_your_app>
[0x00000000]> /\ <search_command>
加密破解
密钥管理流程不当
一些开发人员会将敏感数据保存在本地存储中,并使用在代码中硬编码/可预测的密钥对其进行加密。这样做是不应该的,因为一些逆向工程可能会使攻击者提取机密信息。
使用不安全和/或已弃用的算法
开发人员不应该使用已弃用的算法来执行授权检查,存储或发送数据。一些这些算法包括:RC4,MD4,MD5,SHA1... 如果用于存储密码的哈希,应该使用抗暴力破解的哈希算法,并加盐。
检查
要执行的主要检查包括查找代码中是否存在硬编码的密码/密钥,或者这些是否是可预测的,以及代码是否使用某种弱的加密算法。
有趣的是,您可以使用objection自动监视一些加密 库,方法如下:
ios monitor crypt
有关iOS加密API和库的更多信息,请访问https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06e-testing-cryptography
本地身份验证
本地身份验证在通过加密方法保护远程端点的访问时发挥着至关重要的作用。关键在于,如果没有适当的实现,本地身份验证机制可能会被绕过。
苹果的**本地身份验证框架和钥匙串**为开发人员提供了强大的API,用于促进用户身份验证对话框的显示和安全处理秘密数据。安全区域(Secure Enclave)为Touch ID提供指纹识别,而Face ID则依赖面部识别,而不会泄露生物识别数据。
要集成Touch ID/Face ID,开发人员有两种API选择:
LocalAuthentication.framework
用于高级用户身份验证,无法访问生物识别数据。Security.framework
用于较低级别的钥匙串服务访问,通过生物识别身份验证来保护秘密数据。各种开源包装器使钥匙串访问更简单。
{% hint style="danger" %}
然而,LocalAuthentication.framework
和Security.framework
都存在漏洞,因为它们主要返回布尔值,而不会传输数据进行身份验证过程,使其容易受到绕过攻击(参见Don't touch me that way, by David Lindner et al)。
{% endhint %}
实现本地身份验证
要提示用户进行身份验证,开发人员应该在**LAContext
类中使用evaluatePolicy
**方法,选择以下之一:
deviceOwnerAuthentication
:提示使用Touch ID或设备密码,如果两者都未启用,则失败。deviceOwnerAuthenticationWithBiometrics
:仅提示使用Touch ID。
从**evaluatePolicy
**返回的布尔值表示成功的身份验证,突显了潜在的安全漏洞。
使用钥匙串进行本地身份验证
在iOS应用程序中实现本地身份验证涉及使用钥匙串API安全存储诸如身份验证令牌之类的秘密数据。该过程确保数据只能由用户使用其设备密码或Touch ID等生物识别身份验证来访问。
钥匙串提供了设置带有SecAccessControl
属性的项目的功能,该属性限制对项目的访问,直到用户通过Touch ID或设备密码成功进行身份验证。这一功能对于增强安全性至关重要。
以下是Swift和Objective-C中的代码示例,演示如何将字符串保存到钥匙串中并从中检索出来,利用这些安全功能。示例特别展示了如何设置访问控制以要求Touch ID身份验证,并确保数据仅在设置的设备上可访问,前提是配置了设备密码。
{% tabs %} {% tab title="Swift" %}
// From https://github.com/mufambisi/owasp-mstg/blob/master/Document/0x06f-Testing-Local-Authentication.md
// 1. create AccessControl object that will represent authentication settings
var error: Unmanaged<CFError>?
guard let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
SecAccessControlCreateFlags.biometryCurrentSet,
&error) else {
// failed to create AccessControl object
return
}
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
var query: [String: Any] = [:]
query[kSecClass as String] = kSecClassGenericPassword
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecAttrAccount as String] = "OWASP Account" as CFString
query[kSecValueData as String] = "test_strong_password".data(using: .utf8)! as CFData
query[kSecAttrAccessControl as String] = accessControl
// 3. save item
let status = SecItemAdd(query as CFDictionary, nil)
if status == noErr {
// successfully saved
} else {
// error while saving
}
{% endtab %}
{% tab title="Objective-C" %}
Objective-C
Setting up the environment
- MacOS: You need a MacOS system to develop iOS applications.
- Xcode: Install Xcode from the App Store.
- iOS Device: You can use a physical iOS device or an emulator like the iOS Simulator.
- Apple Developer Account: You need an Apple Developer account to deploy apps on a physical device.
Tools for Pentesting
- Cycript: A runtime manipulation tool for iOS apps.
- Clutch: A tool for dumping decrypted iOS applications.
- Dumpdecrypted: A tool to decrypt encrypted iOS applications.
- Class-dump-z: A tool to display information of classes in a Mach-O file.
- Frida: A dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers.
- Hopper Disassembler: A reverse engineering tool for macOS and iOS applications.
- MobSF: Mobile Security Framework - An automated, all-in-one mobile application (Android/iOS/Windows) pen-testing framework capable of performing static, dynamic analysis, malware analysis, and web API testing.
Resources
Tutorials
{% endtab %}
// 1. create AccessControl object that will represent authentication settings
CFErrorRef *err = nil;
SecAccessControlRef sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecAccessControlUserPresence,
err);
// 2. define keychain services query. Pay attention that kSecAttrAccessControl is mutually exclusive with kSecAttrAccessible attribute
NSDictionary* query = @{
(_ _bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
(__bridge id)kSecAttrAccount: @"OWASP Account",
(__bridge id)kSecValueData: [@"test_strong_password" dataUsingEncoding:NSUTF8StringEncoding],
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacRef
};
// 3. save item
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, nil);
if (status == noErr) {
// successfully saved
} else {
// error while saving
}
现在我们可以从钥匙串中请求保存的项目。钥匙串服务将向用户显示身份验证对话框,并根据是否提供了合适的指纹来返回数据或nil。
// 1. define query
var query = [String: Any]()
query[kSecClass as String] = kSecClassGenericPassword
query[kSecReturnData as String] = kCFBooleanTrue
query[kSecAttrAccount as String] = "My Name" as CFString
query[kSecAttrLabel as String] = "com.me.myapp.password" as CFString
query[kSecUseOperationPrompt as String] = "Please, pass authorisation to enter this area" as CFString
// 2. get item
var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
if status == noErr {
let password = String(data: queryResult as! Data, encoding: .utf8)!
// successfully received password
} else {
// authorization not passed
}
{% endtab %}
{% tab title="Objective-C" %}
Objective-C
Method Swizzling
Method swizzling is the process of changing the implementation of an existing selector at runtime. This technique can be used for various purposes such as logging method calls, adding new functionality to existing methods, or even bypassing security checks.
Example
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(originalMethod);
SEL swizzledSelector = @selector(swizzledMethod);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzjsonledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)originalMethod {
NSLog(@"Original method implementation");
}
- (void)swizzledMethod {
NSLog(@"Swizzled method implementation");
}
In this example, the originalMethod
is swapped with the swizzledMethod
at runtime using method swizzling.
{% endtab %}
// 1. define query
NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecReturnData: @YES,
(__bridge id)kSecAttrAccount: @"My Name1",
(__bridge id)kSecAttrLabel: @"com.me.myapp.password",
(__bridge id)kSecUseOperationPrompt: @"Please, pass authorisation to enter this area" };
// 2. get item
CFTypeRef queryResult = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &queryResult);
if (status == noErr){
NSData* resultData = ( __bridge_transfer NSData* )queryResult;
NSString* password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
NSLog(@"%@", password);
} else {
NSLog(@"Something went wrong");
}
检测
应用程序中使用的框架还可以通过分析应用程序二进制文件的共享动态库列表来检测。可以使用 otool
来完成此操作:
$ otool -L <AppName>.app/<AppName>
如果应用程序中使用了 LocalAuthentication.framework
,输出将包含以下两行(请记住 LocalAuthentication.framework
在底层使用 Security.framework
):
/System/Library/Frameworks/LocalAuthentication.framework/LocalAuthentication
/System/Library/Frameworks/Security.framework/Security
如果使用Security.framework
,只会显示第二个。
本地身份验证框架绕过
Objection
通过位于此 GitHub 页面的Objection生物识别绕过,可以使用一种技术来绕过LocalAuthentication机制。这种方法的核心是利用Frida来操纵evaluatePolicy
函数,确保它始终产生True
结果,而不考虑实际的身份验证成功与否。这对于规避存在缺陷的生物识别身份验证流程特别有用。
要激活此绕过,使用以下命令:
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # ios ui biometrics_bypass
(agent) Registering job 3mhtws9x47q. Type: ios-biometrics-disable
...itudehacks.DVIAswiftv2.develop on (iPhone: 13.2.3) [usb] # (agent) [3mhtws9x47q] Localized Reason for auth requirement: Please authenticate yourself
(agent) [3mhtws9x47q] OS authentication response: false
(agent) [3mhtws9x47q] Marking OS response as True instead
(agent) [3mhtws9x47q] Biometrics bypass hook complete
这个命令触发了一个序列,Objection注册了一个任务,有效地改变了evaluatePolicy
检查的结果为True
。
Frida
来自DVIA-v2应用程序中对**evaluatePolicy
**的使用示例:
+(void)authenticateWithTouchID {
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = @"Please authenticate yourself";
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Authentication Successful" withTitle:@"Success"];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Authentication Failed !" withTitle:@"Error"];
});
}
}];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[TouchIDAuthentication showAlert:@"Your device doesn't support Touch ID or you haven't configured Touch ID authentication on your device" withTitle:@"Error"];
});
}
}
为了实现本地认证的绕过,编写了一个Frida脚本。该脚本针对evaluatePolicy检查,拦截其回调以确保其返回success=1。通过改变回调的行为,认证检查被有效地绕过。
以下脚本被注入以修改evaluatePolicy方法的结果。它将回调的结果更改为始终指示成功。
// from https://securitycafe.ro/2022/09/05/mobile-pentesting-101-bypassing-biometric-authentication/
if(ObjC.available) {
console.log("Injecting...");
var hook = ObjC.classes.LAContext["- evaluatePolicy:localizedReason:reply:"];
Interceptor.attach(hook.implementation, {
onEnter: function(args) {
var block = new ObjC.Block(args[4]);
const callback = block.implementation;
block.implementation = function (error, value) {
console.log("Changing the result value to true")
const result = callback(1, null);
return result;
};
},
});
} else {
console.log("Objective-C Runtime is not available!");
}
要注入Frida脚本并绕过生物识别身份验证,使用以下命令:
frida -U -f com.highaltitudehacks.DVIAswiftv2 --no-pause -l fingerprint-bypass-ios.js
通过IPC暴露敏感功能
自定义URI处理程序 / Deeplinks / 自定义方案
{% content-ref url="ios-custom-uri-handlers-deeplinks-custom-schemes.md" %} ios-custom-uri-handlers-deeplinks-custom-schemes.md {% endcontent-ref %}
通用链接
{% content-ref url="ios-universal-links.md" %} ios-universal-links.md {% endcontent-ref %}
UIActivity共享
{% content-ref url="ios-uiactivity-sharing.md" %} ios-uiactivity-sharing.md {% endcontent-ref %}
UIPasteboard
{% content-ref url="ios-uipasteboard.md" %} ios-uipasteboard.md {% endcontent-ref %}
应用扩展
{% content-ref url="ios-app-extensions.md" %} ios-app-extensions.md {% endcontent-ref %}
WebViews
{% content-ref url="ios-webviews.md" %} ios-webviews.md {% endcontent-ref %}
序列化和编码
{% content-ref url="ios-serialisation-and-encoding.md" %} ios-serialisation-and-encoding.md {% endcontent-ref %}
网络通信
重要的是检查是否发生未加密的通信,以及应用程序是否正确验证服务器的TLS证书。
要检查这类问题,可以使用像Burp这样的代理:
{% content-ref url="burp-configuration-for-ios.md" %} burp-configuration-for-ios.md {% endcontent-ref %}
主机名检查
验证TLS证书的一个常见问题是检查证书是否由受信任的CA签名,但未检查证书的主机名是否为正在访问的主机名。
为了使用Burp检查此问题,在iPhone上信任Burp CA后,您可以为不同主机名使用Burp创建新证书并使用它。如果应用程序仍然正常工作,则存在漏洞。
证书固定
如果应用程序正确使用SSL Pinning,则应用程序仅在证书符合预期时才能正常工作。在测试应用程序时,这可能是一个问题,因为Burp将提供自己的证书。
为了绕过此保护,在越狱设备内部,您可以安装应用程序SSL Kill Switch或安装Burp Mobile Assistant。
您还可以使用objection的ios sslpinning disable
杂项
- 在**
/System/Library
**中,您可以找到手机上系统应用程序使用的框架 - 用户从App Store安装的应用程序位于**
/User/Applications
**中 - **
/User/Library
**包含用户级应用程序保存的数据 - 您可以访问**
/User/Library/Notes/notes.sqlite
**以阅读应用程序内保存的笔记。 - 在已安装应用程序的文件夹中(
/User/Applications/<APP ID>/
),您可以找到一些有趣的文件:iTunesArtwork
:应用程序使用的图标iTunesMetadata.plist
:App Store中使用的应用程序信息/Library/*
:包含首选项和缓存。在**/Library/Cache/Snapshots/*
**中,您可以找到应用程序在发送到后台之前执行的快照。
热修补/强制更新
开发人员可以远程立即修补其应用程序的所有安装,而无需重新提交应用程序到App Store并等待批准。
为此,通常使用JSPatch。 但也有其他选项,如Siren和react-native-appstore-version-checker。
这是一种危险的机制,可能会被恶意第三方SDK滥用,因此建议检查使用哪种方法进行自动更新(如果有)并进行测试。 您可以尝试下载应用程序的先前版本以进行此目的。
第三方
第三方SDK的一个重要挑战是对其功能的缺乏细粒度控制。开发人员面临选择:要么集成SDK并接受其所有功能,包括潜在的安全漏洞和隐私问题,要么完全放弃其好处。通常,开发人员无法自行修补这些SDK中的漏洞。此外,随着SDK在社区中获得信任,一些可能开始包含恶意软件。
第三方SDK提供的服务可能包括用户行为跟踪、广告显示或用户体验增强。然而,这带来了风险,因为开发人员可能并不完全了解这些库执行的代码,从而导致潜在的隐私和安全风险。限制与第三方服务共享的信息至必要信息,并确保不会泄露敏感数据,这一点至关重要。
第三方服务的实施通常有两种形式:独立库或完整SDK。为了保护用户隐私,与这些服务共享的任何数据都应该匿名化,以防止泄露个人可识别信息(PII)。
要识别应用程序使用的库,可以使用**otool
**命令。应该针对应用程序及其使用的每个共享库运行此工具,以发现其他库。
otool -L <application_path>
参考资料和更多资源
- https://mobile-security.gitbook.io/mobile-security-testing-guide/ios-testing-guide/0x06b-basic-security-testing#information-gathering
- iOS & 移动应用渗透测试 - INE
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0057/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0058/
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0059/
- https://mas.owasp.org/MASTG/iOS/0x06d-Testing-Data-Storage
- https://coderwall.com/p/kjb3lw/storing-password-in-keychain-the-smart-way
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0055/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0053
- https://mas.owasp.org/MASTG/techniques/ios/MASTG-TECH-0060/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0060
- https://mas.owasp.org/MASTG/Android/0x05f-Testing-Local-Authentication/
- https://mas.owasp.org/MASTG/tests/ios/MASVS-AUTH/MASTG-TEST-0064
- https://medium.com/securing/bypassing-your-apps-biometric-checks-on-ios-c2555c81a2dc
- https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0054
- https://github.com/ivRodriguezCA/RE-iOS-Apps/ IOS 免费课程(https://syrion.me/blog/ios-swift-antijailbreak-bypass-frida/)
- https://www.sans.org/reading-room/whitepapers/testing/ipwn-apps-pentesting-ios-applications-34577
- https://www.slideshare.net/RyanISI/ios-appsecurityminicourse
- https://github.com/prateek147/DVIA
- https://github.com/prateek147/DVIA-v2
- https://github.com/OWASP/MSTG-Hacking-Playground%20
- OWASP iGoat https://github.com/OWASP/igoat <<< Objective-C 版本 https://github.com/OWASP/iGoat-Swift <<< Swift 版本
- https://github.com/authenticationfailure/WheresMyBrowser.iOS
- https://github.com/nabla-c0d3/ssl-kill-switch2
使用 Trickest 可以轻松构建和 自动化工作流程,使用世界上 最先进 的社区工具。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
从零开始学习 AWS 黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)!
支持 HackTricks 的其他方式:
- 如果您想在 HackTricks 中看到您的 公司广告 或 下载 PDF 版本的 HackTricks,请查看 订阅计划!
- 获取 官方 PEASS & HackTricks 商品
- 探索 PEASS 家族,我们的独家 NFTs
- 加入 💬 Discord 群组 或 电报群组 或 关注 我的 Twitter 🐦 @carlospolopm.
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享您的黑客技巧。