4、SIP注册劫持:注册流程分析、伪造REGISTER请求、会话劫持、防御策略

4.1 先聊聊SIP注册到底是怎么回事

说实话,SIP注册劫持是我在IMS安全评估中遇到最多的问题之一。很多团队把精力都放在信令加密上,却忽略了注册流程本身的设计缺陷。

SIP注册,说白了就是用户告诉网络:「嘿,我在这里,这是我的联系地址」。UAC(用户代理客户端)发送REGISTER请求,Registrar服务器把AOR(地址-of-记录)和Contact地址绑定起来。嗯,这里要注意——这个绑定是有时效的,通常用Expires头域控制。

我见过不少开发人员以为注册成功就万事大吉了。其实不然。注册流程中最脆弱的地方,恰恰是身份验证环节。如果验证不严,攻击者就能伪造REGISTER请求,把自己的设备注册成你的号码。

核心问题: 注册服务器如何确认「你就是你声称的那个人」?如果这个信任链断了,整个通信安全就崩塌了。

4.2 注册流程深度拆解

一个标准的SIP注册流程,我习惯把它分成三个阶段:

  1. 发现阶段: UAC通过DHCP、DNS SRV或手动配置找到Registrar地址
  2. 认证阶段: 服务器返回401/407质询,要求客户端提供凭证
  3. 注册阶段: 客户端携带认证信息重新发送REGISTER

我在项目中遇到过一种情况:某个厂商为了「优化用户体验」,跳过了401质询,直接接受第一次REGISTER请求。你想想看,这等于把大门敞开了。攻击者只需要知道你的SIP URI,就能轻松完成注册劫持。

正常的REGISTER请求长这样:

REGISTER sip:ims.example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060
From: <sip:alice@example.com>;tag=abc123
To: <sip:alice@example.com>
Call-ID: 123456@192.168.1.100
CSeq: 1 REGISTER
Contact: <sip:alice@192.168.1.100:5060>;expires=3600
Authorization: Digest username="alice", realm="ims.example.com", 
                nonce="xyz789", uri="sip:ims.example.com", 
                response="a1b2c3d4"
Content-Length: 0

注意那个Authorization头域。如果它缺失或者可以被绕过,劫持就开始了。

4.3 伪造REGISTER请求——攻击者是怎么干的

伪造REGISTER请求,说白了就是攻击者冒充合法用户向Registrar发送注册消息。我把它分为三种常见手法:

攻击手法 原理 我见过的真实案例
无认证注册 服务器配置不当,允许未认证的REGISTER 某运营商测试环境直接暴露在公网,任何人都能注册任意号码
重放攻击 捕获合法REGISTER请求,修改Contact地址后重放 攻击者用Wireshark抓包,改了IP地址就完成了劫持
密码破解 暴力破解或字典攻击获取共享密钥 弱密码「123456」导致整个企业分机被劫持

伪造请求的代码示例(仅用于教学目的):

# 简化版伪造REGISTER请求
import socket

def forge_register(target_ip, target_port, victim_uri, attacker_contact):
    request = f"""REGISTER sip:{target_ip} SIP/2.0\r
Via: SIP/2.0/UDP {attacker_contact.split('@')[1].split(':')[0]}:5060\r
From: <sip:{victim_uri}>;tag=forged123\r
To: <sip:{victim_uri}>\r
Call-ID: forged@{attacker_contact.split('@')[1]}\r
CSeq: 1 REGISTER\r
Contact: <sip:{attacker_contact}>;expires=3600\r
Content-Length: 0\r
\r"""
    
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(request.encode(), (target_ip, target_port))
    sock.close()

# 攻击者把alice的注册地址改成自己的
forge_register("192.168.1.1", 5060, "alice@example.com", "attacker@10.0.0.5:5060")
⚠️ 警告: 这段代码仅供理解攻击原理。未经授权使用可能违反法律法规。我在做红队演练时才会用到类似技术。

4.4 会话劫持——注册劫持的最终目的

注册劫持不是终点,而是起点。攻击者完成注册劫持后,能做什么?

  • 来电拦截: 所有打给alice的电话,都路由到攻击者的设备上
  • 去电冒充: 攻击者以alice的身份发起呼叫,被叫方看到的是alice的号码
  • 语音/视频窃听: 如果媒体流没有加密,攻击者可以录制通话内容
  • 短信劫持: 在IMS中,SIP也承载即时消息,注册劫持意味着短信也被劫持

我曾经参与过一个事件响应:某公司CEO的号码被劫持,攻击者冒充他向财务总监发了一条「紧急转账」的即时消息。嗯,后果你可以想象。这就是注册劫持的杀伤力——它不只是技术问题,更是业务安全问题。

4.5 防御策略——我总结的实战经验

防御注册劫持,我建议从三个层面入手:

4.5.1 认证强化

  • 强制使用Digest认证: 永远不要接受未认证的REGISTER请求
  • 启用IP白名单: 对已知的注册IP进行限制,减少攻击面
  • 使用TLS传输: 防止REGISTER请求在传输过程中被篡改
💡 我的小技巧: 在Registrar上配置「注册频率限制」。我曾经遇到过攻击者每秒发送上千个伪造REGISTER请求,频率限制能有效阻断这种暴力注册。

4.5.2 注册验证

  • Contact地址验证: 检查Contact地址是否与注册来源IP匹配
  • 多因子注册: 结合IP、User-Agent、地理位置等信息做综合判断
  • 注册冲突检测: 如果同一个AOR突然从不同IP注册,触发告警

4.5.3 监控与响应

  • 注册日志审计: 记录每次REGISTER请求的源IP、User-Agent、时间戳
  • 异常行为告警: 短时间内大量REGISTER请求、频繁更换Contact地址等
  • 自动回滚机制: 检测到劫持后,自动恢复为上一次合法注册

下面这张图是我自己整理的注册劫持攻击链与防御点:

SIP注册劫持攻击链与防御点 1. 信息收集 扫描SIP端口5060 2. 伪造REGISTER 构造恶意请求 3. 注册成功 Contact被覆盖 4. 会话劫持 拦截/冒充通话 防御层一:认证强化(强制Digest + TLS + IP白名单) 防御层二:注册验证(Contact校验 + 多因子 + 冲突检测) 防御层三:监控响应(日志审计 + 异常告警 + 自动回滚) 红色箭头:攻击路径 | 绿色虚线:防御阻断点 三层防御叠加,形成纵深防御体系

4.6 避坑指南——我踩过的坑

最后分享几个我亲身经历过的教训:

  • 别信「内网安全」: 我曾经以为内网环境不需要TLS,结果内部员工用ARP欺骗就完成了注册劫持。内网不等于安全网。
  • Expires时间别设太长: 有些厂商把注册有效期设为24小时。你想想看,如果被劫持了,要等24小时才能自动恢复?我建议设成300-600秒。
  • 别忘了注销处理: 攻击者可能会发送Expires=0的REGISTER来注销合法用户。一定要验证注销请求的合法性。
  • 日志要保留原始包: 出事后排查时,只有摘要日志根本不够用。我习惯保留完整的SIP消息体,方便回溯。
总结一句话: SIP注册劫持的核心问题不是技术有多难,而是「信任」被滥用。防御的关键在于——不要信任任何未经验证的注册请求。

公众号:蓝海资料掘金营,微信deep3321