python3实现的rtsp客户端脚本

一、说明

此客户端使用python3编写

此客户端实现RTSP的OPTIONS, DESCRIBE, SETUP , PLAY, GET_PARAMETER,TEARDOWN方法,未实现SET_PARAMETER方法(因为不懂怎么才能生成这个请求没拦截到数据包)

RTSP有且只有以上7种请求,而且基本是对同一URI依次执行以上7种请求;或者说RTSP就是“7种请求”+“1个URL”,如果想做渗透测试也就针对这“7+1”做参数溢出测试,没很多可测的

此客户端自动依次执行请求:OPTIONS--DESCRIBE(2次)--SETUP(2次)--PLAY--GET_PARAMETER(5次)--TEARDOWN

RTSP有Basic和Digest两种验证方法,此客户端实现Digest方法

总体执行效果如下图所示

二、客户端源代码

import socket
import hashlib
import time

global var_dict
var_dict = {
    ‘server_username‘: ‘admin‘,
    ‘server_password‘: ‘admin‘,
    ‘server_ip‘: ‘192.168.220.128‘,
    ‘server_port‘: 554,
    ‘server_url‘: ‘/chIP=1&streamType=main/‘,
    ‘cseq‘: 2,
    ‘user_agent‘: ‘LibVLC/3.0.2 (LIVE555 Streaming Media v2016.11.28)‘,
    ‘buffer_len‘: 1024
}

def gen_response_value(url,public_method,realm,nonce):
    frist_pre_md5_value = hashlib.md5((var_dict[‘server_username‘] + ‘:‘ + realm + ‘:‘ + var_dict[‘server_password‘]).encode()).hexdigest()
    first_post_md5_value = hashlib.md5((public_method+‘:‘ + url).encode()).hexdigest()
    response_value = hashlib.md5((frist_pre_md5_value + ‘:‘ + nonce + ‘:‘ + first_post_md5_value).encode()).hexdigest()
    return response_value

def gen_options_header():
    global var_dict
    str_options_header = ‘OPTIONS rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[
        ‘server_url‘] + ‘ RTSP/1.0\r\n‘
    str_options_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘]) + ‘\r\n‘
    str_options_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_options_header += ‘\r\n‘
    return str_options_header

def gen_describe_header():
    global var_dict
    str_describe_header = ‘DESCRIBE rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[
        ‘server_url‘] + ‘ RTSP/1.0\r\n‘
    str_describe_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘] + 1) + ‘\r\n‘
    str_describe_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_describe_header += ‘Accept: application/sdp\r\n‘
    str_describe_header += ‘\r\n‘
    return str_describe_header

def gen_describe_auth_header(url,realm,nonce):
    global var_dict
    public_method = ‘DESCRIBE‘
    response_value = gen_response_value(url,public_method,realm,nonce)
    str_describe_auth_header = ‘DESCRIBE rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[‘server_url‘] + ‘ RTSP/1.0\r\n‘
    str_describe_auth_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘] + 2) + ‘\r\n‘
    str_describe_auth_header += ‘Authorization: Digest username="‘+var_dict[‘server_username‘]+‘", realm="‘+realm+‘", nonce="‘+nonce+‘", uri="‘+url+‘", response="‘+response_value+‘"\r\n‘
    str_describe_auth_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_describe_auth_header += ‘Accept: application/sdp\r\n‘
    str_describe_auth_header += ‘\r\n‘
    return str_describe_auth_header

def gen_setup_header(url, realm, nonce):
    global var_dict
    public_method = ‘SETUP‘
    response_value = gen_response_value(url, public_method, realm, nonce)
    str_setup_header  = ‘SETUP rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[‘server_url‘] + ‘/trackID=0 RTSP/1.0\r\n‘
    str_setup_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘] + 3) + ‘\r\n‘
    str_setup_header += ‘Authorization: Digest username="‘+var_dict[‘server_username‘]+‘", realm="‘+realm+‘", nonce="‘+nonce+‘", uri="‘+url+‘", response="‘+response_value+‘"\r\n‘
    str_setup_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_setup_header += ‘Transport: RTP/AVP;unicast;client_port=50166-50167\r\n‘
    str_setup_header += ‘\r\n‘
    return str_setup_header

