一、SIP协议基础回顾

各位同学,咱们今天聊聊SIP协议。说实话,很多搞VoIP安全的人,对SIP的理解都停留在「能打电话就行」的层面。但你要做劫持、做中间人攻击,不懂SIP细节,那就是盲人摸象。

我个人习惯,每次讲SIP之前,都会先问一个问题:SIP到底是个什么玩意儿?

简单说,SIP(Session Initiation Protocol)是应用层信令协议,负责建立、修改和终止多媒体会话。它不负责传输媒体流——那是RTP的事。SIP只管「握手」,不管「握手之后干什么」。

核心要点:SIP是信令协议,不是媒体传输协议。很多攻击者混淆了这一点,结果在信令层面搞了一堆操作,媒体流却纹丝不动——白费功夫。

SIP消息结构:请求与响应

SIP消息分两种:请求(Request)和响应(Response)。结构上,它们都包含起始行、消息头和消息体。

我当年在项目中排查一个诡异的呼叫失败问题,查了三天,最后发现是消息头里少了一个Via字段。嗯,这种坑,踩过一次就记住了。

请求消息

请求消息的起始行格式是:方法 URI SIP版本。常用的方法有:

  • INVITE — 发起会话邀请
  • ACK — 确认响应
  • BYE — 结束会话
  • CANCEL — 取消未完成的请求
  • REGISTER — 注册用户位置
  • OPTIONS — 查询能力

举个例子,一个典型的INVITE请求长这样:

INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: Bob <sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710@pc33.atlanta.com
CSeq: 314159 INVITE
Contact: <sip:alice@pc33.atlanta.com>
Content-Type: application/sdp
Content-Length: 142

(SDP消息体)

响应消息

响应消息的起始行格式是:SIP版本 状态码 原因短语。状态码分6类:

状态码范围 类别 示例
1xx 临时响应 100 Trying, 180 Ringing
2xx 成功 200 OK
3xx 重定向 302 Moved Temporarily
4xx 客户端错误 401 Unauthorized, 404 Not Found
5xx 服务器错误 500 Server Internal Error
6xx 全局错误 603 Decline

个人经验:做安全测试时,我最喜欢看4xx和5xx响应。401 Unauthorized往往意味着认证机制薄弱,500 Internal Error可能暴露服务器实现缺陷。我曾经靠一个404响应,顺藤摸瓜找到了一个未授权的注册服务。

SIP URI与地址格式

SIP URI的格式是:sip:user@host:port。比如sip:alice@atlanta.com:5060。默认端口是5060(UDP/TCP)或5061(TLS)。

这里有个坑,我提醒过很多次:SIP URI中的@符号,在攻击场景下经常被用来做用户枚举。你想想看,如果攻击者不断尝试不同的用户名,看服务器返回的是404还是401,就能判断用户是否存在。这叫「用户枚举攻击」,后面我们会详细讲。

另外,SIP URI还支持参数和头字段,比如:

sip:alice@atlanta.com;transport=tcp?subject=project

分号后面是URI参数,问号后面是头字段。这些在劫持攻击中,经常被用来注入恶意参数。

SIP会话建立流程

标准的SIP会话建立,就是经典的「三次握手」:INVITE → 200 OK → ACK。但实际流程比这个复杂得多。

我画了一张图,帮你理清整个流程:

SIP会话建立流程(基本呼叫) 主叫方 (UAC) 代理服务器 被叫方 (UAS) ① INVITE ① INVITE ② 100 Trying ② 100 Trying ③ 180 Ringing ③ 180 Ringing ④ 200 OK ④ 200 OK ⑤ ACK ⑤ ACK RTP媒体流 RTP媒体流 双向RTP媒体传输 图例说明 SIP请求(实线) SIP临时响应(虚线) 成功响应(绿色) ACK确认(紫色) RTP媒体流(红色虚线)

流程拆解一下:

  1. 主叫方发送INVITE — 携带SDP,描述自己支持的媒体类型和编码
  2. 代理服务器返回100 Trying — 表示正在处理,别急
  3. 被叫方振铃,返回180 Ringing — 电话在响
  4. 被叫方接听,返回200 OK — 携带被叫方的SDP
  5. 主叫方发送ACK — 确认收到200 OK
  6. RTP媒体流开始 — 双方开始通话

⚠️ 安全警示:这个流程中,每一步都可能被劫持。比如INVITE被篡改、200 OK被拦截、ACK被伪造。我见过一个真实案例:攻击者在代理服务器层面拦截了200 OK,把自己的SDP地址替换进去,结果通话双方都在跟攻击者说话,还以为在跟对方通话——典型的中间人攻击。

避坑指南:SIP劫持的常见切入点

基于上面的流程,我总结几个攻击者最喜欢下手的地方:

  • INVITE篡改 — 修改SDP中的IP/端口,把媒体流引向攻击者
  • 200 OK拦截 — 伪造200 OK,让主叫方以为被叫方已接听
  • ACK伪造 — 发送虚假ACK,建立非预期的会话
  • BYE注入 — 发送BYE请求,强行中断通话

我曾经在一个渗透测试项目中,发现对方的SIP服务器没有对INVITE消息做任何校验。我直接构造了一个INVITE,把Contact头改成我的地址,结果所有后续的请求都发到了我这里。嗯,那个漏洞的CVSS评分是9.8。

我的建议:学SIP安全,先把基础协议吃透。不要一上来就搞什么高级攻击手法。你连SIP消息结构都看不懂,怎么知道攻击点在哪?我带的团队里,新人必须先手写10个SIP消息,能闭着眼睛画出消息流程图,才允许碰安全工具。

好了,这一章就到这里。SIP协议基础是后面所有攻击技术的地基。地基不稳,楼盖得再高也是危楼。


专注资料整理