发新帖

2015移动安全挑战赛 iOS 第1题

[复制链接]
5291 2
本帖最后由 wruih 于 2016-4-5 12:14 编辑

安装ipa不知为何,这个ipa在我的iPhone 5, iOS 8.1.2上安装之后无法启动,每次启动均会闪退;我采用了ldid重签名和把app放在/Applications下的方案,都没有解决闪退的问题,不知道是不是出题人故意留给我们的一道坎?我没有深究这个问题,而是尝试在我的iPhone 4s, iOS 6.1.3安装此ipa,竟意外发现app可以成功打开了,如图所示:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/6/61aa6e7a93ce3bf5229d5fa75dabe4f45a7434dd.PNG
把玩app安装成功之后,我们先随便操作一下,看看针对不同的输入,这个app会给我们怎样的反馈。先直接点击“进入”,发现此app直接退出了;再次打开app,输入snakeninny,结果出现了“密码错误”的提示,如图所示:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/3/338b07e3f147811f659f7c1e8fd16342f6258538.PNG
跟我一起思考——
错误提示一定是由代码控制的;既然弹出了错误提示,说明在弹出错误提示的代码之前,一定有输入是否错误的判断;它应该就是我们的输入与正确答案是否相同的判断。因为点击“进入”之后弹框,那么判断操作一定是在按钮的响应函数之后发生的;如果能够找到这个按钮响应函数,就可以顺藤摸瓜,找到这个判断。
那么我们今天的任务,就是找到这个判断的代码,从而找到正确答案。开始操作!
用Cycript找到“进入”按钮的响应函数这个步骤在书上已经不知道重复多少遍了,接下来的操作主要以代码表示,伴以少量解说,跟紧喽!

FunMaker-4s:~ root# ps -e  PID TTY           TIME CMD    1 ??         0:31.21 /sbin/launchd   26 ??         5:53.88 /usr/libexec/UserEventAgent (System)... 3060 ??         0:02.52 /var/mobile/Applications/3E693339-7347-4129-887D-1DBE0C0587AE/level1.app/level1 3079 ??         0:00.02 /usr/libexec/launchproxy /usr/sbin/sshd -i 3082 ??         0:00.28 sshd: root@ttys000  3083 ttys000    0:00.04 -sh 3084 ttys000    0:00.01 ps -eFunMaker-4s:~ root# cycript -p level1cy# ?expandexpand == truecy# [[UIApp keyWindow] recursiveDescription]@"<UIWindow: 0x1fde5d30; frame = (0 0; 320 480); autoresize = W+H; layer = <UIWindowLayer: 0x1fde5e30>>...   |    | <UIButton: 0x1fd5acd0; frame = (110 348; 100 30); opaque = NO; layer = <CALayer: 0x1fd5ac50>>   |    |    | <UIButtonLabel: 0x20872890; frame = (31 4; 37 22); text = '\xe8\xbf\x9b\xe5\x85\xa5'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x208729f0>>   |    | <UIImageView: 0x1fd59030; frame = (0 420; 125.5 40); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1fd596e0>>   |    | <UILabel: 0x1fd58820; frame = (246 430; 64 20); text = '\xe9\x98\xbf\xe9\x87\x8c\xe9\x92\xb1\xe7\x9b\xbe'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x1fd587f0>>   |    | <UIImageView: 0x1fd57c40; frame = (218 427.5; 25 25); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1fd57ca0>>"cy# button = #0x1fd5acd0#"<UIButton: 0x1fd5acd0; frame = (110 348; 100 30); opaque = NO; layer = <CALayer: 0x1fd5ac50>>"cy# [button setHidden:YES]“进入”按钮不见了,界面变成了这样:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/d/d49ad67cc1c4c6b9b8ea9651261ef852d9170d4b.PNG
继续操作:

