Portfinder
¶ ↑
Summary¶ ↑
Portfinder
is a ruby based port scanner with features like network/CIDR scanning, port randomization, hostname discovery and banner grabbing.
Installation¶ ↑
Portfinder
installation is as simple as a gem installation can get.
gem install portfinder
Usage¶ ↑
As a CLI tool¶ ↑
portfinder <host> [--port=PORT] [--thread=THREAD] [--randomize] [--out=OUT_FILE] [--verbose]
portfinder
can also be invoked using it’s aliased form pf
.
To it’s simplest form, single port of a host can be scanned.
portfinder 192.168.1.1 -p 80
It is possible to scan multiple ports of a host. In this case, ports can be a range,
portfinder 192.168.1.1 -p 1-1024
Or, a list of selections:
portfinder 192.168.1.1 -p 22,80,8080,443
Similarly, a scan can be performed on a selection of hosts,
portfinder 192.168.1.1,192.168.1.100,192.168.1.101 -p 1-65535
or, a range of hosts,
portfinder 192.168.1.1-10 -p 1-65535
or, on an entire network block, if you like.
portfinder 192.168.1.0/24 -p 1-65535
If a large number of host needs to be scanned, you may choose to increase the number of concurrent scanners using the available --thread
option.
portfinder 192.168.1.0/24 -p 1-65535 -t 20
By default, ten scanner threads are spawned at max.
When multiple ports are being scanned, they get scanned in the ascending order, or in the provided port selection order. If a randomized scan order is expected, --randomize
flag can be utilized.
portfinder 192.168.1.0/24 -r
As an API¶ ↑
A minimal usage example,
require "portfinder" scanner = Portfinder::Scanner.new("192.168.1.1", [22, 80, 8080], threads = 5) scanner.scan puts "\nOpen ports detected: #{scanner.result[host]}" puts "Raw scan result: #{scanner.result}" yml_stream = scanner.report_as "yml" json_stream = scanner.json_report
It is possible to use the API in different modes,
Mode 1: Blocking mode with monitoring¶ ↑
scanner = Portfinder::Scanner.new( hosts, ports, randomize: false, threaded: true, threads: 10, thread_for: :port ) scanner.log do |monitor| puts "Active threads:\t#{monitor.threads}\nScanning now:\n" while true print "\tHost:\t#{monitor.host}\tPort:\t#{monitor.port}\tStatus: #{ monitor.state}\r" sleep 0.1 end end scanner.scan puts "\nScan complete!\n\nResult: #{scanner.generate_result}" format = "json" file = open("export.#{format}", "wb") file.write scanner.report_as format.to_sym file.close
Mode 2: Partial blocking (join during result invocation)¶ ↑
scanner = Portfinder::Scanner.new("192.168.0.101", 1..65535) #logger can be placed here... scanner.scan synchronus = false # logger can be placed here... puts "\nScan complete!\n\nResult: #{scanner.generate_result}"
Mode 3 (GUI): Non-blocking (callback invocation upon completion)¶ ↑
(NOTE: Parent thread must be alive to receive callback)
scanner = Portfinder::Scanner.new("192.168.0.101", 1..65535) scanner.scan(false) do puts "\nScan complete!\n\nResult: #{scanner.generate_result}" end # logger can be placed here... sleep 10
Please note that the default scanner scans TCP ports using a full handshake (which is not, well…, stealthy. But, if you were expecting this feature, it’s gonna be available on the TCP SYN scanner release).
It’s also worth noting that, the current implementation doesn’t check for host status (alive/dead). So, scan can be considerably slow for dead hosts.
Contributing¶ ↑
If you are interested in contributing, please submit a pull request.