前言


Outernet[1]是一家旨在让访问国际互联网更加方便自由的公司,他们使用卫星来广播维基百科或者其他网站。目前,他们的广播主要使用三颗国际海事卫星[3]的L波段[2],使其广播覆盖全球,大多数接收机是开源的,可是,他们的关键部分是闭源的,比如二进制的数据分发模式和信号的详细信息。实际上,Outernet可能违反了GPL ,因为他们的sdr100[4]是基于librtl SDR和libmirisdr[5]开发的,而这两个使用了GPL开源协议。

详情


最近。我逆向了 Outernet 的信号,并完成了一个完全开源的的解码器,他由一个GNU Radio流图 gr-outernet[6]和python脚本free-outernet[7]组成,前者负责获取信号,后者负责提取出传输的文件。

在这篇文章中,我将描述GNU Radio是如何工作的还会介绍一些我用来逆向信号的工具和技术。这些技术可以同样应用于其他的类型的信号,特别是用于卫星通讯的信号(逆向结束之后,我才知道它使用了现成的卫星广播通讯方式,Datum Systems M7[8]),你可以在我的博客[9]中找到更多有关于Outernet的信息和其他项目。

处理射频信号的第一步始终都是调整设备的频率和带宽。即使你不知道怎么解调信号,他在瀑布图上,频率和带宽是很明显的。在这里,我使用Scott Chapman(K4KDR)[10]从 I-4 F3卫星上获取的I/Q数据信号,它在美国上空的广播频率是1539.8725 MHz,我们可以清楚的看见带宽大概是4.8kHz。如果你运行下面的流图,将会看到输出。

我们如果只看这些,基本对信号一无所知,他看起来像一个4.8khz的宽峰噪音,正如 Phil Karn (KA9Q)[11]所说:“任何一个先进的通讯方案都无法区别噪音。”因为它是一个窄带卫星信号,我们猜测它使用的是PSK方式调制的,但是采用的BPSK还是QPSK?这两种都是有可能的。有一种简单的方式可以猜测PSK的类型而不用把它恢复到星图。这个方法是:首先,我们把信号功率提升到2倍(源信号乘以本身),如果我们发现了直流成分,那么这个是BPSK信号,如果没有,我们提升到4倍,如果这时产生直流成分,那么是QPSK信号。这也适用于高阶PSK信号(不适用于QAM),对于一个M-PSK信号来说,提升一个整数倍m时,会产生直流成分。

你可以看下面的流程,当提升2倍时,出现来直流脉冲,这表明,Outernet是BPSK信号。

下面的任务是获取信号的波特率,有一种叫循环平稳分析的方法可以用来获取信号的波特率。使用延时之后的信号复共轭相乘。最好的解释方式就是看下面的流图。

循环平稳分析的输出显示来一个特定频率下的波特率频率分量,在下面的图中,我们可以看到在4200hz处有分量,这表明,波特率是4.2kbaud。频率图中的高平均是很重要的,否则4200hz的频率分量是很难看到的。

现在,我们知道了波特率,我们可以把它恢复成星图,发现它确实是BPSk信号,有关于PSK的解调[12],GNU Radio入门介绍网页[13]有一篇很好的说明。下面,你可以看到我们的BPSK解调器流图和星图,正如预期,这是一个BPSK信号。

Outernet对外所说比特率约为2 kbps,或为20MB每天,而我们分析得到的比特率是4.2kbaud,所以,很有可能它使用了r=1/2正向纠错编码,参数r被称为速率, R = 1 / 2意味着数据流使用了1/2bits用来在接收器中纠正错误位,实际速率只有我们测得速率的一半,也就是2.1kbps。

