论文题目
SYMTCP:Eluding Stateful Deep Packet Inspection with Automated Discrepancy Discovery
发表会议
Title:SymTCP: Eluding Stateful Deep Packet Inspection with Automated Discrepancy Discovery
Author:Wang, Zhongjie and Zhu, Shitong and Cao, Yue and Qian, Zhiyun and Song, Chengyu and Krishnamurthy, Srikanth V and Chan, Kevin S and Braun, Tracy D
Booktitle:NDSS 2020
一、论文摘要
DPI的一个重要特征就是其单独实现了一个关于网络协议栈的简化状态机,其和许多终端的实现不同。利用 DPI 和终端的网络协议实现的不同可以穿透 DPI 中间件。之前针对 DPI 的绕过攻击大多是基于人工构造对抗性报文,不仅耗时耗力,并且不方便在不同版本的 DPI 之间进行拓展。本文的工作就是实现了一个可以自动生成针对 DPI 对抗性报文的系统,其主要思想是利用 DPI 和终端的网络协议实现之间差异。本文利用符号执行技术自动化探索终端的 tcp 实现过程,明确了针对终端的逃逸 ( 被 DPI 忽略但被 server 接受 ) 和插入 ( 被 DPI 接受但被 server 忽略 ) 的报文;然后利用这些得到的报文针对 DPI 进行测试,来判断 DPI 针对这些报文的处理行为是否和终端相同。本系统可以咋一小时内生成数以万计的对抗性报文,并且我们测试了最先进的 DPI 设备,比如 Zeek 、 Snort 、 GFW( 中国长城防火墙 ) ,不仅发现了已经暴露的逃逸策略,冰企鹅额也发现了一些从未发现的逃逸策略。并且本系统可以很方便地向其他操作系统或者 DPI 中间件进行拓展,本系统也可以作为 DPI 对抗性检测工具。
二、研究动机
当前针对 DPI的绕过攻击研究大多数是基于人工分析其脆弱性,并且研究成果无法方便地向其他系统进行拓展,本文旨在研究并实现一个可以自动化生成 DPI 对抗性报文的系统,来绕过 DPI 检测。
三、脆弱性分析
DPI实现了其自身简化的 TCP 有限状态机,虽然 TCP 的具体协议有统一的标准,但是具体实现起来,不同系统中将会存在差异,这就导致 DPI 和终端系统针对 accept/drop 报文的认定存在一定的差异,利用 DPI 和 endhosts 之间存在的差异,我们可以绕过 DPI 的检测,传输一些非法的报文。
四、主要贡献
作者利用公式定义了 insertion/evasion包,为之后探索 TCP 空间寻找 insertion/evasion 提出了一个通用的方法。
开发了一个端对端的原型系统 SYMTCP,其可以自动化的发现 DPI 以及终端系统中 TCP 实现的差异。
将 SYMTCP针对 Zeek , Snort , Great Firewall of Chine(GFW) 进行测试并发现了许多逃逸策略,并且本系统还十分方便的可以向其他系统或者其他 DPI 进行拓展。
五、背景介绍
(一 ) DPI绕过攻击
DPI主要是针对应用层报文进行判断,来认定其内容是否合法从来进一步选择是否放行报文。 DPI 首先从 interface 中抓取报文信息,经过 parser 处理之后生成 parser output ,然后利用 pattern 匹配进行判断,根据判断结果认定其内容是否合法。
DPI绕过的一个主要原因是针对 TCP 的实现, DPI 和终端系统实现具体不一致,比如针对 Snort 来说,只要是 RST packet 的 sequence number 在接受窗口之内,这个 RST packet 就可以被 Snort 接受,但是针对最新版本的 linux 实现, RST packet 的 number 必须确保其和 rev_next 报文相匹配。
DPI绕过的第二个原因是 DPI 不知道具体的网络拓扑信息,即其放行的报文不确保其可以作用于终端系统,比如一个 TTL 很小的 packet ,大概率是不会到达终端,即其对终端不起作用,但是其可以真实的作用的 DPI 中。
(二 ) 符号执行引擎选择
本文选择了 selective symbolic execution,由于其可以选择性的符号执行我们指定的程序范围内的程序代码,所以其可以更灵活以及方便地测试大型软件,比如 linux 内核,本文中针对 linux 内核中的 tcp 实现过程,利用符号执行过程进行路径探索,针对其余部分采用真实执行,这样通过符号执行过程和真是执行过程的切换,来实现针对 linux 内核的测试。
本文在具体实现环节,采用 S2E作为实际环境,其提供了不同层级的执行一致性,可以在性能、 completeness 、 soundness 之间进行权衡。
六、解决方案
(一 ) 问题定义
首先对问题进行抽象化,便于之后解决问题。前面的几个定义均是为了后面定义 insertion/evasion包做准备。
1. TCP状态机
M = (Q, q0, Σ,Λ, T, G)
Q is the set of states,
q0 ∈ Q is the initial state,
Σ is the input alphabet, i.e., a TCP packet,
Λ is the output alphabet, i.e., the TCP data payload,
T : Q × Σ → Q is the state transition function, and
G : Q × Σ → Λ is the output function.
M表示有限状态机, Q 表示状态集, q0 表示起始状态, Σ 表示输入字符集, Λ 表示输出字符集, T表示状态转函数, G 表示输出函数。
需要特别注意的是,输出对应的是存储应用层内容的 buffer内的内容,而不是生成的 tcp 报文,一是因为 DPI 检测的内容主要是应用层报文,而是因为 DPI 对报文处理之后不生成任何特别的 tcp 报文。
2. Drop
T(q, P) = q ∧ G(q, P) = ε
当状态机 M在 q 状态下处理报文 P 后,既没有状态的改变,也不产生任何的输出,那么认定报文 P 问 drop 报文。
3. Accept
T(q, P) != q ∨ G(q, P) != ε
当状态机 M在 q 状态下处理报文 P 后,或者发生状态的改变,或者产生任何的输出,那么认定报文 P 问 acceptdrop 报文。
4. Bad Keywords and Alarm
将任何可以出发警报的内容称作 bad keywords,并且认为其可以存储在一个 tcp packet 内,并利用过滤函数 F 来判断是否有 keyword 。
5. Synchronized
GMs (q0, P1...n) = GMd (q0, P1...n), P1...n ∈ Σ
当 server的状态机 M 在 q0 状态处理 P1...n 之后产生的输出,同 DPI的状态机在 q0 状态处理 P1...n 之后产生的输出相同时,认为 server和 DPI 和同步。
6. Evasion Packet
a .The server will accept every packet P1...n
b.When handling P1...n-1, the state machine of the server and the DPI engine are synchronized
c .F(GMs (TMs (q0, P1...n+r-1), Pn+r)) = 1 ∧ F(GMd (TMd (q0, P1...n+r-1), Pn+r)) = 0
需要满足三个条件,第一个是 server可以 accept 报文序列 P1...n ;第二个是在处理报文序列 P1...n-1 时, server 和 DPI 是同步的;第三个条件是 DPI 不处理 Pn 报文,由于为了具有可观测行为,在 P1...n 报文序列后又添加了 r 个报文,其中第 r 个报文中含有 bad keywords 。
7. Insertion Packet
同 Evasion报文相反。
(二 ) 状态过程选择
如上图所示,作者在进行符号执行过程之中,只针对状态机中 LISTEM到 ESTABLISH 这一个阶段进行测试,这么做的原因主要有以下原因,首先因为其代表着完整的 insertion/evasion 报文的窗口可能;其次是因为本测试针对的报文序列长度最长为 3 ,这个长度的报文可以完整的将状态机从 LISTEN 状态驱动到 EATABLISH 状态。
(三 ) 符号化报文
符号化变量时,只符号化 tcp header中除了 source port 以及 destination port 以外的内容,即上图中所示蓝色部分,对于 IP 层以及应用层内容,不进行符号化。
额外需要注意的是,由于 checksum字段是需要根据 ip 层以及应用层信息计算,所以作者在实际过程中,针对 checksum 做了抽象,用 0 代表 checksum 为错误,用 1 代表 checksum 为合法字段。 Options 可选字段由于其有多种选择,再加上左右的排列组合,如果正常符号化会大大降低符号执行效率,因为根据监控流量中常见的 options 组合给 options 赋值。
(四 ) 工作流程
程序工作流主要分为线上线下两个测试阶段,首先是进行线下测试,针对的 linux kernel,看作是白盒子;然后是线上测试,针对的是 DPI ,看作是黑盒子。
1. Offline Symbolic Execution
线下针对 linux kernel的测试属于白盒测试,首先需要确定的是程序边界问题。文章中提出了两种方法,一种方法是采用人工具体分析 TCP 实现的代码边界,但是这种方法比较费时费力;第二种办法是直接将 net/ipv4 单元编译成可执行文件,然后监控程序的执行的过程,当程序代码执行到对应的可执行文件代码地址内时,切换实际执行到符号执行,当执行代码执行在这个范围之外时,切换符号执行到实际执行。
而 KLEE原本实现过程之中,在实际执行阶段也会记录约束,切换到符号执行过程时,会引入无关约束,导致求解复杂度增高,因此作者实现过程中,针对 KLEE 做了改动,去除了实际过程中对无关约束的记录;并且在符号执行过程中,并不会对 if 、 else 、 goto 等跳转作出特别的记录,其只针对基本块内部的执行过程,而对于基本之间的边界关系并不在意,而 insertion/evasion 的判断很大程度上取决于基本块之间的跳转关系,所以作者在实现系统时,也对基本快之间的跳转关系做了特别的记录。
在白盒测试阶段的输入为符号化的 tcp packet seed,并且我们实现在 linux kernel 中标记了一些 drop/accept 点,比如当程序执行路径经过 drop point 时,认为此 packet 包被 drop ,当执行路径经过 accept point 时,认为 packet 被 accept 。然后利用混合符合执行进行路径探索,探索结束之后得到针对 linux kernel 的 accept/drop packet 以及对应的约束,以及 linux kernel 经过处理这些包的之后对应的 tcp 状态。
2. Online Probing
在线上针对 DPI的测试为黑盒测试,其输入为针对 linux kernel 白盒测试得到的 accept/drop packet 以及对应的约束,此外还需要一些额外约束,比如 initial sequence number 、 tcp flag 等。将其放入求解器求解得到实际赋值的 packet 。此外还需要链接一些后续报文。
因为 DPI属于黑盒测试,当我们利用事先得到的 packet 进行测试时,不知道其处理完这些 packet 之后处于的 tcp 状态,也就是说无法和 linux kernel 白盒测试之后的 tcp state 进行比对,无法知道 DPI 的 tcp 实现和 linux kernel 的 tcp 实现是否相同。因为我们需要根据他应当处于的 tcp state(linux 白盒测试之后的 tcp state) 构造后续报文,使得其处理之后可以得到可观测反映。
当我们将求得的实际报文以及后续报文拼接之后,对 DPI进行探测,根据观测其反应来判定其和 linux 白盒测试结果是否一致,得出报文是否是 insertion/evasion 报文。
七、 实验结果
作者将系统测试了 Zeek、 Snort 、 GFW 三个 DPI ,得到系统结果如下图所示。
根据上图可以看出针对每一款 DPI, SYMTCP 均测出了许多已知以及未知的 evasion 策略,具体逃逸策略如上图所示。
比如针对 GFW发送报文 FIN packet 但是不带有 ACK flag ,此时 GFW 会断开连接并重连接,而 linux 则直接丢弃这个报文,仍保持连接,后续即可不经 GFW 检测发送未经检查的报文。
八 、结论
在本文中,作者利用符号执行过程驱动生成 insertion/evasion报文对抗 DPI ,我们利用 TCP 的具体实现在 DPI 以及 linux kernel 之间的不同,设计开发了一个端到端系统 SYMTCP ,并且将其针对注明的 DPI 进行了测试,如 Zeek 、 Snort 、 GFW ,其能力均得到了验证,并且本系统可以很方便的向其他系统或者 DPI 进行拓展。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-1-5 09:18
被Seclusion编辑
,原因: