9.8 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
10 High
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:N/AC:L/Au:N/C:C/I:C/A:C
0.973 High
EPSS
Percentile
99.8%
Attempts to print text on a shared printer by calling Print Spooler Service RPC functions.
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 manually 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.
Text to print. Either text or filename need to be specified.
File to read text from (ASCII only).
Printer share name. Optional, by default script tries to enumerate available printer shares.
See the documentation for the smb library.
See the documentation for the smbauth library.
nmap -p 445 <target> --script=smb-print-text --script-args="text=0wn3d"
|_smb-print-text: Printer job started using MyPrinter printer share.
local io = require "io"
local msrpc = require "msrpc"
local smb = require "smb"
local string = require "string"
local stdnse = require "stdnse"
description = [[
Attempts to print text on a shared printer by calling Print Spooler Service RPC functions.
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 manually
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 --script-args="text=0wn3d"
--
-- @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 https://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.debug1("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("a")
file:close()
end
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,string.pack("<I2I2", 0x01, 65406))
if status == false then
stdnse.debug1("SMB: " .. lanman_result)
stdnse.debug1("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 status, convert, entry_count, available_entries = string.unpack("<I2 I2 I2 I2", parameters)
local pos = 1
for i = 1, entry_count, 1 do
local name, share_type = string.unpack(">c14 I2", data, pos)
if share_type == 1 then -- share is printer
name = string.unpack("z", name)
stdnse.debug1("Found printer share %s.", name)
printer = name
break
end
pos = pos + 20
end
end
if not printer then
stdnse.debug1("No printer found, system may be unpatched but it needs at least one printer shared to be vulnerable.")
return false
end
stdnse.debug1("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.debug1("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.debug1("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.debug1("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
9.8 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
10 High
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:N/AC:L/Au:N/C:C/I:C/A:C
0.973 High
EPSS
Percentile
99.8%