diff --git a/CHANGELOG b/CHANGELOG index 993a95bf9..f745a187c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Added smb-print-text script which prints specified text using SMB + shared printer. [Aleksandar Nikolic] + o [NSE] Added mrinfo script whiches queries a target router for multicast information. [Hani Benhabiles] diff --git a/scripts/script.db b/scripts/script.db index 409df9b5f..8ad1af29c 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -341,6 +341,7 @@ Entry { filename = "smb-flood.nse", categories = { "dos", "intrusive", } } Entry { filename = "smb-ls.nse", categories = { "discovery", "safe", } } Entry { filename = "smb-mbenum.nse", categories = { "discovery", "safe", } } Entry { filename = "smb-os-discovery.nse", categories = { "default", "discovery", "safe", } } +Entry { filename = "smb-print-text.nse", categories = { "intrusive", } } Entry { filename = "smb-psexec.nse", categories = { "intrusive", } } Entry { filename = "smb-security-mode.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "smb-server-stats.nse", categories = { "discovery", "intrusive", } } diff --git a/scripts/smb-print-text.nse b/scripts/smb-print-text.nse new file mode 100644 index 000000000..cd6621965 --- /dev/null +++ b/scripts/smb-print-text.nse @@ -0,0 +1,134 @@ +local bin = require "bin" +local msrpc = require "msrpc" +local smb = require "smb" +local string = require "string" +local stdnse = require "stdnse" + +description = [[ +Script calls Print Spooler Service RPC functions to a shared printer +to make it print text. + +In order to use the script, at least one printer needs to be shared +over SMB. If no printer is specified, script tries to enumerate existing +ones by calling LANMAN API which might not be always available. +LANMAN is available by default on Windows XP, but not on Vista or Windows 7 +for example. In that case, you need to specify printer share name manualy +using printer script argument. You can find out available shares +by using smb-enum-shares script. + +Later versions of Windows require valid credentials by default +which you can specify trough smb library arguments smbuser and +smbpassword or other options. + +]] +--- +-- @usage nmap -p 445 --script=smb-print-text +-- +-- @output +-- |_smb-print-text: Printer job started using MyPrinter printer share. +-- +-- @args printer Printer share name. Optional, by default script tries to enumerate available printer shares. +-- @args text Text to print. Either text or filename need to be specified. +-- @args filename File to read text from (ASCII only). +-- + +author = "Aleksandar Nikolic" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive"} + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +action = function(host,port) + local status, smbstate + local text = stdnse.get_script_args(SCRIPT_NAME .. '.text') + local filename = stdnse.get_script_args(SCRIPT_NAME .. '.filename') + if (not text) and (not filename) then + stdnse.print_debug("Script requires either text or filename script argument.") + return false + end + local text_to_print + if text then + text_to_print = text + else + -- read text from file + local file = io.open(filename, "rb") + text_to_print = file:read("*all") + end + status, smbstate = msrpc.start_smb(host, msrpc.SPOOLSS_PATH,true) + if(status == false) then + stdnse.print_debug("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.print_debug("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.print_debug("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,bin.pack("ss",0x01,65406)) + if status == false then + stdnse.print_debug("SMB: " .. lanman_result) + stdnse.print_debug("SMB: Looks like LANMAN API is not available. Try setting printer script arg.") + return false + 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(" printer share.", printer) +end