iOS取证技巧:在无损的情况下完整导出SQLite数据库

栏目: 数据库 · 发布时间: 5年前

内容简介:在为了运行完整的实验,你需要安装以下工具:

上一篇文章 中,我向大家介绍了有关利用iOS DeveloperImage中一些特性的方法,其中包括在已越狱设备上启动带有自定义环境变量的App。说实话,我的最初动机是为了寻找沙箱逻辑问题,但失败了。值得庆幸的是我发现了另一个非常实用的技巧,即通过利用其中的一些特性来提取 SQLite 数据库。该方案需要屏幕解锁和可信USB连接。

为了运行完整的实验,你需要安装以下工具:

https://github.com/libimobiledevice/libimobiledevice

https://github.com/libimobiledevice/ideviceinstaller

https://github.com/emonti/afcclient (可选。如果你不想自己编写libimobiledevice的代码,就用这个)

SQLite日志记录

iOS上当前内置的SQLite支持调试选项:如果设置了 SQLITE_SQLLOG_DIR 环境,则每个数据库在给定目录中都会有一个副本,且 sql 查询为纯文本形式。

sqlite文档: https://www.sqlite.org/src/doc/trunk/src/test_sqllog.c

我们的实验从一个越狱设备开始。只需启动带有SQLITE_SQLLOG_DIR的Gmail应用程序,指向它有权写入的位置:

iOS取证技巧:在无损的情况下完整导出SQLite数据库

修改上一篇文章中的脚本,向环境添加一个新密钥:

const env = ObjC.classes.NSMutableDictionary.alloc().init();
env.setObject_forKey_(
  ObjC.classes.NSString.stringWithString_('/private/var/mobile/Containers/Data/Application/{THE_ACTUAL_UUID_ON_YOUR_DEVICE}/tmp'),
  ObjC.classes.NSString.stringWithString_('SQLITE_SQLLOG_DIR'));

以下是为目录生成的内容:

hello:/private/var/mobile/Containers/Data/Application/.../tmp root# ls
WebKit      sqllog_05860_00000.sql  sqllog_05860_00003.sql  sqllog_05860_01.db
sqllog_05860.idx    sqllog_05860_00001.sql  sqllog_05860_00004.sql  sqllog_05860_02.db
sqllog_05860_00.db  sqllog_05860_00002.sql  sqllog_05860_00005.sql  sqllog_05860_03.db

文件名中的05860是pid,格式化为固定的5位数。idx文件是原始数据库的映射索引。

root# cat sqllog_05860.idx
0 /private/var/mobile/Containers/Shared/AppGroup/21805C48-3DD1-4973-BDB8-F26441BE74B3/GIPPhenotype/phenotype.db
1 /var/mobile/Containers/Data/Application/E89CEF28-30BA-41F8-BDB3-BD05E0598D32/Library/Application Support/data/<a href="/cdn-cgi/l/email-protection" data-cfemail="bdd7d2d5d3ced0d4c9d5fdd2c8c9d1d2d2d693ded2d0">[email protected]</a>/sqlitedb
2 /var/mobile/Containers/Data/Application/E89CEF28-30BA-41F8-BDB3-BD05E0598D32/Library/Application Support/data/<a href="/cdn-cgi/l/email-protection" data-cfemail="98f2f7f0f6ebf5f1ecf0d8f7edecf4f7f7f3b6fbf7f5">[email protected]</a>/imapsqlitedb
3 /private/var/mobile/Containers/Data/Application/E89CEF28-30BA-41F8-BDB3-BD05E0598D32/Library/Caches/com.google.Gmail/Cache.d

例如,所有 /var/mobile/Containers/Data/Application/E89CEF28–30BA-41F8-BDB3-BD05E0598D32/Library/Application Support/data/[email protected]/sqlitedb 的查询被记录在了sqllog_05860_00000.sql文件中。

iOS取证技巧:在无损的情况下完整导出SQLite数据库

sqllog_05860_00.db是其副本。

iOS取证技巧:在无损的情况下完整导出SQLite数据库

未越狱设备

现在问题是,iOS上的应用程序被“监禁”在容器中,如果没有完整备份将仍然无法访问这些容器。每个规则都有一个例外,沙箱配置文件也不例外。

