local bin = require "bin" local msrpc = require "msrpc" local smb = require "smb" local string = require "string" local vulns = require "vulns" local stdnse = require "stdnse" description = [[ Tests whether target machines are vulnerable to ms10-061 Printer Spooler impersonation vulnerability. This vulnerability was used in Stuxnet worm. The script checks for the vuln in a safe way without a possibility of crashing the remote system as this is not a memory corruption vulnerability. In order for the check to work it needs access to at least one shared printer on the remote system. By default it tries to enumerate printers by using LANMAN API which on some systems is not available by default. In that case user should specify printer share name as printer script argument. To find a printer share, smb-enum-shares can be used. Also, on some systems, accessing shares requires valid credentials which can be specified with smb library arguments smbuser and smbpassword. References: - http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2729 - http://technet.microsoft.com/en-us/security/bulletin/MS10-061 - http://blogs.technet.com/b/srd/archive/2010/09/14/ms10-061-printer-spooler-vulnerability.aspx ]] --- -- @usage nmap -p 445 --script=smb-vuln-ms10-061 -- -- @args printer Printer share name. Optional, by default script tries to enumerate available printer shares. -- -- @output -- PORT STATE SERVICE REASON -- 445/tcp open microsoft-ds syn-ack -- Host script results: -- | smb-vuln-ms10-061: -- | VULNERABLE: -- | Print Spooler Service Impersonation Vulnerability -- | State: VULNERABLE -- | IDs: CVE:CVE-2010-2729 -- | Risk factor: HIGH CVSSv2: 9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C) -- | Description: -- | The Print Spooler service in Microsoft Windows XP,Server 2003 SP2,Vista,Server 2008, and 7, when printer sharing is enabled, -- | does not properly validate spooler access permissions, which allows remote attackers to create files in a system directory, -- | and consequently execute arbitrary code, by sending a crafted print request over RPC, as exploited in the wild in September 2010, -- | aka "Print Spooler Service Impersonation Vulnerability." -- | -- | Disclosure date: 2010-09-5 -- | References: -- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2729 -- | http://technet.microsoft.com/en-us/security/bulletin/MS10-061 -- |_ http://blogs.technet.com/b/srd/archive/2010/09/14/ms10-061-printer-spooler-vulnerability.aspx -- -- @see stuxnet-detect.nse author = "Aleksandar Nikolic" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"vuln","intrusive"} hostrule = function(host) return smb.get_port(host) ~= nil end action = function(host,port) local ms10_061 = { title = "Print Spooler Service Impersonation Vulnerability", IDS = {CVE = 'CVE-2010-2729'}, risk_factor = "HIGH", scores = { CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)", }, description = [[ The Print Spooler service in Microsoft Windows XP,Server 2003 SP2,Vista,Server 2008, and 7, when printer sharing is enabled, does not properly validate spooler access permissions, which allows remote attackers to create files in a system directory, and consequently execute arbitrary code, by sending a crafted print request over RPC, as exploited in the wild in September 2010, aka "Print Spooler Service Impersonation Vulnerability." ]], references = { 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2729', 'http://technet.microsoft.com/en-us/security/bulletin/MS10-061', 'http://blogs.technet.com/b/srd/archive/2010/09/14/ms10-061-printer-spooler-vulnerability.aspx' }, dates = { disclosure = {year = '2010', month = '09', day = '5'}, }, exploit_results = {}, } local report = vulns.Report:new(SCRIPT_NAME, host, port) ms10_061.state = vulns.STATE.NOT_VULN local status, smbstate status, smbstate = msrpc.start_smb(host, msrpc.SPOOLSS_PATH,true) if(status == false) then stdnse.debug1("SMB: " .. smbstate) return false, smbstate end local bind_result status, bind_result = msrpc.bind(smbstate,msrpc.SPOOLSS_UUID, msrpc.SPOOLSS_VERSION, nil) if(status == false) then msrpc.stop_smb(smbstate) stdnse.debug1("SMB: " .. bind_result) return false, bind_result end local printer = stdnse.get_script_args(SCRIPT_NAME .. '.printer') -- if printer not set find available printers if not printer then stdnse.debug1("No printer specified, trying to find one...") local lanman_result local REMSmb_NetShareEnum_P = "WrLeh" local REMSmb_share_info_1 = "B13BWz" status, lanman_result = msrpc.call_lanmanapi( smbstate, 0, REMSmb_NetShareEnum_P, REMSmb_share_info_1, "\x01\x00\x7e\xff") if status == false then stdnse.debug1("SMB: " .. lanman_result) stdnse.debug1("SMB: Looks like LANMAN API is not available. Try setting printer script arg.") end local parameters = lanman_result.parameters local data = lanman_result.data local pos, status, convert, entry_count, available_entries = bin.unpack("s",data,pos+14) pos, name = bin.unpack("