对于参数是r=1/2的数据,最流行的是使用国际空间数据系统咨询委员会提出的,r=1/2,卷积码K = 7的协议式。针对这种编码的Viterbi解码器在GNU radio中有相应的模块,叫做“Decode CCSDS 27”。然而,这种编码允许在几个变量上有所更改。我们可以使用Balint Seeber[14]的Auto FEC[15]监视Viterbi译码器的误码率并尝试不同的组合参数,直到发现一个可以正常使用的组合。 Auto FEC也可以删余一些数据(超过1/2的部分)。实际上,你很可能不知道它使用了何种删余率,因为变化太多了。

如果想使用Auto FEC,你需要在GNU Radio上打一个补丁,因为 Viterbi 解码器和 “Decode CCSDS 27”模块需要修改以便输出误码率。在这里[16],你可以找到一个用于GNU Radio当前版本的补丁(3.7.10.1测试版),同样,Auto FEC需要输入的是QPSK信号,这有一个补丁[17]可以让他与BPSK 信号工作。

从下面的流图,你可以看到Auto FEC的运行和他的输出,Auto FEC在控制台上打印各种组合,以尝试得到正确的参数。在这个输出中,需要注意的是把  “Viterbi swap”设置为true。他的含义是在CCSDS编码这个特定的环境中,多项式的数值是交换的。通常,A决定第一位,B 决定第二位。而在这里,第一位来自B,而第二位来自A。为了抵消这一点,我们需要交换每对数据,再把他们送入CCSDS协议解码器。

现在,我们实现了一个 Viterbi 译码器并检查了它的工作。“Swap”模块是一个自定义的模块,它交换每一对浮点数。对于BPSK信号,我们要把两个Viterbi译码器放在输入流上,

其中一个比另一个延后一个样本,因为我们不知道刚开始捕获数据的时候,是一对数据的第一个还是第二个。

你可能会看到如下的输出,其中metric变量表示Viterbi解码器的误码率,当误码率很低的时候metric变量很高,而且几乎有一个恒定的数值,相反,如果解码器没有工作,metric值会很低,并具有类似随机的值。当然,两个译码器只有一个正常工作。当BPSK解调错过一个值或者插入来一个值,(样本流多了或者少了一个bit),这两个Viterbi解码器的工作状态(是否工作正常)就会交换,如果信号质量好,不应该发生这种情况,在这个过程中,是由于树木在风中的移动干扰来信号。另外一个有趣的尝试是关闭“Swap”模块,这样的话两个Viterbi解码器都不会正常工作了。

现在,我们对Viterbi译码器是否工作很有信心,我们接下来把数据流放入raster图,观察是否使用了扰频器,如果使用了,数据流会看起来随机化,如果没有,我们会看到一些比特流的特有结构,实际上,我们基本已经确定它使用了扰频器,因为我们之前看到的BPSK信号很像噪声,而不是展现BPSK的特有频谱结构。

正如你下面看到的,比特流的出现是随机的,所以我们还需要一个解扰器。

选择正确的解扰器是很困难的,因为我们没有办法去猜测它的算法,如果您知道它使用来那种卫星调制解调器,请尝试它支持的所有算法,如果您不知道,那就尝试所有流行的算法。这一步通常需要大量的试验和错误。然而,如果选用正确来,效果也是很明显的,你可你看到他的输出比特流结构,如果不对,输出还是随机的。

最常用的一种是G3RUH的复数乘法器(它用于9.6kbaud业余无线电组和几个业余卫星),数据可以使用GNU  radio中的 “Descrambler” 模块加扰,它使用0x21作为掩码,长度为16 ,这个模块的参数选择很麻烦,详见我的博客。[18]

在这种情况中,G3RUH加扰器是无法工作的。有这样的事实,我们的二进制代码要传递给寄存器进行处理, sdr100在Outernet的软件中作为sdr接收器,那么,他只可能是基于ARM或者86-64架构上运行的Linux操作系统,而最新的软件版本只对arm进行支持,所以,Outernet上用于接收的部分应该是像树莓派3一样的arm板。

