去年的一月,NetSPI在博客中发表了一篇博文——《从IOS设备中提取数据》。尽管NetSPI提供了一篇能让这个过程变得十分简单的脚本,但是它只能在iOS7或者更低的版本中使用并且要求要有GDB。
(GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具)。现在,GDB在iOS8中已经没有了。。。幸运的是,这里还有其他方法来实现GDB的功能并且从运行iOS8系列系统的苹果手机中提取数据。但是它有如下要求:
当然,你还需要一个已经越狱了的iPhone或者iPad。关于这方面的操作我在这就不再缀续了。
首先,开启tcprelay,这样我们就可以通过USB来连接苹果设备。
$ ./tcprelay.py -t 22:2222 1234:1234 Forwarding local port 2222 to remote port 22 Forwarding local port 1234 to remote port 1234 Incoming connection to 2222 Waiting for devices... Connecting to device <MuxDevice: ID 17 ProdID 0x12a8 Serial '0ea150b00ba3deeacb42f399492b7990416a0c87' Location 0x14120000> Connection established, relaying data Incoming connection to 1234 Waiting for devices... Connecting to device <MuxDevice: ID 17 ProdID 0x12a8 Serial '0ea150b00ba3deeacb42f399492b7990416a0c87' Location 0x14120000> Connection established, relaying data
“tcprelay.py -t 22:2222 1234:1234”这条命令是将两个本地端口重定向。前一个端口指令是将22号端口的ssh服务重定向到2222端口实现。后一个是开启debugserver服务端口。
然后你要连接上iOS设备并且开启debug服务(这里我默认已经将软件拷到电脑上了)。如果你没有拷到电脑上,你可以用scp来拷贝。
$ ssh root@127.0.0.1 -p 2222
root@127.0.0.1's password:
如果app已经在运行了,可以通过‘ps aux | grep <appname>’指令来查看app的名称并且将其连接到debugserver服务(注意是app的名称而不是PID):
root# ./debugserver *:1234 -a appname
debugserver-@(#)PROGRAM:debugserver PROJECT:debugserver-320.2.89
for arm64.
Attaching to process appname...
Listening to port 1234 for a connection from *...
Waiting for debugger instructions for process 0.
‘./debugserver *:1234 -a appname’ 命令是告诉软件开启1234端口并且连接到名为‘appname’的app上。这个过程也许要花费一些时间,请耐心等待。在Mac电脑中开启LLDB并且连接到运行在ios设备中的debugserver软件中。
现在,我们有中继端口1324并且debugserver在监听本地的1234端口。
$ lldb
(lldb) process connect connect://127.0.0.1:1234
Process 2017 stopped
* thread #1: tid = 0x517f9, 0x380f54f0 libsystem_kernel.dylib mach_msg_trap + 20, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x380f54f0 libsystem_kernel.dylib mach_msg_trap + 20
libsystem_kernel.dylib mach_msg_trap:
-> 0x380f54f0 <+20>: pop {r4, r5, r6, r8}
0x380f54f4 <+24>: bx lr
libsystem_kernel.dylib mach_msg_overwrite_trap:
0x380f54f8 <+0>: mov r12, sp
0x380f54fc <+4>: push {r4, r5, r6, r8}
现在你可以从app使用的内存中下载数据了。
(lldb) image dump sections appname
Sections for '/private/var/mobile/Containers/Bundle/Application/F3CFF345-71FC-47C4-B1FB-3DAC523C7627/appname.app/appname(0x0000000000047000)' (armv7):
SectID Type Load Address File Off. File Size Flags Section Name
---------- ---------------- --------------------------------------- ---------- ---------- ---------- ----------------------------
0x00000100 container [0x0000000000000000-0x0000000000004000)* 0x00000000 0x00000000 0x00000000 appname.__PAGEZERO
0x00000200 container [0x0000000000047000-0x00000000001af000) 0x00000000 0x00168000 0x00000000 appname.__TEXT
0x00000001 code [0x000000000004e6e8-0x000000000016d794) 0x000076e8 0x0011f0ac 0x80000400 appname.__TEXT.__text
0x00000002 code [0x000000000016d794-0x000000000016e5e0) 0x00126794 0x00000e4c 0x80000400 appname.__TEXT.__stub_helper
0x00000003 data-cstr [0x000000000016e5e0-0x0000000000189067) 0x001275e0 0x0001aa87 0x00000002 appname.__TEXT.__cstring
0x00000004 data-cstr [0x0000000000189067-0x00000000001a5017) 0x00142067 0x0001bfb0 0x00000002 appname.__TEXT.__objc_methname
0x00000005 data-cstr [0x00000000001a5017-0x00000000001a767a) 0x0015e017 0x00002663 0x00000002 appname.__TEXT.__objc_classname
0x00000006 data-cstr [0x00000000001a767a-0x00000000001abe0c) 0x0016067a 0x00004792 0x00000002 appname.__TEXT.__objc_methtype
0x00000007 regular [0x00000000001abe10-0x00000000001ac1b8) 0x00164e10 0x000003a8 0x00000000 appname.__TEXT.__const
0x00000008 regular [0x00000000001ac1b8-0x00000000001aeb20) 0x001651b8 0x00002968 0x00000000 appname.__TEXT.__gcc_except_tab
0x00000009 regular [0x00000000001aeb20-0x00000000001aeb46) 0x00167b20 0x00000026 0x00000000 appname.__TEXT.__ustring
0x0000000a code [0x00000000001aeb48-0x00000000001af000) 0x00167b48 0x000004b8 0x80000408 appname.__TEXT.__symbolstub1
0x00000300 container [0x00000000001af000-0x00000000001ef000) 0x00168000 0x00040000 0x00000000 appname.__DATA
0x0000000b data-ptrs [0x00000000001af000-0x00000000001af4b8) 0x00168000 0x000004b8 0x00000007 appname.__DATA.__lazy_symbol
0x0000000c data-ptrs [0x00000000001af4b8-0x00000000001af810) 0x001684b8 0x00000358 0x00000006 appname.__DATA.__nl_symbol_ptr
0x0000000d regular [0x00000000001af810-0x00000000001b2918) 0x00168810 0x00003108 0x00000000 appname.__DATA.__const
0x0000000e objc-cfstrings [0x00000000001b2918-0x00000000001ba8d8) 0x0016b918 0x00007fc0 0x00000000 appname.__DATA.__cfstring
0x0000000f data-ptrs [0x00000000001ba8d8-0x00000000001baf1c) 0x001738d8 0x00000644 0x10000000 appname.__DATA.__objc_classlist
0x00000010 regular [0x00000000001baf1c-0x00000000001baf4c) 0x00173f1c 0x00000030 0x10000000 appname.__DATA.__objc_nlclslist
0x00000011 regular [0x00000000001baf4c-0x00000000001bafa0) 0x00173f4c 0x00000054 0x10000000 appname.__DATA.__objc_catlist
0x00000012 regular [0x00000000001bafa0-0x00000000001bafa4) 0x00173fa0 0x00000004 0x10000000 appname.__DATA.__objc_nlcatlist
0x00000013 regular [0x00000000001bafa4-0x00000000001bb078) 0x00173fa4 0x000000d4 0x00000000 appname.__DATA.__objc_protolist
0x00000014 regular [0x00000000001bb078-0x00000000001bb080) 0x00174078 0x00000008 0x00000000 appname.__DATA.__objc_imageinfo
0x00000015 data-ptrs [0x00000000001bb080-0x00000000001e0d40) 0x00174080 0x00025cc0 0x00000000 appname.__DATA.__objc_const
0x00000016 data-cstr-ptr [0x00000000001e0d40-0x00000000001e4420) 0x00199d40 0x000036e0 0x10000005 appname.__DATA.__objc_selrefs
0x00000017 regular [0x00000000001e4420-0x00000000001e442c) 0x0019d420 0x0000000c 0x00000000 appname.__DATA.__objc_protorefs
0x00000018 data-ptrs [0x00000000001e442c-0x00000000001e4ab8) 0x0019d42c 0x0000068c 0x10000000 appname.__DATA.__objc_classrefs
0x00000019 data-ptrs [0x00000000001e4ab8-0x00000000001e4e48) 0x0019dab8 0x00000390 0x10000000 appname.__DATA.__objc_superrefs
0x0000001a regular [0x00000000001e4e48-0x00000000001e6184) 0x0019de48 0x0000133c 0x00000000 appname.__DATA.__objc_ivar
0x0000001b data-ptrs [0x00000000001e6184-0x00000000001ea02c) 0x0019f184 0x00003ea8 0x00000000 appname.__DATA.__objc_data
0x0000001c data [0x00000000001ea030-0x00000000001ed978) 0x001a3030 0x00003948 0x00000000 appname.__DATA.__data
0x0000001d zero-fill [0x00000000001ed980-0x00000000001edce0) 0x00000000 0x00000000 0x00000001 appname.__DATA.__bss
0x0000001e zero-fill [0x00000000001edce0-0x00000000001edce8) 0x00000000 0x00000000 0x00000001 appname.__DATA.__common
0x00000400 container [0x00000000001ef000-0x0000000000207000) 0x001a8000 0x00015bf0 0x00000000 appname.__LINKEDIT
接下来要做的就是将刚刚输出的数据转化为LLDB指令来从内存单元中获取我们能用的数据。在转化时,你可以跳过零填充区。
以下面的输出数据举例:
0x00000003 data-cstr [0x000000000016e5e0-0x0000000000189067) 0x001275e0 0x0001aa87 0x00000002 appname.__TEXT.__cstring
转化为LLDB指令后就是:
Memory read --outfile ~/0x00000003data-cstr 0x000000000016e5e0 0x0000000000189067 –force
这指令是告诉LLDB程序去 0x000000000016e5e0到0x0000000000189067之间的内存中取出数据并且存放到 0x00000003data-cstr中。
(lldb) memory read --outfile ~/0x00000003data-cstr 0x000000000016e5e0 0x0000000000189067 –force
这条命令在执行完时,你不会看到所有创建的文件。当所有的文件创建好后,你就可查找你所需要的数据了(也许是数字,也许是密码之类的。)额,文件大概是这个样子的:
0x0016e5e0: 3f 3d 26 2b 00 3a 2f 3d 2c 21 24 26 27 28 29 2a ?=&+.:/=,!$&'()*
0x0016e5f0: 2b 3b 5b 5d 40 23 3f 00 00 62 72 61 6e 64 4c 6f +;[]@#?..brandLo
0x0016e600: 67 6f 2e 70 6e 67 00 54 72 61 64 65 47 6f 74 68 go.png.TradeGoth
0x0016e610: 69 63 4c 54 2d 42 6f 6c 64 43 6f 6e 64 54 77 65 icLT-BoldCondTwe
0x0016e620: 6e 74 79 00 4c 6f 61 64 69 6e 67 2e 2e 2e 00 4c nty.Loading....L
0x0016e630: 6f 61 64 69 6e 67 00 76 31 32 40 3f 30 40 22 4e oading.v12@?0@"N
0x0016e640: 53 44 61 74 61 22 34 40 22 45 70 73 45 72 72 6f SData"4@"EpsErro
0x0016e650: 72 22 38 00 6c 6f 61 64 69 6e 67 50 61 67 65 54 r"8.loadingPageT
0x0016e660: 79 70 65 00 54 69 2c 4e 2c 56 5f 6c 6f 61 64 69 ype.Ti,N,V_loadi
0x0016e670: 6e 67 50 61 67 65 54 79 70 65 00 6f 76 65 72 76 ngPageType.overv
0x0016e680: 69 65 77 52 65 71 52 65 73 48 61 6e 64 6c 65 72 iewReqResHandler
0x0016e690: 00 54 40 22 45 70 73 4f 76 65 72 76 69 65 77 52 .T@"EpsOverviewR
0x0016e6a0: 65 71 52 65 73 48 61 6e 64 6c 65 72 22 2c 26 2c eqResHandler",&,
0x0016e6b0: 4e 2c 56 5f 6f 76 65 72 76 69 65 77 52 65 71 52 N,V_overviewReqR
0x0016e6c0: 65 73 48 61 6e 64 6c 65 72 00 41 50 49 43 61 6c esHandler.APICal
希望你能在IOSapp中发现一些有趣的东西。当然不要用这个拿去干坏事哦。
这种技术可以用来确定应用程序没有删除敏感信息。
还是那句老话,所有应用程序应该释放处理敏感信息的类和方法的内存,否则敏感信息可能会泄露。
*原文: blog.netspi FB小编xiaoqin00编译,转载请注明来自FreeBuf.com