RTSP(Real Time Streaming Protocol)是由Real Network和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议。RTSP对流媒体提供了诸如暂停,快进等控制,而它本身并不传输数据,RTSP的作用相当于流媒体服务器的远程控制。服务器端可以自行选择使用TCP或UDP来传送串流内容,它的语法和运作跟HTTP 1.1类似,但并不特别强调时间同步,所以比较能容忍网络延迟。
RTSP五步会话原理如下
step1:
C->S:OPTION request //询问S有哪些方法可用
S->C:OPTION response //S回应信息中包括提供的所有可用方法
step2:
C->S:DESCRIBE request //要求得到S提供的媒体初始化描述信息
S->C:DESCRIBE response //S回应媒体初始化描述信息,主要是sdp
step3:
C->S:SETUP request //设置会话的属性,以及传输模式,提醒S建立会话
S->C:SETUP response //S建立会话,返回会话标识符,以及会话相关信息
step4:
C->S:PLAY request //C请求播放
S->C:PLAY response //S回应该请求的信息
S->C:发送流媒体数据
step5:
C->S:TEARDOWN request //C请求关闭会话
S->C:TEARDOWN response //S回应该请求
wireshark实战抓包,获取最开始的几步认证即可。
OPTIONS rtsp://207.62.193.8:8554 RTSP/1.0
CSeq: 1
User-Agent: Lavf58.29.100
RTSP/1.0 200 OK
Server: StarDot H264 Server
CSeq: 1
Public: DESCRIBE,OPTIONS,PLAY,SETUP,TEARDOWN
DESCRIBE rtsp://207.62.193.8:8554 RTSP/1.0
Accept: application/sdp
CSeq: 2
User-Agent: Lavf58.29.100
RTSP/1.0 200 OK
Server: StarDot H264 Server
CSeq: 2
Cache-Control: no-cache
Content-Length: 289
Content-Type: application/sdp
观察一个比较完整rtsp格式
rtsp://user:pass@111.111.111.111/xxx/xxx
因此检测的时候主要分几种类型:
1、rtsp未授权访问
2、404需要爆破路径
3、401需要帐密认证
工具思路:
1、先对所有地址进行存活检测。
2、对于存活的地址,如果返回200,则存在未授权访问,返回401则进行帐密爆破,返回404则先进行路径爆破,路径爆破成功则进行帐密爆破。
构造socket包
func genOPTIONS(url string, seq int, ua string) string {
msgRet := "OPTIONS " + url + " RTSP/1.0\r\n"
msgRet += "CSeq: " + strconv.Itoa(seq) + "\r\n"
msgRet += "User-Agent: " + ua + "\r\n"
msgRet += "\r\n"
return msgRet
}
func genDESCRIBLE(url string, seq int, ua string) string {
msgRet := "DESCRIBE " + url + " RTSP/1.0\r\n"
msgRet += "CSeq: " + strconv.Itoa(seq) + "\r\n"
msgRet += "User-Agent: " + ua + "\r\n"
msgRet += "Accept: application/sdp\r\n"
msgRet += "\r\n"
return msgRet
}
socket通信
func Handler(serv models.Service) int {
ua := "LibVLC/2.0.3 (LIVE555 Streaming Media v2011.12.23)"
addr := fmt.Sprintf("%v:%v", serv.Ip, serv.Port)
conn, err := net.DialTimeout("tcp", addr, vars.Timeout)
if err != nil {
return 0
}
conn.SetReadDeadline(time.Now().Add(vars.Timeout))
conn.SetWriteDeadline(time.Now().Add(vars.Timeout))
seq := 1
msg := genOPTIONS(serv.Url, seq, ua)
data := make([]byte, 255)
_, err = conn.Write([]byte(msg))
_, err = conn.Read(data)
if err != nil {
return 0
}
seq += 1
msg = genDESCRIBLE(serv.Url, seq, ua)
_, err = conn.Write([]byte(msg))
_, err = conn.Read(data)
if err != nil {
return 0
}
if strings.Contains(string(data), "200 OK") {
return 200
}
if strings.Contains(string(data), "401 Unauthorized") {
return 401
}
if strings.Contains(string(data), "404 Not Found") {
return 404
}
return 0
}
本工具仅面向合法授权的企业安全建设行为,且仅供学习研究自查使用,切勿用于非法用途,由使用该工具产生的一切风险均与本人无关!