APP测试-DIVA
2022-03-22 18:16:08 # android

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,报错,原因是开放了另一个端口

image-20220322182127434

换个端口就好了,因为有多个模拟器,占用的端口不一样

image-20220322183554442

将apk放进模拟器,打开

image-20220322182505484

测试

第一关 不安全的日志输出

产生原因:由于app代码中将敏感信息(如凭据,会话ID,财务详细信息等)通过log.e输出,所以在app的表单中输入的内容,可以在相关的日志中输出。

这里模拟输入敏感信息“111”

image-20220322183612462

通过adb logcat查看运行日志

image-20220322183707309

把apk文件拖到Android-Killer,然后还原java代码,在LogActivity#checkout方法中发现,会将用户输入的credit输出到日志中

image-20220322184236504

第二关 硬编码-第一部分

硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中的软件开发实践,与从外部获取数据或在运行时生成数据不同。

随便输入

image-20220322184606248

然后定位到源码HardcodeActivity#access方法中,发现vendor key的值

image-20220322184651281

提交

image-20220322184737128

第三关 不安全的数据存储-第一部分

产生原因:使用了SharedPreferences类,该类是Android平台上一个轻量级的存储类,主要是用来保存一些常用的配置,本例中是用该类存储了用户名和密码,因此是具有风险的。SharedPreferences类存储的数据会以.xml的形式存储在/data/data/app的包名/shared_prefs目录下。

首先随意输入用户名和密码点击保存

image-20220322184924591

进入shell模式,在/data/data/jakhar.aseem.diva/shared_prefs/目录中查看jakhar.aseem.diva_preferences.xml文件,也可以输入adb pull /data/data/jakhar.aseem.diva/shared_prefs ./将文件复制出来查看,发现文件中保存了刚刚输入的用户名和密码。

image-20220322185107256

查看源码

image-20220322185225572

第四关 不安全的数据存储-第二部分

产生原因:将敏感数据保存在本地的sqlite3数据库中,对应的数据库目录: /data/data/app的包名/databases

输入用户名和密码

image-20220322185334417

进入/data/data/jakhar.aseem.diva/databases/目录中,将数据库文件ids2下载到本地,adb pull /data/data/jakhar.aseem.diva/databases/ids2 .,使用sqlite数据库管理工具打开即可查看到保存的用户名和密码。

image-20220322213625717

InsecureDataStorage2Activity#saveCredentials中可以看到,将输入的用户名和密码插入到sqlite3数据库。

image-20220322214059563

第五关 不安全的数据存储-第三部分

产生原因:将敏感数据保存在临时文件中,对应的临时文件目录: /data/data/app的包名/

输入用户名和密码

image-20220322214605016

进入/data/data/jakhar.aseem.diva/目录中查看该目录下临时文件uinfo-1161629033tmp

image-20220322214839395

查看源码,在InsecureDataStorage3Activity#saveCredentials,代码将用户的输入保存到tmp文件中

image-20220322215122161

第六关 不安全的数据存储-第四部分

产生原因:将敏感数据保存在sd卡中,对应的目录一般在:/mnt/sdcard,也可以通过logcat查看保存路径。

输入用户名和密码

image-20220322215319664

进入/mnt/sdcard/目录中,查看文件.unifo.txt

image-20220322215456142

查看源码,在InsecureDataStorage4Activity#saveCredentials,代码将用户名和密码保存在sd卡的.uinfo.txt文件中

image-20220322215659410

第七关 输入校验问题-第一部分

产生原因:某些不安全控件内输入sql或其他数据库的一些语句,因为在使用前未进行检验长度和过滤等操作,从而达到欺骗服务器执行恶意代码影响到数据库的数据。

首先输入test’和test’’试探一下,test’什么也不返回,而test’’会返回”not found”

image-20220322220405444

输入万能密码test' or '1'='1尝试,返回了所有用户的数据

image-20220322220539575

SQLInjectionActivity#search,可以看到直接将输入的用户名拼接在SQL语句后面,没有做任何过滤,导致SQL注入的发生。

image-20220322221227874

第八关 输入校验问题-第二部分

产生原因:在处理转跳时存在漏洞,导致允许从http域跨向file域,实现跨域漏洞,在 File 域下,同源策略跨域访问则能够对私有目录文件进行访问

输入一段url点击可以看到访问了这个页面

image-20220322221552254

将https/http协议换成File协议,利用file协议读取之前存储在sd卡的账号文件/mnt/sdcard/.uinfo.txt

image-20220322221937870

