简介:2019年9月12日,AdaptiveMobile Security公布了一种针对SIM卡S@T Browser的远程攻击方式:Simjacker。攻击者使用普通手机发送特殊构造的短信即可远程定位目标,危害较大 。SIM卡在手机上的使用非常普遍,一旦出现问题就会造成非常大的影响。在当年的报告披露中,全球估算共有10亿设备的SIM卡容易遭受SIM Jacker攻击,本文将对整个攻击进行浅析。
1.一点点背景
要理解攻击,先要搞清楚短信是如何传递的。GSM是全球移动通信系统,由欧洲电信标准组织ETSI制定,是一种数字制式的蜂窝移动通信系统,为的是让全球各地可以共用一套移动电话网络标准,因此它还有一个接地气的俗称——全球通。
GSM与以前的标准相比,最大的不同是信令和语音信道都是数字式的,所以GSM被看作第二代(2G)移动电话系统。短信(SMS)就是基于GSM网络标准的通信服务,允许通过GSM网络发送和接收文本消息。下面看一下整个短信发送流程。

这其中最主要涉及三个主体:发送者、短信中心、接收者。短信必须经过短信中心转发才能到达接收者的SIM卡上。整个流程还涉及不同基站的功能,完整的详细过程可参考这里。
具体步骤如下:
- 发送者编辑短信,通过无线信号(SIM卡)将消息内容发送到基站。
- 基站收到消息,经过一系列网元处理后转发到运营商短信服务中心。
- 运营商短信服务中心经过一系列网元处理,将数据转发到接收者附近的基站。
- 接收者附近的基站将短信内容发送到接收者手机上。
2.PDU模式短信的格式
GSM收发短消息有三种模式:BLOCK模式、TEXT模式和PDU模式。BLOCK模式现在用得很少;TEXT模式只能发送ASCII码,不能发送中文的UNICODE码(技术上可行,但国内手机基本不支持);PDU模式开发起来较为复杂,需要将文本转换为PDU格式,但被所有手机支持,可以使用任何字符集,也是手机默认的编码方式。下面重点了解PDU模式下的短信格式。
以一个真实示例来讲解,下面是用16进制表示的PDU数据:
0891683108200805F011190D91683188902848F40008FF108FD9662F4E0067616D4B8BD577ED4FE1
拆解如下:
- 短信中心地址字段:
0891683108200805F0
- FirstOctet字段:
11
- 消息参考值:
19
- 接收者号码字段:
0D91683188902848F4
- 协议标识:
00
- 编码方法:
08
- 有效期:
FF
- 用户数据长度:
F10
- 用户数据:
8F......E1
短信中心地址字段
这是短信中心的地址,一般SIM卡已写好,所以经常看到00表示默认。08表示字节长度,9168就是+86,表示中国号码,后面跟着号码。
FirstOctet字段
这个字段非常关键,每一bit都有用途。先把十六进制的11转为二进制00010001,从最低位开始,从右往左看:
- 最低两位(
01)表示短信类型,常见的有SMS-SUBMIT(01)和SMS-DELIVER(00)。SMS-SUBMIT表示终端发送到短信中心,SMS-DELIVER表示短信中心发送到终端。这里的01说明这是一条发送者的短信。
- 第2位(
0)表示是否要拒绝重复消息,0为否。
- 接下来两位(
10)表示短信有效期的形式,10表示使用相对时间,这也是常用设置。
- 第5位,这是一个很有意思的参数:状态报告请求。简单说,就是请求网络反馈发送者接收者是否已收到短信。这一机制在USENIX23上被用来实现定位。
- 第6位是用户数据头标示(UDHI)。当它为
0时,表示这是一条普通短信;如果是OTA消息(例如SIM Jacker攻击),就必须设为1。
- 第7位是设置回复路径。每个SIM卡都设置了短信中心号码,如果该位为
0,接收者回复短信时也使用发送者的短信中心;如果为1,接收者将使用自己的短信中心。
下面这张表格可以对照着看:

消息参考值
类似ID,范围0~255。若一条短信被分成多片,短信中心可根据此值将其组装起来。
目标地址
设置与短信中心类似,0D表示号码数字的长度(13个数字)。
协议标识符
它指明一条短信的用途或协议,不仅能用于传统短信传输,也可传输传真、电子邮件或WAP消息。00表示没有特殊协议。静默短信的设置也与此相关,需要将其改为40,这种短信发给接收者时完全无提示。
数据编码方案
指明PDU的编码方式。PDU收发短信有三种编码:7-bit、8-bit和UCS2。00为7-bit编码,04为8-bit,08为UCS2编码,能表达更多字符,7-bit仅简单英文,UCS2可以发送中文。
有效期
根据前面常见的相对有效期设置,FF表示最大30天,00最小5分钟。
用户数据长度
后面跟着的用户数据的长度。
3.一点点实验
了解PDU模型后,一个标准的PDU可以直接用在线网站生成,比如 http://www.sendsms.cn/pdu/。大部分格式固定后,可以修改部分参数。