def gen_setup_session_header(url, realm, nonce,session):
    global var_dict
    public_method = ‘SETUP‘
    response_value = gen_response_value(url, public_method, realm, nonce)
    str_setup_session_header = ‘SETUP rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[
        ‘server_url‘] + ‘/trackID=1 RTSP/1.0\r\n‘
    str_setup_session_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘] + 4) + ‘\r\n‘
    str_setup_session_header += ‘Authorization: Digest username="‘+var_dict[‘server_username‘]+‘", realm="‘+realm+‘", nonce="‘+nonce+‘", uri="‘+url+‘", response="‘+response_value+‘"\r\n‘
    str_setup_session_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_setup_session_header += ‘Transport: RTP/AVP;unicast;client_port=50168-50169\r\n‘
    str_setup_session_header += ‘Session: ‘+session+‘\r\n‘
    str_setup_session_header += ‘\r\n‘
    return str_setup_session_header

def gen_play_header(url, realm, nonce,session):
    global var_dict
    public_method = ‘PLAY‘
    response_value = gen_response_value(url, public_method, realm, nonce)
    str_play_header = ‘PLAY rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[
        ‘server_url‘] + ‘ RTSP/1.0\r\n‘
    str_play_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘] + 5) + ‘\r\n‘
    str_play_header += ‘Authorization: Digest username="‘+var_dict[‘server_username‘]+‘", realm="‘+realm+‘", nonce="‘+nonce+‘", uri="‘+url+‘", response="‘+response_value+‘"\r\n‘
    str_play_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_play_header += ‘Session: ‘+session+‘\r\n‘
    str_play_header += ‘Range: npt=0.000-\r\n‘
    str_play_header += ‘\r\n‘
    return str_play_header

def gen_get_parameter_header(url, realm, nonce, session,count):
    global var_dict
    public_method = ‘GET_PARAMETER‘
    response_value = gen_response_value(url, public_method, realm, nonce)
    str_get_parameter_header = ‘GET_PARAMETER rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[
        ‘server_url‘] + ‘ RTSP/1.0\r\n‘
    str_get_parameter_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘] + 6+int(count)) + ‘\r\n‘
    str_get_parameter_header += ‘Authorization: Digest username="‘ + var_dict[
        ‘server_username‘] + ‘", realm="‘ + realm + ‘", nonce="‘ + nonce + ‘", uri="‘ + url + ‘", response="‘ + response_value + ‘"\r\n‘
    str_get_parameter_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_get_parameter_header += ‘Session: ‘ + session + ‘\r\n‘
    str_get_parameter_header += ‘\r\n‘
    return str_get_parameter_header

def gen_teardown_header(url, realm, nonce, session):
    global var_dict
    public_method = ‘TEARDOWN‘
    response_value = gen_response_value(url, public_method, realm, nonce)
    str_teardown_header = ‘TEARDOWN rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[‘server_url‘] + ‘ RTSP/1.0\r\n‘
    str_teardown_header += ‘CSeq: ‘ + str(var_dict[‘cseq‘] + 11) + ‘\r\n‘
    str_teardown_header += ‘Authorization: Digest username="‘ + var_dict[
        ‘server_username‘] + ‘", realm="‘ + realm + ‘", nonce="‘ + nonce + ‘", uri="‘ + url + ‘", response="‘ + response_value + ‘"\r\n‘
    str_teardown_header += ‘User-Agent: ‘ + var_dict[‘user_agent‘] + ‘\r\n‘
    str_teardown_header += ‘Session: ‘ + session + ‘\r\n‘
    str_teardown_header += ‘\r\n‘
    return str_teardown_header

socket_send = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_send.settimeout(5)
socket_send.connect((var_dict[‘server_ip‘], var_dict[‘server_port‘]))

url = ‘rtsp://‘ + var_dict[‘server_ip‘] + ‘:‘ + str(var_dict[‘server_port‘]) + var_dict[‘server_url‘]

print(‘now start to check options operation‘)
str_options_header = gen_options_header()
socket_send.send(str_options_header.encode())
msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
if ‘200 OK‘ in msg_recv:
    print(‘OPTIONS request is OK‘)
else:
    print(‘OPTIONS request is BAD‘)
str_describe_header = gen_describe_header()
socket_send.send(str_describe_header.encode())
msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
if msg_recv.find(‘401 Unauthorized‘) == -1:
    msg_recv_dict = msg_recv.split(‘\r\n‘)
    print(‘first DESCRIBE request occur error: ‘)
    print(msg_recv_dict[0])
