1. SIP协议基础:从一次失败的呼叫说起
各位同学,今天咱们聊聊SIP协议。说实话,我最早接触SIP是在2008年,那时候帮一家企业排查VoIP通话问题。用户说电话打不通,我抓了个包一看——好家伙,SIP消息格式全乱了。从那以后我就明白,搞安全的人,必须先吃透协议本身。
SIP,全称Session Initiation Protocol,中文叫会话初始协议。说白了,它就是用来建立、修改和终止多媒体会话的。你可以把它想象成电话系统的“接线员”,只不过这个接线员是数字化的。
1.1 SIP协议概述
SIP是IETF在RFC 3261中定义的。它是个应用层协议,基于文本,跟HTTP很像。我个人习惯把SIP比作“打电话的HTTP”——你想想看,HTTP用来传输网页,SIP用来建立通话,本质上都是“请求-响应”模式。
我在项目中遇到过不少新手,上来就问:“SIP是不是就是VoIP?”嗯,这里要澄清一下:SIP只是VoIP体系中的一部分。它负责信令控制,真正的媒体流(你的声音)是通过RTP协议传输的。这个区分很重要,后面讲重放攻击时你会明白为什么。
核心要点:SIP只负责“打电话”这件事的控制流程,不负责“说话”本身。
1.2 SIP消息结构
SIP消息分两种:请求和响应。它们的结构基本一致,我直接上代码:
INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
From: Alice <sip:alice@atlanta.com>;tag=1928301774
To: Bob <sip:bob@biloxi.com>
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta.com>
Content-Type: application/sdp
Content-Length: 142
看到没?结构很清晰:
- 起始行:第一行,标明是请求还是响应
- 消息头:从第二行到空行之前,包含各种元数据
- 消息体:空行之后的内容,通常是SDP描述
这里有个坑,我曾经吃过亏:消息头中的每个字段都有严格顺序要求。比如Via字段必须在From之前,否则某些老旧的SIP服务器会直接丢弃消息。做重放攻击时,如果你修改了消息头顺序,很可能被对端识别出来。
警告:SIP消息头顺序不是随便排的。RFC 3261第7.3.1节有明确规定。做安全测试时,保持原始顺序是最稳妥的做法。
1.3 SIP请求与响应
SIP定义了6种基本请求方法。我列个表,方便你对照:
| 方法 | 用途 | 我的经验 |
|---|---|---|
| INVITE | 发起会话 | 最常被攻击的目标 |
| ACK | 确认响应 | 重放时容易被忽略 |
| BYE | 终止会话 | 可以用来强制挂断 |
| CANCEL | 取消请求 | 注入攻击的好载体 |
| REGISTER | 注册用户 | 注册劫持的入口 |
| OPTIONS | 查询能力 | 信息收集利器 |
响应码也很有规律。1xx是临时响应,2xx是成功,3xx是重定向,4xx是客户端错误,5xx是服务器错误,6xx是全局错误。我刚开始做VoIP安全时,经常记混4xx和5xx。后来我总结了个口诀:“4是你错了,5是我错了”。
举个例子,你发送INVITE请求,对方返回:
SIP/2.0 200 OK
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
From: Alice <sip:alice@atlanta.com>;tag=1928301774
To: Bob <sip:bob@biloxi.com>;tag=88sdf8
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:bob@pc33.biloxi.com>
Content-Type: application/sdp
Content-Length: 143
注意看,To字段多了个tag参数。这个tag是接收方生成的唯一标识。做重放攻击时,如果你直接复制粘贴这条200 OK响应,tag值不变,对端立刻就能发现异常。
技巧:抓包分析时,重点关注Call-ID和tag。这两个字段是会话的唯一标识。重放攻击成功的关键,就是让对端认为你是在同一个会话中。
1.4 SIP URI与地址格式
SIP URI的格式是:sip:user@host:port。比如sip:alice@atlanta.com:5060。5060是默认端口,UDP和TCP都用这个。
这里有个细节,我当年踩过坑:URI中的user部分可以包含特殊字符。比如sip:alice%20smith@atlanta.com,%20代表空格。有些SIP实现会正确解码,有些不会。做注入测试时,你可以利用这个差异来绕过某些过滤规则。
另外,SIP URI还支持参数。比如:
sip:alice@atlanta.com;user=phone
sip:bob@biloxi.com;transport=tcp
第一个表示用户是电话号码格式,第二个指定传输协议用TCP。这些参数在重放攻击中很有用——你可以尝试修改参数值,看看对端会不会处理异常。
嗯,说到地址格式,我记得有一次做渗透测试,目标系统只验证了URI中的host部分,完全忽略了user部分。我就在user里塞了个SQL注入payload,结果还真把数据库给拖出来了。所以说,搞安全的人,对协议细节要足够敏感。
总结一下:SIP协议看似简单,但每个字段、每个参数都可能成为攻击面。理解消息结构、请求响应流程、URI格式,是后续学习重放与注入攻击的基础。别急着上手工具,先把协议吃透。
好了,这一章的内容就到这里。记住我强调的:协议细节决定成败。下一章我们会深入SIP认证机制,到时候你会看到,很多安全漏洞其实就藏在今天讲的这些基础概念里。
公众号:蓝海资料掘金营,微信deep3321