本文提供一种SDR应用玩法,供各位参考。
你的跑步打卡都是真实的吗?
背景&契机
实际上搞个项目(不应该叫项目),应该叫小技术应用的契机在于“时间短缺+自身疲累”(就是懒),希望通过技术帮实现跑步打卡的目标。
这完全是突发奇想。当时正在做一个Drone Spoofing的项目,其中有一种实现的方式就是通过软件无线电发送一个假的GPS“位置”,从而完成欺骗任务。那么,想到为什么不能用hackrf 模拟运动轨迹呢?
可能说到这里有些大佬会问,为什么不用fake location?可惜,各位师傅可以去调研一下fake location 在ios运行的效果,不忍直视。lol
提前声明,本篇文章仅仅作为技术分享,作为一种组合技术利用展示,不鼓励大家真正使用。跑步一定要自己来哦!保持一个健康的身体。
真实跑步情况下,软件是如何记录的?
回顾我近期发布的两篇文章,再加上这篇文章,在设计对抗方法时都会涉及到原理,或者说软件(或硬件)功能实现最本质的几个元素的探讨,好像是一种物理层逆向。
热衷于破解芯片的大佬应该可以明白我做要阐述的意思,无论这个PCB板上有多么复杂的电阻、电容、芯片······ 都是存在功能分区的,比如破解电子锁,找到MCU的关键引脚改变其逻辑电压值便可完成开锁操作。类比到程序也就是我们把SDK拖到IDA点击F5,然后find 关键字,改程序。
废话不多说,以这个跑步软件为例,让我来给各位师傅阐述一下什么叫物理层逆向(没逆向跑步软件,我仅从功能实现反推)。“撸”这玩意我们一定要具备的先验知识,这个软件可以记录我们的跑步信息。那么有什么信息呢?可以记录位置、海拔、步频、速度、时间等参数。
好的,我们分治了这个大问题,类比一下,这几个参数的记录至少都各自需要一个.a 文件。下一步“拖拽”到IDA中,分析这几个参数需要什么物理表征?
(1)时间—— 这个参数有两种可能本机系统时间或者软件公司服务器时间。
(2)位置、海拔、速度等信息——手机接收到的GPS信号(海拔信息不确定)。
(3)步频—— 本机传感器信息。
到此为止,从功能实现->参数分治->获取方式都分析出来了(猜想),也就是程序中找到实现功能的函数。下一步是什么呢?看具体功能怎么实现的,决定是执行伪造,还是删改操作。接下来结合三类参数展开讨论:
- 时间:
“搞”之前要判断这个分支重不重要,否则就是浪费时间。在这问题中就不用搞,无论几点只要跑步者开始跑了就一定会记录。 - GPS信息:
这个分支可以说是问题的核心,但是github上已经有比较成熟的软件可以搞定这个问题了——gps-sdr-sim(后续会详细介绍软件安装使用过程)轨迹信息通过Google Map导出kml记录,通过SatGen Trajectory Generation (下载链接见文末,windows软件)生成.nmea文件便可保存下位置以及海拔信息。
跑步速度由生成的标记点投放速度决定。 - 步频:
源于本机的振动传感器,换句话找个外设可以摇摆、震动即可。
如何生成对抗?(实验设计)
需要的硬件设备:
1) computer
2) arduino uno
3) hackrf_one(TCXO时钟模块、天线、数据线)
4) phone(IPhone···)
5) 亚克力手机架子(自制)
需要的软件:
1)hackrf_tools;
2) Google Earth;
3) SatGen Trajectory Generation;
4) gps-sdr-sim
“攻击”的基本流程:
-
伪造GPS轨迹:
通过hackrf,或者说通过SDR伪造GPS定位,可以说是一个比较老生常谈的话题。伪造GPS定位在下是通过hackrf_tools和gps-sdr-sim完成 的。这一部分相较简单。
仅仅通过这个两个软件完成轨迹也是可以的,但是,相信各位师傅都了解,跑步软件不仅会记录跑步者的位置(GPS位置信息)还会记录下海拔信息。为了追求完美,实现比较“真实”的跑步效果,这一部分也就用到了上一个章节向大家介绍的nmea文件。(这一部分参考的是Freebuf上一篇文章,可惜现在被下架了)gps-sdr-sim软件中可以直接载入nmea文件,至此便可在hackrf 辐射出的伪GPS信号中加上海拔参数。 -
解决步频问题(架子摇摆):
这个部分解决的思路实际上是“蛮力法”。开发思路有两种,一去撸代码、搞apple homekit-IOS SDK,加上Xcode强大的功能完成步频API的调用工作。二就是设计一个外设(架子),模拟跑步时的震动,完成步频的伪造。
仔细考量时间成本过后,在下选择了第二种方案。由于这种方案依靠简单的arduino程序,加上几个舵机就可以完成。总结一下,我们的实验设计分为两个部分,对应提供给跑步软件不同类型的参数。hackrf 用于提供GPS轨迹、对应位置的海拔信息;摇摆的架子用于生成步频参数。成功伪造出位置信息和步频参数,有经验的师傅便已知此次跑步过程一定可以被成功记录。
伪造(攻击)跑步轨迹示意图:
具体实验方法&效果
实验方法:
1)RINEX 导航电文:
众所周知要伪造 GPS 信号,首先需要获取 GPS 卫星的观测数据,也就是 RINEX 文件, RINEX 是一种文本文件。
下图我展示一个RINEX文件:
可以在NASA官网上获取 RINEX 格式的 GPS 导航电文,打开这个地址 ftp://cddis.gsfc.nasa.gov/pub/gps/data/daily, 里面是多个以年份命名的文件夹,在里面的 brdc 子目录中,按照上面的命名规则,找到并下载相应年积日对应的 GPS 导航电文文件,比如 2016 年 12 月 31 日的数据,文件名是brdc3660.16n.z,下载然后解压缩,得到的 brdc3660.16n 就是导航电文文件。
有时NASA对外服务器可能公布不是很稳定,建议直接访问NASA官网下载导航电文。
2)轨迹nmea文件生成
得到了导航电文,也就是得到了gps信号的基础。这里我参考之前在freebuf上《超级跑马机》生成的。这种方法需要VPN,这一点就“仁者见仁。智者见智”了lol。
在Google Map上尽量圆润地把各位希望的轨迹描绘出来,生成.kml备用。
下面就要开始骚操作了,还记得我们之前提到的SatGen Trajectory Generation,这款轻量级软件可以生成我们所需要的.nmea文件。放一张软件打开时的截图:
点击load kml,将刚刚生成的kml文件载入,然后在这个GUI界面上调参,使轨迹、速度像个跑步的人,要做到有变化。
为了用户友好,在这里我提供一下我自己调好的参数。我要模拟的是14min左右跑3km。
上述参数可能存在偏差,仅供参考,各位师傅可以按照自己的需要调参。这个程序很友好,会显示总的用时、平均速度。
关于kml以及Satgen软件的图文说明在gps-sdr-sim的satgen目录下有,有需要的师傅详见“3)”在下会详细介绍如何下载gps-sdr-sim软件。
之后点击生成 nmea文件即可。展示一下我自己生成的nmea文件格式(文本编辑器打开)
3)生成hackrf 所需二进制文件:
关于hackrf 命令行控制,Linux版本网上已经广为流传,这里我用mac操作系统举例。
首先,要下载gps-sdr-sim:
$ git clone https://github.com/osqzss/gps-sdr-sim.git
$ cd gps-sdr-sim
gps-sdr-sim 默认最大只能生成 300 秒的数据,需要在编译前,修改 gpssim.h 文件,找到这一行:
#define USER_MOTION_SIZE(3000)
将此处的时长改为各位师傅需要的时长,经验总结这个时长最好是目标时长加上40~70s。
完成生成时长的设定,便可以编译,生成可执行文件。
$ gcc gpssim.c -lm -O3 -o gps-sdr-sim
通过之前的描述,我们有了导航电文,此时有了所需轨迹nmea文件,便可以通过外设hackrf辐射gps 信号。参考代码:
$ ./gps-sdr-sim –e <导航电文文件> -g <轨迹文件> -b 8 -o <输出二进制文件路径>
$ hackrf_transfer -t gpssim.bin(刚生成的二进制文件) -f 1575420000 -s 2600000 -a 1 -x 19 –R
其中,hackrf 二进制文件对应8 bit,1575420000为gps信号输出频段即 GPS 民用L1 频段的频率,2600000为采样率。“-a”代表是否增益,“-x”代表增益dB数最大值为25。
tips:为什么要把生成数据时长增加? 因为通过测试从hackrf辐射gps信号到手机成功更改为对应位置大概需要30~50s的时间。也就是说为了保证跑步距离足够需要在生成路径时故意多生成一段距离,同时要保证尽量在室内等外界gps信号弱的区域,以免造成干扰(出现瞬移)。
具体gps-sdr-sim软件的使用方法,详见根目录下readme文件。
4)步频问题解决:
这部分的设计比较随意,检测到只要是不规则的震动,跑步软件就会识别成成跑步的状态。那么,结合到机械运动,周期性摆动变完美的契合了这一点。这一版中是初稿,而且考虑到实现的时间成本因素,没有用上自己设计的亚克力架子,是在网上购买。
组装好架子,用arduino 作控制器,在IDE上基于舵机编写程序,实现不规则摆动,解决步频检测问题。
参考代码:
#include <Servo.h>
Servo myservo_1; // 定义Servo对象来控制
Servo myservo_2;
Servo myservo_3;
int pos = 0;// 角度存储变量
int potPin = A0; //定义开关
long val = 0;
int angle_right =68;//define 前后旋转角度
int angle_left = 180;
void setup() {
Serial.begin(9600);
pinMode(potPin,INPUT); //define 类型
myservo_1.attach(8); // 下
myservo_2.attach(9); //right
myservo_3.attach(10); //left
myservo_1.write(0);
delay(600);
}
void loop() {
val = analogRead(potPin);
Serial.print(val);
if (val>550){
myservo_3.write(angle_left);
delay(10);
for (pos = 0; pos <= 180; pos ++) { // 0°到180°
// in steps of 1 degree
myservo_1.write(pos);// 舵机角度写入
delay(8);
myservo_2.write(angle_right);
delay(10);// 等待转动到指定角度
if(angle_right<85)
angle_right++;
}
for (pos = 180; pos >= 0; pos --) { // 从180°到0°
myservo_1.write(pos);// 舵机角度写入
delay(8);
myservo_2.write(angle_right);
delay(10);// 等待转动到指定角度
if(angle_right>75)
angle_right--;
}
}
}
实验结果
完事具备,把手机放在架子上运行arduino程序,同时运行hackrf 伪造gps信号。
直接上效果图吧(说的太多,有点用户不友好)
成功搞定。
Attention please!!! 健康的身体需要运动,本推文仅仅作技术分享,以及作分析、解决问题的案例。 如任何人引用本文技术做任何事,与作者无关。
如何改进“攻击”payload
通过以上描述相信大家已经可以发现本方法存在一些问题。
(1) 这里GPS信号是通过无线传播的,具有一定的不确定性,虽然可以通过提高增益来解决,但是噪声也会相应增加,一旦SNR不足够,手机便会产生位置跳变。
(2)再来通过实验表明这种方法可能对IPhone 11及以上版本不适用,猜想这系列手机的天线经过重新设计,有可能接收的gps不是L1 频段gps,或者存在什么算法。这个在后续推文中会进一步研究。
(3)现在任何攻击渗透手段都向着自动化、可视化发展,我的接下来研究可能会形成一个完整的GUI软件。
(4)欢迎各位大佬批评指正。
to be continue
Satgen 软件下载链接:
https://pan.baidu.com/s/1sPQcQhBi4dzQf4D0KQtRLg 密码:g2rm
- 本文作者: Mori
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/230
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!