Parent

Class/Module Index [+]

Quicksearch

Rex::Parser::FoundstoneDocument

Public Instance Methods

check_for_correct_report_type(attrs,&block) click to toggle source

Nothing technically stopping us from parsing this as well, but saving this for later

# File lib/rex/parser/foundstone_nokogiri.rb, line 82
def check_for_correct_report_type(attrs,&block)
        report_type = attr_hash(attrs)["ReportType"]
        if report_type == "Network Inventory"
                @report_type_ok = true
        else
                if report_type == "Risk Data"
                        msg = "The Foundstone/Mcafee report type '#{report_type}' is not currently supported"
                        msg << ",\nso no data will be imported. Please use the 'Network Inventory' report instead."
                else
                        msg = ".\nThe Foundstone/Macafee report type '#{report_type}' is unsupported."
                end
                db.emit(:warning,msg,&block) if block
                @report_type_ok = false
        end
end
collect_banner() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 170
def collect_banner
        return unless in_tag("Service")
        return unless in_tag("ServicesFound")
        return unless in_tag("Host")
        return if @text.nil? || @text.empty?
        banner = normalize_foundstone_banner(@state[:service]["ServiceName"],@text)
        unless banner.nil? || banner.empty?
                @state[:service][:banner] = banner
        end
        @text = nil
end
collect_cve() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 107
def collect_cve
        return unless in_tag("VulnsFound")
        return unless in_tag("HostData")
        return unless in_tag("Host")
        cve = @text.to_s
        @state[:vuln][:cves] ||= []
        @state[:vuln][:cves] << cve unless cve == "CVE-MAP-NOMATCH"
        @text = nil
end
collect_host_data() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 200
def collect_host_data
        @report_data[:host] = @state[:host]["IPAddress"]
        if @state[:host]["NBName"] && !@state[:host]["NBName"].empty?
                @report_data[:name] = @state[:host]["NBName"]
        elsif @state[:host]["DNSName"] && !@state[:host]["DNSName"].empty?
                @report_data[:name] = @state[:host]["DNSName"]
        end
        if @state[:host]["OSName"] && !@state[:host]["OSName"].empty?
                @report_data[:os_fingerprint] = @state[:host]["OSName"]
        end
        @report_data[:state] = Msf::HostState::Alive
        @report_data[:mac] = @state[:mac] if @state[:mac]
end
collect_port() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 152
def collect_port
        return unless in_tag("Service")
        return unless in_tag("ServicesFound")
        return unless in_tag("Host")
        return if @text.nil? || @text.empty?
        @state[:service][:port] = @text.strip
        @text = nil
end
collect_protocol() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 161
def collect_protocol
        return unless in_tag("Service")
        return unless in_tag("ServicesFound")
        return unless in_tag("Host")
        return if @text.nil? || @text.empty?
        @state[:service][:proto] = @text.strip
        @text = nil
end
collect_risk() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 98
def collect_risk
        return unless in_tag("VulnsFound")
        return unless in_tag("HostData")
        return unless in_tag("Host")
        risk = @text.to_s.to_i
        @state[:vuln][:risk] = risk
        @text = nil
end
collect_service() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 182
def collect_service
        return unless in_tag("ServicesFound")
        return unless in_tag("Host")
        return unless @state[:service][:port]
        @report_data[:ports] ||= []
        port_hash = {}
      port_hash[:port] = @state[:service][:port]
      port_hash[:proto] = @state[:service][:proto]
      port_hash[:info] = @state[:service][:banner]
      port_hash[:name] = db.nmap_msf_service_map(@state[:service]["ServiceName"])
        @report_data[:ports] << port_hash
end
collect_vuln() click to toggle source

Determines if we should keep the vuln or not. Note that we cannot tie them to a service.

# File lib/rex/parser/foundstone_nokogiri.rb, line 119
def collect_vuln
        return unless in_tag("VulnsFound")
        return unless in_tag("HostData")
        return unless in_tag("Host")
        return if @state[:vuln][:risk] == 0
        @report_data[:vulns] ||= []
        vuln_hash = {}
        vuln_hash[:name] = @state[:vuln]["VulnName"]
        refs = []
        refs << "FID-#{@state[:vuln]["id"]}"
        if @state[:vuln][:cves]
                @state[:vuln][:cves].each {|cve| refs << cve}
        end
        vuln_hash[:refs] = refs
        @report_data[:vulns] << vuln_hash
end
end_element(name=nil) click to toggle source

When we exit a tag, this is triggered.

# File lib/rex/parser/foundstone_nokogiri.rb, line 42
def end_element(name=nil)
        block = @block
        return unless @report_type_ok
        case name
        when "Host" # Wrap it up
                collect_host_data
                host_object = report_host &block
                if host_object
                        db.report_import_note(@args[:wspace],host_object)
                        report_fingerprint(host_object)
                        report_services(host_object)
                        report_vulns(host_object)
                end
                # Reset the state once we close a host
                @state.delete_if {|k| k != :current_tag}
        when "Port"
                @state[:has_text] = false
                collect_port
        when "Protocol"
                @state[:has_text] = false
                collect_protocol
        when "Banner"
                collect_banner
                @state[:has_text] = false
        when "Service"
                collect_service
        when "Vuln"
                collect_vuln
        when "Risk"
                @state[:has_text] = false
                collect_risk
        when "CVE"
                @state[:has_text] = false
                collect_cve
        end
        @state[:current_tag].delete name
end
first_line(str) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 287
def first_line(str)
        str.split("\n").first.to_s.strip
end
first_line_only?(service) click to toggle source

Services where we only care about the first line of the banner tag.

