# SIP(会话初始化协议)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* 你在一个**网络安全公司**工作吗?你想在HackTricks中看到你的**公司广告**吗?或者你想获得**PEASS的最新版本或下载PDF格式的HackTricks**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家[NFT收藏品**The PEASS Family**](https://opensea.io/collection/the-peass-family)
* 获得[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**Telegram群组**](https://t.me/peass) 或 **关注**我在**Twitter**上的[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **提交PR来分享你的黑客技巧。**
## 基本信息
SIP(会话初始化协议)是一种广泛用于在IP网络上建立、修改和终止多媒体会话(包括语音、视频和即时消息)的**信令和呼叫控制协议**。由**互联网工程任务组(IETF)**开发,SIP在**RFC 3261**中定义,并已成为VoIP和统一通信的事实标准。
SIP的一些关键特点包括:
1. **基于文本的协议**:SIP是一种基于文本的协议,使其易于阅读和调试。它基于请求-响应模型,类似于HTTP,并使用INVITE、ACK、BYE和CANCEL等方法来控制呼叫会话。
2. **可扩展性和灵活性**:SIP具有高度可扩展性,可用于小规模部署以及大型企业和运营商级环境。它可以轻松扩展新功能,使其适应各种用例和需求。
3. **互操作性**:SIP的广泛采用和标准化确保不同设备、应用程序和服务提供商之间更好的互操作性,促进各个平台之间的无缝通信。
4. **模块化设计**:SIP与其他协议(如实时传输协议(RTP)用于媒体传输和会话描述协议(SDP)用于描述多媒体会话)配合工作。这种模块化设计允许更大的灵活性和与不同媒体类型和编解码器的兼容性。
5. **代理和重定向服务器**:SIP可以使用代理和重定向服务器来促进呼叫路由,并提供呼叫转发、呼叫转移和语音邮件等高级功能。
6. **存在和即时消息**:SIP不仅限于语音和视频通信。它还支持存在和即时消息,实现了广泛的统一通信应用。
尽管SIP具有许多优点,但在配置和管理方面可能会很复杂,特别是在处理NAT穿越和防火墙问题时。然而,它的多功能性、可扩展性和行业广泛支持使其成为VoIP和多媒体通信的热门选择。
### SIP方法
在**RFC 3261**中定义的核心SIP方法包括:
1. **INVITE**:用于**初始化新会话(呼叫)**或修改现有会话。INVITE方法携带会话描述(通常使用SDP)以向接收方提供有关建议会话的详细信息,例如媒体类型、编解码器和传输协议。
2. **ACK**:用于**确认对INVITE请求的最终响应的接收**。ACK方法通过提供端到端的确认,确保INVITE事务的可靠性。
3. **BYE**:用于**终止已建立的会话(呼叫)**。BYE方法由会话中的任一方发送,表示他们希望结束通信。
4. **CANCEL**:用于在建立会话之前**取消挂起的INVITE请求**。如果发件人改变主意或接收方没有响应,CANCEL方法允许发件人中止INVITE事务。
5. **OPTIONS**:用于**查询SIP服务器或用户代理的功能**。OPTIONS方法可以发送以请求有关支持的方法、媒体类型或其他扩展的信息,而无需实际建立会话。
6. **REGISTER**:由用户代理使用以**向SIP注册服务器注册其当前位置**。REGISTER方法有助于维护用户的SIP URI和其当前IP地址之间的最新映射,实现呼叫路由和传递。
{% hint style="warning" %}
请注意,要拨打某人的电话,**不需要使用REGISTER**进行任何操作。\
但是,为了执行**INVITE**,呼叫方可能需要**先进行身份验证**,否则将收到**`401 Unauthorized`**响应。
{% endhint %}
除了这些核心方法外,还有**几种SIP扩展方法**在其他RFC中定义,例如:
1. **SUBSCRIBE**:在RFC 6665中定义,SUBSCRIBE方法用于**请求有关特定资源状态的通知**,例如用户的存在状态或呼叫状态。
2. **NOTIFY**:也在RFC 6665中定义,NOTIFY方法由服务器发送给已订阅的用户代理,**通知其监视资源状态的更改**。
3. **REFER**:在RFC 3515中定义,REFER方法用于**请求接收方执行转移或引用第三方**。这通常用于**呼叫转移**场景。
4. **MESSAGE**:在RFC 3428中定义,MESSAGE方法用于在SIP用户代理之间**发送即时消息**,在SIP框架内实现基于文本的通信。
5. **UPDATE**:在RFC 3311中定义,UPDATE方法允许**修改会话而不影响现有对话的状态**。这对于在进行中的呼叫期间更新会话参数(如编解码器或媒体类型)非常有用。
6. **PUBLISH**:在RFC 3903中定义,PUBLISH方法由用户代理使用以**将事件状态信息发布到服务器**,使其对其他感兴趣的方可用。
### SIP响应代码
* **1xx(临时响应)**:这些响应表示请求已接收,并且服务器正在继续处理它。
* 100 Trying:请求已接收,服务器正在处理中。
* 180 Ringing:被叫正在被提醒并将接听电话。
* 183 Session Progress:提供有关呼叫进度的信息。
* **2xx(成功响应)**:这些响应表示请求已成功接收、理解和接受。
* 200 OK:请求成功,服务器已完成。
* 202 Accepted:请求已接受处理,但尚未完成。
* **3xx(重定向响应)**:这些响应表示需要进一步操作才能满足请求,通常是通过联系其他资源。
* 300 Multiple Choices:有多个可用选项,用户或客户端必须选择一个。
* 301 Moved Permanently:所请求的资源已被分配新的永久URI。
* 302 Moved Temporarily:所请求的资源暂时可在不同的URI上获得。
* 305 Use Proxy:请求必须发送到指定的代理。
* **4xx(客户端错误响应)**:这些响应表示请求包含错误的语法或服务器无法满足请求。
* 400 Bad Request:请求格式错误或无效。
* 401 Unauthorized:请求需要用户身份验证。
* 403 Forbidden:服务器理解请求但拒绝满足。
* 404 Not Found:在服务器上未找到所请求的资源。
* 408 Request Timeout:服务器在准备等待的时间内未收到完整的请求。
* 486 Busy Here:被叫当前忙碌,无法接听电话。
* **5xx(服务器错误响应)**:这些响应表示服务器无法满足有效请求。
* 500 Internal Server Error:服务器在处理请求时遇到错误。
* 501 Not Implemented:服务器不支持满足请求所需的功能。
* 503 Service Unavailable:由于维护或过载,服务器当前无法处理请求。
* **6xx(全局失败响应)**:这些响应表示任何服务器都无法满足请求。
* 600 Busy Everywhere:呼叫的所有可能目标都忙碌。
* 603 Decline:被叫不希望参与呼叫。
* 604 Does Not Exist Anywhere:所请求的资源在网络中无处可用。
## 示例
### SIP INVITE示例
```
INVITE sip:jdoe@example.com SIP/2.0
Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds
Max-Forwards: 70
To: John Doe
From: Jane Smith ;tag=1928301774
Call-ID: a84b4c76e66710
CSeq: 314159 INVITE
Contact:
User-Agent: ExampleSIPClient/1.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
Content-Type: application/sdp
Content-Length: 142
v=0
o=jsmith 2890844526 2890842807 IN IP4 pc33.example.com
s=-
c=IN IP4 pc33.example.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000te
```
每个参数的解释
1. **Request-Line**: `INVITE sip:jdoe@example.com SIP/2.0` - 这一行指示了方法(INVITE),请求URI(sip:[jdoe@example.com](mailto:jdoe@example.com))和SIP版本(SIP/2.0)。
2. **Via**: `Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds` - Via头部指定了传输协议(UDP)和客户端的地址(pc33.example.com)。"branch"参数用于循环检测和事务匹配。
3. **Max-Forwards**: `Max-Forwards: 70` - 这个头字段限制了请求可以被代理转发的次数,以避免无限循环。
4. **To**: `To: John Doe ` - To头部指定了呼叫的接收者,包括他们的显示名称(John Doe)和SIP URI(sip:[jdoe@example.com](mailto:jdoe@example.com))。
5. **From**: `From: Jane Smith ;tag=1928301774` - From头部指定了呼叫的发送者,包括他们的显示名称(Jane Smith)和SIP URI(sip:[jsmith@example.org](mailto:jsmith@example.org))。"tag"参数用于唯一标识发送者在对话中的角色。
6. **Call-ID**: `Call-ID: a84b4c76e66710` - Call-ID头部唯一标识了两个用户代理之间的呼叫会话。
7. **CSeq**: `CSeq: 314159 INVITE` - CSeq头部包含一个序列号和请求中使用的方法。它用于将响应与请求匹配并检测乱序消息。
8. **Contact**: `Contact: ` - Contact头部提供了一个直接的路由到发送者,可以用于后续的请求和响应。
9. **User-Agent**: `User-Agent: ExampleSIPClient/1.0` - User-Agent头部提供了关于发送者的软件或硬件的信息,包括其名称和版本。
10. **Allow**: `Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO` - Allow头部列出了发送者支持的SIP方法。这有助于接收者了解在通信过程中可以使用哪些方法。
11. **Content-Type**: `Content-Type: application/sdp` - Content-Type头部指定了消息体的媒体类型,在这种情况下是SDP(会话描述协议)。
12. **Content-Length**: `Content-Length: 142` - Content-Length头部指示消息体的大小(以字节为单位)。
13. **消息体**: 消息体包含了SDP会话描述,其中包括有关所提议会话的媒体类型、编解码器和传输协议的信息。
* `v=0` - 协议版本(SDP为0)
* `o=jsmith 2890844526 2890842807 IN IP4 pc33.example.com` - 发起者和会话标识符
* `s=-` - 会话名称(单个连字符表示没有会话名称)
* `c=IN IP4 pc33.example.com` - 连接信息(网络类型、地址类型和地址)
* `t=0 0` - 时间信息(开始和结束时间,0 0表示会话没有边界)
* `m=audio 49170 RTP/AVP 0` - 媒体描述(媒体类型、端口号、传输协议和格式列表)。在这种情况下,它指定了使用RTP/AVP(实时传输协议/音频视频配置文件)和格式0(PCMU/8000)的音频流。
* `a=rtpmap:0 PCMU/8000` - 将格式(0)映射到编解码器(PCMU)和其时钟速率(8000 Hz)的属性。
### SIP REGISTER示例
REGISTER方法用于会话初始化协议(SIP)中,允许用户代理(UA),如VoIP电话或软电话,向SIP注册服务器注册其位置。这个过程让服务器知道将来自注册用户的SIP请求路由到何处。注册服务器通常是SIP代理服务器或专用注册服务器的一部分。
下面是一个详细的SIP消息示例,涉及到REGISTER身份验证过程:
1. UA向注册服务器发起初始**REGISTER**请求:
```yaml
REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
Max-Forwards: 70
From: Alice ;tag=565656
To: Alice
Call-ID: 1234567890@192.168.1.100
CSeq: 1 REGISTER
Contact: ;expires=3600
Expires: 3600
Content-Length: 0
```
这个初始的REGISTER消息由用户代理(Alice)发送给注册服务器。它包括重要的信息,如期望的注册持续时间(Expires),用户的SIP URI(sip:[alice@example.com](mailto:alice@example.com)),以及用户的联系地址(sip:alice@192.168.1.100:5060)。
2. 注册服务器返回的**401 Unauthorized**响应:
```css
cssCopy codeSIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
From: Alice ;tag=565656
To: Alice ;tag=7878744
Call-ID: 1234567890@192.168.1.100
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="example.com", nonce="abcdefghijk", algorithm=MD5, qop="auth"
Content-Length: 0
```
注册服务器会回复一个包含"401 Unauthorized"消息的响应,其中包含一个"WWW-Authenticate"头部。该头部包含了用户代理进行身份验证所需的信息,如**身份验证领域、随机数和算法**。
3. 使用身份验证凭证的注册请求:
```vbnet
REGISTER sip:example.com SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
Max-Forwards: 70
From: Alice ;tag=565656
To: Alice
Call-ID: 1234567890@192.168.1.100
CSeq: 2 REGISTER
Contact: ;expires=3600
Expires: 3600
Authorization: Digest username="alice", realm="example.com", nonce="abcdefghijk", uri="sip:example.com", response="65a8e2285879283831b664bd8b7f14d4", algorithm=MD5, cnonce="lmnopqrst", qop=auth, nc=00000001
Content-Length: 0
```
UA发送另一个REGISTER请求,这次包括了"Authorization"头部,其中包含必要的凭证,如用户名、领域、随机数和使用提供的信息和用户密码计算得出的响应值。
这是如何计算"Authorization"响应的方法:
```python
import hashlib
def calculate_sip_md5_response(username, password, realm, method, uri, nonce, nc, cnonce, qop):
# 1. Calculate HA1 (concatenation of username, realm, and password)
ha1_input = f"{username}:{realm}:{password}"
ha1 = hashlib.md5(ha1_input.encode()).hexdigest()
# 2. Calculate HA2 (concatenation of method and uri)
ha2_input = f"{method}:{uri}"
ha2 = hashlib.md5(ha2_input.encode()).hexdigest()
# 3. Calculate the final response value (concatenation of h1, stuff and h2)
response_input = f"{ha1}:{nonce}:{nc}:{cnonce}:{qop}:{ha2}"
response = hashlib.md5(response_input.encode()).hexdigest()
return response
# Example usage
username = "alice"
password = "mysecretpassword"
realm = "example.com"
method = "REGISTER"
uri = "sip:example.com"
nonce = "abcdefghijk"
nc = "00000001"
cnonce = "lmnopqrst"
qop = "auth"
response = calculate_sip_md5_response(username, password, realm, method, uri, nonce, nc, cnonce, qop)
print(f"MD5 response value: {response}")
```
4. **注册成功**来自注册服务器的响应:
```yaml
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
From: Alice ;tag=565656
To: Alice ;tag=7878744
Call-ID: 1234567890@192.168.1.100
CSeq: 2 REGISTER
Contact: ;expires=3600
Expires: 3600
Content-Length: 0
```
在注册服务器验证提供的凭据后,**它发送一个"200 OK"的响应来表示注册成功**。响应包括已注册的联系信息和注册的过期时间。此时,用户代理(Alice)已成功注册到SIP注册服务器,并且可以将针对Alice的传入SIP请求路由到相应的联系地址。
### 呼叫示例
{% hint style="info" %}
没有提到,但是用户B需要在能够接收呼叫之前向代理2发送一个**REGISTER消息**。
{% endhint %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* 你在一家**网络安全公司**工作吗?想要在HackTricks中**宣传你的公司**吗?或者想要**获取PEASS的最新版本或下载PDF格式的HackTricks**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品——[**The PEASS Family**](https://opensea.io/collection/the-peass-family)
* 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组**](https://discord.gg/hRep4RUj7f)或[**电报群组**](https://t.me/peass),或者**关注**我在**Twitter**上的[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **和**[**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud) **提交PR来分享你的黑客技巧。**