Find Printers with Nmap
Whats the best way to find printers in my network with nmap? Is it possible to save the printers ip to a file?
If you're leery of doing OS Fingerprinting for some reason, you can do a more targeted port-scan:
nmap -p 9100,515,631 192.168.1.1/24 -oX printers.xml
That'll scan for ports common to printers and printing systems.
- 9100 = the RAW port for most printers, also known as the direct-IP port
- 515 = the LPR/LPD port, for most printers, as well as older print-servers
- 631 = the IPP port, for most modern printers, and CUPS-based print-server
Output is in XML.
This reply answers your first question directly. For the second question, understanding the command will let you also put printer IP addresses in a file. So here we go:
nmap -p 515,631,9100 -oG - 10.81.129.0/24 | gawk '/open/{print $2}' | xargs --delimiter='\n' nmap -sU -p 161 -oG - | gawk '/open/{print $2}' | xargs --replace=$ipaddress snmpget -v 1 -O v -c public $ipaddress system.sysDescr.0 | sed 's/STRING:\s//'
Process description
- It scans a network searching for network entities that are listening on the default printer ports.
- Using the results of the previous step it will check for SNMP support on these devices.
- For each device that has SNMP support it queries the network entity for a device description.
Command breakdown
nmap - Network scanning. (Nmap.org)
-
-p 515,631,9100
Scan for TCP Port 515, 631 and 9100. -
-oG -
Use the grep-able output format. -
-sU -p 161
Scan for UDP port 161.
gawk or awk - Process column-oriented text data. By default, whitespaces separates the line into columns. (Wikipedia)
-
gawk '/regexp/'
Use regulair expression with gawk to filter out lines matching this regulair expression. -
gawk '{<code>}'
Use the awk C-like input language to manipulate the output. -
gawk '{/open/print $2}'
Search for lines matching “open” and print the second column.
xarg - Build and execute commands from given input. By default whitespaces separates the line into arguments. (Wikipedia)
-
--delimiter='\n'
Separate arguments per new line (\n) instead of whitespace. -
--replace=$ipaddress
For each line, store the argument into $ipaddress.
snmpget or snmpwalk - Use SNMP GET request to query for information on a network entity. (net-snmp.org, more about SNMP on Wikipedia)
-
-c public
Set community string to public. -
-v 1
Set SNMP version to 1. -
-O v
Don’t print OID. -
system.sysDescr.0
Variable to query. Description of this particular variable: "A textual description of the entity. This value should include the full name and version identification of the system's hardware type, software operating-system, and networking software. It is mandatory that this only contain printable ASCII characters."
sed - Parses and transforms text. (Wikipedia)
-
's/day/night/'
Find the first occurrence of the string day in a line, and replace it with night. -
's/STRING:\s//'
Find STRING:\s and replace it with nothing. This removes STRING:\s from the input. \s stands for a whitespace.
There are some UNIX supported commands involved. Personally I made this chain work on a Windows machine using Cygwin to obtain those commands.
The easiest way is to scan with nmap -O
: nmap will usually correctly determine if a machine is a printer or not based on the OS.
nmap -O 192.168.1.1/24 -oG - | grep printer >> outfile
Should make it one entry per line and dump it to a file called "outfile". Obviously change the ip range to whatever range you're scanning