Parent

Class/Module Index [+]

Quicksearch

Rex::Parser::MbsaDocument

Public Instance Methods

characters(text) click to toggle source

This breaks xml-encoded characters, so need to append

# File lib/rex/parser/mbsa_nokogiri.rb, line 38
def characters(text)
        return unless @state[:has_text]
        @text ||= ""
        @text << text
end
collect_advice_data() click to toggle source

So far, just care about Host OS There is assuredly more interesting things going on in here.

# File lib/rex/parser/mbsa_nokogiri.rb, line 153
def collect_advice_data
        return unless in_tag("SecScan")
        return unless in_tag("Check")
        collect_os_name
        @text = nil
end
collect_bulletin_title() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 120
def collect_bulletin_title
        return unless @state[:check_state]["ID"] == 500.to_s
        return unless in_tag("UpdateData")
        return unless @state[:update]
        return if @text.to_s.strip.empty?
        @state[:update]["Title"] = @text.to_s.strip
end
collect_check_data() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 191
def collect_check_data
        return unless in_tag("SecScan")
        @state[:check_state] = {}
end
collect_detail_data() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 183
def collect_detail_data
        return unless in_tag("SecScan")
        return unless in_tag("Check")
        if @report_data[:missing_updates]
                @report_data[:vulns] = @report_data[:missing_updates]
        end
end
collect_host_data() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 196
def collect_host_data
        return unless @state[:address]
        return if @state[:address].strip.empty?
        @report_data[:host] = @state[:address].strip
        if @state[:hostname] && !@state[:hostname].empty?
                @report_data[:name] = @state[:hostname]
        end
        @report_data[:state] = Msf::HostState::Alive
end
collect_missing_update() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 136
def collect_missing_update
        return unless @state[:check_state]["ID"] == 500.to_s
        return if @state[:update]["IsInstalled"] == "true"
        @report_data[:missing_updates] ||= []
        this_update = {}
        this_update[:name] = @state[:update]["Title"].to_s.strip
        this_update[:refs] = []
        if @state[:update]["BulletinID"].empty?
                this_update[:refs] << "URL-#{@state[:update][:url]}"
        else
                this_update[:refs] << "MSB-#{@state[:update]["BulletinID"]}"
        end
        @report_data[:missing_updates] << this_update
end
collect_os_name() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 160
def collect_os_name
        return unless @state[:check_state]["ID"] == 10101.to_s
        return unless @text
        return if @text.strip.empty?
        os_match = @text.match(/Computer is running (.*)/)
        return unless os_match
        os_info = os_match[1]
        os_vendor = os_info[/Microsoft/]
        os_family = os_info[/Windows/]
        os_version = os_info[/(XP|2000 Advanced Server|2000|2003|2008|SBS|Vista|7 .* Edition|7)/]
        if os_info
                @report_data[:os_fingerprint] = {}
                @report_data[:os_fingerprint][:type] = "host.os.mbsa_fingerprint"
                @report_data[:os_fingerprint][:data] = {
                        :os_vendor => os_vendor,
                        :os_family => os_family,
                        :os_version => os_version,
                        :os_accuracy => 100,
                        :os_match => os_info.gsub(/\x2e$/,"")
                }
        end
end
collect_title() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 113
def collect_title
        return unless in_tag("SecScan")
        return unless in_tag("Check")
        collect_bulletin_title
        @text = nil
end
collect_updatedata() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 128
def collect_updatedata
        return unless in_tag("SecScan")
        return unless in_tag("Check")
        return unless in_tag("Detail")
        collect_missing_update
        @state[:updates] = {}
end
collect_url() click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 88
def collect_url
        return unless in_tag("References")
        return unless in_tag("UpdateData")
        return unless in_tag("Detail")
        return unless in_tag("Check")
        @state[:update][:url] = @text.to_s.strip
        @text = nil
end
end_element(name=nil) click to toggle source

When we exit a tag, this is triggered.

# File lib/rex/parser/mbsa_nokogiri.rb, line 45
def end_element(name=nil)
        block = @block
        case name
        when "SecScan" # 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_vulns(host_object,&block)
                end
                # Reset the state once we close a host
                @state.delete_if {|k| k != :current_tag}
        when "Check"
                collect_check_data
        when "Advice"
                @state[:has_text] = false
                collect_advice_data
        when "Detail"
                collect_detail_data
        when "UpdateData"
                collect_updatedata
        when "Title"
                @state[:has_text] = false
                collect_title
        when "InformationURL"
                collect_url
                @state[:has_text] = false
        end
        @state[:current_tag].delete name
end
host_is_okay() click to toggle source

We need to override the usual host_is_okay because MBSA apparently doesn't report on open ports at all.

# File lib/rex/parser/mbsa_nokogiri.rb, line 241
def host_is_okay
        return false unless @report_data[:host]
        return false unless valid_ip(@report_data[:host])
        return false unless @report_data[:state] == Msf::HostState::Alive
        if @args[:blacklist]
                return false if @args[:blacklist].include?(@report_data[:host])
        end
        return true
end
record_check(attrs) click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 228
def record_check(attrs)
        return unless in_tag("SecScan")
        @state[:check_state] = attr_hash(attrs)
end
record_detail(attrs) click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 233
def record_detail(attrs)
        return unless in_tag("SecScan")
        return unless in_tag("Check")
        @state[:detail_state] = attr_hash(attrs)
end
record_host(attrs) click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 222
def record_host(attrs)
        host_attrs = attr_hash(attrs)
        @state[:address] = host_attrs["IP"]
        @state[:hostname] = host_attrs["Machine"]
end
record_updatedata(attrs) click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 214
def record_updatedata(attrs)
        return unless in_tag("SecScan")
        return unless in_tag("Check")
        return unless in_tag("Detail")
        update_attrs = attr_hash(attrs)
        @state[:update] = attr_hash(attrs)
end
report_fingerprint(host_object) click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 77
def report_fingerprint(host_object)
        return unless host_object.kind_of? ::Mdm::Host
        return unless @report_data[:os_fingerprint]
        fp_note = @report_data[:os_fingerprint].merge(
                {
                        :workspace => host_object.workspace,
                        :host => host_object
        })
        db_report(:note, fp_note)
end
report_host(&block) click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 206
def report_host(&block)
        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_vulns(host_object, &block) click to toggle source
# File lib/rex/parser/mbsa_nokogiri.rb, line 97
def report_vulns(host_object, &block)
        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|
                next unless vuln[:refs]
                if vuln[:refs].empty?
                        next
                end
                if block
                        db.emit(:vuln, ["Missing #{vuln[:name]}",1], &block) if block
                end
                db_report(:vuln, vuln.merge(:host => host_object))
        end
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/mbsa_nokogiri.rb, line 14
def start_element(name=nil,attrs=[])
        attrs = normalize_attrs(attrs)
        block = @block
        @state[:current_tag][name] = true
        case name
        when "SecScan"
                record_host(attrs)
        when "IP" # TODO: Check to see if IPList/IP is useful to import
        when "Check" # A list of MBSA checks. They have an ID and a Name.
                record_check(attrs)
        when "Advice" # Check advice. Free form text about the check
                @state[:has_text] = true
        when "Detail" # Check/Detail is where missing fixes are.
                record_detail(attrs)
        when "UpdateData" # Info about installed/missing hotfixes
                record_updatedata(attrs)
        when "Title" # MSB Title
                @state[:has_text] = true
        when "InformationURL" # Only use this if we don't have a Bulletin ID
                @state[:has_text] = true
        end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.