MobSF框架简要分析(上)

MobSF框架是一个开源的自动app检测的框架,国内相关的技术也有,BAT三家都有。开源项目里MobSF做的应该是很好的了,链接是https://github.com/MobSF/Mobile-Security-Framework-MobSF。本文记录一下学习和改进的过程,大概用了一下午一晚上,毕竟代码不是很多。

通过docker启动

官方提供了使用docker来启动的方法,拖下整个docker的repo,然后运行,对于docker老手来说应该是很简单的操作,对于我来说基本是 "ctrl+C/V, enter" 一把梭。

1
2
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

官方提供的这两句话,确实能跑的起来,改完代码发现不生效,但后来跟chenyuan大佬请教了一下,发现docker不是这么用的。

先来示范一个错误的安装方法:

1
sudo apt install docker

这个docker和我们所说的docker同名,但完全不一样。 正确应该是

1
2
curl -FsSL get.docker.com -o get_docker.sh
sh get_coder.sh --mirror Aliyun

再示范一个错误的启动方法:

1
2
3
4
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
Ctrl+c 打断
nano settings.py
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

这样做是没有用的,docker run是按照原始镜像新开一个容器,每个image同时可以存在多个容器,它们有的活着,有的被关掉,可以类比为同一个root的多个虚拟机。 再来正确的示范:

1
git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git --depth 1

先把代码拿下来,方便改代码,万一里面抽风了还得手动改。

1
docker run -dit --name my_mobsf -v /foo/bar/Mobile-Security-Framework-MobSF:/root/Mobile-Security-Framework-MobSF -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest

别名取为 --name my_mobsf

文件映射 -v /foo/bar/mobsf /root/mobsf

端口映射 -p 8000:8000

image选择 opensecurity/mobile-security-framework-mobsf:latest

这句话执行完了会返回一个hash-string,假设是66ccff

docker ps -a 可以看到所有容器的状态和hash,包括我们的66ccff和之前瞎搞创建的一大堆

docker exec -it 66ccff /bin/bash 对66ccff执行这个命令,shell进虚拟机里看看。

进入虚拟机里 python manager.py runserver 0.0.0.0:8000 即可实现官方提供的功能

docker stop 66ccff 关闭这个container

1
2
docker start 66ccff
docker start my_mobsf

开这个container 此时修改 /foo/bar/mobsf 里的文件,会与container里保持同步,在容器里杀死python再重启python即可,所以也可以开心改代码了。

Tips:

  • 正常情况下docker run只需要执行一遍,完成创建即可
  • docker exec 有 -d 参数表示后台运行
  • docker能实现的,我们手动也可以实现一遍

python直接启动

因为整个proj是python写的,偶尔调用一下处理android的jar包,按照requirements.txt装好,这几个依赖基本没啥特别的,对版本没什么要求。

然后python manager.py runserver 0.0.0.0:8000 即可,比docker还方便,推荐。

代码阅读

前端和数据库就不管了,只关心对apk的处理过程。

静态分析

- StaticAnalyzer/android/static_analyze.py -> static_analyze(request)

提供两种文件格式,apk和zip,后者要求是Eclipse或者Android Studio的源码,只关心apk的部分。

  1. 获取一些基本信息,例如文件大小,证书信息,没啥骚操作;
  2. 解码Manifest.xml,临时存一下,没操作;
  3. 获取app图标,没操作;
  4. 分析Manifest,manifest_analysis ,模式匹配的方式检查某些标签的某些属性是否被设置,提取组件的相关信息,过滤出其中有可能导出的组件。
  5. 分析native库,elf_analysis ,检测是否开启PIE和CANARY,前者的检查方法是检查ELF文件格式的某些flag,后者的检查方法是字符串__stack_chk_guard/fail 是否在strtab 的项里。
  6. 分析资源文件,res_analysis ,遍历文件,寻找某些字符串,例如svchost.ext,虽然这玩意没有任何叼用,android里哪来的这东西。
  7. 打印cert的相关信息。
  8. 分析恶意软件,首先是apkid_analysis ,这个坑了我好几个小时,有句yara.load(rules_path)总觉得作者写的是错的,但就是不crash,代码也不报错,后来发现是这个功能根本没开启,手动开启后就会crash,智障开发者。按照预期,作用是反序列化yarc文件,得到yara规则后对解压出来的内容进行匹配,匹配成功认为可疑的文件。
  9. ===这里插播一下yara的知识===== yara是一款用来匹配某些字符串,为安全工作者提供方便的扫描器一样的东西。 python 使用 pip install yara-python,但是requirement.txt里没有这个,让我很怀疑这段代码。进container里python import yara也会报错,非常不解。 尝试了连续N个yara-python版本,都不行;下载了c版本的yara,仍然不能用,只能强行观察一下版本号了。 看commit不知道是哪个contributor想要装逼,加了这个功能,而yarc是强版本相关的东西,文件头是"YARA"+magic,magic=(VERSION)<<16MAX_THREAD ,这个傻逼contributor的magic是一个不存在的magic,不可能算出来,但是yara代码里check的是整个int32,VERSION和MAX_THREAD必须保持一致,否则不给继续走。 而且yarc比yara大多了,不知道什么心态。 ===================
  10. 继续说apkid_analysis,检查了classes.dex是否存在,没有考虑到multi-dex技术。
  11. 调用jar包,把dex拆解为smali/java,这里仍然没有考虑到multi-dex技术,差评。
  12. 进行code_analysis,这里应该是静态分析里最重要的部分了,我们来看看这葫芦里装的是什么比,代码里依次对text进行了code_rule_matcher /api_rule_matcher /url_email_matcher ,均使用正则匹配或者字符串搜索,只是输出结果的格式有差异,而且对于url进行了本地和在线的检验,确认url是否在公开的恶意软件列表里,虽然并没有什么卵用,显然老外不懂中国特色。Ok 静态分析就这么多了。

