whklhh 发表于 2017-10-10 02:38

【世安杯CTF】Android

本帖最后由 whklhh 于 2017-10-10 02:39 编辑

本场CTF是实验吧举办的呢
这个题目的分数并不高,但是由于安卓版本问题真是问题频发……

于是分享一下解决问题的过程


直接打开程序发现是空荡荡的页面
http://img.blog.csdn.net/20171010015951664?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


对APK反编译,发现设置了一个Send_to_Activity广播接收函数当收到"msg":"OpenSesame"的广播时设置CTFRevceiver


http://img.blog.csdn.net/20171010020038098?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


那我们就用adb连接shell发送一个广播呗


C:\Users\hasee>adb shell
root@x86:/ # am broadcast -a "com.flagstore.ctf.INCOMING_INTENT" --es msg "OpenSesame"
-a "com.flagstore.ctf.INCOMING_INTENT" --es msg "OpenSesame"               <
Broadcasting: Intent { act=com.flagstore.ctf.INCOMING_INTENT (has extras) }
Broadcast completed: result=0


然后就出现了一个巨大的按钮“BroadCast",点击没有反应
(之前用的夜神模拟器,直接停止运行了→ →调试发现问题出在Utilities.update上)
(后来看了一下这个题目似乎是今年新出的,以为要64位系统,找了半天最后用了雷电模拟器的5.1系统,虽然不是64位不过也能正常运行了~)


分析源码可以发现它生成了两个字符串
然后调用了JNI中的getPhrase函数,最后再生成一个intent把它广播了出去


http://img.blog.csdn.net/20171010020630186?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast


分析一下so文件可以找到getPhrase函数的操作,应该是三个字符串进行异或

http://img.blog.csdn.net/20171010020541934?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

解决办法有很多种
最简单的就是直接用Drozer监听广播,收到最后发送的广播消息
次一点的是用动态调试下断观察变量值(或者打log也一样)
最后是参照源码进行逆向生成字符串,然后依照getPhrase函数进行异或生成flag
(看到的WP中有一篇没有解决堆栈溢出报错的问题,所以IDA远程调控dump下来三个字符串的值再手动异或也一样)


因为懒得安装Drozer了所以直接jeb2动态调了~
首先运行程序,发送广播,等到出现按钮后
在jeb2中附加进程(gdb要先连接上)

http://img.blog.csdn.net/20171010021213637?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
然后在最后广播的地方下断

http://img.blog.csdn.net/20171010021943190?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
查看变量,就能发现三个字符串的值了
http://img.blog.csdn.net/20171010022100488?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
而我们的flag由于是放在intent中的,还需要稍微找一下
从代码中可以看出这个intent是v3,查一下发现putExtra的实现实际上是利用的Extra的ArrayMap
(临时抱佛脚百度来的,因为我还没学安卓╮(╯_╰)╭然而逆向之前不研究正向其实是不对的,别学我哟)

http://img.blog.csdn.net/20171010022325738?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2hrbGhoaGg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast
这样就找到了flag

参考:
直接Drozer接收广播:https://russtone.io/2017/02/14/bssidessf-2017-flagreceiver/
IDA远程调试找到字符串手动异或:https://ctf.rip/bsides-sf-ctf-2017-flag-receiver-mobile-reverse-engineering/

其中前者用的linux上的x64模拟器,所以也没有报错;而后者也报错了,所以只能从内存中拿到字符串再加工

如果不考虑报错问题的话,这题的确分值不高,只需要读懂反编译然后接收广播或者打log就行了
不过如果算上报错状况这难度一下子就上去了……
刚开始看第二篇WP还以为堆栈溢出是题目准备好的障碍,吓得我都傻了(:з」∠)

下载链接:
http://ctf1.shiyanbar.com/shian-file/android.rar
(文件太大附件不来╮(╯_╰)╭)

亲亲多美丽 发表于 2017-10-10 06:10

看不懂,谢谢分享

天游客 发表于 2017-10-10 08:40

感谢分享

mayl8822 发表于 2017-10-10 10:26

感谢分享

caddy 发表于 2017-10-10 10:36

thx for share.

d214800040 发表于 2017-10-10 12:30

虽然看的不懂,但是还是感谢您的分享,希望可以帮助到其他人

0xxx 发表于 2017-10-10 15:04

感谢分享

我是书生 发表于 2017-10-10 20:35


感谢大神分享

d214800040 发表于 2017-10-10 21:26

感谢大神分享,3Q

EvillenG 发表于 2017-10-10 22:00

CTF最近很火热啊
页: [1] 2 3
查看完整版本: 【世安杯CTF】Android