技术分享 | TCP ISN安全性分析
让我们从TCP经典的三次握手开始。正常的TCP连接基于一个三次握手:
1)客户端向服务器发送一个SYN报文,携带初始化序列号ISN(Initial Sequence Number),ISN是一个随机数X;
2)服务器以SYN-ACK报文回应这个客户端,确认序列号为X+1,并且携带自己的初始化序列号ISN,随机数Y;
3)客户端再以ACK报文回应这个服务器的ISN,确认序列号Y+1,完成三次握手。
三次握手过程是建立TCP连接的第一步,所以这里的序列号叫初始序列号ISN。在后续通信中的序列号都是基于ISN计算出来的。所以ISN是后续通信的基础,如果在后续的报文中检查序列号不匹配,这个报文将被认为是非法报文,做丢弃处理。
TCP报文的头部结构如下图所示:
可以看出序列号字段占用32位长度,代表序列号是32位的整数,范围从0-4294967295。
序列号是保证TCP通信可靠性的关键基础,TCP通过序列号来判断报文是否丢失、是否需要重传。
每一个新建立的TCP连接都会分配一个初始序列号ISN,为了防止因为延迟、重传等扰乱三次握手,为了TCP协议栈的稳定性,ISN不能随便选取。一般推荐的ISN生成基本规则:
1)递增,直到超过最大值,再从较小的值开始。ISN如果不是递增的,就可能因为网络延迟导致ISN重复,引起后续通信错乱,连接失败。
2)随机,ISN必须是不可预测的随机数,如果ISN可以预测,将会引起很多安全问题。
序列号对TCP通信来讲就相当于双方对话的暗号,这边说“天王盖地虎”,那边就要说“宝塔镇河妖”,对上号了数据就进入后续环节进行处理。所以TCP ISN最重要的特性就是随机性或不可预测性,如果ISN可以预测,那就会带来各种安全问题。
本节假设TCP的ISN可以被预测,并且传输没有加密,双方仅使用IP地址进行验证,讨论几个ISN相关的攻击。但是并不是说加密就可以避免ISN的相关攻击,只是对于的攻击类型不同,要更复杂。
假设C和S正在进行TCP通信,X是破坏者,可以预测TCP ISN。X可能的攻击包括:
一、身份仿冒
攻击过程简述如下:
1)X首先对C进行攻击(比如Syn Flood),导致C不可用。
2)然后X仿冒C的地址对S发起连接请求。
3)S对C进行回应,附带ISN。注意:这个报文X是收不到的。
4)X可以预测ISN,可以按预测的ISN直接给S回应确认,这时S误认为已经和C建立了连接。
5)X这时就可以仿冒C的地址,发送恶意指令给S,S会认为这是C下发的指令,被欺骗执行,攻击生效。
这个攻击过程中,X不需要获得S的任何报文,就可以对S下发数据,这些数据可能是恶意指令,从而达到攻击的目的。
二、DoS攻击
因为X可以预测C和S的序列号,就可以在C和S通信的过程中,假冒一方的IP地址,频繁抢先一步发送错误的报文:
1)发送序列号正确的ack报文,导致很多正确的报文被丢弃,TCP连接看上起正常,但是因为很多正确的报文被丢弃,实际处于拒绝服务状态。
2)发送序列号正确的fin报文,导致TCP连接关闭,系统处于拒绝服务状态。
三、信息投毒
和DoS攻击类似,但属于更高级别的攻击。因为X可以预测ISN,就可以在通信过程中,假冒其中一方,使用正确的序列号抢先发送非法内容,而正确的报文在到达时被认为是重复的无效报文被丢弃。
这种攻击需要对双方通信协议的内容有一定的了解,塞入的报文符合原来通信规格要求,被认为是合法报文进行了处理。
RFC793是TCP的重要规范文档,该文档中指出ISN可以看作是一个32bit的计数器,每4ms加1,这样选择序号的目的在于防止在网络中被延迟的分组在以后被重复传输,而导致某个连接的一端对它作错误的判断。
TCP协议(RFC793 by Jon Postel)特别指出,在设计ISN生成算法时有几点要关注:
1)是否满足TCP的稳定性、可操作性要求?
2)是否容易实现?
3)是否对性能有较大影响?
4)是否经得起时间的考验?
为了解决ISN随机性问题,1996年制定了RFC1948。在RFC1948中,提出了通过使用HASH单向加密函数,能够使远程攻击者无从下手,但不能阻止同一网段的攻击者通过监听网络上的数据来判断ISN。
RFC 1948提出了一种很难预测的TCP ISN的生成方法,难以预测也就难以发起相关的攻击。此方法通过建立TCP连接的五元组(准确讲是四元组,因为协议固定是TCP,延续惯例我们仍然成为五元组)区分序列号空间。每一个五元组由本地地址、本地端口、远程地址、远程端口来组成,由一个函数对这4个参数进行计算,得到唯一的序列号地址空间偏移值。注意这个函数不能被攻击者获得,否则攻击者就也可以通过计算得到ISN。然后,ISN就在这个偏移值上增加。如果按照这个算法来生成ISN,所有的对TCP ISN的远程攻击都变得非常困难。
我们来看看RFC1948定义的这个算法:
ISN = M + F (Sip, Sport, Dip, Dport, <Some Secret>)
其中
ISN:32位的初始序列号
M:单调增加的计数器
F:单向散列哈希函数 (例如 MD4 or MD5)
Sip:源IP地址
Sport:源端口
Dip:目的IP地址
Dport:目的端口
<Some Secret>:哈希函数可选部分,使远程攻击者更难猜到ISN。
为了保证TCP协议的稳定性,ISN自身的值是需要按照一定规律稳定增加,所以函数F()也需要保持相对的稳定性。而根据RFC所提出的,<Some Secret>是一个系统特定的值(例如机器的启动时间、密码、初始随机数等),这些值并不会频繁发生变化。
有些系统的ISN生成器,为了加快TCP建立连接的时间,提升性能,会采用减少了轮数的MD4函数。削弱了Hash函数,会带来新的弱点,Hash函数的可预测性增强了。
为了弥补这个弱点,有些系统启用定时更换的<Some Secret>来加强安全性。但是因为更换<Some Secret>,可能带来ISN的随机性增强,不能保证稳定增长,可能会影响RFC793提到的可靠性,需要另外采取一些措施来进行可靠性保证。
可以看到,安全性和性能、可靠性之间是有本质冲突的,我们只能找一个平衡,没有一个最优解。如果只是追求随机性,可以采取一些强随机算法生成相对更安全的随机数,但是这将带来的一个问题是ISN空间里面的值的可能很容易互相重复或重叠。这违反了许多RFC(RFC 793, RFC 1185, RFC 1323, RFC1948等)的假设——ISN单调增加。这将对TCP协议的稳定性和可靠性带来不可预计的问题。
最后,虽然RFC有一些ISN相关的规定和建议,但是各个系统都是可以按照自己的设计来实现的。因为生成ISN相对是独立的功能点,这个实现算法不影响TCP协议的对接。早期很多系统在设计时对安全性考虑不足,没有把安全性作为第一要素来考虑,所以现在看早期的一些操作系统,比如Windows 95、Windows 98、Windows 2003,ISN的实现算法都比较简单。有些系统虽然采取了RFC1948的算法,但是没有使用<Some Secret>或者使用固定的<Some Secret>,导致ISN生成算法不够强健。
注意:基于ISN的统计特征来反向推导通信双方的系统和版本也是一个研究议题,推导出操作系统及版本号之后,系统相关的漏洞库就可以派上用途,可以根据漏洞库有目的的构造攻击。
从计算机的工作原理来看,我们很难用一台计算机去生成一些完全不可预测的数字。
计算机被设计成一种可以重复和准确的方式去执行一套指令的机器。所以如果算法是固定的,在其他机器上也可以生成同样的结果。如果能够推断计算机的相关状态,攻击者就可以预测它的输出。
另外所有的算法最终会使ISN回绕,按一定的规律重复生成以前的ISN,所以攻击者即使不知道远程主机的ISN生成函数,仍然可以推断ISN。当前仍然有一部分随机数生成器是产生几百个数字就开始回绕的。
真正解决伪随机数的方法是引入外部随机源,比如键盘的敲击数据、I/O中断数据等。把这些外部数据和一个合理的HASH函数结合起来,就可以产生出32位的不可预知的TCP ISN的值,同时又隐藏了主机的内部状态。但是现在几乎没有TCP ISN产生器是按这种思路去设计的。
随机数预测是数学领域的问题,这里我们简单介绍一下几种常用的随机数预测算法,不做深入分析。
一、线性回归预测法
线性回归是机器学习中的概念,线性回归预测算法一般用以解决“使用已知样本对未知公式参数的估计”类问题。
回归(regression):用已知样本对未知公式参数的估计。
线性回归(linear regression):回归的一种,回归函数是一次函数。
逻辑回归(logistic regression):将回归函数结果一化到[0, 1]区间。
简单来说,逻辑回归是线性回归的一种,线性回归是回归的一种。
线性回归的预测模型虽然是一元线性方程,但现实中很多应用场景符合这个模型。对于早期很多操作系统的ISN生成算法,线性回归预测法的准确率已经相当高,相对误差小于万分之一。
二、加权一阶预测法
加权一阶预测法属于混沌时间序列预测算法,一般应用在天气预报、电力负荷预测、信号处理、自动控制、电子对抗等领域。根据前面的介绍,ISN本质还是和时间序列具有强相关性(根据时间随机递增,达到最大值再回绕),所以加权一阶预测法也可以用来做ISN预测。
加权一阶预测法一般包括4个步骤:
1、重构相空间,即选择一定时间范围内的时间序列数据;
2、选取邻接点,在序列中选择中心点和K个邻接点;
3、计算预测模型的参数,确定参数后,才能根据模型进行预测;
4、预测计算,计算下一个时间序列的值。
三、Delay Coordinates预测法
Delay Coordinates预测法也是通过对历史采样数据的分析来预测以后的数据。这种算法相比上面说的2中算法,要更复杂一些,适用于动态系统和非线性系统。
Delay Coordinates算法在进行ISN预测时,可以构建三维空间(x,y,z)来观察ISN的变化,把ISN这个随机数转换为三维空间的一个点,然后通过三维空间的形状对ISN进行预测。如果三维空间的形状越规则,就代表可分析性越好,ISN越容易预测。
对于攻击者来说,通过delay coordinates,可以观察ISN数列的特征。比如,这个空间模型呈现很明显的空间轮廓,如一个正方体,一个圆柱体,或者一个很小的区域,那么ISN很可能就是这个空间模型A中的一点,预测范围就从一个巨大的三维空间缩小到这个具体的三维空间。
注意:对于工控环境来讲,现场有很多遗留的老旧系统,ISN算法都很简单,很容易预测,也很容易被攻击。
现在,我们来总结一下前面的内容:
1)ISN如果可以预测,就会面临多种攻击;
2)ISN生成算法有局限性,尤其是历史操作系统版本,ISN生成算法比我们想象的还要弱;
3)ISN预测算法已经比较成熟,准确率也比较高。
那么问题来了:对于设备生产厂商,应该采取什么样的ISN生成算法才能保证ISN的安全?对于设备使用者,怎么评价设备的ISN生成算法是否安全?
ISA(International Society of Automation),即国际自动化协会,在制定的嵌入式设备协议健壮性测试用例中,第一个TCP安全测试用例就是验证ISN的随机性,其中要求使用NIST 随机性验证套件来验证。详情可以参考官方网站:https://www.isasecure.org/en-US/Certification/IEC-62443-EDSA-Certification
NIST的STS(Statistical Test Suite)是美国国家标准与技术研究院专门为随机数验证发布的测试软件套件及文档说明。详情可以参考官方网站:https://csrc.nist.gov/projects/random-bit-generation/documentation-and-software
NIST的STS套件中介绍了15种算法,在ISA的EDSA测试用例中,关于TCP的ISN验证要求使用其中的3种算法:STS Monobit、STS Runs、STS Serial。本文主要简单介绍一下这三种算法。
一、STS Monobit算法
这是一种频率验证算法,首先要把随机数序列转换为0、1序列,测试的重点是整个序列中0和1的比例,测试的目的是确定序列中1和0的数量是否与真正随机序列的预期值大致相同。根据随机性定义,序列中的1和0的数量应该大致相同。
这个测试是STS中所有其他测试的基础,只有通过这个测试后,才能再进行其他测试。
算法最终会给出评估值,称为P-Value,一般P-Value大于等于0.01表示通过随机性验证。
二、STS Runs算法
这个算法也叫游程检验算法,测试的重点是游程总次数,其中游程是相同位的不间断序列,比如连续的“11111”或“000”。长度为k的游程就表示由k个相同的位组成。
游程测试的目的是确定各种长度的1和0的游程的数目是否与随机序列的预期一致。 具体讲,就是判断这样的游程之间的振荡切换是否太快或太慢。
算法最终会给出评估值,称为P-Value,一般P-Value大于等于0.01表示通过随机性验证。
三、STS Serial算法
本检验的重点是看整个序列中所有可能的重叠m位模式的频率,目的是判定2^m个m位重叠模式的出现数目是否跟随机情况下预期的值相近似。随机序列具有均匀性也就是说对于每个m位模式出现的概率应该是一样的。选择m后,算法会同时计算m-1、m-2位重叠模式的出现次数进行综合评估。比如m选择为5,那么算法会计算长度为5的所有2进制序列的次数、长度为4的所有2进制序列的次数、程度为3的所有2进制序列的次数,再进行综合评估。
这个算法建议2进制序列长度大于100万个,算法最终会给出2个评估值,称为P-Value1、P-Value2,只有两个P-Value都大于等于0.01,表示通过随机性验证。
NIST 的STS测试套件可以下载源码工程进行编译,源码是Linux下的工程,可以在Linux下直接运行。如果需要在Windows下调试运行,需要下载Cygwin进行编译,注意在安装Cygwin时需要必须选择安装gcc相关组件。
小威自主研发的工控漏洞挖掘平台支持进行协议健壮性验证,当然也包括本文提到的TCP ISN随机性验证。工控漏洞挖掘平台使用的ISN验证算法就是ISA推荐的NIST的三种经典算法,支持采样10万个ISN进行随机性验证。通过漏洞挖掘平台的测试验证,帮助你了解被测系统ISN生成算法的安全性,做到心中有数,从而帮助安全人员决策下一步可能采取的安全缓解措施。
工控漏洞挖掘平台是软硬一体的硬件设备,采用高性能的机架式硬件设计和优化的软件架构设计,可通过直连或桥接方式部署于测试环境中,满足工控设备漏洞挖掘的不同场景需求。系统主要特点:
1、智能Fuzzing测试:通过横向字段关联和纵向状态关联,极大的提升了测试用例的效率。
2、完备的测试用例集:包括风暴测试、语法测试、Fuzzing测试、一致性测试等。
3、全面的TCP/IP协议支持:Ethernet、ARP、IP、ICMP、UDP、TCP。
4、全面的工控协议支持:Modbus TCP、SIEMENS S7、GOOSE、MMS、DNP3、IEC104、Profinet 等多种主流工控协议。
5、方便的漏洞根源分析:采用循环分段检测机制,迅速定位漏洞根源。
6、丰富完整的测试报表:通过多种测试报告模板,全面展示漏洞挖掘结果。
威努特工控漏洞挖掘平台
限于篇幅,本文提到的攻击和相关算法只是做了简单介绍,没有详细说明。如果读者对其中的内容感兴趣,可以联系小威,小威有专业的攻防实验室为你进行攻击解读,看透攻击的内幕和本质,学习攻击缓解的技巧。
更多阅读:
技术分享 |【八步】提高城市轨道交通ISCS系统网络安全(上)
威努特工控安全
专注工控·捍卫安全