1625-5 王子昂 总结《2017年10月24日》 【连续第389天总结】
A. Xp0int-so fun—zjdroid安卓脱壳
B.
首先,也许zjdroid这个工具的确已经很老了,不过作为学习、脱一些简单的壳应该还是可以的
(主要是官方Wp中说的这个工具,那肯定它是可以的嘛。当然优先复现它咯~)
遇到了很多坑,换了俩模拟器最后在真机上搞定,折腾了数个小时才搞定,感觉自己的排错能力真的提升了不少OTZ
Xposed和Zjdroid这命令,debug得我都轻车熟路了……
使用Zjdroid这个工具需要先安装Xposed框架,注意安装框架和安装模块完后都需要重启
(不注意看提示会掉坑撒)
重启后开启两个命令行,一个命令行查看log中的返回数据,另一个命令行来执行命令
Zjdroid的命令结果全都是通过broadcast返回的,因此需要logcat来接收
第一步:
adb shell dumpsys activity top
这个命令可以显示当前显示程序的包名和pid
有了这个包名以后我们就可以筛选log了(否则太多啦)
一个命令行使用
adb logcat -s zjdroid-shell-com.jnu.ctf2017
意思是从log中筛选zjdroid-shell-com.jnu.ctf2017
当发现程序在运行以后就会显示hook到的数据:
然后另一个命令行进入shell中开始执行zjdroid的命令就好了:
首先得到内存中dex的信息
root@x86:/ # am broadcast -a com.zjdroid.invoke --ei target 2102 --es cmd '{"action":"dump_dexinfo"}'
-a com.zjdroid.invoke --ei target 【目标程序PID】 --es cmd '{"action":"dump_dexinfo"}'
注意要在shell中输入哦
我刚开始用adb shell am xxxxxx的方式输入时无限报错,最后去掉单引号就能成功dump出dex信息了,但是后一步就没办法了╮(╯_╰)╭试了好久好久
【搜索的时候发现有不少人问log中显示the cmd is valid,都没有查到结果;除了命令确实输错以外,就可能是这个原因,请仔细检查单引号、cmd后的空格、以及是否在shell中和是否具有root权限(在Shell中输入su一下即可)】
这样在另一边的Log窗口就能看到信息啦:
两个filepath就是内存中的文件了,壳解密出的东西就是它们了
我们只需要把它们dump下来就OK咯!
(注意mCookie:-1,这是第一个大坑)
dump命令:
root@x86:/ # am broadcast -a com.zjdroid.invoke --ei target 【目标程序PID】 --es cmd '{"action":"backsmali",dexpath:"/data/app/com.jnu.ctf2017-1/base.apk"}'
结果:
嗯?!咋回事儿?
试了几遍都是这样
按照提示去源码中查了一下:
我知道mCookie=-1肯定不对劲儿,可是这Cookie是你给的啊(╯‵□′)╯︵┻━┻
权限也都是最高的了,没道理出错啊
那我们乖乖看log呗:
我选中的部分就是核心出错点,上半部分是正常的log,加载了backsmali命令
下半部分是出错位置的调用堆栈,可以看到,位置在backsmaliDexFile方法中的getCookie中出错了
这个错误似乎是long到int的类型转换出错了……
估计是程序返回的cookie太大,超过了int的范围;而Zjdroid中的变量是int类型,导致溢出直接转换报错,返回-1了……
说到这我想起来,所用模拟器(雷电模拟器)是安卓5.1版本,似乎应用了64位系统。我用它也正是因为上一次做的某个CM要求64位系统。也许是这个原因吧。
当时也差不多猜到可能这个系统太新了的缘故,于是换回以前使用的夜神模拟器。
值得一说的是,Xposed的APK我是从官网下的最新版,结果拖进夜神直接报错
查了一波发现有旧版的可以给夜神用,遂安装成功
同样步骤进行下来,返回的mCookie终于正常了:
看到这个巨大的负数简直让我兴奋的不行,暗想幸亏我还留着这个以前跟着我的模拟器……没想到这是另外一个坑
继续下一步,dump:
好嘛,这次更恐怖,直接结束运行了……
又试了一次,换别的app dump也一样,说明还是Zjdroid和系统的适配问题……
这次不猜了,乖乖看Log吧:
同样的位置,从开始向下看一下就找到了
这次Cookie对了,但是找不到框架中的libdvmnative.so库了
我查了一下,似乎有人说这个库是闭源的啊,有人说是安装过程的问题啊等等
报错的进程是davikvm虚拟机,我感觉跟模拟器是x86处理器架构,而真机是ARM处理器架构有关
于是我就掏出尘封已久的价值一百块的二手中兴真机,再来一遍
(别问我为啥不一开始就上真机,太菜了不好意思掏出来(而且懒得充电落灰很久了
再值得一说的是,那个适用于夜神的老版Xposed居然不适用于辣鸡中兴
我本来以为脱壳无望了,查了一波发现有人修改处了努比亚专用的Xposed……安装竟然成功了,自此一帆风顺
这次终于没问题了……
以上是脱壳和查错教程
(其实一开始就上真机就一点问题都没了啊(╯‵□′)╯︵┻━┻)
下面开始本题的WP
so fun
查壳的时候发现有两个文件,apk和secData.jar
这个jar其实我比赛的时候就看到了,感觉有点问题但是反编译不出来,就没太在意
原来这个就是关键的加密dex啊!
dump下来以后拖入jeb反编译,查看MainActivity:
过程太简单了好感动
取到输入字符串以后传入checkstr方法,这个方法是native导出的,要去so库中找
IDA反编译以后找到checkstr导出函数
checkstr调用的时候实际上送入了一个参数,就是这里的v0了
v1来自于genstr生成
然后cmpstr比对
genstr里还算简单,不过随机数有点麻烦,需要模拟环境
今天太晚了我就不开虚拟机搞了,明天再说吧
另外strcmp函数并不是简单的字符串对比,里面还有一个处理:
再异或一下0x6a,内部生成flag
官方WP的方法是直接新建一个工程调用so库文件,动态调试cmpstr,找到v2的值后脚本跑出v3
我觉得其实直接IDA附加到这个库上应该也可以
再不济通过linux还原genstr应该也行吧;不过不知道linux的x86处理器和安卓的ARM处理器会不会对随机数算法有什么影响……应该没有吧,只要库文件相同,算法就相同的
明天尝试一下解决方案
话说这个题目不脱壳其实也能做啊,直接反编译这个库然后研究出返回值就行了……虽然不脱壳也不知道APK里有没有对JNI方法返回的值再做变换就是了……
但是也好气人好可惜啊~
C. 明日计划
Reversing.kr
CRC1

被折叠的 条评论
为什么被折叠?