某些内置应用程序有写入权限到 /var/mobile/Media/iTunes_Control/iTunes 目录。

iOS取证技巧:在无损的情况下完整导出SQLite数据库

以及一些应用程序还拥有 com.apple.security.exception.files.absolute-path.read-write 或 com.apple.security.exception.files.home-relative-path.read-write 权限。

你可以通过以下命令读取这些权限。

ideviceinstaller -l -o list_system -o xml

VioceMemo:

<key>com.apple.security.exception.files.absolute-path.read-write</key>
<array>
    <string>/private/var/mobile/Media/Recordings/</string>
</array>
<key>platform-application</key>
<true/>

MobileSafari:

<key>com.apple.security.exception.files.home-relative-path.read-write</key>
   <array>
    <string>/Library/com.apple.itunesstored/</string>
    <string>/Library/com.apple.iTunesCloud/</string>
    <string>/Library/Caches/com.apple.Music/</string>
    <string>/Library/Cookies/</string>
    <string>/Media/</string>
    <string>/Library/Caches/com.apple.Radio/</string>
    <string>/Library/Caches/com.apple.iTunesStore/</string>
    <string>/Library/Caches/sharedCaches/com.apple.Radio.RadioImageCache/</string>
    <string>/Library/Caches/sharedCaches/com.apple.Radio.RadioRequestURLCache/</string>
    <string>/Library/com.apple.MediaSocial/</string>
    <string>/Library/DeviceRegistry/</string>
    <string>/Library/Logs/MediaServices/</string>
   </array>

iOS允许在 /var/mobile/Media 中进行沙箱文件访问。许多第三方iPhone管理 工具 允许你直接操作此位置,甚至还会提供一个GUI界面。

➜  afcclient git:(master) ✗ ./afcclient mkdir Downloads/SQLite

另一个可读的位置是CrashReporter。你可以使用idevicecrashreport获取文件。

iOS取证技巧:在无损的情况下完整导出SQLite数据库

但需要提醒大家的是,并非所有内置的应用程序都有这些例外,更别说是那些第三方应用了。

Demo

在测试期间启动Instruments,并使用上一篇文章中的frida脚本将bundle ID更改为目标。

/*
run Instruments.app, then
frida Instruments -l msg.js
*/
function getDevice() {
  const devices = ObjC.classes.XRDeviceDiscovery.availableDevices();
  const count = devices.count().valueOf();
  for (var i = 0; i < count; i++) {
    var device = devices.objectAtIndex_(i);
    if (device.platformName().toString() === 'iPhoneOS' && device.connection()) {
      return device;
    }
  }
  throw new Error('unable to find device');
}