现在有了PDU格式,怎么发出去呢?最简单的是买一个GSM模块,插上能发短信的SIM卡。不过为了让大家快速体验,也可以使用一台已经Root的手机。我用的是魅族m3 note,比较好Root,大家也可以尝试。
首先通过adb调试,确认已获取root权限:


因为安卓基于Linux,一切皆文件,插入的SIM卡也会映射成文件。一个示例操作如下:

接下来需要找到插入SIM卡后对应的文件。最简单的方法是对比插入前后的变化。直接查看/proc/devices没有变化,说明设备接口早就准备好了。使用dmesg又会因为数据线供电产生很多杂乱信息,而且魅族上使用的也不是smd*。一个一个尝试也会遇到很多问题。
这里有一个更好的办法:查看设备的radio日志:
logcat -b radio | grep dev
先挂起日志监控,再插入SIM卡,会输出大量信号,由此成功定位到SIM卡映射的设备节点。

每个设备对换行符的处理不同,所以建议几种方式一起试,例如:
echo -e "AT+COPS?" > /dev/pts/4
echo -e "AT+COPS?\r" > /dev/pts/4
echo -e "AT+COPS?\r\n" > /dev/pts/4
echo -e "AT+COPS?\n" > /dev/pts/4
echo -e "AT+COPS?;" > /dev/pts/4
echo -e "AT+COPS?;\r" > /dev/pts/4
echo -e "AT+COPS?;\r\n" > /dev/pts/4
echo -e "AT+COPS?;\n" > /dev/pts/4

逐一筛选,这里合适的结尾是\n。
然后发送一条短信试试:
echo -e "AT+CMGF=0\n" > /dev/pts/4 # PDU模式
echo -e "AT+CMGS=20\n" > /dev/pts/4 # 字符长度
echo -e "0031000D9168xxxxxxxxxxxx00000005E8329BFD06\032\n" > /dev/pts/4
之后接收者就能收到短信。\032对应Ctrl+Z,是短信结束符,不计入总长度。
4.SIM Jacker
前面铺垫了这么多,现在来看 SIM Jacker 这个攻击。我们不去细究攻击后果,主要理解背后的原理。
(1)OTA消息
OTA消息也称为二进制消息,是包含一组(U)SIM应用工具包(USAT)命令的特定APDU消息,这些消息针对SIM卡内的特定应用程序,应用程序再执行消息中提供的USAT命令,比如设置呼叫、发送短信、更新SIM信息、编辑SIM文件等。
OTA消息一般是从运营商发给用户,服务提供商可以通过它引入新的SIM服务、修改SIM内容、执行软件更新、配置设置甚至更新加密密钥。正是因为这一特性,导致了SIM Jacker的发生:OTA消息也可以由普通用户发送,而不必出自短信中心。
SIM Jacker的发生需要满足三个条件:
- 短信中心能够接受并转发PDU消息;
- 接收者能够解析SIM应用工具包命令的PDU消息;
- SIM卡上部署了S@T浏览器技术,并且设置为“不应用任何安全措施”的最低安全级别。
还有一些默认开启的条件(如主动UICC命令),在此不赘述。
让我们再回到PDU模式短信的FirstOctet字段,其中有一位可以把普通用户数据变成对SIM卡特定应用程序的执行命令,也就是要把第6位的用户数据头标示设为1。很多SIM Jacker攻击中的PDU也是以0041开头的。
先用一张图来说明整体结构:

前面的字段和之前一样,这里重点解释后面的UD部分:
- 用户数据头(UDH),包含用户数据头的字节长度和设置,可以指明是否包含安全头。
- 命令包(CP)包含有关消息安全性、目标应用程序以及要执行的实际命令等关键信息。
- 命令包长度(CPL):整个命令包的字节长度。
- 命令头长度(CHL):命令头的字节长度。
- 命令头由6个不同值组成:
- 安全参数指示符(SPI)指定是否对消息应用任何安全性。在SIM Jacker中,SPI设为
0x0000。
- 加密密钥标识符(KIC)指明加密类型,设为
0x00。
- 密钥标识符(KID)指定用于加密的密钥,设为
0x00。
- 目标应用程序参考(TAR)标识SIM卡上要发送到的应用程序,这里使用S@T浏览器:
TAR = 0x505348。
- 计数器和填充计数器(CNTR & PCNTR):设置为
CNTR = 0x0000000000,PCNTR = 0x00。
- 安全数据(S@T/STK命令):这是有效载荷中最重要的部分,包含希望S@T浏览器应用程序执行的命令,这些命令使用STK字节码构建,例如可以设置呼叫、发送短信等。
(2)示例分析
下面是一个具体的例子:
AT+CMGF=0
AT+CMGS=69
>0041000B910516325476F87FF6XX027000YYYY0D0000000050534800000000000042230121...2D0C100383...2B00 (CTRL + Z)
将这些字段对应回图上,就能一目了然:

目前已有SIMTester这类检测工具,配合一个读卡器即可进行测试,不过国内SIM卡尚未发现此类攻击案例,自己测试也没有复现。

参考文献
对于移动通信安全与SIM卡攻击的更多深度探讨,欢迎访问云栈社区安全版块。