第3章 网络流量基础:TCP/IP协议栈、数据包结构、常见协议
3.1 为什么必须先搞懂网络流量?
做基于来源IP的异常检测,说白了就是“看包说话”。你连TCP/IP协议栈长什么样都不清楚,抓到IP包也读不懂。
我最早入行时接手过一个告警:某个源IP每秒发几百个SYN包。当时我连SYN到底在三次握手第几步都含糊,查了半天手册才明白——哦,这是SYN Flood。从那以后我再也不敢跳过协议基础了。
这一章我会带你过三个核心东西:
- TCP/IP协议栈的四层模型
- IP包和TCP/UDP段的结构
- 三种常用协议——HTTP、DNS、SSH——在线索层面长什么样
你想想看,攻击者不管用什么花招,最终都要通过这几层把数据送出去。源头IP就在IP层,行为特征藏在传输层和应用层。
3.2 TCP/IP协议栈:分层的艺术
网络通信就像寄快递。你写一封信(应用层),装进信封写上地址(传输层),交给快递公司选路线(网络层),最后快递员用车轮把你送到(链路层)。
常见的分层模型有两种,我做项目时习惯拿TCP/IP四层模型说话,因为更贴近实际的Wireshark抓包界面。
| 层级 | 典型协议 | 检测视角的关键 |
|---|---|---|
| 应用层 | HTTP, DNS, SSH | 请求内容、域名、登录行为 |
| 传输层 | TCP, UDP | 端口号、状态位、序列号 |
| 网络层 | IP, ICMP | 源IP、目的IP、TTL |
| 网络接口层 | Ethernet | MAC地址(通常不用于跨网段检测) |
我的习惯: 在异常检测系统里,我一般只关心网络层和传输层头部。应用层数据太大,处理不过来,除非做深度包检测。
3.3 数据包结构:IP包头与TCP/UDP头
一个IP包长什么样子?你打开Wireshark看看就知道了。但我建议先记几个关键字段,因为异常行为往往就藏在这些字段的“反常”里。
3.3.1 IP包头
- 源IP地址(32位):我们这整门课的主角。
- 目的IP地址:攻击目标。
- TTL(生存时间):每过一个路由器减1。我曾遇到一个攻击者精心伪造了源IP,但忘了改TTL初始值,结果暴露了自己真实操作系统类型。
- 协议号:6=TCP,17=UDP。
3.3.2 TCP头
TCP是面向连接的,三次握手那个经典图大家都画过。但对于异常检测,你更需要关注的是:
- 源端口、目的端口
- 标志位:SYN、ACK、FIN、RST、PSH、URG。我最喜欢看SYN和RST的组合——比如SYN+RST包,正常情况不可能出现,但某些扫描工具会发。
- 序列号与确认号:异常模式如“静默监听”“序列号盲猜”都会在这里露馅。
3.3.3 UDP头
UDP简单,只有源端口、目的端口、长度、校验和。但简单不代表安全。DNS放大攻击就靠小型UDP请求配大响应包,把源IP换成受害者IP。嗯,这些都是我们要检测的。
核心结论: 一个IP包+TCP/UDP头部,一共也就40~60字节。但里面能提取出至少20个特征,足够做一个简单的异常检测模型了。我在第一个落地项目中就用这20个特征,准确率干到了87%。
注意: 千万别忽略IP分片。有些攻击者故意把恶意载荷分片绕过检测。你需要把分片重组后再分析。
3.4 常见协议:HTTP、DNS、SSH
这三个协议在异常检测场景里出现频率最高。我按照“攻击者常用的异常模式”给你拆解。
3.4.1 HTTP——Web世界的灵魂
HTTP基于TCP,默认80端口。HTTP请求行长这样:
GET /login.php?user=admin&pass=123456 HTTP/1.1
Host: target.com
User-Agent: Mozilla/5.0
异常检测常见手法:
- 暴力破解:同一个源IP短时间内大量POST到/login,User-Agent固定。
- SQL注入:URL参数里带单引号、SQL关键字。我曾经用正则匹配 '%27|select|union' 就抓出过一个爬虫类注入器。
- HTTP隧道/代理:攻击者把C2通信伪装成正常HTTP流量。关键特征是请求间隔非常规律(比如每30秒一次),而正常用户是泊松分布。
3.4.2 DNS——域名背后的杠杆
DNS使用UDP 53端口,少数情况切TCP。查一个域名就发一个查询包,返回一个应答包。攻击者特别喜欢用它做反射放大:
- DNS放大攻击:查询类型是ANY,响应包能比请求包大几十倍。源IP伪造为受害者,海量大包淹向受害者。
- DNS隧道:把数据编码在域名里,比如 'data123.evil.com'。检测方法是看域名子串的熵——正常域名像“www.baidu.com”,子串长度和随机性都很低;隧道域名往往高熵、长度超长。
3.4.3 SSH——越过高墙的暗流
SSH默认22端口,加密传输。但别以为加密了就没办法。我们还看以下几个特征:
- 登录失败次数:一个源IP五分钟内尝试50次不同的用户名,基本是暴力破解。
- 会话时长:我见过一个攻击者通过SSH隧道做跳板,每次连接只维持几秒就断,来回反复。正常管理员保持连接至少几分钟。
- 协议版本:有些老旧的SSH客户端版本暴露了对方是攻击工具。
下面我把这三个协议在异常检测场景的关键差异整理成一个表格,方便你速查。
| 协议 | 传输层 | 异常检测关注点 | 常见攻击类型 |
|---|---|---|---|
| HTTP | TCP 80/443 | 请求频次、URL路径、User-Agent | 暴力破解、SQL注入、CC攻击 |
| DNS | UDP 53 | 查询类型、响应大小、域名熵 | 放大攻击、DNS隧道、域流劫持 |
| SSH | TCP 22 | 登录失败率、会话时长、版本号 | 暴力破解、跳板渗透、后门传输 |
3.5 本章知识体系:一张图理清脉络
下面这张SVG图把TCP/IP分层、数据包核心字段及三个常见协议的检测要点串起来了。我建议你先看全局,再回看具体章节。
3.6 实战视角:如何从抓包提取特征?
你不可能手工分析每一个包。所以我们要写脚本。我这里给一个极简的Python示例,用scapy抓取并输出关键字段——这是在给你的检测模型准备原料。
from scapy.all import *
def packet_handler(packet):
if IP in packet:
src_ip = packet[IP].src
dst_ip = packet[IP].dst
protocol = packet[IP].proto # 6=TCP, 17=UDP
if TCP in packet:
sport = packet[TCP].sport
dport = packet[TCP].dport
flags = packet[TCP].flags
print(f"TCP: {src_ip}:{sport} → {dst_ip}:{dport}, flags={flags}")
elif UDP in packet:
sport = packet[UDP].sport
dport = packet[UDP].dport
print(f"UDP: {src_ip}:{sport} → {dst_ip}:{dport}")
sniff(prn=packet_handler, count=10)
避坑指南: 我曾经在生产环境直接跑上面的代码,结果服务器上没装scapy。后来我就把抓包交给tcpdump,再把pcap文件离线分析。建议你在测试机上用scapy,生产环境用tcpdump抓pcap,然后用Python解析。
好了,现在你已经知道TCP/IP分层、包结构以及HTTP/DNS/SSH在异常检测视角下的关键特征了。下一件事就是拿着这些特征去“看”每一个来源IP的行为——这正是我们后面几章会深入的内容。