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

  1. It scans a network searching for network entities that are listening on the default printer ports.
  2. Using the results of the previous step it will check for SNMP support on these devices.
  3. 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