MASTG-TECH-0096: 进程探索
在测试应用时,进程探索可以为测试人员提供对应用进程内存的深入了解。它可以通过运行时检测来实现,并允许执行诸如以下任务:
- 检索内存映射和加载的库。
- 搜索特定数据的出现位置。
- 在进行搜索后,获取内存映射中某个偏移量的位置。
- 执行内存转储,并离线检查或逆向工程二进制数据。
- 在二进制文件或框架运行时对其进行逆向工程。
如您所见,这些任务更具有支持性和/或被动性,它们将帮助我们收集数据和信息,以支持其他技术。因此,它们通常与其他技术(如方法钩取)结合使用。
在以下各节中,您将使用 r2frida从应用运行时直接检索信息。首先启动一个到目标应用的r2frida会话(例如, iGoat-Swift),该应用应在您的 iPhone 上运行(通过 USB 连接)。使用以下命令
r2 frida://usb//iGoat-Swift
内存映射和检查¶
您可以通过运行 :dm
检索应用的内存映射
[0x00000000]> :dm
0x0000000100b7c000 - 0x0000000100de0000 r-x /private/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app/iGoat-Swift
0x0000000100de0000 - 0x0000000100e68000 rw- /private/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app/iGoat-Swift
0x0000000100e68000 - 0x0000000100e97000 r-- /private/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app/iGoat-Swift
...
0x0000000100ea8000 - 0x0000000100eb0000 rw-
0x0000000100eb0000 - 0x0000000100eb4000 r--
0x0000000100eb4000 - 0x0000000100eb8000 r-x /usr/lib/TweakInject.dylib
0x0000000100eb8000 - 0x0000000100ebc000 rw- /usr/lib/TweakInject.dylib
0x0000000100ebc000 - 0x0000000100ec0000 r-- /usr/lib/TweakInject.dylib
0x0000000100f60000 - 0x00000001012dc000 r-x /private/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app/Frameworks/Realm.framework/Realm
在搜索或探索应用内存时,您可以随时验证当前偏移量在内存映射中的位置。您可以运行 :dm.
,而不是在列表中记录和搜索内存地址。您可以在以下“内存搜索”部分中找到一个示例。
如果您只对应用已加载的模块(二进制文件和库)感兴趣,则可以使用命令 :il
列出所有模块
[0x00000000]> :il
0x0000000100b7c000 iGoat-Swift
0x0000000100eb4000 TweakInject.dylib
0x00000001862c0000 SystemConfiguration
0x00000001847c0000 libc++.1.dylib
0x0000000185ed9000 Foundation
0x000000018483c000 libobjc.A.dylib
0x00000001847be000 libSystem.B.dylib
0x0000000185b77000 CFNetwork
0x0000000187d64000 CoreData
0x00000001854b4000 CoreFoundation
0x00000001861d3000 Security
0x000000018ea1d000 UIKit
0x0000000100f60000 Realm
正如您可能期望的那样,您可以将库的地址与内存映射相关联:例如, iGoat-Swift的主应用名为“iGoat-Swift”,位于0x0000000100b7c000
,Realm Framework位于0x0000000100f60000
。
您还可以使用 objection for iOS来显示相同的信息。
$ objection --gadget OWASP.iGoat-Swift explore
OWASP.iGoat-Swift on (iPhone: 11.1.2) [usb] # memory list modules
Save the output by adding `--json modules.json` to this command
Name Base Size Path
-------------------------------- ----------- -------------------- ------------------------------------------------------------------------------
iGoat-Swift 0x100b7c000 2506752 (2.4 MiB) /var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGo...
TweakInject.dylib 0x100eb4000 16384 (16.0 KiB) /usr/lib/TweakInject.dylib
SystemConfiguration 0x1862c0000 446464 (436.0 KiB) /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguratio...
libc++.1.dylib 0x1847c0000 368640 (360.0 KiB) /usr/lib/libc++.1.dylib
内存搜索¶
内存搜索是一种非常有用的技术,可用于测试可能存在于应用内存中的敏感数据。
请参阅 r2frida 中关于搜索命令的帮助 (:/?
),以了解搜索命令并获取选项列表。以下仅显示了其中的一部分
[0x00000000]> :/?
/ search
/j search json
/w search wide
/wj search wide json
/x search hex
/xj search hex json
...
您可以使用搜索设置 :e~search
来调整搜索。例如,:e search.quiet=true;
将仅打印结果并隐藏搜索进度
[0x00000000]> :e~search
e search.in=perm:r--
e search.quiet=false
现在,我们将继续使用默认设置,并专注于字符串搜索。在第一个示例中,您可以首先搜索您知道应该位于应用主二进制文件中的内容(例如, iGoat-Swift 应用的名称)
[0x00000000]> :/ iGoat
Searching 5 bytes: 69 47 6f 61 74
Searching 5 bytes in [0x0000000100b7c000-0x0000000100de0000]
...
hits: 509
0x100d7d332 hit2_0 iGoat_Swift24StringAnalysisExerciseVCC
0x100d7d3b2 hit2_1 iGoat_Swift28BrokenCryptographyExerciseVCC
0x100d7d442 hit2_2 iGoat_Swift23BackgroundingExerciseVCC
0x100d7d4b2 hit2_3 iGoat_Swift9AboutCellC
0x100d7d522 hit2_4 iGoat_Swift12FadeAnimatorV
现在获取第一个命中,跳转到它并检查您在内存映射中的当前位置
[0x00000000]> s 0x100d7d332
[0x100d7d332]> :dm.
0x0000000100b7c000 - 0x0000000100de0000 r-x /private/var/containers/Bundle/Application/3ADAF47D-A734-49FA-B274-FBCA66589E67/iGoat-Swift.app/iGoat-Swift
正如预期的那样,您位于主 iGoat-Swift 二进制文件 (r-x, read and execute) 的区域中。在上一节中,您看到主二进制文件位于 0x0000000100b7c000
和 0x0000000100e97000
之间。
现在,对于第二个示例,您可以搜索不在应用二进制文件或任何加载的库中的内容,通常是用户输入。打开 iGoat-Swift 应用,并在菜单中导航到身份验证->远程身份验证->开始。您将在那里找到一个可以覆盖的密码字段。写入字符串“owasp-mstg”,但暂时不要单击登录。执行以下两个步骤。
[0x00000000]> :/ owasp-mstg
hits: 1
0x1c06619c0 hit3_0 owasp-mstg
实际上,该字符串可以在地址 0x1c06619c0
找到。使用 s
跳转到那里,并使用 :dm.
检索当前内存区域。
[0x100d7d332]> s 0x1c06619c0
[0x1c06619c0]> :dm.
0x00000001c0000000 - 0x00000001c8000000 rw-
现在您知道该字符串位于内存映射的 rw-(读写)区域中。
此外,您可以搜索 字符串的宽版本 (/w
) 的出现次数,并再次检查它们的内存区域
这次我们为所有匹配 glob
hit5_*
的@@
命中运行:dm.
命令。
[0x00000000]> /w owasp-mstg
Searching 20 bytes: 6f 00 77 00 61 00 73 00 70 00 2d 00 6d 00 73 00 74 00 67 00
Searching 20 bytes in [0x0000000100708000-0x000000010096c000]
...
hits: 2
0x1020d1280 hit5_0 6f0077006100730070002d006d00730074006700
0x1030c9c85 hit5_1 6f0077006100730070002d006d00730074006700
[0x00000000]> :dm.@@ hit5_*
0x0000000102000000 - 0x0000000102100000 rw-
0x0000000103084000 - 0x00000001030cc000 rw-
它们位于不同的 rw- 区域中。请注意,搜索字符串的宽版本有时是找到它们的唯一方法,您将在下一节中看到。
内存搜索对于快速了解某些数据是否位于主应用二进制文件、共享库或其他区域中非常有用。您也可以使用它来测试应用在内存中保存数据方面的行为。例如,您可以继续上一个示例,这次单击“登录”,然后再次搜索数据的出现次数。此外,您可以检查在登录完成后是否仍然可以在内存中找到这些字符串,以验证此敏感数据在使用后是否已从内存中擦除。
内存转储¶
您可以使用 objection for iOS 和 Fridump 转储应用的进程内存。要在非越狱设备上利用这些工具,必须使用 frida-gadget.so
重新打包 Android 应用并重新签名。 自动将 Frida Gadget 注入 IPA中详细介绍了此过程。要在越狱手机上使用这些工具,只需安装并运行 frida-server。
使用 objection 可以使用命令 memory dump all
转储设备上运行进程的所有内存。
$ objection explore
iPhone on (iPhone: 10.3.1) [usb] # memory dump all /Users/foo/memory_iOS/memory
Dumping 768.0 KiB from base: 0x1ad200000 [####################################] 100%
Memory dumped to file: /Users/foo/memory_iOS/memory
或者,您可以使用 Fridump。首先,您需要要转储的应用的名称,可以使用 frida-ps
获取。
$ frida-ps -U
PID Name
---- ------
1026 Gadget
之后,在 Fridump 中指定应用名称。
$ python3 fridump.py -u Gadget -s
Current Directory: /Users/foo/PentestTools/iOS/fridump
Output directory is set to: /Users/foo/PentestTools/iOS/fridump/dump
Creating directory...
Starting Memory dump...
Progress: [##################################################] 100.0% Complete
Running strings on all files:
Progress: [##################################################] 100.0% Complete
Finished! Press Ctrl+C
添加 -s
标志时,所有字符串都从转储的原始内存文件中提取,并添加到文件 strings.txt
,该文件存储在 Fridump 的转储目录中。
在这两种情况下,如果在 radare2 中打开该文件,您可以使用其搜索命令 (/
)。请注意,首先我们执行了一个标准的字符串搜索,但没有成功,接下来我们搜索 宽字符串,它成功地找到了我们的字符串“owasp-mstg”。
$ r2 memory_ios
[0x00000000]> / owasp-mstg
Searching 10 bytes in [0x0-0x628c000]
hits: 0
[0x00000000]> /w owasp-mstg
Searching 20 bytes in [0x0-0x628c000]
hits: 1
0x0036f800 hit4_0 6f0077006100730070002d006d00730074006700
接下来,我们可以使用 s 0x0036f800
或 s hit4_0
跳转到它的地址,并使用 psw
(表示打印宽字符串)打印它,或者使用 px
打印其原始十六进制值
[0x0036f800]> psw
owasp-mstg
[0x0036f800]> px 48
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x0036f800 6f00 7700 6100 7300 7000 2d00 6d00 7300 o.w.a.s.p.-.m.s.
0x0036f810 7400 6700 0000 0000 0000 0000 0000 0000 t.g.............
0x0036f820 0000 0000 0000 0000 0000 0000 0000 0000 ................
请注意,为了使用 strings
命令找到此字符串,您必须使用 -e
标志指定编码,在这种情况下,l
表示 16 位小端字符。
$ strings -e l memory_ios | grep owasp-mstg
owasp-mstg