DIVA简介
DIVA(该死的不安全和易受攻击的应用程序)是故意设计的存在很多漏洞的Android app。
源代码链接:https://github.com/payatu/diva-android
apk文件链接:http://payatu.com/wp-content/uploads/2016/01/diva-beta.tar.gz
工具
- 逍遥模拟器
- JDK1.8
- Apktool
- dex2jar、jd-gui、Android-Killer
环境搭建
adb连接模拟器,adb.exe connect 127.0.0.1:21503,报错,原因是开放了另一个端口
换个端口就好了,因为有多个模拟器,占用的端口不一样
将apk放进模拟器,打开
测试
第一关 不安全的日志输出
产生原因:由于app代码中将敏感信息(如凭据,会话ID,财务详细信息等)通过log.e输出,所以在app的表单中输入的内容,可以在相关的日志中输出。
这里模拟输入敏感信息“111”
通过adb logcat
查看运行日志
把apk文件拖到Android-Killer,然后还原java代码,在LogActivity#checkout
方法中发现,会将用户输入的credit输出到日志中
第二关 硬编码-第一部分
硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中的软件开发实践,与从外部获取数据或在运行时生成数据不同。
随便输入
然后定位到源码HardcodeActivity#access
方法中,发现vendor key的值
提交
第三关 不安全的数据存储-第一部分
产生原因:使用了SharedPreferences
类,该类是Android平台上一个轻量级的存储类,主要是用来保存一些常用的配置,本例中是用该类存储了用户名和密码,因此是具有风险的。SharedPreferences
类存储的数据会以.xml的形式存储在/data/data/app的包名/shared_prefs目录下。
首先随意输入用户名和密码点击保存
进入shell模式,在/data/data/jakhar.aseem.diva/shared_prefs/目录中查看jakhar.aseem.diva_preferences.xml文件,也可以输入adb pull /data/data/jakhar.aseem.diva/shared_prefs ./将文件复制出来查看,发现文件中保存了刚刚输入的用户名和密码。
查看源码
第四关 不安全的数据存储-第二部分
产生原因:将敏感数据保存在本地的sqlite3数据库中,对应的数据库目录: /data/data/app的包名/databases
输入用户名和密码
进入/data/data/jakhar.aseem.diva/databases/目录中,将数据库文件ids2下载到本地,adb pull /data/data/jakhar.aseem.diva/databases/ids2 .
,使用sqlite数据库管理工具打开即可查看到保存的用户名和密码。
在InsecureDataStorage2Activity#saveCredentials
中可以看到,将输入的用户名和密码插入到sqlite3数据库。
第五关 不安全的数据存储-第三部分
产生原因:将敏感数据保存在临时文件中,对应的临时文件目录: /data/data/app的包名/
输入用户名和密码
进入/data/data/jakhar.aseem.diva/目录中查看该目录下临时文件uinfo-1161629033tmp
查看源码,在InsecureDataStorage3Activity#saveCredentials
,代码将用户的输入保存到tmp文件中
第六关 不安全的数据存储-第四部分
产生原因:将敏感数据保存在sd卡中,对应的目录一般在:/mnt/sdcard,也可以通过logcat查看保存路径。
输入用户名和密码
进入/mnt/sdcard/目录中,查看文件.unifo.txt
查看源码,在InsecureDataStorage4Activity#saveCredentials
,代码将用户名和密码保存在sd卡的.uinfo.txt文件中
第七关 输入校验问题-第一部分
产生原因:某些不安全控件内输入sql或其他数据库的一些语句,因为在使用前未进行检验长度和过滤等操作,从而达到欺骗服务器执行恶意代码影响到数据库的数据。
首先输入test’和test’’试探一下,test’什么也不返回,而test’’会返回”not found”
输入万能密码test' or '1'='1
尝试,返回了所有用户的数据
在SQLInjectionActivity#search
,可以看到直接将输入的用户名拼接在SQL语句后面,没有做任何过滤,导致SQL注入的发生。
第八关 输入校验问题-第二部分
产生原因:在处理转跳时存在漏洞,导致允许从http域跨向file域,实现跨域漏洞,在 File 域下,同源策略跨域访问则能够对私有目录文件进行访问
输入一段url点击可以看到访问了这个页面
将https/http协议换成File协议,利用file协议读取之前存储在sd卡的账号文件/mnt/sdcard/.uinfo.txt
在InputValidation2URISchemeActivity#get
,代码没有对输入的数据进行处理直接loadUrl
第九关 访问控制问题-第一部分
点击按钮
这里我们要不使用按钮就获取到API凭据,先定位到APICredsActivity
类名,
查看AndroidManifest.XML文件,找到了相关的activity
通过观察代码发现,这个activity设置了intent filter,如果为一个Activity设置了IntentFilter,你就可以在应用内或者其他应用中,用特定的隐式Intent来启动这个Activity,如果没有为Activity设置IntentFilter,那么你就只能通过显示Intent来启动这个Activity。
adb启动activity组件,输入命令,即可启动APICredsActivity
1 | adb shell am start jakhar.aseem.diva/.APICredsActivity |
第十关 访问控制问题-第二部分
从题目描述可以知道,通过注册后才能拥有tveeter API Credentials,所以要通过不注册来获取API Credentials
尝试上一关的方式,跳到了一个需要输入PIN的activity,这表明程序做了相应的措施
查看源码APICreds2Activity
,获取到上一个activity传来的boolean值,并当该值为false时就获取到apikey
查看上一个activity,即AccessControl2Activity
,在代码如下位置发现设置的boolean值
这个类中bool值是通过单选项来决定的,而且把值传给下个activity,这时我们可以使用–ez来传递一个boolean键值对,但是要获取到2131099686值对应的key值是什么,十进制2131099686转换为16进制0x7f060026,在AndroidKiller中搜索0x7f060026
得到对于的name值为chk_pin,再全局搜索name值,得到key为check_pin
最后adb启动activity命令,成功弹出
1 | adb shell am start -a jakhar.aseem.diva.action.VIEW_CREDS2 -n jakhar.aseem.diva/.APICreds2Activity --ez check_pin false |
第十一关 访问控制问题-第三部分
根据题目的描述,这是个私人笔记app,一开始需要设置密码才能使用,现在我们尝试不设置密码就开始使用
定位到类NotesProvider
,对应到AndroidManifest.XML文件
代码如下
1 | <provider android:authorities="jakhar.aseem.diva.provider.notesprovider" android:enabled="true" android:exported="true" android:name="jakhar.aseem.diva.NotesProvider"/> |
这里使用了ContentProvider,android:enabled表示是否能由系统初始化,android:exported表示是否能被其他应用使用,android:authorities标识这个ContentProvider,调用者可以根据这个标识来找到它,看到2个值都为true,我们就可以使用content://访问里面的数据了,查看包含content://的字符串文件/smali/jakhar/aseem/diva/NotesProvider.smali
我们可以使用以下命令访问该uri
1 | adb shell content query –-uri content://jakhar.aseem.diva.provider.notesprovider/notes |
第十二关 硬编码-第二部分
随便输入
在源码Hardcode2Activity#access
,这里使用了DivaJni类
查看DivaJni类的代码
这里加载了divajni库,一般库文件都放在/lib下,在目录下找到libdivajni.so文件
linux下可以使用strings查看二进制文件里的字符串
1 | __cxa_finalize |
逐个尝试,得到olsdfgad;lh
第十三关 输入校验问题-第三部分
随便试试
当输入长的数据时,程序崩溃了,应该是缓冲区溢出了
查看源码InputValidation3Activity#push
查看该类的源码https://github.com/payatu/diva-android/blob/master/app/src/main/jni/divajni.c,使用的是strcpy,典型的字符串复制溢出