# File lib/rex/parser/foundstone_nokogiri.rb, line 270
def first_line_only?(service)
        svcs = %{
                vnc ftp ftps smtp oracle-tns nntp ssh ntp
        }
        9.times {|i| svcs << "vnc-#{i}"}
        svcs.include? service
end
needs_more_processing?(service) click to toggle source

Services where we need to do more processing before handing the banner back.

# File lib/rex/parser/foundstone_nokogiri.rb, line 280
def needs_more_processing?(service)
        svcs = %{
                microsoft-ds loc-srv http https sunrpc netbios-ns
        }
        svcs.include? service
end
normalize_foundstone_banner(service,banner) click to toggle source

Foundstone's banners are pretty free-form and often not just banners. Clean them up for the :info field, delegate off for other protocol data we can use.

# File lib/rex/parser/foundstone_nokogiri.rb, line 257
def normalize_foundstone_banner(service,banner)
        return "" if(banner.nil? || banner.strip.empty?)
        if first_line_only? service
                return (first_line banner)
        elsif needs_more_processing? service
                return process_service(service,banner)
        else
                return (first_line banner)
        end
end
process_service(service,banner) click to toggle source

XXX: Actually implement more of these

# File lib/rex/parser/foundstone_nokogiri.rb, line 292
def process_service(service,banner)
        meth = "process_service_#{service.gsub("-","_")}"
        if self.respond_to? meth
                self.send meth, banner
        else
                return (first_line banner)
        end
end
process_service_http(banner) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 322
def process_service_http(banner)
        server = nil
        banner.each_line do |line|
                if line =~ /^Server:\s+(.*)/
                        server = $1
                        break
                end
        end
        server || first_line(banner)
end
process_service_https(banner) click to toggle source
process_service_microsoft_ds(banner) click to toggle source

XXX: Make this behave more like the smb scanner

# File lib/rex/parser/foundstone_nokogiri.rb, line 310
def process_service_microsoft_ds(banner)
        lm_regex = /Native LAN Manager/
        lm_banner = nil
        banner.each_line { |line|
                if line[lm_regex]
                        lm_banner = line
                        break
                end
        }
        lm_banner || first_line(banner)
end
process_service_netbios_ns(banner) click to toggle source

XXX: Register a proper netbios note as the regular scanner does.

# File lib/rex/parser/foundstone_nokogiri.rb, line 303
def process_service_netbios_ns(banner)
        mac_regex = /[0-9A-Fa-f:]{17}/
        @state[:mac] = banner[mac_regex]
        first_line banner
end
process_service_rtsp(banner) click to toggle source
record_host(attrs) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 195
def record_host(attrs)
        return unless in_tag("HostData")
        @state[:host] = attr_hash(attrs)
end
record_service(attrs) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 146
def record_service(attrs)
        return unless in_tag("ServicesFound")
        return unless in_tag("Host")
        @state[:service] = attr_hash(attrs)
end
record_vuln(attrs) click to toggle source

These are per host.

# File lib/rex/parser/foundstone_nokogiri.rb, line 137
def record_vuln(attrs)
        return unless in_tag("VulnsFound")
        return unless in_tag("HostData")
        return unless in_tag("Host")
        @state[:vulns] ||= []

        @state[:vuln] = attr_hash(attrs) # id and VulnName
end
report_fingerprint(host_object) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 223
def report_fingerprint(host_object)
        fp_note = {
                :workspace => host_object.workspace,
                :host => host_object,
                :type => 'host.os.foundstone_fingerprint',
                :data => {:os => @report_data[:os_fingerprint] }
        }
        db_report(:note, fp_note)
end
report_host(&block) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 214
def report_host(&block)
        return unless in_tag("HostData")
        if host_is_okay
                db.emit(:address,@report_data[:host],&block) if block
                host_info = @report_data.merge(:workspace => @args[:wspace])
                db_report(:host,host_info)
        end
end
report_services(host_object) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 233
def report_services(host_object)
        return unless in_tag("HostData")
        return unless host_object.kind_of? ::Mdm::Host
        return unless @report_data[:ports]
        return if @report_data[:ports].empty?
        @report_data[:ports].each do |svc|
                db_report(:service, svc.merge(:host => host_object))
        end
end
report_vulns(host_object) click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 243
def report_vulns(host_object)
        return unless in_tag("HostData")
        return unless host_object.kind_of? ::Mdm::Host
        return unless @report_data[:vulns]
        return if @report_data[:vulns].empty?
        @report_data[:vulns].each do |vuln|
                db_report(:vuln, vuln.merge(:host => host_object))
        end
end
start_document() click to toggle source
# File lib/rex/parser/foundstone_nokogiri.rb, line 11
def start_document
        @report_type_ok = true # Optimistic
end
start_element(name=nil,attrs=[]) click to toggle source

Triggered every time a new element is encountered. We keep state ourselves with the @state variable, turning things on when we get here (and turning things off when we exit in end_element()).

# File lib/rex/parser/foundstone_nokogiri.rb, line 18
def start_element(name=nil,attrs=[])
        attrs = normalize_attrs(attrs)
        block = @block
        return unless @report_type_ok
        @state[:current_tag][name] = true
        case name
        when "ReportInfo"
                check_for_correct_report_type(attrs,&block)
        when "Host"
                record_host(attrs)
        when "Service"
                record_service(attrs)
        when "Port", "Protocol", "Banner"
                @state[:has_text] = true
        when "Vuln" # under VulnsFound, ignore risk 0 things
                record_vuln(attrs)
        when "Risk" # for Vuln
                @state[:has_text] = true
        when "CVE" # Under Vuln
                @state[:has_text] = true
        end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.