某安卓程序数据库解密详解

admin 2023年3月17日11:04:58评论32 views字数 4357阅读14分31秒阅读模式

某安卓程序数据库解密详解

最近遇到一个软件数据库中离线数据进行了加密,希望通过这个例子让大家了解一个APP数据解析的工作流程。首先从豌豆荚网站(www.wandoujia.com)下载到该APP的APK安装包,然后通过ADB命令将APK安装到手机或者模拟器当中。将软件安装注册后,浏览文章下有个离线下载的功能,如下图所示。


某安卓程序数据库解密详解


当点击下载后,帖子就可以在“收藏/下载”页面离线观看了,如下图所示。


某安卓程序数据库解密详解


通过分析,发现这里下载的帖子存放在数据库NOTEDATA字段中并且内容是加密的。一般情况下,安卓程序的数据库存放在目录data/data/程序包名/databases目录下,这里的数据库可以通过ADB命令导出到电脑,并且内容是加密的,如下图所示。


某安卓程序数据库解密详解


现在我们需要解密数据库中NOTEDATA字段的数据。首先,用反编译工具jadx-gui载入APK文件(该工具现在有不依赖Java环境的版本,下载地址https://github.com/skylot/jadx/releases)。也可以考虑使用GDA工具代替,GDA是国内团队开发的反编译工具。不依赖Java环境,更新频率高,并且可以检测出APK加壳的厂商,笔者是习惯使用jadx-gui的搜索功能。


载入后,通过观察发现该APK没有加壳,直接点击jadx-gui工具界面的放大镜按钮打开搜索文本界面(或者直接单击工具栏中的“导航”->“搜索文本”),如下图所示。


某安卓程序数据库解密详解


该APP数据库本身是没有加密的,且只需要解密NOTEDATA字段的数据,所以在搜索文本的文本框内输入“NOTEDATA”,搜索结果如下图所示。


某安卓程序数据库解密详解


可以看到这里搜索到了代码中包含“NOTEDATA”的关键点有24个,说明程序操作数据库中“NOTEDATA”字段的数据大概率就在这24个关键位置中,这里就需要一些简单的判断了。//根据经验或者一个个去排除找到关键位置,这里搜索到24个相关位置,可以通过批量hook来判断想要的地方。


通过分析,在模拟器中访问离线下载的帖子时,程序应该是先从数据库中读取对应字段的数据,再解密显示出来,所以大概率会用到查询数据库的语句。根据判断,发现关键位置在上图节点第三行,代码如下:int columnIndex = query.getColumnIndex("NOTEDATA"); 在文本搜索界面双击代码所在行,跳转到代码位置,如下图所示。


某安卓程序数据库解密详解


从上图红色方框的代码看出,第一行是先将“NOTEDATA”的索引取出放到columnIndex变量,然后第二行通过query.getBlob(columnIndex)取出数据库中对应索引的加密数据,看到取出的数据作为encryptBytes方法的参数,然后encryptBytes的返回值又作为uncompress方法的参数传入,猜测是做了两次解密,这里也有一点技巧,因为有两次解密,第一次解密肯定是看不到明文的,因此先分析第二个方法uncompress,双击上图方框中的uncompress方法,跳转到uncompress方法所在的类,如下图所示。


某安卓程序数据库解密详解


可以从上图看到uncompress方法在类CompressEncrypt中,这里可以右键点击上图红色方框的CompressEncrypt类,会弹出“复制类名”,如下图所示。


某安卓程序数据库解密详解


复制类名发现完整类名是cn.tianya.util.CompressEncrypt。由于之前的分析都是通过代码看到的,并不确定程序真的运行了这里的代码,这里笔者通过frida进行hook来判断。运行模拟器,电脑打开终端(这里需要模拟器跟电脑都安装了相同版本的frida,并且电脑上安装了ADB和objection,这些工具网上有很多安装教程,这里不再赘述)。输入命令“adb shell”后按下回车键,连接模拟器,如下图所示。


某安卓程序数据库解密详解


然后输入命令 “cd data/local/tmp”,因为这个目录下有笔者安装的frida-server工具,并且重命名为o15,如下图所示。


某安卓程序数据库解密详解


进入到该目录后,继续输入命令“./o15”运行frida-server,运行完成之后,光标移到下一行,并且没有任何输出代表运行成功,如下图所示。


某安卓程序数据库解密详解


当模拟器的frida-server运行成功后,该终端就不需要管理了,最小化即可。在电脑上再开一个终端,在终端中输入命令“objection -g cn.tianya.light explore”并按下回车(其中cn.tianya.light是我们分析的APK程序的包名),frida会自动将模拟器中要分析的程序运行起来,如下图所示界面。


某安卓程序数据库解密详解


上图所显示界面代表objection运行成功,接下来通过hook判断程序是否运行到uncompress方法,在终端继续输入命令“android hooking watch class_method cn.tianya.util.CompressEncrypt.uncompress --dump-args --dump-backtrace --dump-return”,这里的命令可以学习objection工具了解,大概的作用就是hook了uncompress方法,并输出参数,调用堆栈和返回值。按下回车,结果如下图所示代表hook成功。


某安卓程序数据库解密详解


当hook成功后,我们在模拟器中点击浏览离线下载的帖子(这里不演示帖子内容),当我们访问离线内容,这时的终端会有内容输出,因为输出内容较多,这里只截了方法的参数和返回值的内容,如下图所示。


某安卓程序数据库解密详解

uncompress方法的参数


某安卓程序数据库解密详解

uncompress方法的返回值


发现返回值就是离线下载的内容,这时可以确定找到的是正确的代码位置。

这里继续分析两个加密方法具体实现。回到jadx-gui工具静态分析代码的位置,如下图所示。


某安卓程序数据库解密详解


双击上图红色方框内的方法,跳转到方法实现的位置。如下图所示。


某安卓程序数据库解密详解


uncompress方法中只有一个unzip方法,根据名字猜测就是一个解压zip的功能,再次双击unzip方法跳转到方法实现的代码位置,如下图所示。


某安卓程序数据库解密详解


根据代码分析得知,unzip方法就是解压zip数据的功能,那么umcompress方法也就是解压数据的功能,下面继续分析encryptBytes方法,如下图所示。


某安卓程序数据库解密详解


双击上图红色方框中的encryptBytes方法,界面跳转到encryptBytes方法的代码实现位置,如下图所示。


某安卓程序数据库解密详解


从上方图片代码中分析得知,encryptBytes方法传入的参数作为encryptData方法的参数,说明主要解密的代码在encryptData方法中,再次双击encryptData方法,跳转到对应代码实现,如下图所示。


某安卓程序数据库解密详解


从上图得知,方法encryptData被native修饰,说明了该方法的代码实现在C语言层,也就是说对应代码在jadx-gui中看不到,需要用IDA加载对应的so文件才能观察到代码,接下来的目标就是找encryptData方法所在的so文件。继续观察上图,发现红色方框内的System.loadLibrary方法参数是“tianya”,可以判断出encryptData方法所在so文件是libtianya.so。成功找到so文件名,就该找对应文件了,将分析的.apk安装包后缀改成.zip的压缩包,然后解压缩得到对应文件夹,如下图所示。


某安卓程序数据库解密详解


上图中我们重点关注lib文件夹,该文件夹下存放的就是APK中用到的so文件。双击打开lib文件夹,发现里面还有三个文件夹。这里三个文件夹下的so文件代码是一样的,这里打开“armeabi-v7a”文件夹,找到对应so文件,如下图所示。


某安卓程序数据库解密详解


找到文件,用IDA将so文件载入,载入成功后在函数窗口中搜索“Java”关键字,如下图所示。


某安卓程序数据库解密详解


从上图中函数窗口看到Java_cn_tianya_jni_EncryptJni_encryptData()函数,该函数就是我们在jadx-gui工具中分析的encryptData方法的实现,双击该函数,跳转到函数的代码位置,双击过去后发现是汇编代码,代码如下图所示。


某安卓程序数据库解密详解


这里的汇编看起来很是头疼,这里鼠标单击汇编代码所在页面,摁下键盘的F5键,或者单击“View”->“Open subview”->“Generate pseudocode”,如下图所示。


某安卓程序数据库解密详解


页面跳转到IDA翻译汇编代码到伪代码界面,如下图所示。


某安卓程序数据库解密详解


这里可能读者有点疑问,明明在jadx-gui工具中看到的encryptData方法只有一个参数,但在IDA中看到Java_cn_tianya_jni_EncryptJni_encryptData()函数有三个参数,是不是IDA分析错了呢,并不是的,因为涉及到一些开发的知识,这里不作介绍,只需要了解在IDA中

Java_cn_tianya_jni_EncryptJni_encryptData()函数的第三个参数就是jadx-gui中看到的encryptData方法的实际参数,上图中的bytes就是encryptData方法的参数,上图中的代码,真正解密数据在上图代码页面第9行j_EncryptData()函数里面,该函数第一个参数v6就是加密的数据,第二个参数就是加密数据的长度。双击上图中j_EncryptData()函数,进入函数内部代码,如下图所示。


某安卓程序数据库解密详解


跟进后,发现仅仅调用了EncryptData()函数,继续双击EncryptData()函数, 跳转到EncryptData()函数代码实现位置,如下图所示。


某安卓程序数据库解密详解


进入代码位置后,发现又调用其他函数j_j_ReOrderData(),再双击进入函数,跳转到对应代码位置,进去还是调用了一个函数j_ReOrderData(),继续双击进入函数代码位置,终于找到加密的代码,如下图所示。


某安卓程序数据库解密详解


这里代码比较简单,数据库中加密数据的解密也十分简单,就是将数据库中加密的字段读取出来,经过上图代码函数解密后(上方函数第一个参数是读取出来的密文,第二个参数是密文的长度),进行一次zip的解压缩即可得到明文。


安全为先,洞鉴未来,奇安信盘古石取证团队竭诚为您提供电子数据取证专业的解决方案与服务。如需试用,请联系奇安信各区域销售代表,或致电95015,期待您的来电!







“盘古石”团队是奇安信科技集团股份有限公司旗下专注于电子数据取证技术研发的团队,由来自国内最早从事电子数据取证的成员组成。盘古石团队以“安全为先,洞鉴未来”为使命,以“漏洞思维”解决电子数据取证难题,以“数据驱动安全”为技术思想,以安全赋能取证,研发新一代电子数据取证产品,产品涵盖计算机取证、移动终端取证、网络空间取证、IoT取证、取证数据分析平台等电子数据取证全领域产品和解决方案,为包括公安执法、党政机关、司法机关以及行政执法部门等提供全面专业的支持与服务。





某安卓程序数据库解密详解


原文始发于微信公众号(盘古石取证):某安卓程序数据库解密详解

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年3月17日11:04:58
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   某安卓程序数据库解密详解https://cn-sec.com/archives/1226503.html

发表评论

匿名网友 填写信息