mirror of
https://github.com/nmap/nmap.git
synced 2025-12-13 03:09:02 +00:00
Merged smb-print-text script from my dev branch
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# 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
|
o [NSE] Added mrinfo script whiches queries a target router for multicast
|
||||||
information. [Hani Benhabiles]
|
information. [Hani Benhabiles]
|
||||||
|
|
||||||
|
|||||||
@@ -341,6 +341,7 @@ Entry { filename = "smb-flood.nse", categories = { "dos", "intrusive", } }
|
|||||||
Entry { filename = "smb-ls.nse", categories = { "discovery", "safe", } }
|
Entry { filename = "smb-ls.nse", categories = { "discovery", "safe", } }
|
||||||
Entry { filename = "smb-mbenum.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-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-psexec.nse", categories = { "intrusive", } }
|
||||||
Entry { filename = "smb-security-mode.nse", categories = { "default", "discovery", "safe", } }
|
Entry { filename = "smb-security-mode.nse", categories = { "default", "discovery", "safe", } }
|
||||||
Entry { filename = "smb-server-stats.nse", categories = { "discovery", "intrusive", } }
|
Entry { filename = "smb-server-stats.nse", categories = { "discovery", "intrusive", } }
|
||||||
|
|||||||
134
scripts/smb-print-text.nse
Normal file
134
scripts/smb-print-text.nse
Normal file
@@ -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 <code>printer</code> 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 <code>smbuser</code> and
|
||||||
|
<code>smbpassword</code> or other options.
|
||||||
|
|
||||||
|
]]
|
||||||
|
---
|
||||||
|
-- @usage nmap -p 445 <target> --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("<SSSS", parameters)
|
||||||
|
pos = 0
|
||||||
|
local share_type
|
||||||
|
for i = 1, entry_count, 1 do
|
||||||
|
_,share_type = bin.unpack(">s",data,pos+14)
|
||||||
|
pos, name = bin.unpack("<z", data, pos)
|
||||||
|
|
||||||
|
-- pos needs to be rounded to the next even multiple of 20
|
||||||
|
pos = pos + ( 20 - (#name % 20) ) - 1
|
||||||
|
if share_type == 1 then -- share is printer
|
||||||
|
stdnse.print_debug("Found printer share %s.", name)
|
||||||
|
printer = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not printer then
|
||||||
|
stdnse.print_debug("No printer found, system may be unpached but it needs at least one printer shared to be vulnerable.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
stdnse.print_debug("Using %s as printer.",printer)
|
||||||
|
-- call RpcOpenPrinterEx - opnum 69
|
||||||
|
local status, result = msrpc.spoolss_open_printer(smbstate,"\\\\"..host.ip.."\\"..printer)
|
||||||
|
if not status then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local printer_handle = string.sub(result.data,25,#result.data-4)
|
||||||
|
stdnse.print_debug("Printer handle %s",stdnse.tohex(printer_handle))
|
||||||
|
-- call RpcStartDocPrinter - opnum 17
|
||||||
|
status,result = msrpc.spoolss_start_doc_printer(smbstate,printer_handle,"nmap_print_test.txt") -- patched version will allow this
|
||||||
|
if not status then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local print_job_id = string.sub(result.data,25,#result.data-4)
|
||||||
|
stdnse.print_debug("Start doc printer job id %s",stdnse.tohex(print_job_id))
|
||||||
|
|
||||||
|
-- call RpcWritePrinter - 19
|
||||||
|
status, result = msrpc.spoolss_write_printer(smbstate,printer_handle,text_to_print)
|
||||||
|
if not status then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local write_result = string.sub(result.data,25,#result.data-4)
|
||||||
|
stdnse.print_debug("Written %s bytes to a file.",stdnse.tohex(write_result))
|
||||||
|
|
||||||
|
status,result = msrpc.spoolss_end_doc_printer(smbstate,printer_handle)
|
||||||
|
|
||||||
|
return string.format("Printer job started using <%s> printer share.", printer)
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user