cy# [button allTargets][NSSet setWithArray:@[#"<ViewController: 0x20869990>"]]]cy# [button allControlEvents]64cy# [button actionsForTarget:#0x20869990 forControlEvent:64]@["onClick"]好了,按钮的响应函数是[ViewController onClick],开始分析汇编代码。
从[ViewController onClick]出发,找到答案[ViewController onClick]的汇编执行流程如图所示:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/6/6683c53559d0fe1061a489c5706ce45847f77709.png
整个流程并不复杂(比书上的几个例子要简单得多,大致浏览一遍,你就一定会注意到下图这个红色的方块:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/a/acbb6167f3a62521bac22fd95c4f878fc4cbfdff.jpg
它的汇编代码是:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/7/76d12a3c5a32f184a19c99f6bec92db21a99e465.png很明显,这段汇编代码从textField里读text,转换成UTF8String之后和某个东西作判断,并根据判断结果跳转。这个现象跟我们上一节作出的预测不谋而合,我们在这段代码的开头下个断点,然后单步执行,看看每个objc_msgSend都是做的什么操作。
先用debugserver挂载level1:

FunMaker-4s:~ root# debugserver *:1234 -a level1debugserver-199 for armv7.Listening to port 1234...然后用LLDB连过去:

192:~ snakeninny$ lldb(lldb) process connect connect://localhost:12342015-10-19 16:29:37.015 lldb[15434:956234] Metadata.framework [Error]: couldn't get the client portProcess 3112 stopped* thread #1: tid = 0x1e03, 0x3c606eb4 libsystem_kernel.dylib`mach_msg_trap + 20, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP    frame #0: 0x3c606eb4 libsystem_kernel.dylib`mach_msg_trap + 20libsystem_kernel.dylib`mach_msg_trap:->  0x3c606eb4 <+20>: pop    {r4, r5, r6, r8}    0x3c606eb8 <+24>: .long  0xe12fff1e                ; unknown opcodelibsystem_kernel.dylib`mach_msg_overwrite_trap:    0x3c606ebc <+0>:  mov    r12, sp    0x3c606ec0 <+4>:  push   {r4, r5, r6, r8}(lldb) cProcess 3112 resuming在0000B76A下断点(这些操作也都在书上重复过无数遍了,下面还是以码代字):

(lldb) image list -o -f[  0] 0x00054000 /var/mobile/Applications/3E693339-7347-4129-887D-1DBE0C0587AE/level1.app/level1(0x0000000000058000)[  1] 0x00077000 /Library/MobileSubstrate/MobileSubstrate.dylib(0x0000000000077000)[  2] 0x0328e000 /Users/snakeninny/Library/Developer/Xcode/iOS DeviceSupport/6.1.3 (10B329)/Symbols/System/Library/Frameworks/Foundation.framework/Foundation[  3] 0x0328e000 /Users/snakeninny/Library/Developer/Xcode/iOS DeviceSupport/6.1.3 (10B329)/Symbols/System/Library/Frameworks/UIKit.framework/UIKit...(lldb) br s -a '0x00054000+0x0000B76A'Breakpoint 1: where = level1`___lldb_unnamed_function36$$level1 + 202, address = 0x0005f76a(lldb)点击按钮,触发断点:

Process 3112 stopped* thread #1: tid = 0x1e03, 0x0005f76a level1`___lldb_unnamed_function36$$level1 + 202, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1    frame #0: 0x0005f76a level1`___lldb_unnamed_function36$$level1 + 202level1`___lldb_unnamed_function36$$level1:->  0x5f76a <+202>: movw   r0, #0x346c    0x5f76e <+206>: mov    r10, r4    0x5f770 <+208>: movt   r0, #0x1    0x5f774 <+212>: ldr.w  r8, [sp, #0x10](lldb) ni...Process 3112 stopped* thread #1: tid = 0x1e03, 0x0005f792 level1`___lldb_unnamed_function36$$level1 + 242, queue = 'com.apple.main-thread', stop reason = instruction step over    frame #0: 0x0005f792 level1`___lldb_unnamed_function36$$level1 + 242level1`___lldb_unnamed_function36$$level1:->  0x5f792 <+242>: movw   r1, #0x3492    0x5f796 <+246>: movt   r1, #0x1    0x5f79a <+250>: add    r1, pc    0x5f79c <+252>: ldr    r5, [r1](lldb) po $r0snakeninny(lldb) ni...Process 3112 stopped* thread #1: tid = 0x1e03, 0x0005f7a0 level1`___lldb_unnamed_function36$$level1 + 256, queue = 'com.apple.main-thread', stop reason = instruction step over    frame #0: 0x0005f7a0 level1`___lldb_unnamed_function36$$level1 + 256level1`___lldb_unnamed_function36$$level1:->  0x5f7a0 <+256>: blx    0x6ff18                   ; symbol stub for: objc_msgSend    0x5f7a4 <+260>: mov    r4, r0    0x5f7a6 <+262>: mov    r0, r6    0x5f7a8 <+264>: mov    r1, r5(lldb) p (char *)$r1(char *) $3 = 0x39eb1d27 "UTF8String"(lldb) niProcess 3112 stopped* thread #1: tid = 0x1e03, 0x0005f7a4 level1`___lldb_unnamed_function36$$level1 + 260, queue = 'com.apple.main-thread', stop reason = instruction step over    frame #0: 0x0005f7a4 level1`___lldb_unnamed_function36$$level1 + 260level1`___lldb_unnamed_function36$$level1:->  0x5f7a4 <+260>: mov    r4, r0    0x5f7a6 <+262>: mov    r0, r6    0x5f7a8 <+264>: mov    r1, r5    0x5f7aa <+266>: blx    0x6ff18                   ; symbol stub for: objc_msgSend(lldb) p (char *)$r0(char *) $4 = 0x1c520110 "snakeninny"(lldb) niProcess 3112 stopped...* thread #1: tid = 0x1e03, 0x0005f7aa level1`___lldb_unnamed_function36$$level1 + 266, queue = 'com.apple.main-thread', stop reason = instruction step over    frame #0: 0x0005f7aa level1`___lldb_unnamed_function36$$level1 + 266level1`___lldb_unnamed_function36$$level1:->  0x5f7aa <+266>: blx    0x6ff18                   ; symbol stub for: objc_msgSend    0x5f7ae <+270>: mov    r5, r0    0x5f7b0 <+272>: ldrb   r0, [r5]    0x5f7b2 <+274>: cmp    r0, #0x0(lldb) p (char *)$r1(char *) $5 = 0x39eb1d27 "UTF8String"(lldb) po $r0Sp4rkDr0idKit(lldb) niProcess 3112 stopped* thread #1: tid = 0x1e03, 0x0005f7ae level1`___lldb_unnamed_function36$$level1 + 270, queue = 'com.apple.main-thread', stop reason = instruction step over    frame #0: 0x0005f7ae level1`___lldb_unnamed_function36$$level1 + 270level1`___lldb_unnamed_function36$$level1:->  0x5f7ae <+270>: mov    r5, r0    0x5f7b0 <+272>: ldrb   r0, [r5]    0x5f7b2 <+274>: cmp    r0, #0x0    0x5f7b4 <+276>: beq    0x5f7d6                   ; <+310>(lldb) p (char *)$r0(char *) $7 = 0x1d016640 "Sp4rkDr0idKit"...看到了一个可疑的字符串“Sp4rkDr0idKit”,你应该已经猜到了,它就是我们的答案(不信的话自己试一下 http://7xibfi.com1.z0.glb.clouddn.com/images/emoji/apple/wink.png?v=0 )。知其然,还要知其所以然,我们继续分析,看看正确的判断逻辑是怎样的。
分析判断逻辑顺着上面的代码,我们接着分析:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/1/160f2d949696728f13f99e409121f88e6cdd8883.png
每一行汇编是什么意思,我都已经标注在图里了,强烈建议你先自己分析一遍,有不明白的地方再看图,然后自己再分析一遍,直到自己能独立分析为止。
值得一提的是,这个判断逻辑有一个bug——即我们输入的字符串,只需要含有“Sp4rkDr0idKit”这个前缀就可以了,而不用全文匹配这个字符串,如图所示:
http://7xibfi.com1.z0.glb.clouddn.com/uploads/default/original/2X/0/0cffc46ebba4c26fcd8f6c83934f482d82f6c054.PNG

举报 使用道具

回复

精彩评论2

蜀黍的秘密    发表于 2016-4-5 18:54:14 | 显示全部楼层
支持一下。。。。

举报 使用道具

回复
manger    发表于 2017-4-20 13:34:22 | 显示全部楼层
默默收藏,改天实践下!

举报 使用道具

回复 支持 反对
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表