我对x86-64架构下的客户端程序中的sdr100二进制文件进行了逆向,来获取Outernet解扰算法,原来,这是 IESS-30解码器,很显然,这个算法的详细细节在卫星地球站的文档中没有公开。但是,我还是找到了一个文档[19](见28页),里面的描述有助于我的逆向。

我设计了一个模块用于 IESS-308 解码,您可以在这里[20]看到这个模块的代码。如果你熟悉乘法加扰器,你会发现这个加扰器很普通,但是,它用了一个计数器。

下面的流图可以测试我们的 IESS-308 解码器

输入流显示出了很明显的结构,所以我们有信心,这个解码器是正常的。你可以看到一些白色和青色的水平线,这符合长时间连续二进制0,1传输的特征。这张图中的每行每列的水平线的数量和分布代表着二进制的数据,如果把它们垂直摆放在一条线上,看起来可能更明显,我们会很容易发现什么数据是不改变的(例如报文头)或者改变的(例如数据段)。在这条推文中[21],你可以看到进行如上工作的一个例子。

下一步工作是解帧,通常,我们可以通过仔细观察比特流来识别帧标记,但是,在这里我们可以通过逆向sdr100二进制代码的方式减轻工作量。sdr100中,有一些函数的名称中含有HDLC,所以我们猜测可能是使用来HDLC帧,我们尝试从数据流中恢复HDLC帧。

GNU Radio中,提供了用于解HDLC帧的模块,但是,我准备用我自己的gr-kiss[22]模块。这个模块的好处是可以去保留CRC码校验错误的数据帧。有的时候,可能一个数据帧只有几个bit是错误的,他就被完全丢弃了。然而,保留CRC校验错误的帧对于逆向协议和分析测试是很有用的。有时候,HDLC帧会有几个bit的错误,那可能是因为干扰或者解码器参数没有优化,也有可能碰巧只有16位的CRC码出现了错误。在这种情况下,保留错误帧也是很有用的。

到现在为止,我们还没有考虑信号的极性,在接受 BPSK信号的时候,你不知到他是一个原始信号还是一个翻转信号(即0,1的互换),是否进行了180度的相位翻转是模糊的,很多时候,采用差分编码来消除这种模糊性。HDLC 可能采用的是NRZ-I,也可能没有采用差分编码,而采用其他方式消除模糊,这又是一个实验和试错的过程。

实际上,Outernet不使用任何一种差分编码,因此我们需要一个正置的数据流和一个反置的数据流,只有一个可以正常工作,但是我们实现不知道是哪一个。(当我们失去信号之后,下一次连接,它可能改变。)

下面是HDLC解帧的流图,“Invert bit”是一个自定义的模块,他的功能就是进行位翻转。也可以使用程序提供的模块实现这一功能。下面,我把两个HDLC解帧模块连接在数据流上,在其中一个前面进行位翻转。

当我们运行这个流图之后,在控制台上会看到数据帧的出现。因为我们开启了CRC检查,

所以我们确信我们的接收机可以正常工作。毕竟,如果我们在处理的时候有错误,是不可能出现这么多通过CRC校验的数据帧。

我们GNU Radio阶段的任务就完成了,一旦提取了HDLC数据帧,就需要使用free-outernet[23]这个Python脚本进行UDP发送,或者把它们存在一个文件里。free-outernet会回复被传输的文件,它还会打印一些有趣的调试和技术信息。

下面你可以看到脚本可以恢复的两个文件,e89f-messages-0.html.tbz2包含了用于业余无线电的APRS[25]信息,和ed57-amazon.com.html.tbz2,其中包含亚马逊的维基百科网页[26]。大部分的文件是以tbz2压缩格式发送的。另一个有趣的事情是,每分钟,会有一个时间数据包。这用来更新接收器的时钟信号,因为使用的是小型ARM,所以没有真实的时钟或者网络连接。

提取文件后,我们可以在Web浏览器中打开亚马逊的维基百科页面。这页是一个HTML文件,其中包含CSS样式表和图片。它为独立的查看而进行了小尺寸优化,所以所有的超链接已被删除。

