Skip to content

Instantly share code, notes, and snippets.

@taf2
Created November 17, 2009 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save taf2/236941 to your computer and use it in GitHub Desktop.
Save taf2/236941 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
# adapted: http://snippets.dzone.com/posts/show/6242
# file: portscan.rb
require 'socket'
require 'timeout'
require File.expand_path(File.join(File.dirname(__FILE__),'progressbar.rb'))
require 'rubygems'
require 'hpricot'
class PortScanner
def initialize(host)
high = 8192
service_file = File.expand_path(File.join(File.dirname(__FILE__),"service_ports.xml"))
doc_result = main(service_file, host, high)
end
def main(service_file, host, high)
puts "open: #{service_file.inspect}, write to: out.xml"
doc = Hpricot.XML(File.read(service_file))
# create a port map
ports_map = {}
(doc/:port).each do|port|
number = port[:number]
ports_map[number] ||= {}
ports_map[number][port[:type].to_sym] = {:name => port[:name], :desc => port.inner_text}
end
prog = ProgressBar.new("Scanning", high)
File.open("out.xml","wb") do|out|
out << %(<?xml version="1.0" encoding='UTF-8'?>\n)
out << %(<records>\n)
for port in 1 .. high
begin
Timeout::timeout(1) {
begin
#puts "check(tcp) #{host} port: #{port}..."
TCPsocket.open(host, port) do|s|
#print "port: #{port}"
# lookup the port
port_node = ports_map[port.to_s]
if port_node
port_type = port_node[:tcp]
#puts " tcp:#{port_type[:name]} #{port_type[:desc]}"
#discovered << {:type => 'tcp', :name => port_type[:name], :desc => port_type[:desc]}
out << %(\t<port number="#{port}" name="#{port_type[:name]}" type="tcp">#{port_type[:desc]}</port>\n)
else
#puts " tcp:unknown"
out << %(\t<port number="#{port}" name="" type="tcp"></port>\n)
end
end
rescue Errno::ECONNREFUSED
# pass
end
}
rescue Timeout::Error => e
end
begin
Timeout::timeout(1) {
begin
#puts "check(udp) #{host} port: #{port}..."
udp = UDPSocket.open
udp.connect('127.0.0.1', 7)
udp.send('', 0) # empty dgram: http://www.auditmypc.com/freescan/readingroom/port_scanning.asp
response = udp.recvfrom(64)
#print "port: #{port}"
# lookup the port
port_node = ports_map[port.to_s]
if port_node
port_type = port_node[:udp]
#puts " udp:#{port_type[:name]} #{port_type[:desc]}"# "%s/%sopen\t%s\n", port, node_port[:type], node_port[:name]
#discovered << {:type => 'udp', :name => port_type[:name], :desc => port_type[:desc]}
out << %(\t<port number="#{port}" name="#{port_type[:name]}" type="udp">#{port_type[:desc]}</port>\n)
else
#discovered << {:type => 'udp', :name => '', :desc => ''}
out << %(\t<port number="#{port}" name="" type="udp"></port>\n)
end
rescue Errno::ECONNREFUSED
# pass
ensure
udp.close if udp
end
}
rescue Timeout::Error => e
end
prog.inc
end
prog.finish
out << %(</records>)
end
puts "Results saved to: #{Dir.getwd}/out.xml"
end
end
if __FILE__ == $0 then
ps = PortScanner.new('192.168.1.1')
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment