从Android短信漏洞到手机钓鱼木马

本文所涉及的技术和代码仅供研究之用,严禁将之用于非法用途,如有违反,所引发的一切后果与本人无关!

认识刘尼玛

  在一个阳光明媚的早晨,小职员刘尼玛像往常一样来到了公司,从表面上看,他是个普通的上班族,每天照常挤地铁,加班,但实际上,他是某秘密组织派到公司卧底的商业间谍,代号叉叉圈圈。

  刘尼玛不是高富帅,相反是典型的屌丝,他得到的情报大部分来源于老总的秘书兼公开情人杨尼美,挫丑穷的刘尼玛之所以能吸引到身材火辣的杨尼美,只是因为他长了一张性感的香肠嘴,杨尼美最喜欢香肠嘴的男人,与刘尼玛有着同样特征的还有老总,只不过杨尼美喜欢的不止是他的香肠嘴,还有他手里大把的票子。

  这家公司有个最奇怪的现象,普通职员刘尼玛和老总的秘书杨尼美当众调情,老总本人却毫不介意,甚至装作什么也不知道,这一点刘尼玛自己也相当诧异。

  “或许老总只是把杨尼美当作玩物吧,对她并不是真的上心.” 刘尼玛一边想,一边把一本名叫《三只小猪的故事》的儿童读物装进纸袋子,交给快递员。”这是我给小侄女买的。” 刘尼玛告诉同事。其实这不是一本普通的书,书的某一页上有他传递给组织的最新信息。

0×00 一个安卓漏洞的原理

  刘尼玛传来的信息说,他注意到老总经常在一个在线交易平台上进行操作,他需要一个短信木马来伪造该交易平台发送的短信,诱使老总访问钓鱼页面来获得账号和密码,现在我是刘尼玛的”Q博士”,我来帮他造这个木马:

  我这里有一个2012年底发布的高危短信漏洞,虽然是老洞,但并不代表没有利用价值,因为移动平台的漏洞生命力是相当强的,原因是没有PC上那么完善的漏洞修补体系,安卓系统漏洞需要进行系统更新来修补,大部分时候是要重刷固件的,这一点普通用户根本办不到,大部分山寨厂家甚至根本不会推出更新固件,所以一个用户买到手机的时候系统是安卓2.3,五年以后他可能还在用这个版本.

  该漏洞影响android4.2以下所有版本,在安卓系统的底层短信代码中,一个名为com.android.mms.transaction.SmsReceiverService的服务的android:export属性被设置为了true,也就是说,外部程序可以任意调用这个服务。

  在安卓系统接收到pdu短信代码之后,会通过名为android.provider.Telephony.SMS_RECEIVED的action调用此服务,先将pdu短信解码,然后将之显示在手机屏幕上,恶意攻击者可以在自己的程序中通过一个同名的action,不经过任何短信接收程序,直接伪造一条pdu短信调用此服务,具体过程如下图所示:

  根据这个流程可以看出,这个漏洞发送的短信并不经过GSM网络,所以即使手机没有插sim卡,也照样可以收到短信,这让大部分的短信防火墙完全失效。

0×01 PDU短信的结构

  要利用此漏洞,我们首先要清楚手机短信的结构,短信在手机操作系统中并不是以我们平常见到的文本格式传送的,而是有特定的编码格式,其中最为广泛使用的就是PDU,短信被编码成PDU串,然后转换成byte传输,这其中发送短信和接收短信的PDU串格式是不同的,由于这个漏洞直接触发了接收流程,所以这里我们只介绍接收格式,发送格式请自行google.

  接收短信的PDU结构如下:

SCA

PDU TYPE

OA

PID

DCS

SCTS

UDL

UD

短信中心地址

PDU类型(可选)

发送短信的手机地址

协议标志一般为00

编码标准

短信接收的时间

短信内容的长度

短信内容

长度

短信中心类型(可选)

短信中心号码

长度

地址类型(可选)

发送号码

看着晕了吧,其实并不复杂,下面每部分分别叙述:

1 SCA短信中心地址

实际上中间的短信中心类型大部分时候是不用的,我们只需构造号码的长度+号码即可。

2 PDU TYPE短信类型

有七个值可选,一般写04代表普通sms短信.

3 OA 手机地址

格式同SCA。

4 PID 协议标志

所有运营商都支持00这个值,所以直接输入。

5 DCS 编码标准

一般常用的是两种,输入00代表7bit编码,只能传输英文,输入08代表UCS2编码,可以传输中文,但最多只能传送70个字,这就是为什么我们在发送长短信时常常被分割成几段的原因,这里我们理所当然要输入08.

6 SCTS 接收时间

这个时间所用的格式与我们平常所见的不同,是一种倒过来的格式,结构如下: 年+月+日+时+分+秒+offset

其中每一项都是反着位数写的,且年份为两位数,比如2013年11月20日21时38分51秒,按这个格式写就是: 31110212831523 最后的23是offset,代表你现在所处时区和格林威治时间所偏移的值,查阅资料得知北京时间的值就是23.

7和8没什么好解释的,就是短信的长度和内容.

之所以费了这一大段讲述PDU的结构,是因为不熟悉这个,后面的内容根本无法看懂。

休息一下,刘尼玛乱入

这个漏洞在安卓4.2以下才有效,那到底刘尼玛老总的手机是不是在这个范围内?列位看官放心,这个刘尼玛早就打听到了,老总的手机是2012年8月份买的,也就是在4.2发布之前,这个重要情报是在杨尼美坐在刘尼玛大腿上调情的时候,刘尼玛好不容易套出来的,当时的刘尼玛早已经”飞龙在天”,他一边咽着口水一边拼命把它记了下来,屌丝情报员真不容易啊。

0×02 漏洞触发的代码实现

  光把短信编码成PDU串是不够的,短信的号码和内容实际上是以二进制的BCD码格式传输的,google已经提供了十进制数转BCD码的函数networkPortionToCalledPartyBCD,我们可以直接把号码转换成BCD,至于短信内容,这个比较复杂,直接从网 上扒拉了一个现成的字符串转BCD函数str2Bcd.

新建一个工程,名为SMSAttack,将主要攻击代码写成一个名为smsservice的服务,该服务在AndroidManifesy.xml中注册名称为SMS_SERVICE.

(代码太长,见下方“阅读原文”)

在手机上调试,程序启动后,收到10条冒充移动公司发来的短信:

注意我这里测试用的手机上并没有插sim卡,但仍然成功收到短信。

0×03 从Exploit到完善的木马

  上面这个程序虽然实现了伪造短信的过程,但充其量只能算是个Exploit,要把它改造成一个可用的钓鱼木马,我们还有很多工作要做.

  安卓平台的木马程序和PC上的有很大的不同,其原因主要有以下两个方面:

  一是网络的问题,手机和平板不可能时时都有稳定的网络连接,会经常在不同的wifi和gsm网络之间切换,而且有时网络会被人为关闭,所以安卓木马注定是被动连接的,且不能使用socket,只能基于http协议来反向连接.

  二是流量的问题,安卓手机上都有流量监控软件,当处在gsm网络时,控制端不可能发送大量的数据包,这样会引发流量报警的.

  基于以上考虑,我们需要设计一个流程来打造我们的木马:

首先我们需要注册一个新的服务smsdaemon,在AndroidManifest.xml中的注册名称为SMS_DAEMON,并把它设置为开机自动启动,当启动后,开始探测网络连接,如果有网络可用,则连接远程控制端的http服务器,获取控制指令,触发SMS_SERVICE服务发送短信,如果没有网络可用,则在后台等待,注册网络状态监听广播BootBroadcastReceiver,当网络可用时再连接服务器。

  以上方法有个问题,每当网络状态改变一次,SMS_DAEMON就会从服务器获取指令触发短信接收,因为手机的网络状态经常改变,所以短信有可能被重复发送很多次,所以接下来我们要给SMS_SERVICE注册一个AlarmReceiver广播,在服务器上加入时间控制指令,SMS_SERVICE接到SMS_DAEMON发来的控制指令,会一直等待,直到到达指令中指定的触发时间才发送短信,具体流程如下图所示:

然后是流量的问题,一般来说,手机客户端从http服务器获取数据有两种方式:xml和json,显然后者要省流量的多,所以我们需要先搭建一个web服务器,然后在上面构建一个json控制页面。

Web服务器地球人都知道如何搭建,我在这里不再详述,只构造json的指令结构:

number: string 伪造的短信发件人号码
message: string 短信内容.
count: int 短信的发送次数.
issend: bool 是否发送短信.
date: string 短信的触发时间