对广播文件协议的介绍超出了本文的范围,你可以在我的博客[27]中找到完整的描述。我唯一不能逆向的是使用了应用级FEC的LDPC编码。它可以使接受程序在一些数据帧错误的情况下恢复文件,由于LDPC码的译码没有实现,所以你需要获取一个文件所有的数据帧才能使用我们的脚本恢复,你可以看到github上有关于LDPC的进展[28]。

参考链接


[1]https://outernet.is/

[2]https://en.wikipedia.org/wiki/L_band

[3]https://en.wikipedia.org/wiki/Inmarsat

[4]https://github.com/Outernet-Project/outernet-linux-lband/blob/master/bin/sdr100-1.0.4

[5]http://sdr.osmocom.org/trac/wiki/rtl-sdr

[5]http://cgit.osmocom.org/libmirisdr/

[6]https://github.com/daniestevez/gr-outernet

[7]https://github.com/daniestevez/free-outernet

[8]http://datumsystems.com/m7

[9]http://destevez.net/tag/outernet/

[10]https://twitter.com/scott23192

[11]http://www.ka9q.net/oldquotes.html

[12]http://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorial_PSK_Demodulation

[13]http://gnuradio.org/redmine/projects/gnuradio/wiki/Guided_Tutorials

[14]http://spench.net/

[15]http://wiki.spench.net/wiki/Gr-baz#auto_fec

[16]https://gist.github.com/daniestevez/79f6f9971e1c6f883cb67a2989ba33e6

[17]https://gist.github.com/daniestevez/70d570292493daac33efb1767fc478ed

[18]http://destevez.net/2016/05/scramblers-and-their-implementation-in-gnuradio/

[19]http://www.etsi.org/deliver/etsi_etr/100_199/192/01_60/etr_192e01p.pdf

[20]https://github.com/daniestevez/gr-outernet/blob/master/lib/descrambler308_impl.cc#L72

[21]https://twitter.com/ea4gpz/status/786518040141717505

[22]https://github.com/daniestevez/gr-kiss

[23]https://github.com/daniestevez/free-outernet

[24]http://www.ax25.net/kiss.aspx

[25] http://aprs.org/outnet.html

[26]https://en.wikipedia.org/wiki/Amazon.com

[27]http://destevez.net/2016/10/reverse-engineering-outernet-time-and-file-services/

[28]https://github.com/daniestevez/free-outernet/issues/1

发表于360安全客 http://bobao.360.cn/learning/detail/3181.html

转载于:https://www.cnblogs.com/backahasten/p/6119315.html

