arachni 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -0
- data/README.md +9 -2
- data/components/checks/active/code_injection.rb +5 -5
- data/components/checks/active/code_injection_timing.rb +3 -3
- data/components/checks/active/no_sql_injection_differential.rb +3 -2
- data/components/checks/active/os_cmd_injection.rb +11 -5
- data/components/checks/active/os_cmd_injection_timing.rb +11 -4
- data/components/checks/active/path_traversal.rb +2 -2
- data/components/checks/active/sql_injection.rb +1 -1
- data/components/checks/active/sql_injection/patterns/mssql +1 -0
- data/components/checks/active/sql_injection_differential.rb +3 -2
- data/components/checks/active/unvalidated_redirect.rb +3 -3
- data/components/checks/passive/common_directories/directories.txt +2 -0
- data/components/checks/passive/common_files/filenames.txt +1 -0
- data/lib/arachni/browser.rb +17 -1
- data/lib/arachni/check/auditor.rb +5 -2
- data/lib/arachni/check/base.rb +30 -5
- data/lib/arachni/element/capabilities/analyzable/differential.rb +2 -5
- data/lib/arachni/element/capabilities/auditable.rb +3 -1
- data/lib/arachni/element/capabilities/with_dom.rb +1 -0
- data/lib/arachni/element/capabilities/with_node.rb +1 -1
- data/lib/arachni/element/cookie.rb +2 -2
- data/lib/arachni/element/form.rb +1 -1
- data/lib/arachni/element/header.rb +2 -2
- data/lib/arachni/element/link_template.rb +1 -1
- data/lib/arachni/framework.rb +21 -1144
- data/lib/arachni/framework/parts/audit.rb +282 -0
- data/lib/arachni/framework/parts/browser.rb +132 -0
- data/lib/arachni/framework/parts/check.rb +86 -0
- data/lib/arachni/framework/parts/data.rb +158 -0
- data/lib/arachni/framework/parts/platform.rb +34 -0
- data/lib/arachni/framework/parts/plugin.rb +61 -0
- data/lib/arachni/framework/parts/report.rb +128 -0
- data/lib/arachni/framework/parts/scope.rb +40 -0
- data/lib/arachni/framework/parts/state.rb +457 -0
- data/lib/arachni/http/client.rb +33 -30
- data/lib/arachni/http/request.rb +6 -2
- data/lib/arachni/issue.rb +55 -1
- data/lib/arachni/platform/manager.rb +25 -21
- data/lib/arachni/state/framework.rb +7 -1
- data/lib/arachni/utilities.rb +10 -0
- data/lib/version +1 -1
- data/spec/arachni/browser_spec.rb +13 -0
- data/spec/arachni/check/auditor_spec.rb +1 -0
- data/spec/arachni/check/base_spec.rb +80 -0
- data/spec/arachni/element/cookie_spec.rb +2 -2
- data/spec/arachni/framework/parts/audit_spec.rb +391 -0
- data/spec/arachni/framework/parts/browser_spec.rb +26 -0
- data/spec/arachni/framework/parts/check_spec.rb +24 -0
- data/spec/arachni/framework/parts/data_spec.rb +187 -0
- data/spec/arachni/framework/parts/platform_spec.rb +62 -0
- data/spec/arachni/framework/parts/plugin_spec.rb +41 -0
- data/spec/arachni/framework/parts/report_spec.rb +66 -0
- data/spec/arachni/framework/parts/scope_spec.rb +86 -0
- data/spec/arachni/framework/parts/state_spec.rb +528 -0
- data/spec/arachni/framework_spec.rb +17 -1344
- data/spec/arachni/http/client_spec.rb +12 -7
- data/spec/arachni/issue_spec.rb +35 -0
- data/spec/arachni/platform/manager_spec.rb +2 -3
- data/spec/arachni/state/framework_spec.rb +15 -0
- data/spec/components/checks/active/code_injection_timing_spec.rb +5 -5
- data/spec/components/checks/active/no_sql_injection_differential_spec.rb +4 -0
- data/spec/components/checks/active/os_cmd_injection_spec.rb +20 -7
- data/spec/components/checks/active/os_cmd_injection_timing_spec.rb +5 -5
- data/spec/components/checks/active/sql_injection_differential_spec.rb +4 -0
- data/spec/components/checks/active/sql_injection_spec.rb +2 -3
- data/spec/support/servers/arachni/browser.rb +31 -0
- data/spec/support/servers/checks/active/code_injection.rb +1 -1
- data/spec/support/servers/checks/active/no_sql_injection_differential.rb +36 -34
- data/spec/support/servers/checks/active/os_cmd_injection.rb +6 -12
- data/spec/support/servers/checks/active/os_cmd_injection_timing.rb +9 -4
- data/spec/support/servers/checks/active/sql_injection.rb +1 -1
- data/spec/support/servers/checks/active/sql_injection_differential.rb +37 -34
- data/spec/support/shared/element/capabilities/with_node.rb +25 -0
- data/spec/support/shared/framework.rb +26 -0
- data/ui/cli/output.rb +2 -0
- data/ui/cli/rpc/server/dispatcher/option_parser.rb +1 -1
- metadata +32 -4
- data/components/checks/active/sql_injection/patterns/coldfusion +0 -1
@@ -396,26 +396,31 @@ describe Arachni::HTTP::Client do
|
|
396
396
|
called.should be_false
|
397
397
|
end
|
398
398
|
|
399
|
-
context 'when the callback creates new requests
|
399
|
+
context 'when the callback creates new requests' do
|
400
400
|
it 'run these too' do
|
401
401
|
called = false
|
402
402
|
subject.after_run do
|
403
|
-
subject.
|
403
|
+
subject.get do
|
404
|
+
called = true
|
405
|
+
end
|
404
406
|
end
|
405
407
|
subject.run
|
408
|
+
called.should be_true
|
409
|
+
|
410
|
+
called = false
|
411
|
+
subject.run
|
406
412
|
called.should be_false
|
413
|
+
end
|
414
|
+
end
|
407
415
|
|
416
|
+
context 'when the callback creates new callbacks' do
|
417
|
+
it 'run these too' do
|
408
418
|
called = false
|
409
419
|
subject.after_run do
|
410
|
-
subject.get
|
411
420
|
subject.after_run { called = true }
|
412
421
|
end
|
413
422
|
subject.run
|
414
423
|
called.should be_true
|
415
|
-
|
416
|
-
called = false
|
417
|
-
subject.run
|
418
|
-
called.should be_false
|
419
424
|
end
|
420
425
|
end
|
421
426
|
end
|
data/spec/arachni/issue_spec.rb
CHANGED
@@ -29,6 +29,24 @@ describe Arachni::Issue do
|
|
29
29
|
issue.name.should == "Check name \u2713"
|
30
30
|
end
|
31
31
|
|
32
|
+
describe '#recheck' do
|
33
|
+
it 'rechecks the issue' do
|
34
|
+
Arachni::Options.paths.checks = fixtures_path + '/taint_check/'
|
35
|
+
Arachni::Options.audit.elements :links, :forms, :cookies
|
36
|
+
|
37
|
+
issue = nil
|
38
|
+
Arachni::Framework.new do |f|
|
39
|
+
f.options.url = "#{web_server_url_for( :auditor )}/link"
|
40
|
+
f.checks.load :taint
|
41
|
+
|
42
|
+
f.run
|
43
|
+
issue = f.report.issues.first.variations.first
|
44
|
+
end
|
45
|
+
|
46
|
+
issue.recheck.should == issue
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
32
50
|
describe '#to_rpc_data' do
|
33
51
|
let(:issue) { issue_with_variations }
|
34
52
|
let(:data) { issue.to_rpc_data }
|
@@ -79,6 +97,12 @@ describe Arachni::Issue do
|
|
79
97
|
it "restores 'variation'" do
|
80
98
|
restored_issue.variation?.should == issue.variation?
|
81
99
|
end
|
100
|
+
|
101
|
+
it 'restores variation parent' do
|
102
|
+
restored_issue.variations.each do |v|
|
103
|
+
v.parent.should == restored_issue
|
104
|
+
end
|
105
|
+
end
|
82
106
|
end
|
83
107
|
|
84
108
|
[:page=, :referring_page=, :vector=].each do |m|
|
@@ -607,6 +631,10 @@ describe Arachni::Issue do
|
|
607
631
|
end
|
608
632
|
root.variations.should be_nil
|
609
633
|
end
|
634
|
+
|
635
|
+
it 'has a #parent' do
|
636
|
+
issue.as_variation.parent.should == issue
|
637
|
+
end
|
610
638
|
end
|
611
639
|
|
612
640
|
describe '#to_solo!' do
|
@@ -645,6 +673,13 @@ describe Arachni::Issue do
|
|
645
673
|
variation.vector.affected_input_name.should be_true
|
646
674
|
variation.to_solo!( parent ).vector.affected_input_name.should be_true
|
647
675
|
end
|
676
|
+
|
677
|
+
it 'skips #parent' do
|
678
|
+
parent = issue.with_variations
|
679
|
+
variation = issue.as_variation
|
680
|
+
|
681
|
+
variation.to_solo!( parent ).parent.should be_nil
|
682
|
+
end
|
648
683
|
end
|
649
684
|
|
650
685
|
describe '#to_solo' do
|
@@ -276,7 +276,6 @@ describe Arachni::Platform::Manager do
|
|
276
276
|
describe '#db' do
|
277
277
|
it 'returns the database list' do
|
278
278
|
platforms.db.should be_kind_of Arachni::Platform::List
|
279
|
-
platforms.db.valid.sort.should == described_class::DB.sort
|
280
279
|
end
|
281
280
|
end
|
282
281
|
|
@@ -385,11 +384,11 @@ describe Arachni::Platform::Manager do
|
|
385
384
|
it 'returns all valid platforms' do
|
386
385
|
platforms.valid.sort.should ==
|
387
386
|
[:unix, :linux, :bsd, :solaris, :windows,
|
388
|
-
:
|
387
|
+
:db2, :emc, :informix, :interbase, :mssql, :mysql,
|
389
388
|
:oracle, :firebird, :maxdb, :pgsql, :sqlite, :apache, :iis, :nginx,
|
390
389
|
:tomcat, :asp, :aspx, :jsp, :perl, :php, :python, :ruby, :rack,
|
391
390
|
:sybase, :frontbase, :ingres, :hsqldb, :access, :jetty, :mongodb,
|
392
|
-
:aix].sort
|
391
|
+
:aix, :sql, :nosql].sort
|
393
392
|
end
|
394
393
|
end
|
395
394
|
|
@@ -508,6 +508,21 @@ describe Arachni::State::Framework do
|
|
508
508
|
end
|
509
509
|
end
|
510
510
|
|
511
|
+
describe '#done?' do
|
512
|
+
context 'when #status is :done' do
|
513
|
+
it 'returns true' do
|
514
|
+
subject.status = :done
|
515
|
+
subject.should be_done
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
context 'when not done' do
|
520
|
+
it 'returns false' do
|
521
|
+
subject.should_not be_done
|
522
|
+
end
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
511
526
|
describe '#aborted' do
|
512
527
|
it 'sets the #status to :aborted' do
|
513
528
|
subject.aborted
|
@@ -14,11 +14,11 @@ describe name_from_filename do
|
|
14
14
|
|
15
15
|
def issue_count_per_element
|
16
16
|
{
|
17
|
-
Element::Form =>
|
18
|
-
Element::Link =>
|
19
|
-
Element::Cookie =>
|
20
|
-
Element::Header =>
|
21
|
-
Element::LinkTemplate =>
|
17
|
+
Element::Form => 4,
|
18
|
+
Element::Link => 4,
|
19
|
+
Element::Cookie => 4,
|
20
|
+
Element::Header => 3,
|
21
|
+
Element::LinkTemplate => 4
|
22
22
|
}
|
23
23
|
end
|
24
24
|
|
@@ -12,14 +12,27 @@ describe name_from_filename do
|
|
12
12
|
Element::LinkTemplate ]
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
{
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
def issue_count_per_element_per_platform
|
16
|
+
h = {}
|
17
|
+
[:unix, :bsd, :aix].each do |platform|
|
18
|
+
h[platform] = {
|
19
|
+
Element::Form => 22,
|
20
|
+
Element::Link => 22,
|
21
|
+
Element::Cookie => 22,
|
22
|
+
Element::Header => 19,
|
23
|
+
Element::LinkTemplate => 21
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
h[:windows] = {
|
28
|
+
Element::Form => 44,
|
29
|
+
Element::Link => 44,
|
30
|
+
Element::Cookie => 44,
|
31
|
+
Element::Header => 38,
|
32
|
+
Element::LinkTemplate => 44
|
22
33
|
}
|
34
|
+
|
35
|
+
h
|
23
36
|
end
|
24
37
|
|
25
38
|
easy_test
|
@@ -14,11 +14,11 @@ describe name_from_filename do
|
|
14
14
|
|
15
15
|
def issue_count_per_element
|
16
16
|
{
|
17
|
-
Element::Form =>
|
18
|
-
Element::Link =>
|
19
|
-
Element::Cookie =>
|
20
|
-
Element::Header =>
|
21
|
-
Element::LinkTemplate =>
|
17
|
+
Element::Form => 14,
|
18
|
+
Element::Link => 14,
|
19
|
+
Element::Cookie => 14,
|
20
|
+
Element::Header => 14,
|
21
|
+
Element::LinkTemplate => 14
|
22
22
|
}
|
23
23
|
end
|
24
24
|
|
@@ -4,9 +4,8 @@ describe name_from_filename do
|
|
4
4
|
include_examples 'check'
|
5
5
|
|
6
6
|
def self.platforms
|
7
|
-
[:access, :
|
8
|
-
:
|
9
|
-
:pgsql, :sqlite, :sybase]
|
7
|
+
[:access, :db2, :emc, :firebird, :frontbase, :hsqldb, :informix, :ingres,
|
8
|
+
:interbase, :maxdb, :mssql, :mysql, :oracle, :pgsql, :sqlite, :sybase]
|
10
9
|
end
|
11
10
|
|
12
11
|
def self.elements
|
@@ -244,6 +244,37 @@ get '/fire_event/form/onsubmit' do
|
|
244
244
|
EOHTML
|
245
245
|
end
|
246
246
|
|
247
|
+
get '/fire_event/form/select' do
|
248
|
+
<<-EOHTML
|
249
|
+
<html>
|
250
|
+
<script>
|
251
|
+
function submitForm() {
|
252
|
+
document.getElementById("container-name").innerHTML =
|
253
|
+
document.getElementsByName("name")[0].value;
|
254
|
+
|
255
|
+
document.getElementById("container-email").innerHTML =
|
256
|
+
document.getElementById("email").value;
|
257
|
+
}
|
258
|
+
</script>
|
259
|
+
|
260
|
+
<body>
|
261
|
+
<form onsubmit="submitForm();return false;">
|
262
|
+
<textarea name="name" ></textarea>
|
263
|
+
<select name="email" id="email"/>
|
264
|
+
<option value="the.other.dude@abides.com">The other Dude</option>
|
265
|
+
<option value="the.dude@abides.com">The Dude</option>
|
266
|
+
</select>
|
267
|
+
</fom>
|
268
|
+
|
269
|
+
<div id="container-name">
|
270
|
+
</div>
|
271
|
+
<div id="container-email">
|
272
|
+
</div>
|
273
|
+
</body>
|
274
|
+
</html>
|
275
|
+
EOHTML
|
276
|
+
end
|
277
|
+
|
247
278
|
get '/fire_event/form/image-input' do
|
248
279
|
<<HTML
|
249
280
|
<html>
|
@@ -2,7 +2,7 @@ require 'sinatra'
|
|
2
2
|
require 'sinatra/contrib'
|
3
3
|
|
4
4
|
REGEXP = {
|
5
|
-
php: '
|
5
|
+
php: 'print\s([0-9]+)\s?\+\s?([0-9]+);',
|
6
6
|
perl: 'print\s([0-9]+)\s?\+\s?([0-9]+);',
|
7
7
|
python: 'print\s([0-9]+)\s?\+\s?([0-9]+)$',
|
8
8
|
asp: 'Response.Write\(\s?([0-9]+)\s?\+\s?([0-9]+)\s?\)'
|
@@ -17,45 +17,47 @@ def get_result( str )
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
[:nosql].each do |platform|
|
21
|
+
get "/#{platform}" do
|
22
|
+
<<-EOHTML
|
23
|
+
<a href="/#{platform}/link?input=default">Link</a>
|
24
|
+
<a href="/#{platform}/form">Form</a>
|
25
|
+
<a href="/#{platform}/cookie">Cookie</a>
|
26
|
+
<a href="/#{platform}/header">Header</a>
|
27
|
+
EOHTML
|
28
|
+
end
|
28
29
|
|
29
|
-
get
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
30
|
+
get "/#{platform}/link" do
|
31
|
+
<<-EOHTML
|
32
|
+
<a href="/#{platform}/link/append?input=default">Link</a>
|
33
|
+
EOHTML
|
34
|
+
end
|
34
35
|
|
35
|
-
get
|
36
|
-
|
37
|
-
end
|
36
|
+
get "/#{platform}/link/append" do
|
37
|
+
get_result( params['input'] )
|
38
|
+
end
|
38
39
|
|
39
|
-
get
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
40
|
+
get "/#{platform}/form" do
|
41
|
+
<<-EOHTML
|
42
|
+
<form action="/#{platform}/form/append">
|
43
|
+
<input name='input' value='default' />
|
44
|
+
</form>
|
45
|
+
EOHTML
|
46
|
+
end
|
46
47
|
|
47
|
-
get
|
48
|
-
|
49
|
-
end
|
48
|
+
get "/#{platform}/form/append" do
|
49
|
+
get_result( params['input'] )
|
50
|
+
end
|
50
51
|
|
51
52
|
|
52
|
-
get
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
53
|
+
get "/#{platform}/cookie" do
|
54
|
+
<<-EOHTML
|
55
|
+
<a href="/#{platform}/cookie/append">Cookie</a>
|
56
|
+
EOHTML
|
57
|
+
end
|
57
58
|
|
58
|
-
get
|
59
|
-
|
60
|
-
|
59
|
+
get "/#{platform}/cookie/append" do
|
60
|
+
cookies['cookie'] ||= default
|
61
|
+
get_result( cookies['cookie'] )
|
62
|
+
end
|
61
63
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sinatra'
|
2
2
|
require 'sinatra/contrib'
|
3
|
+
require_relative '../check_server'
|
3
4
|
|
4
5
|
STRINGS = {
|
5
6
|
unix: '/bin/cat /etc/passwd',
|
@@ -26,19 +27,12 @@ multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional"
|
|
26
27
|
',
|
27
28
|
}
|
28
29
|
|
29
|
-
def exec( system, str, prefix = nil, postfix = nil )
|
30
|
-
OUT[system] if "#{prefix} #{STRINGS[system]}#{postfix}" == str
|
31
|
-
end
|
32
|
-
|
33
|
-
def variations
|
34
|
-
@@v ||= [ '', '&&', '|', ';' ]
|
35
|
-
end
|
36
|
-
|
37
30
|
def get_variations( system, str )
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
31
|
+
current_check.payloads[system].each do |payload|
|
32
|
+
return OUT[system] if payload == str
|
33
|
+
end
|
34
|
+
|
35
|
+
''
|
42
36
|
end
|
43
37
|
|
44
38
|
STRINGS.keys.each do |platform|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sinatra'
|
2
2
|
require 'sinatra/contrib'
|
3
|
+
require_relative '../check_server'
|
3
4
|
|
4
5
|
REGEXP = {
|
5
6
|
windows: 'ping \-n (\d+) localhost',
|
@@ -27,10 +28,14 @@ def variations
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def get_variations( platform, str )
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
# current_check.payloads[platform].each do |payload|
|
32
|
+
time = str.scan( Regexp.new( REGEXP[platform] ) ).flatten.first
|
33
|
+
return if !time
|
34
|
+
|
35
|
+
sleep( Integer( time ) - 1 )
|
36
|
+
# end
|
37
|
+
|
38
|
+
''
|
34
39
|
end
|
35
40
|
|
36
41
|
REGEXP.keys.each do |platform|
|
@@ -11,7 +11,7 @@ end
|
|
11
11
|
@@ignore ||= IO.read( File.dirname( __FILE__ ) + '/../../../../../components/checks/active/sql_injection/regexp_ignore.txt' )
|
12
12
|
|
13
13
|
def variations
|
14
|
-
@@variations ||= [ '\'`--', ')' ]
|
14
|
+
@@variations ||= [ '"\'`--', ')' ]
|
15
15
|
end
|
16
16
|
|
17
17
|
def get_variations( platform, str )
|