Class: Arachni::Report

Inherits:
Object show all
Includes:
Utilities
Defined in:
lib/arachni/report.rb

Overview

Author:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utilities

#available_port, #caller_name, #caller_path, #cookie_decode, #cookie_encode, #cookies_from_document, #cookies_from_file, #cookies_from_response, #exception_jail, #exclude_path?, #follow_protocol?, #form_decode, #form_encode, #forms_from_document, #forms_from_response, #generate_token, #get_path, #hms_to_seconds, #html_decode, #html_encode, #include_path?, #links_from_document, #links_from_response, #normalize_url, #page_from_response, #page_from_url, #parse_set_cookie, #path_in_domain?, #path_too_deep?, #port_available?, #rand_port, #random_seed, #redundant_path?, #remove_constants, #request_parse_body, #seconds_to_hms, #skip_page?, #skip_path?, #skip_resource?, #skip_response?, #to_absolute, #uri_decode, #uri_encode, #uri_parse, #uri_parse_query, #uri_parser, #uri_rewrite

Constructor Details

#initialize(options = {}) ⇒ Report



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/arachni/report.rb', line 41

def initialize( options = {} )
    options.each { |k, v| send( "#{k}=", v ) }

    @version     ||= Arachni::VERSION
    @plugins     ||= {}
    @sitemap     ||= {}
    self.options ||= Options
    @issues      ||= {}

    @start_datetime  ||= Time.now
    @finish_datetime ||= Time.now
end

Instance Attribute Details

#finish_datetimeTime



39
40
41
# File 'lib/arachni/report.rb', line 39

def finish_datetime
  @finish_datetime
end

#optionsHash



23
24
25
# File 'lib/arachni/report.rb', line 23

def options
  @options
end

#pluginsHash



31
32
33
# File 'lib/arachni/report.rb', line 31

def plugins
  @plugins
end

#sitemapHash<String, Integer>



27
28
29
# File 'lib/arachni/report.rb', line 27

def sitemap
  @sitemap
end

#start_datetimeTime



35
36
37
# File 'lib/arachni/report.rb', line 35

def start_datetime
  @start_datetime
end

#versionString



19
20
21
# File 'lib/arachni/report.rb', line 19

def version
  @version
end

Class Method Details

.from_rpc_data(data) ⇒ DOM



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/arachni/report.rb', line 246

def self.from_rpc_data( data )
    data['start_datetime']  = Time.parse( data['start_datetime'] )
    data['finish_datetime'] = Time.parse( data['finish_datetime'] )

    data['issues'] = data['issues'].map { |i| Arachni::Issue.from_rpc_data( i ) }

    data['plugins'] = data['plugins'].inject({}) do |h, (k, v)|
        k    = k.to_sym
        h[k] = v.my_symbolize_keys(false)
        next h if !h[k][:options]

        h[k][:options] = v['options'].map do |option|
            klass = option['class'].split( '::' ).last.to_sym
            Component::Options.const_get( klass ).from_rpc_data( option )
        end
        h
    end

    new data
end

.load(file) ⇒ Report

Loads and a saved Arachni::Report object from file.



123
124
125
126
127
128
129
130
131
# File 'lib/arachni/report.rb', line 123

def self.load( file )
    File.open( file, 'rb' ) do |f|
        f.seek -4, IO::SEEK_END
        summary_size = f.read( 4 ).unpack( 'N' ).first

        f.rewind
        from_rpc_data RPC::Serializer.load( f.read( f.size - summary_size ) )
    end
end

.read_summary(report) ⇒ Hash



106
107
108
109
110
111
112
113
114
# File 'lib/arachni/report.rb', line 106

def self.read_summary( report )
    File.open( report ) do |f|
        f.seek -4, IO::SEEK_END
        summary_size = f.read( 4 ).unpack( 'N' ).first

        f.seek -summary_size-4, IO::SEEK_END
        RPC::Serializer.load( f.read( summary_size ) )
    end
end

Instance Method Details

#==(other) ⇒ Object



267
268
269
# File 'lib/arachni/report.rb', line 267

def ==( other )
    hash == other.hash
end

#delta_timeString

Note:

If no #finish_datetime has been provided, it will use ‘Time.now`.

Returns ‘#start_datetime - #finish_datetime` in `00:00:00` (`hours:minutes:seconds`) format.