else:
    print(‘first DESCRIBE is ok,now we will execute second DESCRIBE for auth‘)
    realm_pos = msg_recv.find(‘realm‘)
    realm_value_begin_pos = msg_recv.find(‘"‘, realm_pos)+1
    realm_value_end_pos = msg_recv.find(‘"‘, realm_pos + 8)
    realm_value = msg_recv[realm_value_begin_pos:realm_value_end_pos]
    nonce_pos = msg_recv.find(‘nonce‘)
    nonce_value_begin_pos = msg_recv.find(‘"‘, nonce_pos)+1
    nonce_value_end_pos = msg_recv.find(‘"‘, nonce_pos + 8)
    nonce_value = msg_recv[nonce_value_begin_pos:nonce_value_end_pos]
    str_describe_header = gen_describe_auth_header(url, realm_value, nonce_value)
    socket_send.send(str_describe_header.encode())
    msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
    if msg_recv.find(‘200 OK‘) == -1:
        msg_recv_dict = msg_recv.split(‘\r\n‘)
        print(‘second DESCRIBE request occur error: ‘)
        print(msg_recv_dict[0])
    else:
        print(‘second DESCRIBE is ok,now we will execute first SETUP for session‘)
        str_setup_header = gen_setup_header(url, realm_value, nonce_value)
        socket_send.send(str_setup_header.encode())
        msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
        if msg_recv.find(‘200 OK‘) == -1:
            msg_recv_dict = msg_recv.split(‘\r\n‘)
            print(‘first SETUP request occur error: ‘)
            print(msg_recv_dict[0])
        else:
            print(‘first SETUP is ok,now we will execute second SETUP‘)
            session_pos = msg_recv.find(‘Session‘)
            session_value_begin_pos = msg_recv.find(‘ ‘,session_pos+8)+1
            session_value_end_pos = msg_recv.find(‘;‘,session_pos+8)
            session_value = msg_recv[session_value_begin_pos:session_value_end_pos]
            str_setup_session_header = gen_setup_session_header(url, realm_value, nonce_value,session_value)
            socket_send.send(str_setup_session_header.encode())
            msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
            if msg_recv.find(‘200 OK‘) == -1:
                msg_recv_dict = msg_recv.split(‘\r\n‘)
                print(‘first SETUP request occur error: ‘)
                print(msg_recv_dict[0])
            else:
                print(‘second SETUP is ok, now we wil execute PLAY‘)
                str_play_header = gen_play_header(url, realm_value, nonce_value, session_value)
                socket_send.send(str_play_header.encode())
                msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
                if msg_recv.find(‘200 OK‘) == -1:
                    msg_recv_dict = msg_recv.split(‘\r\n‘)
                    print(‘PLAY request occur error: ‘)
                    print(msg_recv_dict[0])
                else:
                    print(‘PLAY is ok, we will execute GET_PARAMETER every 10 seconds and 5 times total‘)
                    for i in range(5):
                        str_get_parameter_header = gen_get_parameter_header(url, realm_value, nonce_value, session_value,str(i))
                        socket_send.send(str_get_parameter_header.encode())
                        msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
                        msg_recv_dict = msg_recv.split(‘\r\n‘)
                        print(str(i)+‘*10:‘+msg_recv_dict[0])
                        time.sleep(10)
                    print(‘now we will execute TEARDOWN to disconnect with server‘)
                    str_teardown_header = gen_teardown_header(url, realm_value, nonce_value, session_value)
                    socket_send.send(str_teardown_header.encode())
                    msg_recv = socket_send.recv(var_dict[‘buffer_len‘]).decode()
                    print(msg_recv)
                    print(‘program execute finished, thank you‘)

socket_send.close()

参考:

https://www.cnblogs.com/MikeZhang/archive/2012/10/29/rtspTcpClient_DSS_20121029.html

https://blog.csdn.net/joeblackzqq/article/details/22383005

https://docs.python.org/3/library/index.html

原文地址:https://www.cnblogs.com/lsdb/p/9090198.html

时间: 2024-10-10 10:27:32

python3实现的rtsp客户端脚本的相关文章

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient)——实现篇:(五)用户接口层之提取媒体流数据

当RTSP客户端向RTSP服务端发送完PLAY命令后,RTSP服务端就会另外开启UDP端口(SDP协商定义的端口)发送RTP媒体流数据包.这些数据包之间会间隔一段时间(毫秒级)陆续被发送到RTSP客户端,此时RTSP客户端可以调用GetMediaData等接口获取媒体流数据. 一.uint8_t * RtspClient::GetMediaData(string media_type, uint8_t * buf, size_t * size, size_t max_size) 该函数的作用即获

webControls与客户端脚本路径

网上有用的资料不多,在一本电子书中摘抄了内容如下 webControls配置节只有一个clientScriptsLocation属性,此属性用于指定ASP.NET客户端脚本的默认存放路径.这些文件是包含在HTML代码生成的ASPX页面时这些需要的客户端功能,如智能导航和客户端控件验证. <webControls clientScriptsLocation="/aspnet_client/{0}/{1}/"/> 上述代码就是<webControls>的默认内容.c

客户端脚本语言javascript

2015.11.27  客户端脚本语言javascript. (叫这个名字的原因.想要攀高枝,希望变得和他一样通用.关于名字之间的关系类似于雷锋和雷峰塔,巴基斯坦和卡巴斯基,苏格拉底跟格拉苏蒂的关系一样.阿迪王 和阿迪达斯)康师傅和康帅博 也是javaweb中的一个环节,javascript现在做的也很强大.主要应用于b/s部分的b也就是浏览器客户端的部分. 1.javascript语言,在运行的时候是不需要服务器的,只有浏览器就可以对js代码进行解释. 2.脚本语言:自身无法独立在浏览器端运行

客户端脚本攻击

什么是客户端脚本植入攻击 所谓客户端脚本植入攻击,是指将可以执行的脚本插入到表单.图片.动画或超链接文字等对象内.当用户打开这些对象后,黑客所植入的脚本就会被执行,进而开始攻击. 可以被用做脚本植入攻击的HTML标签包括以下5个方面: (1)以script标签标记的Javascript 和VBScript 等页面脚本程序.在script标签内可以指定Javascript程序代码,也可以在src属性内指定Javascript文件的URL路径.(2)以object标签标记的对象.这些对象通常是Jav

PHP漏洞全解(三)-客户端脚本植入

本文主要介绍针对PHP网站的客户端脚本植入攻击方式.所谓客户端脚本植入攻击,是指将可以执行的脚本插入到表单.图片.动画或超链接文字等对象内.当用户打开这些对象后,黑客所植入的脚本就会被执行,进而开始攻击. 客户端脚本植入(Script Insertion),是指将可以执行的脚本插入到表单.图片.动画或超链接文字等对象内.当用户打开这些对象后,攻击者所植入的脚本就会被执行,进而开始攻击. 可以被用作脚本植入的HTML标签一般包括以下几种: 1.<script>标签标记的javascript和vb

常用的生成客户端脚本方法

常用的生成客户端脚本方法: RegisterArraryDeclaration -- 添加javascript数组     RegisterClientScriptBlock-- 在 Web 窗体的开始处(紧接着 <form runat="server"> 标识之后)    RegiserStartScript-- ------- 在</form>前添加script代码块 RegisterStartupScript-- 在 Web 窗体的结尾处    Regis

服务器端脚本语言和客户端脚本语言

(一)常见的服务器端脚本语言,php,jsp,asp. 像我们普通浏览网页基于一种BS模式,其实它也只是一种统一于Browser(浏览器)的CS模式.我们的浏览器作为客户端,在点击链接或者输入地址时,向目的主机发送HTML,FTP等等服务请求,然后目的主机根据请求类型,请求内容给予响应.这种万变不离其宗的服务形式普遍存在于所有的网络通信模式中. 服务器脚本很简单,它是应于提交和处理表单,实现动态内容而出现的.想象一下一个中型网站大约有几千个链接地址,你总不能为每一个地址增加一个页面吧.于是服务器

一个基于JRTPLIB的轻量级RTSP客户端(myRTSPClient):(二)示例

一.搭建RTSP服务器 要想测试RTSP客户端,没有服务端怎么行呢?然而,有时候条件有限,手头并没有独立的RTSP服务器拿来用,那么我们不妨自己撘一个. 以下有2种方便的做法可供选择: 第一种:使用vlc播放器(推荐做法) 这种方法最方便,而且任何视频格式的文件都可以拿来测试,具体做法网上有很多,以下提供一个链接以供参考. http://blog.csdn.net/beitiandijun/article/details/9232405 这种方法只有一个地方需要注意一下: 如果你想让你的vlc

ASP.NET AJAX入门系列(7):使用客户端脚本对UpdateProgress编程

在本篇文章中,我们将通过编写JavaScript来使用客户端行为扩展UpdateProgress控件,客户端代码将使用ASP.NET AJAX Library中的PageRequestManager,在UpdateProgress控件中,将添加一个Button,来允许用户取消异步更新,并且使用客户端脚本来显示或者隐藏进度信息. 主要内容 1.通过客户端脚本取消异步更新 2.通过客户端脚本显示或者隐藏进度信息 一.通过客户端脚本取消异步更新 1.创建一个Web页面并切换到设计视图. 2.在工具箱中