一条完整的控制指令应该是下面的样子:

{"command":{"number":"10086","message":"移动不是垃圾","count":1,"issend":true,"date":"2014_01_10_00_00_00"}}

我们还要在SMS_DAEMON中编写代码,让它在获取指令后将其存入SharedPreferences中,调用SMS_SERVICE后再由其从中读取.

现在万事具备,我们来看如何用代码实现:

注册一个BootBroadcastReceiver,将SMS_DAEMON设为开机启动。

再写一个AlarmReceiver来监听时间,将所有的服务和广播在AndroidManifest.xml中注册SMS_DAEMON的代码如下。

(代码见下方“阅读原文”)

0×04 运行结果

代码编写完成后,编译并上传到手机调试,在控制指令指定的时间,手机成功收到了短信:

刘尼玛现在还不能使用它

木马是编写完成了,但还不能投入使用,因为我们要把它注入到一个正常的程序中,欺骗刘尼玛的老总安装它,但那是另一个故事了……

预知后事如何,且听下回分解.

本文的所有源代码和本文的PDF版已打包提供下载:

http://pan.baidu.com/s/1gdxczDp

‍本文章为红客联盟(cnhonker)b41k3r写的刘尼玛系列的第一篇,经他本人同意发到Freebuf,同时感谢Freebuf给我们提供一个良好的交流平台。

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2014-04-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏梦里茶室

收藏的技术文章链接(ubuntu,python,android等)

开发过程中收藏在Chrome书签栏里的技术文章,与自己的文章分开。 主要涉及python,android,ubuntu等内容,我自己常常在这里面找回忘了的知识...

45911
来自专栏大数据挖掘DT机器学习

如何通过python爬虫来全自动抢微博红包?!

作者:admin IDF实验室 http://blog.idf.cn/2015/02/programming-of-grabing-red-envelop...

8805
来自专栏Python数据科学

这些世界杯球星你真的认识吗?不如通过Python来认识一下吧

回到我们的正题,对于世界杯的球星们,人们知道的一般都是C罗,梅西,德罗巴等巨星,而对一些其它球星却很少了解。对于这些球星,你认识的有多少呢?下面就跟我一起认识一...

862
来自专栏AI-vell

黑科技:程序员如何打造属于自己的分体键盘

为了不要这么纠结,就自己diy一个咯,正好有台3D打印机(又一个装B神器,你值得拥有,O(∩_∩)O哈哈~),全部外壳自己打印,控制板用Arduino Leon...

9958
来自专栏進无尽的文章

地图| 高德地图源码级使用大全

高德地图提供包括:web前端、Android、iOS、服务器、小程序等平台的地图服务, 地图功能众多,本文记载的只是自己遇到的一些问题,绝大部分功能只要参照官...

4762
来自专栏AI科技评论

开发 | 星际争霸2人工智能研究环境 SC2LE 初体验

1 前言 昨天,也就是2017年8月10号,DeepMind联合暴雪发布了星际争霸2人工智能研究环境SC2LE,从而使人工智能的研究进入到一个全新的阶段。这次...

4758
来自专栏移动端开发

AVFoundation 框架初探究(一)

夜深时动笔 ----       前面一篇文章写了视频播放的几种基本的方式,算是给这个系列开了一个头,这里面最想说和探究的就是AVFoundation框架,很想...

7165
来自专栏龙行天下CSIEM

科学瞎想系列之八十二 永磁电机(5)

【图片部分来自网络如有侵权敬请邮箱联系。欢迎原文转发到朋友圈,未经许可的媒体平台谢绝转载,如需转载或合作请邮件联系。联系邮箱laolicsiem@126.com...

1080
来自专栏北京马哥教育

余生只够写50行代码,这么写绝对赚翻了

学Python最简单的方法是什么?推荐阅读:Python开发工程师成长魔法 假如有一天死神来找你,警告你最多只能再写50行代码,然后就得随他而去,应该写点什么...

3208
来自专栏BIT泽清

教你如何提审iOS马甲包不会遇到2.1大礼包或4.3正确姿势分享

App Store 搜索关键词 世界杯 或者 通过链接下载 皇冠Ьet365-世界杯体育赛事直播吧:https://itunes.apple.com/cn/ap...

8315

扫码关注云+社区

领取腾讯云代金券