CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/parser/burp_issue_document.rb
Views: 1904
1
# -*- coding: binary -*-
2
require "rex/parser/nokogiri_doc_mixin"
3
require 'uri'
4
5
module Rex
6
module Parser
7
8
# If Nokogiri is available, define Burp Issue document class.
9
load_nokogiri && class BurpIssueDocument < Nokogiri::XML::SAX::Document
10
11
include NokogiriDocMixin
12
13
def start_element(name=nil,attrs=[])
14
attrs = normalize_attrs(attrs)
15
block = @block
16
@state[:current_tag][name] = true
17
case name
18
when "host", "name", "info", "issueDetail", "references"
19
@state[:has_text] = true
20
end
21
end
22
23
def end_element(name=nil)
24
block = @block
25
case name
26
when "issue"
27
report_web_host_info
28
report_web_service_info
29
report_vuln
30
# Reset the state once we close a host
31
@state = @state.select {|k| [:current_tag].include? k}
32
when "host"
33
@state[:has_text] = false
34
collect_host_info
35
@text = nil
36
when "name"
37
@state[:has_text] = false
38
collect_name
39
@text = nil
40
when "issueDetail"
41
@state[:has_text] = false
42
collect_issue_detail
43
@text = nil
44
when "references"
45
@state[:has_text] = false
46
collect_references
47
@text = nil
48
end
49
@state[:current_tag].delete name
50
end
51
52
def collect_host_info
53
return unless in_issue
54
return unless has_text
55
uri = URI(@text)
56
57
@state[:host] = uri.host
58
@state[:service_name] = uri.scheme
59
@state[:proto] = "tcp"
60
61
case @state[:service_name]
62
when "http"
63
@state[:port] = 80
64
when "https"
65
@state[:port] = 443
66
end
67
end
68
69
def collect_name
70
return unless in_issue
71
return unless has_text
72
@state[:vuln_name] = @text
73
end
74
75
def collect_issue_detail
76
return unless in_issue
77
return unless has_text
78
@state[:issue_detail] = @text
79
end
80
81
def collect_references
82
return unless in_issue
83
return unless has_text
84
uri = @text.match('href=[\'"]?([^\'" >]+)')[1]
85
@state[:refs] = ["URI-#{uri}"]
86
end
87
88
def report_web_host_info
89
return unless @state[:host]
90
address = Rex::Socket.resolv_to_dotted(@state[:host]) rescue nil
91
host_info = {workspace: @args[:workspace]}
92
host_info[:address] = address
93
host_info[:name] = @state[:host]
94
db_report(:host, host_info)
95
end
96
97
def report_web_service_info
98
return unless @state[:host]
99
return unless @state[:port]
100
return unless @state[:proto]
101
return unless @state[:service_name]
102
service_info = {workspace: @args[:workspace]}
103
service_info[:host] = @state[:host]
104
service_info[:port] = @state[:port]
105
service_info[:proto] = @state[:proto]
106
service_info[:name] = @state[:service_name]
107
@state[:service_object] = db_report(:service, service_info)
108
end
109
110
def report_vuln
111
return unless @state[:service_object]
112
return unless @state[:vuln_name]
113
return unless @state[:issue_detail]
114
vuln_info = {workspace: @args[:workspace]}
115
vuln_info[:service_id] = @state[:service_object].id
116
vuln_info[:host] = @state[:host]
117
vuln_info[:name] = @state[:vuln_name]
118
vuln_info[:info] = @state[:issue_detail]
119
vuln_info[:refs] = @state[:refs]
120
@state[:vuln_object] = db_report(:vuln, vuln_info)
121
end
122
123
def in_issue
124
return false unless in_tag("issue")
125
return false unless in_tag("issues")
126
return true
127
end
128
129
def has_text
130
return false unless @text
131
return false if @text.strip.empty?
132
@text = @text.strip
133
end
134
end
135
136
end
137
end
138
139
140