我的翻译--针对Outernet卫星信号的逆向工程相关推荐

  1. java 存储卫星定位数据_gps卫星信号模拟器的特点介绍

    gps卫星信号模拟器是针对不同的用户机设计开发.生产测试.教学演示.测试验收.故障诊断等应用而推出的导航信号源.gps卫星信号模拟器可以模拟出GPS卫星导航定位系统及授时信号,能满足各类GPS信号导航 ...

  2. 【定位不准的烦心事系列】第2篇:卫星信号弱到底是咋回事

    对于每个使用手机导航App的用户来说,最怕听到的就是"卫星导航信号弱"这个提示,因为这意味着定位不准了,用户可能无法获得准确的指引.那么信号弱到底是咋回事呢?明明没有遮挡,咋就收不 ...

  3. GPS卫星信号(一):测距码信号

    GPS卫星信号(一):测距码信号 一.伪随机码 1.码的基础概念 ①.码    表达不同信息的二进制数及其不同组合. ②.码元  一位二进制数叫一个码元(0 或 1). ③.编码  按某种标准用二进制 ...

  4. GPS卫星的导航电文和卫星信号

    基本内容:导航电文的定义.内容:码.比特.随机码.伪随机码的概念:C/A码.P码的产生.数字指标. 重点:导航电文的定义.内容:伪随机码的概念:C/A码.P码的产生.数字指标. 难点:伪随机码的的产生 ...

  5. GPS研究---GPS卫星信号

    文章目录 1.GPS 卫星信号 2.C/A码与P码 1. C/A 码 2. P 码 3.GPS 卫星的导航电文 4.卫星位置计算 1.GPS 卫星信号 GPS 卫星信号是 GPS 卫星向广大用户发送的 ...

  6. GNSS原理与应用(五)——GPS卫星信号

    目录 1.前言 2.GPS卫星信号的组成 2.1关于GPS的三种信号 2.2GPS卫星信号结构 2.3GPS卫星信号频率 3.载波 3.1载波的作用 3.2载波的类型 3.3载波的特点 4.GPS的测 ...

  7. 利用GPS北斗卫星信号开发设计NTP网络时间服务器

    利用GPS北斗卫星信号开发设计NTP网络时间服务器 利用GPS北斗卫星信号开发设计NTP网络时间服务器 引言 准确的时间是天文观测所必需的.天文望远镜在特定时间内的准确指向.CCD曝光时间的控制以及不 ...

  8. 如何高效的实现大型设备中卫星信号的传输和分配?

    无论是在有线.地面站还是传送站,可靠的信号传输和分配是设备保持稳定运行的基础.从卫星天线的信号接收,到设备内的处理和分配,再到最终分配,必须正确设计和管理信号质量可用性.冗余在保证最大可靠性和正常运行 ...

  9. 卫星信号的上行下行学习笔记

    >>>>>>我的博客目录导航 最近被卫星电视信号的发射接收过程弄的头疼,于是潜心找了本书<卫星电视接收DIY>细细看看下. 1.地面信号上星 以前在家弄 ...

最新文章

  1. python添加行索引_python-熊猫在特定级别向多索引添加行
  2. html画三个重叠的矩形,html5 实现两个矩形的叠加
  3. Hashtable,HashMap,ConcurrentHashMap都是Map的实现类,它们在处理null值的存储上有细微的区别,下列哪些说法是正确的
  4. python:编写登陆接口(day 1)
  5. OpenCV gPhoto2 VideoCapture的用法(附完整代码)
  6. SQLErrorCodeSQLExceptionTranslator 使用以下的匹配规则
  7. .Net Core HttpClient处理响应压缩
  8. python获取股票数据_python根据股票代码获取当前数据
  9. 微型计算机技术及应用 考试,陕西理工学院微型计算机技术及应用考试试卷(5份)...
  10. mysql主从之slave-skip-errors和sql_slave_skip_counter
  11. 企业可视化大屏如何搭建
  12. Photoshop操作秘籍
  13. Glide 4.0.0 RC0 使用详解
  14. 聊聊我的 2018 年
  15. c++早绑定和晚绑定
  16. 技嘉显卡性能测试软件,技嘉RTX 3080 GAMING OC魔鹰显卡评测:全方位压倒前辈的新秀...
  17. 手码万字-带你全面了解存储基础知识
  18. JAVA基础(JAVA移位运算符)
  19. 如何正确安装朗文英文当代大词典(2CD版)
  20. MegaCli安装及使用

热门文章

  1. 大白菜装机教程win10_如何通过U盘重装win10系统?
  2. DLink624+A拨号失败的问题
  3. 超级硬干货| 电脑蓝屏代码大全及解决办法合集
  4. 【MySQL基础】MySQL介绍及安装
  5. 个人项目(一)-- 音乐播放器
  6. 九。温暖地待人,你才会得到意想不到的惊喜结果。
  7. 罗克韦尔AB PLC RSLogix5000中计数器指令使用方法介绍
  8. 距离(distance)算法小结
  9. 数学建模之2019年亚太杯(APMCM)S奖获奖经历(零基础)
  10. 怎么打造属于自己的天猫精灵