const newMsgFunc = ObjC.classes.DTXMessage['+ messageWithSelector:objectArguments:'].implementation;
const newMsg = new NativeFunction(newMsgFunc, 'pointer',
  ['pointer', 'pointer', 'pointer', '...', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer']);

const opt = ObjC.classes.NSMutableDictionary.alloc().init();
opt.setObject_forKey_(0, ObjC.classes.NSString.stringWithString_('StartSuspendedKey')); // required

const args = ObjC.classes.NSMutableArray.alloc().init();
args.addObject_(ObjC.classes.NSString.stringWithString_('--if-you-need-some-thing')); // argv

const env = ObjC.classes.NSMutableDictionary.alloc().init();
env.setObject_forKey_(
  ObjC.classes.NSString.stringWithString_('3'),
  ObjC.classes.NSString.stringWithString_('CFNETWORK_DIAGNOSTICS')); // environment variables

const msg = new ObjC.Object(newMsg(
  ObjC.classes.DTXMessage,
  ObjC.selector('+ messageWithSelector:objectArguments:'),
  ObjC.selector('launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:'),

  ObjC.classes.NSString.stringWithString_('this makes no sense'), // path, SpringBoard simply ignores it
  ObjC.classes.NSString.stringWithString_('com.apple.calculator'), // bundle id, must be already installed
  ObjC.classes.NSDictionary.dictionaryWithDictionary_(env),
  args.copy(),
  ObjC.classes.NSDictionary.dictionaryWithDictionary_(opt),
  NULL
))

const channel = getDevice().connection().makeChannelWithIdentifier_(
  'com.apple.instruments.server.services.processcontrol.feature.deviceio') // channel id

channel.sendControlSync_replyHandler_(msg, new ObjC.Block({
  retType: 'void',
  argTypes: ['object', 'pointer'],
  implementation: function(reply, len) {
    console.log('reply', reply.payloadObject())
  }
}))

com.apple.mobilesafari

这里有Safari浏览器状态,书签,历史记录,每个站点首选项,HTML5本地存储甚至缓存。请注意,通常Cache.db不会包含在备份中,并且它是以纯文本格式存储http请求的。

➜  afcclient git:(master) ✗ ./afcclient mkdir iTunes_Control/iTunes/safari
Created directory: iTunes_Control/iTunes/safari
➜  afcclient git:(master) ✗ ./afcclient cat iTunes_Control/iTunes/safari/sqllog_02343.idx
0 /private/var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/Image Cache/Favicons/Favicons.db
1 /var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/Safari/BrowserState.db
2 /private/var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/Image Cache/Touch Icons/TouchIconCacheSettings.db
3 /private/var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/Image Cache/Password Icons/TouchIconCacheSettings.db
4 /var/mobile/Library/Safari/Bookmarks.db
5 /private/var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/Safari/History.db
6 /var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/WebKit/WebsiteData/LocalStorage/https_mobile.twitter.com_0.localstorage
7 /private/var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/Safari/PerSitePreferences.db
8 /private/var/mobile/Containers/Data/Application/9210B36C-89E2-4728-9831-40CAA961C15E/Library/Caches/com.apple.mobilesafari/Cache.db

com.apple.mobilemail

➜  afcclient git:(master) ✗ ./afcclient cat Mail/sqllog_04465.idx
0 /var/mobile/Library/Mail/Envelope Index
1 /var/mobile/Library/Mail/Protected Index
2 /var/mobile/Library/DeviceRegistry/5CFB9E7E-C465-4A92-B3ED-C744367AB766/NanoMail/registry.sqlite
3 /var/mobile/Library/AddressBook/AddressBook.sqlitedb

com.apple.mobilephone

地址簿和通话记录:

hello:~ root# procexp all fds | grep -i sms.db
IMDPersistenceA    812 FD  4u  /private/var/mobile/Library/SMS/sms.db @0x0
IMDPersistenceA    812 FD  5u  /private/var/mobile/Library/SMS/sms.db-wal @0x0
IMDPersistenceA    812 FD  6u  /private/var/mobile/Library/SMS/sms.db-shm @0x0
hello:~ root# ps aux | grep 812
mobile           812   0.0  0.0  1664672   1296   ??  Ss   22Oct18   0:01.77 /System/Library/PrivateFrameworks/IMDPersistence.framework/XPCServices/IMDPersistenceAgent.xpc/IMDPersistenceAgent
root            6008   0.0  0.1  1593504   1536 s000  S+    2:50PM   0:00.01 grep 812
hello:~ root#
➜  afcclient git:(master) ✗ ./afcclient mkdir iTunes_Control/iTunes/Phone
Created directory: iTunes_Control/iTunes/Phone
➜  afcclient git:(master) ✗./afcclient cat iTunes_Control/iTunes/Phone/sqllog_04322.idx
0 /var/mobile///Library/CallHistoryDB/CallHistory.storedata
1 /var/mobile///Library/CallHistoryDB/CallHistoryTemp.storedata
2 /var/mobile/Library/AddressBook/AddressBook.sqlitedb

但你无法提取sms.db,因为它属于xpc服务IMDPersistenceAgent。消息应用com.apple.MobileSMS通过XPC与其通信,而不是打开数据库。

*参考来源: medium ,FB小编secist编译,转载请注明来自FreeBuf.COM


以上所述就是小编给大家介绍的《iOS取证技巧:在无损的情况下完整导出SQLite数据库》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Ruby on Rails Tutorial

Ruby on Rails Tutorial

Michael Hartl / Addison-Wesley Professional / 2012-8-6 / USD 44.99

"Ruby on Rails(TM) Tutorial by Michael Hartl has become a must-read for developers learning how to build Rails apps." -Peter Cooper, Editor of Ruby Inside Using Rails, developers can build web applica......一起来看看 《Ruby on Rails Tutorial》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具