本文隐去了公司名、人名、应用名、以及应用特征等敏感信息。 本文作者@CuGBabyBeaR
0、背景和事先分析
前段时间看见一个能够和现实进行交互的应用,觉得挺有意思,恰巧有一个下午的空闲时间,于是就把APP下载下来进行分析。
应用本身是免费的,但是解锁功能需要激活码,并且交互需要摄像头识别相应卡片(Augmented Reality AR卡)。去他们的官方淘宝店看了看,算下来是5块钱一张,正在打折。
整个APK 120m+ ,显然是将模型数据放在APK中,通过摄像头识别卡片,通过识别到的内容调用不同的模型,和卡片的姿态进行交互。
1、所用技术研究
使用apktool dex2jar 反编译应用,通过jd-gui查看源代码。代码分为3部分:一是主activity的代码,二是QR识别的代码,三是Unity3D。显然游戏使用的引擎是Unity3D,而其中部分代码混淆过,类名和变量名都改成了a b c等无意义的名字,这一部分代码可能是来自 https://developer.vuforia.com/ 。
稍微分析了一下activity的代码后,便放弃了。然后转去研究资源文件。res的资源文件只有应用图标而已,有意义的资源都在assets里。除开QR识别的资源外,就是Unity3D使用的dll和模型文件了。模型文件进行了简单的分割,意义不明。
2、发现
分析资源文件的过程中,发现了一个数据库。一开始对其并不在意,在分析完assets中的资源文件之后,关注点就转移到这个数据库身上了。是一个sqlit3数据库,用SQLite Expert 打开后,其中有两个表。一个表是卡的数据,数据列两列,包括卡的代码和是否启用。另一个表的列名让我很在意“ActivedCode”,难道是激活码?找到第一行此列值,输入到应用里,发现...激活了...
我顿时就凌乱了,另外一列的名字叫QRCode 。于是找了最后一行的QRCode,找了一个在线QR码生成器,QRCode输入进去,用应用识别生成的QR图。又激活了。
因为AR卡本身只是一张卡片,卡片只是通过卡片上图案特征进行识别的。而在其他的AR卡应用中(如PSV的和其他非盈利性的Android AR卡应用)即便是复印的也可以被正确识别。而这个应用中有卡片的图片,只要将图片提取或者截屏下来,按照原卡片的大小打印裁切,应该是可以用的...如果这3万条数据被泄露出去...恐怕这款应用是赚不到钱了。
3、反馈和解决
我去这个公司的官网,找到了一个该应用IOS版开发者的QQ号,把这件事和他说了一下,他说转告同事去处理了。
过了半个月,我又想起了这件事,找那位开发者要了Android版开发者的QQ号。和Android版开发者交流了一下,他说是测试的时候将数据库放进了APK中,发布的时候忘记拿出来了,而数据库也从新的APK中去掉了。
4、总结和分析
这个事件还算是完美地解决了。不过出现这个问题的原因,除了Android应用本身,容易被反编译的客观原因之外,我感觉有两个主要主观原因:
(1) 没有分开开发环境和生产环境。不过Android开发环境中貌似没有原生的开发生产分开的功能,只能用ANT。这样的话有一个土办法,做一个checklist,每次发布按照这个checklist做,这样就不会有不应该出现在产品中的东西遗留在产品中。
(2) 激活码明码保存。虽然说一般激活码的数据库都只会放在服务器上,不会被泄露出来。然而如果一个不小心数据库被流出了,作为最后的保险,我认为数据库本身最好还是加密一下。所有可用激活码的明文,由项目负责一人管理。激活码的发布和验证分开:激活码的发布由项目负责将激活码明文交由发布渠道,如印刷或其他销售渠道。而负责激活的服务器上激活码的数据库都是使用不可逆加密算法加密的密文。验证的时候用户输入激活码后,服务器将输入内容加密,与数据库中的内容进行比较,执行激活操作。这样即使激活码数据库被泄露也不怕其用来被激活。