【世安杯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
(文件太大附件不来╮(╯_╰)╭) 看不懂,谢谢分享 感谢分享 感谢分享 thx for share. 虽然看的不懂,但是还是感谢您的分享,希望可以帮助到其他人 感谢分享
感谢大神分享 感谢大神分享,3Q
CTF最近很火热啊