63
64
65
# File 'lib/arachni/report.rb', line 63

def delta_time
    seconds_to_hms( (@finish_datetime || Time.now) - @start_datetime )
end

#hashObject



271
272
273
274
275
276
277
# File 'lib/arachni/report.rb', line 271

def hash
    h = to_hash
    [:start_datetime, :finish_datetime, :delta_datetime].each do |k|
        h.delete k
    end
    h.hash
end

#issue_by_digest(digest) ⇒ Issue



97
98
99
# File 'lib/arachni/report.rb', line 97

def issue_by_digest( digest )
    @issues[digest]
end

#issuesArray<Issue>



90
91
92
# File 'lib/arachni/report.rb', line 90

def issues
    @issues.values
end

#issues=(issues) ⇒ Array<Issue>



80
81
82
83
84
85
86
# File 'lib/arachni/report.rb', line 80

def issues=( issues )
    @issues = {}
    issues.each do |issue|
        @issues[issue.digest] = issue
    end
    self.issues
end

#save(location = nil) ⇒ String



138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/arachni/report.rb', line 138

def save( location = nil )
    default_filename = "#{URI(url).host} #{@finish_datetime.to_s.gsub( ':', '_' )}.afr"

    if !location
        location = default_filename
    elsif File.directory? location
        location += "/#{default_filename}"
    end

    IO.binwrite( location, to_afr )

    File.expand_path( location )
end

#summaryHash



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/arachni/report.rb', line 191

def summary
    by_severity = Hash.new(0)
    @issues.each { |_, issue| by_severity[issue.severity.to_sym] += 1 }

    by_type = Hash.new(0)
    @issues.each { |_, issue| by_type[issue.name] += 1 }

    by_check = Hash.new(0)
    @issues.each { |_, issue| by_check[issue.check[:shortname]] += 1 }

    {
        version:         @version,
        url:             url,
        checks:          @options[:checks],
        plugins:         @options[:plugins].keys,
        issues: {
            total:       @issues.size,
            by_severity: by_severity,
            by_type:     by_type,
            by_check:    by_check
        },
        sitemap_size:    @sitemap.size,
        start_datetime:  @start_datetime.to_s,
        finish_datetime: @finish_datetime.to_s,
        delta_time:      delta_time
    }
end

#to_afrString



154
155
156
157
158
159
160
161
162
# File 'lib/arachni/report.rb', line 154

def to_afr
    afr = RPC::Serializer.dump( self )

    # Append metadata to the end of the dump.
     = RPC::Serializer.dump( summary )
    afr << [, .size].pack( 'a*N' )

    afr
end

#to_hHash Also known as: to_hash



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/arachni/report.rb', line 166

def to_h
    h = {
        version:         @version,
        options:         Arachni::Options.hash_to_rpc_data( @options ),
        sitemap:         @sitemap,
        start_datetime:  @start_datetime.to_s,
        finish_datetime: @finish_datetime.to_s,
        delta_time:      delta_time,
        issues:          issues.map(&:to_h),
        plugins:         @plugins.dup
    }

    h[:plugins].each do |plugin, data|
        next if !data[:options]
        h[:plugins][plugin] = h[:plugins][plugin].dup
        h[:plugins][plugin][:options] = h[:plugins][plugin][:options].dup
        h[:plugins][plugin][:options] = data[:options].map(&:to_h)
    end

    h#.recode
end

#to_rpc_dataHash



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/arachni/report.rb', line 221

def to_rpc_data
    data = {}
    instance_variables.each do |ivar|
        data[ivar.to_s.gsub('@','')] = instance_variable_get( ivar )
    end

    data['options'] = Arachni::Options.hash_to_rpc_data( data['options'] )

    data['plugins'].each do |plugin, d|
        next if !d[:options]

        data['plugins'] = data['plugins'].dup
        data['plugins'][plugin] = data['plugins'][plugin].dup
        data['plugins'][plugin][:options] = data['plugins'][plugin][:options].dup
        data['plugins'][plugin][:options] = d[:options].map(&:to_rpc_data)
    end

    data['issues']          = data['issues'].values.map(&:to_rpc_data)
    data['start_datetime']  = data['start_datetime'].to_s
    data['finish_datetime'] = data['finish_datetime'].to_s
    data
end

#urlObject



54
55
56
# File 'lib/arachni/report.rb', line 54

def url
    @options[:url]
end