动态分析

- DynamicAnalyzer/android/android_dynamic.py -> def android_dynamic_analyzer

动态调试比较麻烦,配了很久环境还是没有成功,作者提供了4种方式,都是比较老旧的方法了,而且遇到顽固的软件也不一定有用,这里建议在读懂代码的情况下,使用真机操作。

作者也比较诈唬,上来就给了一个编译好的操作系统和一个virtualbox版的安卓快照,还让我以为这里面插桩啊还是改了什么内核调用,准备自己编译一个出来,读完代码发现根本没用到什么特殊的特性。

从入口看起,第一步肯定是先启动机器,作者提供三种方法,VirtualBoxVM/AVDManager/ReadDevice,前两者看着就烦,当然是要使用第三种啦,于是开启了漫长的踩坑之旅,具体在下篇进行介绍。

  1. 点击"create Environment"后,调用get_env。
    1. 创建PC上的MITM Proxy,真机的情况下要提供PC上的IP-Port;
    2. 再调用connect建立adb的连接,这部分代码作者写的是不能用的,作者是使用tcp去连接手机的,而我们是USB。
    3. 过程中的adb使用的是repo里自带的,和当前的版本不一致,会相互kill对方,建议将adb替换为最新版的。
    4. 同样,作者依赖superSU,而我们使用的是userdebug的su,命令写法是不一致的,不能正常运行。
    5. 最后安装并且运行目标APP。还需要安装Xposed和一些插件,用来记录和过掉检测。
  2. 通过ajax的方式按照顺序去调用其他的API,包括mobsf_ca 安装证书,通过将证书复制到/system/etc/security/cacerts 来实现,以及ClipDump,用来监控剪切板。
  3. 留出来的几个按钮均对应ajax,show/stop screen对应screen_cast ,启动opensecurity提供的app提供的Service,之后通过截屏、传输屏幕的方式,每300ms刷新一帧。Remove MobSF RootCA移除证书。Take a screencapture截屏,Finish结束并且生成报告,存好快照,进行打包。
  4. 这里有两个有趣的功能,start exported activity tester 和 start activity tester。对应的python代码里使用adb shell am start的功能开Activity,等待一小段时间后进行截屏,再force-stop,记录一下。虽然设计的不错,但针对大型APP基本都要跪,毕竟启动需要时间,intent为空很可能退出。
  5. 生成报告的话,主要有Xposed的logcat,ActivityManager的logcat,MITM的日志,dumpsys的信息。
  6. 代码里有针对的分析,主要是对log进行正则,之后输出API的调用情况和url的过滤情况。

总结

看起来MobSF确实仅仅是一个框架,实现了一些常见的BUG检测,距离实用还很遥远,主要仍然是大量正则的堆叠,本来期待的动态分析以为是多高级的东西,以为是fuzz插桩,结果是监控API,有点失望。扫出来的东西绝大部分没啥卵用,毕竟做出来了,还是给作者点个赞吧!

真机的patch

做这个的原因是动态调试代码完全不能跑,不想用虚拟机(有手机,任性!)。太累了,下篇记录一下修改过程。