利⽤HackrfOne进⾏GPS定位欺骗制作超级跑马机
0×00 驾校的困惑
现⾏规定要求每个学员都必须在驾校练习够规定的学时,才能参加考试,在每台教练车上都安装有计时计程终端,学员刷卡刷指纹后开始累计⾥程。但是⽬前中国的很多驾校,存在车少⼈多的情况,假设有 300 个学员,但是只有 20 台车,每个学员要跑够 50km,⽽学员都很忙,只能业余时间练习,这种情况下是完全不可能满⾜要求的。
于是,跑马机应运⽽⽣,它通过伪造 GPS 轨迹,欺骗车载计程终端,达到刷学时数的⽬的。然⽽,受限于其硬件,使⽤效果⾮常不好,每个跑马机只能安装于⼀个终端,并且速度很不稳定,时快时慢,可能会长时间静⽌,也可能从飙车速度突然降到步⾏速度.使⽤跑马机的驾校经常会出现如下的场⾯:
汽车gps定位因为跑马机很不可靠,所以对于实在刷不够的学时,教练只能开着车去⾼速公路兜⼀圈,在油价飞涨的今天,每兜⼀圈驾校⽼板的⼼都要滴⼀次⾎。
既然跑马机的原理是伪造 GPS 信号,那么我想起了那个被我⽤来折腾过所有能接触到的遥控门,遥控车,遥控飞机之后,留在⾓落⾥吃⼟很久的 hackrf one。
Hackrf one 可以稳定的伪造 GPS 信号,并且不需要安装在接收设备上,只要是在发射范围内的接收机,
都可能被伪造的信号欺骗,所以把它当做”超级跑马机”使⽤,理论上是完全可以的。想到了这⼀点,我⼀⾔不合就开始⼲。
需要的设备:
笔记本电脑⼀台,配置随意,最好安装 linux 系统;hackrf one ⼀块(带 TCXO 时钟模块和天线);连接数据线⼀条.
然后安装好 hackrf 所需的驱动和 hackrf-tools,具体安装⽅法这⾥不做介绍,⽹上有很多.
⽤到的软件:
gps-sdr-sim;Gnuradio;hackrf-tools;SatGen Trajectory Generation;Google Earth
具体流程: 获取GPS导航电⽂->制作运动轨迹⽂件->⽣成采样数据->发射模拟GPS 信号.
0×01 GPS 导航电⽂
要伪造 GPS 信号,⾸先需要获取 GPS 卫星的观测数据,在早期,各个接收机⼚商的数据格式各不相同,现在已经普遍采⽤统⼀的 RINEX 格式, RINEX 本质上是⽂本⽂件, 其数据记录与接收机的制造⼚商
和具体型号⽆关,可以做到全通⽤,⽬前使⽤最⼴泛的是其第 2 版格式,RINEX ⽂件遵循标准的命名规则,具体如下图所⽰:
以上每种⽂件类型,其数据格式均不相同,这⾥我们只需要使⽤ GPS 导航电⽂,⽤⽂本编辑器打开后,其具体内容和格式说明如下:
那么问题来了,我们从哪⾥获取 RINEX 格式的 GPS 导航电⽂呢?
答案是 NASA.
打开这个地址 ftp://cddis.v/pub/gps/data/daily,⾥⾯是多个以年份命名的⽂件夹,在⾥⾯的 brdc ⼦⽬录中,按照上⾯的命名规则,到并下载相应年积⽇对应的GPS 导航电⽂⽂件,⽐如 2016 年 12 ⽉ 31 ⽇的数据,⽂件名是brdc3660.16n.z,下载然后解压缩,得到的 brdc3660.16n 就是导航电⽂⽂件.
0×02 运动坐标轨迹⽂件
导航电⽂有了,我们就有了 GPS 信号的数据资源,接下来我们还需要具体的运动轨迹坐标,事实上,现在很多的驾校都是有电⼦围栏的,也就是说,教练车的运动轨迹随时都在监控之中,其坐标必须在驾校的活动场地之内才能算学时,所以我们要伪造的运动轨迹,也必须使⽤真实的所在驾校的坐标,这⾥
我们需要利⽤ Google Earth。
⾸先启动 Google Earth,调整视野,寻到驾校所在地区,然后寻驾校的位置,让驾校的练习场地完全出现在视野中,然后点击⼯具栏上的添加路径:
在地图上,沿着驾校的练习场地,点击勾画出⼀个运动轨迹,尽可能的符合正常⾏车的路线:
为路径起名,点击确定后,它就会出现在左侧的位置列表之中,在上⾯点击右键,选择”将位置另存为”,将之保存为 kml ⽂件:
保存后的 kml ⽂件,是不能够直接使⽤的,它本质上只是⼀种包含路径中关键坐标点的格式,并不包含实际运动轨迹中加速,减速,静⽌这样的数据,我们要对其进⾏转换。
在本案例中,我们需要将 kml ⽂件转换成两种格式的轨迹数据⽂件(两种中任⼀种),下⾯分别做介绍:
1. NMEA 格式⽂件
NMEA 是 GPS 导航设备统⼀的 RTCM 标准协议,具体内容是⼀⾏⾏的描述坐标,海拔及时间轨迹的语句,主要有 GPGGA、GPGSA、GPGSV、GPRMC、GPVTG、GPGLL 等语句格式,这⾥我们只需要 GPGGA 格式,其内容如下:
2. ECEF 坐标轨迹⽂件
ECEF 坐标系⼜叫地⼼地固坐标系,它是⼀个笛卡尔右⼿坐标系,⽤ xyz 三个坐标轴来描述地表的某特定位置,具体如下图所⽰:
ECEF 的原点与地球质⼼重合,x 轴从原点出发,延伸⾄本初⼦午线与⾚道的交点,z轴延伸⾄北极点,y 轴遵循右⼿坐标系与 x 和 z 构成的平⾯垂直。
ECEF 的轨迹⽂件(csv 格式),格式很简单:时间(秒),x 坐标,y 坐标,z 坐标,⽰例如下:
0.0,-3813477.954, 3554276.552, 3662785.237
0.1,-3813477.599, 3554276.226, 3662785.918
0.2,-3813477.240, 3554275.906, 3662786.598
0.3,-3813476.876, 3554275.590, 3662787.278
0.4,-3813476.508, 3554275.280, 3662787.958
0.5,-3813476.135, 3554274.975, 3662788.638
0.6,-3813475.757, 3554274.675, 3662789.318
0.7,-3813475.375, 3554274.381, 3662789.997……………
格式介绍完了,接下来,我们把 kml ⽂件转换成 NMEA 格式,这⾥我们需要⽤到⼀个⼩⼯具,它由 LabSat 提供,是 SatGen 软件的⼀个极简免费版(下载地址见⽂末):
将频率设置为 10hz,然后点击”Load KML file”,就会⾃动加载 kml 路径,然后点击”Generate NMEA file”,即可⽣成标准的 NMEA 轨迹⽂件。
注意此软件会模拟真实的运动情况,⽐如拐弯会减速,起步和结束时会有停留,这些由横向加速度、纵向加速度、加加速度、最⼤速度、起步停留时间、结束停留时间这⼏个参数控制,默认设置是不适合于我们的。这⾥我们举个例⼦,⼀辆由⽼司机驾驶的汽车,和钢铁侠进⾏对⽐:
很明显,在越复杂的运动轨迹下,参数设置的越接近实际物理情况,平均速度就越慢,要想在驾校稳定保持 100km/h 以上的飙车速度,我们必须增⼤三个加速度和最⼤速度的值,然后将起步和结束停留时间设置为 0 才可以。当然,如果驾校没有电⼦围栏,我们完全可以⽣成⼀个包含超长纯直线路径的 kml ⽂件,这样使⽤默认设置转换成NMEA 后,仍然可以达到 100km/h 的稳定匀速.
0×03 ⽣成采样数据⽂件
利⽤上⾯得到的 GPS 导航电⽂和 NMEA ⽂件, 我们可以使⽤开源项⽬ gps-sdr-sim,⽣成⼀个采样数据⽂件,该⽂件会作为我们后⾯实际⼯作时的数据源。⾸先下载 gps-sdr-sim 的源码:
$ git clone github/osqzss/gps-sdr-sim.git
$ cd gps-sdr-sim
然后编译运⾏:
$ gcc gpssim.c -lm -O3 -o gps-sdr-sim
最后按以下参数执⾏:
[NMEA 轨迹]
$./gps-sdr-sim -e <;导航电⽂⽂件> -g <;轨迹⽂件> -b 8[ECEF 轨迹]
$./gps-sdr-sim –e <;导航电⽂⽂件> -u <;轨迹⽂件> -b 8
如果不事先指定名称,默认在程序所在⽬录⽣成名为 gpssim.bin 的数据⽂件。关于 ECEF 轨迹⽂件, gps-sdr-sim 在 satgen ⽬录中提供了⼀个⼩⼯具,可以把 NMEA 格式转换为 ECEF:
$ cd satgen
$ gcc nmea2um.c –o nmea2um
然后执⾏ nmea2um <;源⽂件> <⽬标⽂件>就可以了.事实上,查阅源码会发现,在实际使⽤中, gps-sdr-sim 也是把 NMEA 转换成 ECEF 使⽤的.
为了更好的说明 gps-sdr-sim 各项参数的含义,我在编译前对 Usage 做了:
gps-sdr-sim 默认最⼤只能⽣成 300 秒的数据,需要在编译前,修改 gpssim.h ⽂件,到这⼀⾏:
#define USER_MOTION_SIZE(3000)
注意这⾥的值是乘以⼗的,3000 代表 300 秒,将其修改为我们需要的时间再编译即可,修改的值越⼤,⽣成的⽂件体积越⼤,⽐如修改为 3000 秒后体积会达到将近15G ⼤⼩,不过相对于现在动辄 1t 的硬盘容量来说,这点体积并没有什么卵⽤.
需要特别注意的是,不管是哪种轨迹格式,实际使⽤中其持续时间受限于⽂件中的时间长度,即使按照前⾯的⽅法修改了 USER_MOTION_SIZE 的值,如果轨迹⽂件的时间长度⼩于该值,仍然会以轨迹⽂件为准。
为了让持续时间长⼀些,我们可以制作多个轨迹⽂件,然后进⾏合并,或者⼲脆图省事,⽤⽂本编辑器把轨迹⽂件的所有⾏全选,然后复制 N 遍└(^o^)┘
0×04 猥琐的⾏为终于开始了
现在,⼀切就绪,我们把⽣成的 gpssim.bin ⽂件,转换为信号发射出去,车载计程终端会被⼲扰,将其当做真实的 gps 信号,然后我们的⽬的就达到了,驾校的每⼀辆车都会以飙车速度”狂奔”.然后驾校⽼板笑逐颜开,然后我们会有银⼦赚,哇卡卡卡…..≥▽≤
这⾥特别说明,最初下载的 GPS 导航电⽂的年积⽇是哪⼀天,开始发射信号后,接收终端的时间就会变成相应的⽇期,如果需要准确⽇期,请下载当天的导航电⽂或者在⽣成采样数据时,使⽤-T 参数强制指定⽇期和时间.发射信号具体的实现,有以下三种⽅法:
1. 驾校⽼板只想傻⽠化:
安装 gnuradio ,按照下图搭个流程图,运⾏即可:
以上流程图中,采样速率使⽤ 2600000,发射频率 1575420000hz 即是 GPS 民⽤L1 频段的频率.File Source 模块使⽤的是我们⽣成的 gpssim.bin ⽂件.
2. 驾校⽼板想⽤命令⾏,这样看起来⽐较⾼⼤上:
使⽤ hackrf-tools ⾃带的 hackrf_transfer,执⾏如下命令:
$ hackrf_transfer -t gpssim.bin -f 1575420000 -s 2600000 -a 1 -x 0 –R
3. 驾校⽼板⾮常厉害,会编程(好像实际中也不⼤可能-_-|||)
在 gps-sdr-sim 的 player ⼦⽬录中,有段源码 hackplayer.c,可以直接调⽤libhackrf 发射信号,不过奇怪的是它居然是 Windows 代码,但移植到 Linux 也很简单,稍作改动即可,这⾥我直接提供改好的代码下载(地址见⽂末),然后编译,运⾏:
$ gcc hackplayer.c -lhackrf -O3 -o hackplayer
$ ./hackplayer gpssim.bin
以上三种⽅法,效果完全⼀样,不同的只是逼格,下⾯是实际测试的效果,⾮常好,⼀台 hackrf 可以同时为很多个终端提供服务,并且速度基本稳定维持在预先定义的100km/h:
当然,如果⽼板不怕考试中⼼的交警叔叔来⿇烦,或者⽼板和交警叔叔是好基友,那么你预先设置成钢铁侠速度甚⾄⽕箭速度也是可以的… -.-
0×05 补充
我们还可以进⼀步节约成本,⽤安装好 Linux 的 arm 开发板来替代电脑,这样成本只需⼏百块钱,这⾥我使⽤ Cubietruck,系统为 Debian 7,Debian 源⾥已经有了armhf平台的hackrf,直接apt-get 安装,然后把⽣成好的gpssim.bin拷贝进去(需要注意,此类开发板功率⽐较低,同时接硬盘和 hackrf 带不起来,⽽ gpssim.bin 体积⽐较⼤,所以只能使⽤⼤容量 tf 卡来存放),写个两⾏脚本(gpssim.bin15的路径写成实际的绝对路径):
#!/bin/bash
hackrf_transfer –t gpssim.bin -f 1575420000 -s 2600000 -a 1 -x 0
保存成 start.sh,添加权限:
$ sudo chmod 777 start.sh
然后在/etc/rc.local 加⼊⼀⾏(start.sh 的路径写成实际的绝对路径):
sh start.sh
⽤ usb 线接好开发板和 hackrf one,这样开发板在启动后就会⾃动开启 hackrfone 的信号发射:
最后,我必须严肃的,负责任的,不误⼈⼦弟的讲清楚,即便因为⼈多车少或者⾃⼰没有时间练习亦或是其他原因,⽤了这样的⽅法在驾校刷够了学时,拿到了驾照,但是仍然应该⾃⼰想办法,以其他⽅式进⾏多次练习直⾄熟练才能真正上路,毕竟,有⽆数⾎的教训证明,靠作弊得来的驾照,上路真的危险重重……
SatGen Trajectory Generation
发布评论