前言:

最近入门开始玩android的安全,但是国内研究的真的很少,国外有本牛逼的书《Android Hacker's Handbook》,写的不错,但是看着睡着了好几次。泪奔。前几天测试了下drozer,感觉挺好用,应xsser要求写一篇关于APP中sql注入的文章。由于本人刚入门,描述或者说法难免有错误,还望大牛们跟贴指正。

1. android中的数据存储与查询

1.1 数据存储

众所周知,Android中的数据多是存储在Sqlite数据库中,这个文件一般在手机的系统路径如:/data/data/com.xx.yy/databases/zzz.db。其中com.xx.yy为包名。zzz.db名字随意,为数据库文件。

在安卓应用程序中,有一个非常重要的组件,即“content provider”

当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。

可以看出,该组件的目的就是将自己的数据暴露出去,也就是说程序A提供了一个provider,然后程序B可以通过访问这个provider来获取A暴露的数据。如此一来即达到了数据共享的目的。那么程序B又是如何访问这个provider的呢?

1.2 数据查询

一个程序要访问暴露的provider,首先要知道访问的目标地址,类似http协议,provider也有自己的规范,即类似content://com.aaaa.bbb.class/tablename

其中,com.aaaa.bbb为包名,class为类名,tablename为表名,一般是这样子,具体看自己定义了。

看一个查询例子:

Cursor cursor = contentResolver.query(
    Words_CONTENT_URI, new String[]{"user","pwd"},
    null, null, null);

这是调用contentResolver的query方法进行数据库查询,返回一个cursor对象,即类似DataReader的东西,里面是返回结果。

来看看query的参数

Cursor android.content.ContentResolver.query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

uri即content://com.aaaa.bbb.class/tablename

projection即你要查询的列名

selection和selectionArgs共同控制后面的sql语句中的where内容.

sortOrder即order by xxx的内容。

那么例子中的查询整个构造的语句即:

select user,pwd from tablename;

2.Sql注入问题

综合上面的内容,我们可以看到,query里至少两个参数我们可控,一个是projection,一个是selection,这两个都会影响SQL与的组成,也就为注入提供了可能。

这里以某app为例(虽然感觉漏洞影响有限,但是为了尊重厂商,请允许打码处理),该app对外暴露了一个content provider,uri为:content://com.masaike.mobile.downloads/my_downloads,其中com.masaike.mobile为包名,downloads为库的名字,my_downloads为表名(不一定,可自定义的哦)。

现在语句这么写:

Cursor cursor = contentResolver.query("content://com.masaike.mobile.downloads/my_downloads", new String[]{"_id'","method"},null, null, null);

其中_id和method为两个字段名,我们在_id后面加个单引号,运行下看logcat内容:

logcat内容

从上图很容易看出来,SQL语句因为有个单引号,导致出错。所以注入是存在的。

而如果我们修改projection的内容为"* from sqlite_master where type='table';--",这样子即在闭合后面查询的情况下显示出来全部的表名。当然也可以构造其他语句了。

3. 延伸问题

3.1.update

如果有些敏感配置文件存放在库里面,并且存在注入,我们可以通过contentResolver的update方法去修改配置文件,达到间接控制的目的,这个可以用来修改敏感配置、生成短消息钓鱼之类的。

3.2. 跨库

很多情况下,暴露的是一些无关紧要的东西,比如“downloads”这个库,里面仅仅放了一些下载历史。还有些比如message,里面只放了一些通知。这个时候影响很有限,但是同时,在download.db的同目录下还有个account.db,这个里面存放了所有用户名和密码,如果可以跨到这个库,我们会收获更多。而sqlite本身是支持attach来跨库操作的,但是我测试的时候无法在一个完整的sql语句中完成跨库读取,具体问题见:http://zone.wooyun.org/content/15084

3.3. 任意文件读取

数据存储的uri很多时候并不依赖于sqlite库,还有些是本地文件,会根据content/com.xx.yy/filepath 这种uri来读取文件,当这个filepath可控的时候,我们就可以借助这个uri读取任意文件,当然得是应用程序有权限读取的文件。某漏洞

4. 自动化发现漏洞

推荐工具:drozer

使用参考案例:http://www.freebuf.com/tools/26503.html

练手可以看下官方的文档即可。

自动化语句:run scanner.provider.injection 即可自动化发掘已安卓的app中的SQL注入问题。

5. 总结

这个漏洞的影响点我个人认为有两个问题,一是content provider不应该暴露让任意程序都可访问。二是其他程序是否可以update数据库,比如直接修改配置参数之类的。如果仅仅是读取一些不敏感信息,影响有限,但是如果update的话,影响就会变大。如果可以跨库读取内容,那影响就会变得更大。

[原文地址]

留言评论(旧系统):

CCC @ 2014-12-17 16:34:33

这个东西既然有注入 直接抓出链接在本地日 日出数据日主站 然后打包APP 就可以 生成个毛钓鱼 。。。现在的小孩怎么都这么浮躁

本站回复:

-_-|||

电小弟 @ 2014-12-18 09:38:30

关关雎鸠,在河之洲!

本站回复:

窈窕淑女,君子好逑!

a@lcx.cc @ 2014-12-21 09:39:28

5天不更新了,怎么活?

本站回复:

最近太忙了,一有空就抽时间更新。