InputValidation2URISchemeActivity#get,代码没有对输入的数据进行处理直接loadUrl

image-20220322222226194

第九关 访问控制问题-第一部分

点击按钮

image-20220322222521636

这里我们要不使用按钮就获取到API凭据,先定位到APICredsActivity类名,

查看AndroidManifest.XML文件,找到了相关的activity

image-20220322223824358

通过观察代码发现,这个activity设置了intent filter,如果为一个Activity设置了IntentFilter,你就可以在应用内或者其他应用中,用特定的隐式Intent来启动这个Activity,如果没有为Activity设置IntentFilter,那么你就只能通过显示Intent来启动这个Activity。

adb启动activity组件,输入命令,即可启动APICredsActivity

1
2
3
4
5
6
7
adb shell am start jakhar.aseem.diva/.APICredsActivity
或者
adb shell am start -n jakhar.aseem.diva/.APICredsActivity -a jakhar.aseem.diva.action.VIEW_CREDS
am start: 启动activity 管理工具
-a:指定action
-n:指定完整 component 名
命令详情:https://developer.android.google.cn/studio/command-line/adb#am

image-20220322224436885

第十关 访问控制问题-第二部分

从题目描述可以知道,通过注册后才能拥有tveeter API Credentials,所以要通过不注册来获取API Credentials

image-20220322224826794

尝试上一关的方式,跳到了一个需要输入PIN的activity,这表明程序做了相应的措施

image-20220322224932400

查看源码APICreds2Activity,获取到上一个activity传来的boolean值,并当该值为false时就获取到apikey

image-20220322225416042

查看上一个activity,即AccessControl2Activity,在代码如下位置发现设置的boolean值

image-20220322230828762

这个类中bool值是通过单选项来决定的,而且把值传给下个activity,这时我们可以使用–ez来传递一个boolean键值对,但是要获取到2131099686值对应的key值是什么,十进制2131099686转换为16进制0x7f060026,在AndroidKiller中搜索0x7f060026

image-20220322231629557

得到对于的name值为chk_pin,再全局搜索name值,得到key为check_pin

image-20220322231856128

最后adb启动activity命令,成功弹出

1
adb shell am start -a jakhar.aseem.diva.action.VIEW_CREDS2 -n jakhar.aseem.diva/.APICreds2Activity --ez check_pin false

image-20220322232125667

第十一关 访问控制问题-第三部分

根据题目的描述,这是个私人笔记app,一开始需要设置密码才能使用,现在我们尝试不设置密码就开始使用

image-20220322232513013

定位到类NotesProvider,对应到AndroidManifest.XML文件

image-20220322233008111

代码如下

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

image-20220322234116133

我们可以使用以下命令访问该uri

1
adb shell content query –-uri content://jakhar.aseem.diva.provider.notesprovider/notes

image-20220322234352521

第十二关 硬编码-第二部分

随便输入

image-20220322234520188

在源码Hardcode2Activity#access,这里使用了DivaJni类

image-20220322234636623

查看DivaJni类的代码

image-20220322234839930

这里加载了divajni库,一般库文件都放在/lib下,在目录下找到libdivajni.so文件

image-20220322235157544

linux下可以使用strings查看二进制文件里的字符串

image-20220322235505909

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
__cxa_finalize
__cxa_atexit
Java_jakhar_aseem_diva_DivaJni_access
Java_jakhar_aseem_diva_DivaJni_initiateLaunchSequence
strcpy
JNI_OnLoad
_edata
__bss_start
_end
libstdc++.so
libm.so
libc.so
libdl.so
libdivajni.so
<$!H
olsdfgad;lh
.dotdot
;*3$"
GCC: (GNU) 4.9 20140827 (prerelease)
gold 1.11
.shstrtab
.dynsym
.dynstr
.hash
.rela.dyn
.rela.plt
.text
.rodata
.eh_frame
.eh_frame_hdr
.fini_array
.init_array
.dynamic
.got
.got.plt
.data
.bss
.comment
.note.gnu.gold-version

逐个尝试,得到olsdfgad;lh

image-20220322235833870

第十三关 输入校验问题-第三部分

随便试试

image-20220322235939860

当输入长的数据时,程序崩溃了,应该是缓冲区溢出了

image-20220323000317916

查看源码InputValidation3Activity#push

image-20220323000835749

查看该类的源码https://github.com/payatu/diva-android/blob/master/app/src/main/jni/divajni.c,使用的是strcpy,典型的字符串复制溢出

image-20220323001418193

参考

https://mp.weixin.qq.com/s/DmonezeCfUdx5_Bzr1lFuw