arachni 0.2.2.1 → 0.2.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG.md +30 -0
  2. data/CONTRIBUTORS.md +1 -0
  3. data/README.md +28 -8
  4. data/Rakefile +1 -0
  5. data/bin/arachni_web_autostart +46 -0
  6. data/lib/anemone/page.rb +1 -0
  7. data/lib/arachni.rb +1 -1
  8. data/lib/framework.rb +8 -3
  9. data/lib/http.rb +9 -39
  10. data/lib/mixins/observable.rb +87 -0
  11. data/lib/module/auditor.rb +14 -0
  12. data/lib/module/base.rb +0 -14
  13. data/lib/nokogiri/xml/node.rb +42 -0
  14. data/lib/ui/cli/cli.rb +1 -1
  15. data/lib/ui/web/log.rb +21 -14
  16. data/lib/ui/web/report_manager.rb +100 -15
  17. data/lib/ui/web/server.rb +24 -33
  18. data/lib/ui/web/server/public/reports/demo.testfire.net:Sun Mar 20 02:48:10 2011.afr +104829 -0
  19. data/lib/ui/web/server/views/layout.erb +1 -1
  20. data/lib/ui/web/server/views/options.erb +10 -2
  21. data/lib/ui/web/server/views/plugins.erb +1 -1
  22. data/lib/ui/web/server/views/reports.erb +8 -4
  23. data/lib/ui/xmlrpc/xmlrpc.rb +1 -1
  24. data/metamodules/autothrottle.rb +2 -2
  25. data/metamodules/timeout_notice.rb +1 -1
  26. data/modules/audit/sqli_blind_rdiff.rb +1 -1
  27. data/modules/recon/common_files/filenames.txt +2 -0
  28. data/modules/recon/directory_listing.rb +1 -0
  29. data/modules/recon/interesting_responses.rb +3 -3
  30. data/path_extractors/generic.rb +5 -1
  31. data/plugins/autologin.rb +15 -4
  32. data/plugins/content_types.rb +2 -2
  33. data/plugins/cookie_collector.rb +9 -16
  34. data/plugins/profiler.rb +237 -0
  35. data/reports/html.rb +21 -6
  36. data/reports/html/default.erb +4 -2
  37. data/reports/plugin_formatters/html/autologin.rb +63 -0
  38. data/reports/plugin_formatters/html/profiler.rb +71 -0
  39. data/reports/plugin_formatters/html/profiler/template.erb +177 -0
  40. data/reports/plugin_formatters/stdout/autologin.rb +55 -0
  41. data/reports/plugin_formatters/stdout/profiler.rb +90 -0
  42. data/reports/plugin_formatters/xml/autologin.rb +68 -0
  43. data/reports/plugin_formatters/xml/profiler.rb +120 -0
  44. metadata +23 -68
data/reports/html.rb CHANGED
@@ -111,12 +111,14 @@ class HTML < Arachni::Report::Base
111
111
  }
112
112
  }
113
113
 
114
+ @total_severities = 0
115
+ @total_elements = 0
116
+ @total_verifications = 0
114
117
  @audit_store.issues.each_with_index {
115
118
  |issue, i|
116
119
 
117
120
  @graph_data[:severities][issue.severity] ||= 0
118
121
  @graph_data[:severities][issue.severity] += 1
119
- @total_severities ||= 0
120
122
  @total_severities += 1
121
123
 
122
124
  @graph_data[:issues][issue.name] ||= 0
@@ -124,19 +126,20 @@ class HTML < Arachni::Report::Base
124
126
 
125
127
  @graph_data[:elements][issue.elem] ||= 0
126
128
  @graph_data[:elements][issue.elem] += 1
127
- @total_elements ||= 0
128
129
  @total_elements += 1
129
130
 
130
131
  verification = issue.verification ? 'Yes' : 'No'
131
132
  @graph_data[:verification][verification] ||= 0
132
133
  @graph_data[:verification][verification] += 1
133
- @total_verifications ||= 0
134
134
  @total_verifications += 1
135
135
 
136
136
  issue.variations.each_with_index {
137
137
  |variation, j|
138
138
 
139
139
  if( variation['response'] && !variation['response'].empty? )
140
+
141
+ variation['response'] = variation['response'].force_encoding( 'utf-8' )
142
+
140
143
  @audit_store.issues[i].variations[j]['escaped_response'] =
141
144
  Base64.encode64( variation['response'] ).gsub( /\n/, '' )
142
145
  end
@@ -158,17 +161,29 @@ class HTML < Arachni::Report::Base
158
161
 
159
162
  @graph_data[:severities].each {
160
163
  |severity, cnt|
161
- @graph_data[:severities][severity] = ((cnt/Float(@total_severities)) * 100).to_i
164
+ begin
165
+ @graph_data[:severities][severity] = ((cnt/Float(@total_severities)) * 100).to_i
166
+ rescue
167
+ @graph_data[:severities][severity] = 0
168
+ end
162
169
  }
163
170
 
164
171
  @graph_data[:elements].each {
165
172
  |elem, cnt|
166
- @graph_data[:elements][elem] = ((cnt/Float(@total_elements)) * 100).to_i
173
+ begin
174
+ @graph_data[:elements][elem] = ((cnt/Float(@total_elements)) * 100).to_i
175
+ rescue
176
+ @graph_data[:elements][elem] = 0
177
+ end
167
178
  }
168
179
 
169
180
  @graph_data[:verification].each {
170
181
  |verification, cnt|
171
- @graph_data[:verification][verification] = ((cnt/Float(@total_verifications)) * 100).to_i
182
+ begin
183
+ @graph_data[:verification][verification] = ((cnt/Float(@total_verifications)) * 100).to_i
184
+ rescue
185
+ @graph_data[:verification][verification] = 0
186
+ end
172
187
  }
173
188
 
174
189
  end
@@ -1,3 +1,5 @@
1
+ <%# Encoding: utf-8%>
2
+
1
3
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
4
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
5
 
@@ -180,7 +182,7 @@
180
182
 
181
183
  var verification;
182
184
  $(document).ready(function() {
183
- elements = new Highcharts.Chart({
185
+ verification = new Highcharts.Chart({
184
186
  chart: {
185
187
  renderTo: 'chart-verification',
186
188
  backgroundColor: '#ccc'
@@ -949,7 +951,7 @@
949
951
  <p> &nbsp; </p>
950
952
 
951
953
  <%@plugins.values.each do |plugin|%>
952
- <p><%=plugin%></p>
954
+ <p><%=plugin.force_encoding( 'utf-8' )%></p>
953
955
  <%end%>
954
956
  </section>
955
957
 
@@ -0,0 +1,63 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+
13
+ module Reports
14
+
15
+ class HTML
16
+ module PluginFormatters
17
+
18
+ #
19
+ # HTML formatter for the results of the AutoLogin plugin
20
+ #
21
+ # @author: Tasos "Zapotek" Laskos
22
+ # <tasos.laskos@gmail.com>
23
+ # <zapotek@segfault.gr>
24
+ # @version: 0.1
25
+ #
26
+ class AutoLogin < Arachni::Plugin::Formatter
27
+
28
+ def initialize( plugin_data )
29
+ @results = plugin_data[:results]
30
+ @description = plugin_data[:description]
31
+ end
32
+
33
+ def run
34
+ return ERB.new( tpl ).result( binding )
35
+ end
36
+
37
+ def tpl
38
+ %q{
39
+ <h3>AutoLogin</h3>
40
+ <blockquote><pre><%=::Arachni::Reports::HTML.prep_description(@description)%></pre></blockquote>
41
+
42
+ <h4>Result</h4>
43
+ <blockquote><%=@results[:msg]%></blockquote>
44
+
45
+ <% if @results[:cookies].is_a?( Hash )%>
46
+ <h5>Cookies were set to:</h5>
47
+ <ul>
48
+ <% @results[:cookies].each_pair do |name, val|%>
49
+ <li><%=name%> = <%=val%></li>
50
+ <%end%>
51
+ <ul>
52
+ <%end%>
53
+ }
54
+
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,71 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ require 'json'
12
+
13
+ module Arachni
14
+
15
+ module Reports
16
+
17
+ class HTML
18
+ module PluginFormatters
19
+
20
+ #
21
+ # HTML formatter for the results of the Profiler plugin
22
+ #
23
+ # @author: Tasos "Zapotek" Laskos
24
+ # <tasos.laskos@gmail.com>
25
+ # <zapotek@segfault.gr>
26
+ # @version: 0.1
27
+ #
28
+ class Profiler < Arachni::Plugin::Formatter
29
+
30
+ def initialize( plugin_data )
31
+ @results = plugin_data[:results]
32
+ @description = plugin_data[:description]
33
+ end
34
+
35
+ def run
36
+
37
+ @results['times'].each_with_index {
38
+ |itm, i|
39
+ @results['times'][i] = escape_hash( itm )
40
+ }
41
+
42
+ times = @results['times'].map{ |item| item['time'] }
43
+ total_time = 0
44
+ times.each {
45
+ |time|
46
+ total_time += time
47
+ }
48
+
49
+ avg_time = total_time / times.size
50
+ times.reject!{ |time| time < avg_time }
51
+
52
+ return ERB.new( IO.read( File.dirname( __FILE__ ) + '/profiler/template.erb' ) ).result( binding )
53
+ end
54
+
55
+ def escape_hash( hash )
56
+ hash.each_pair {
57
+ |k, v|
58
+ hash[k] = CGI.escape( v ) if v.is_a?( String )
59
+ hash[k] = escape_hash( v ) if v.is_a? Hash
60
+ }
61
+
62
+ return hash
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,177 @@
1
+ <h3>Profiler</h3>
2
+ <blockquote><pre><%=::Arachni::Reports::HTML.prep_description(@description)%></pre></blockquote>
3
+
4
+ <script type="text/javascript">
5
+
6
+ var tooltip_data = <%=@results['times'].to_json%>;
7
+ var chart;
8
+ $(document).ready(function() {
9
+ chart = new Highcharts.Chart({
10
+ chart: {
11
+ renderTo: 'chart-response-times',
12
+ zoomType: 'x',
13
+ spacingRight: 20,
14
+ backgroundColor: '#ccc'
15
+ },
16
+ title: {
17
+ text: 'Response times exceeding the average (<%=times.size%> out of <%=@results['times'].size%> responses)'
18
+ },
19
+ subtitle: {
20
+ text: document.ontouchstart === undefined ?
21
+ 'Click and drag in the plot area to zoom in' :
22
+ 'Drag your finger over the plot to zoom in'
23
+ },
24
+ xAxis: {
25
+ title: {
26
+ text: null
27
+ }
28
+ },
29
+ yAxis: {
30
+ title: {
31
+ text: 'Seconds'
32
+ },
33
+ min: <%=times.min%>,
34
+ startOnTick: false,
35
+ showFirstLabel: false
36
+ },
37
+ tooltip: {
38
+ formatter: function() {
39
+ return 'URL: <b>' + unescape( tooltip_data[this.x]['url'] ) + '</b><br/>' +
40
+ 'Response time: <b>' + this.y +'</b> seconds<br/>';
41
+ }
42
+ },
43
+ legend: {
44
+ enabled: false
45
+ },
46
+ plotOptions: {
47
+ area: {
48
+ fillColor: {
49
+ linearGradient: [0, 0, 0, 300],
50
+ stops: [
51
+ [0, 'rgba(0,0,0,0)'],
52
+ [1, 'rgba(2,0,0,0)']
53
+ ]
54
+ },
55
+ lineWidth: 1,
56
+ marker: {
57
+ enabled: false,
58
+ states: {
59
+ hover: {
60
+ enabled: true,
61
+ radius: 5
62
+ }
63
+ }
64
+ },
65
+ shadow: false,
66
+ states: {
67
+ hover: {
68
+ lineWidth: 1
69
+ }
70
+ }
71
+ }
72
+ },
73
+
74
+ series: [{
75
+ type: 'area',
76
+ pointInterval: 1,
77
+ data: <%=times.to_s%>
78
+ }]
79
+ });
80
+
81
+
82
+ });
83
+ </script>
84
+
85
+
86
+ <h4>Response time analysis</h4>
87
+
88
+ <strong>Average response time</strong>: <%=avg_time%> seconds <br/>
89
+ <strong>Max</strong>: <%=times.max%> seconds <br/>
90
+ <strong>Min</strong>: <%=@results['times'].map{ |item| item['time'] }.min%> seconds <br/>
91
+ <strong>Sample size</strong>: <%=@results['times'].size%> responses <br/>
92
+
93
+ <div id="chart-response-times" style="width: 1000px"></div>
94
+
95
+ <p>&nbsp;</p>
96
+
97
+ <h4>Inputs that affect output (Taint analysis)</h4>
98
+ <% @results['inputs'].each_with_index do |item, idx| %>
99
+
100
+ <h5>
101
+ <%=item['element']['type'].capitalize%>
102
+
103
+ <%if item['element']['name']%>
104
+ named '<%=item['element']['name']%>'
105
+ <%end%>
106
+
107
+ <%if item['element']['altered']%>
108
+ using the '<%=item['element']['altered']%>' input
109
+ <%end%>
110
+
111
+ <%if item['element']['owner']%>
112
+ at <a href="<%=CGI.escapeHTML( item['element']['owner'] )%>"> <%=item['element']['owner']%> </a>
113
+ <%end%>
114
+
115
+ <%if item['element']['action']%>
116
+ pointing to <a href="<%=CGI.escapeHTML( item['element']['action'] )%>"> <%=item['element']['action']%> </a>
117
+ <%end%>
118
+
119
+ <%if item['element']['method']%>
120
+ using <%=item['request']['method']%>
121
+ <%end%>
122
+ </h5>
123
+
124
+ <p>
125
+ It was submitted using the following parameters:
126
+ <ul>
127
+ <%item['element']['auditable'].each_pair do |k, v| %>
128
+ <li><%=k%> = <%=v%></li>
129
+ <%end%>
130
+ </ul>
131
+
132
+ The taint landed in the following elements at <a href="<%=CGI.escapeHTML( item['request']['url'] )%>"> <%=item['request']['url']%> </a>:
133
+ <ul>
134
+ <%item['landed'].each do |elem| %>
135
+ <li>
136
+ <%=elem['type'].capitalize%>
137
+
138
+ <%if elem['name']%>
139
+ named '<%=elem['name']%>'
140
+ <%end%>
141
+
142
+ <%if elem['altered']%>
143
+ using the '<%=elem['altered']%>' input
144
+ <%end%>
145
+
146
+ <%if elem['auditable']%>
147
+ <ul>
148
+ <%elem['auditable'].each_pair do |k, v| %>
149
+ <li><%=k%> = <%=v%></li>
150
+ <%end%>
151
+ </ul>
152
+ <%end%>
153
+ </li>
154
+ <%end%>
155
+ </ul>
156
+
157
+ <div class="hidden" id="inspection-dialog_<%=idx%>" title="Relevant content is shown in red.">
158
+ <% match = CGI.escapeHTML( item['response']['body'] )%>
159
+ <pre> <%=CGI.escapeHTML( item['response']['body'] ).gsub( item['taint'], '<strong style="color: red">' + item['taint'] + '</strong>' ) %> </pre>
160
+ </div>
161
+
162
+ <form style="display:inline" action="#">
163
+ <input onclick="javascript:inspect( '#inspection-dialog_<%=idx%>')" type="button" value="Inspect" />
164
+ </form>
165
+
166
+ <form style="display:inline" action="<%=item['request']['url']%>" target="_blank" method="<%=item['request']['method']%>">
167
+ <% item['request']['params'].each_pair do |name, value|%>
168
+ <input type="hidden" name="<%=CGI.escapeHTML(name)%>" value="<%=CGI.escapeHTML( value )%>" />
169
+ <%end%>
170
+ <input type="submit" value="Replay" />
171
+ </form>
172
+
173
+ </p>
174
+
175
+ <p>&nbsp;</p>
176
+
177
+ <%end%>
@@ -0,0 +1,55 @@
1
+ =begin
2
+ Arachni
3
+ Copyright (c) 2010-2011 Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>
4
+
5
+ This is free software; you can copy and distribute and modify
6
+ this program under the term of the GPL v2.0 License
7
+ (See LICENSE file for details)
8
+
9
+ =end
10
+
11
+ module Arachni
12
+ module Reports
13
+
14
+ class Stdout
15
+ module PluginFormatters
16
+
17
+ #
18
+ # Stdout formatter for the results of the AutoLogin plugin
19
+ #
20
+ #
21
+ # @author: Tasos "Zapotek" Laskos
22
+ # <tasos.laskos@gmail.com>
23
+ # <zapotek@segfault.gr>
24
+ # @version: 0.1
25
+ #
26
+ class AutoLogin < Arachni::Plugin::Formatter
27
+
28
+ def initialize( plugin_data )
29
+ @results = plugin_data[:results]
30
+ @description = plugin_data[:description]
31
+ end
32
+
33
+ def run
34
+ print_status( 'AutoLogin' )
35
+ print_info( '~~~~~~~~~~~~~~' )
36
+
37
+ print_info( 'Description: ' + @description )
38
+ print_line
39
+ print_ok( @results[:msg] )
40
+
41
+ return if !@results[:cookies]
42
+ print_info( 'Cookies set to:' )
43
+ @results[:cookies].each_pair {
44
+ |name, val|
45
+ print_info( ' * ' + name + ' = ' + val )
46
+ }
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+ end
55
+ end