arachni 0.2.2.1
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.
- data/ACKNOWLEDGMENTS.md +14 -0
- data/AUTHORS.md +6 -0
- data/CHANGELOG.md +162 -0
- data/CONTRIBUTORS.md +10 -0
- data/EXPLOITATION.md +429 -0
- data/HACKING.md +101 -0
- data/LICENSE.md +341 -0
- data/README.md +350 -0
- data/Rakefile +86 -0
- data/bin/arachni +22 -0
- data/bin/arachni_web +77 -0
- data/bin/arachni_xmlrpc +21 -0
- data/bin/arachni_xmlrpcd +82 -0
- data/bin/arachni_xmlrpcd_monitor +74 -0
- data/conf/README.webui.yaml.txt +44 -0
- data/conf/webui.yaml +11 -0
- data/external/metasploit/LICENSE +24 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_exec.rb +142 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_path_traversal.rb +113 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_php_eval.rb +150 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_php_include.rb +141 -0
- data/external/metasploit/modules/exploits/unix/webapp/arachni_sqlmap.rb +92 -0
- data/external/metasploit/plugins/arachni.rb +536 -0
- data/getoptslong.rb +241 -0
- data/lib/anemone.rb +2 -0
- data/lib/anemone/cookie_store.rb +35 -0
- data/lib/anemone/core.rb +371 -0
- data/lib/anemone/exceptions.rb +5 -0
- data/lib/anemone/http.rb +144 -0
- data/lib/anemone/page.rb +337 -0
- data/lib/anemone/page_store.rb +160 -0
- data/lib/anemone/storage.rb +34 -0
- data/lib/anemone/storage/base.rb +75 -0
- data/lib/anemone/storage/exceptions.rb +15 -0
- data/lib/anemone/storage/mongodb.rb +89 -0
- data/lib/anemone/storage/pstore.rb +50 -0
- data/lib/anemone/storage/redis.rb +90 -0
- data/lib/anemone/storage/tokyo_cabinet.rb +57 -0
- data/lib/anemone/tentacle.rb +40 -0
- data/lib/arachni.rb +16 -0
- data/lib/audit_store.rb +346 -0
- data/lib/component_manager.rb +293 -0
- data/lib/component_options.rb +395 -0
- data/lib/exceptions.rb +76 -0
- data/lib/framework.rb +637 -0
- data/lib/http.rb +809 -0
- data/lib/issue.rb +302 -0
- data/lib/module.rb +4 -0
- data/lib/module/auditor.rb +455 -0
- data/lib/module/base.rb +188 -0
- data/lib/module/element_db.rb +158 -0
- data/lib/module/key_filler.rb +87 -0
- data/lib/module/manager.rb +87 -0
- data/lib/module/output.rb +68 -0
- data/lib/module/trainer.rb +240 -0
- data/lib/module/utilities.rb +110 -0
- data/lib/options.rb +547 -0
- data/lib/parser.rb +2 -0
- data/lib/parser/auditable.rb +522 -0
- data/lib/parser/elements.rb +296 -0
- data/lib/parser/page.rb +149 -0
- data/lib/parser/parser.rb +717 -0
- data/lib/plugin.rb +4 -0
- data/lib/plugin/base.rb +110 -0
- data/lib/plugin/manager.rb +162 -0
- data/lib/report.rb +4 -0
- data/lib/report/base.rb +119 -0
- data/lib/report/manager.rb +92 -0
- data/lib/rpc/xml/client/base.rb +71 -0
- data/lib/rpc/xml/client/dispatcher.rb +49 -0
- data/lib/rpc/xml/client/instance.rb +88 -0
- data/lib/rpc/xml/server/base.rb +90 -0
- data/lib/rpc/xml/server/dispatcher.rb +357 -0
- data/lib/rpc/xml/server/framework.rb +206 -0
- data/lib/rpc/xml/server/instance.rb +191 -0
- data/lib/rpc/xml/server/module/manager.rb +46 -0
- data/lib/rpc/xml/server/options.rb +124 -0
- data/lib/rpc/xml/server/output.rb +299 -0
- data/lib/rpc/xml/server/plugin/manager.rb +58 -0
- data/lib/ruby.rb +5 -0
- data/lib/ruby/object.rb +32 -0
- data/lib/ruby/string.rb +74 -0
- data/lib/ruby/xmlrpc/server.rb +27 -0
- data/lib/spider.rb +200 -0
- data/lib/typhoeus/request.rb +91 -0
- data/lib/typhoeus/response.rb +34 -0
- data/lib/ui/cli/cli.rb +744 -0
- data/lib/ui/cli/output.rb +279 -0
- data/lib/ui/web/log.rb +82 -0
- data/lib/ui/web/output_stream.rb +94 -0
- data/lib/ui/web/report_manager.rb +222 -0
- data/lib/ui/web/server.rb +903 -0
- data/lib/ui/web/server/db/placeholder +0 -0
- data/lib/ui/web/server/public/banner.png +0 -0
- data/lib/ui/web/server/public/bodybg-small.png +0 -0
- data/lib/ui/web/server/public/bodybg.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/pbar-ani.gif +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/lib/ui/web/server/public/css/smoothness/jquery-ui-1.8.9.custom.css +573 -0
- data/lib/ui/web/server/public/favicon.ico +0 -0
- data/lib/ui/web/server/public/footer.jpg +0 -0
- data/lib/ui/web/server/public/icons/error.png +0 -0
- data/lib/ui/web/server/public/icons/info.png +0 -0
- data/lib/ui/web/server/public/icons/ok.png +0 -0
- data/lib/ui/web/server/public/icons/status.png +0 -0
- data/lib/ui/web/server/public/js/jquery-1.4.4.min.js +167 -0
- data/lib/ui/web/server/public/js/jquery-ui-1.8.9.custom.min.js +781 -0
- data/lib/ui/web/server/public/logo.png +0 -0
- data/lib/ui/web/server/public/nav-left.jpg +0 -0
- data/lib/ui/web/server/public/nav-right.jpg +0 -0
- data/lib/ui/web/server/public/nav-selected-left.jpg +0 -0
- data/lib/ui/web/server/public/nav-selected-right.jpg +0 -0
- data/lib/ui/web/server/public/reports/placeholder +1 -0
- data/lib/ui/web/server/public/sidebar-bottom.jpg +0 -0
- data/lib/ui/web/server/public/sidebar-h4.jpg +0 -0
- data/lib/ui/web/server/public/sidebar-top.jpg +0 -0
- data/lib/ui/web/server/public/spider.png +0 -0
- data/lib/ui/web/server/public/style.css +604 -0
- data/lib/ui/web/server/tmp/placeholder +0 -0
- data/lib/ui/web/server/views/dispatcher.erb +85 -0
- data/lib/ui/web/server/views/dispatcher_error.erb +14 -0
- data/lib/ui/web/server/views/error.erb +1 -0
- data/lib/ui/web/server/views/flash.erb +18 -0
- data/lib/ui/web/server/views/home.erb +14 -0
- data/lib/ui/web/server/views/instance.erb +213 -0
- data/lib/ui/web/server/views/layout.erb +95 -0
- data/lib/ui/web/server/views/log.erb +40 -0
- data/lib/ui/web/server/views/modules.erb +71 -0
- data/lib/ui/web/server/views/options.erb +23 -0
- data/lib/ui/web/server/views/output_results.erb +51 -0
- data/lib/ui/web/server/views/plugins.erb +42 -0
- data/lib/ui/web/server/views/report_formats.erb +30 -0
- data/lib/ui/web/server/views/reports.erb +55 -0
- data/lib/ui/web/server/views/settings.erb +120 -0
- data/lib/ui/web/server/views/welcome.erb +38 -0
- data/lib/ui/xmlrpc/dispatcher_monitor.rb +204 -0
- data/lib/ui/xmlrpc/xmlrpc.rb +843 -0
- data/logs/placeholder +0 -0
- data/metamodules/autothrottle.rb +74 -0
- data/metamodules/timeout_notice.rb +118 -0
- data/metamodules/uniformity.rb +98 -0
- data/modules/audit/code_injection.rb +136 -0
- data/modules/audit/code_injection_timing.rb +115 -0
- data/modules/audit/code_injection_timing/payloads.txt +4 -0
- data/modules/audit/csrf.rb +301 -0
- data/modules/audit/ldapi.rb +103 -0
- data/modules/audit/ldapi/errors.txt +26 -0
- data/modules/audit/os_cmd_injection.rb +103 -0
- data/modules/audit/os_cmd_injection/payloads.txt +2 -0
- data/modules/audit/os_cmd_injection_timing.rb +104 -0
- data/modules/audit/os_cmd_injection_timing/payloads.txt +3 -0
- data/modules/audit/path_traversal.rb +141 -0
- data/modules/audit/response_splitting.rb +105 -0
- data/modules/audit/rfi.rb +193 -0
- data/modules/audit/sqli.rb +120 -0
- data/modules/audit/sqli/regexp_ids.txt +90 -0
- data/modules/audit/sqli_blind_rdiff.rb +321 -0
- data/modules/audit/sqli_blind_timing.rb +103 -0
- data/modules/audit/sqli_blind_timing/payloads.txt +51 -0
- data/modules/audit/trainer.rb +89 -0
- data/modules/audit/unvalidated_redirect.rb +90 -0
- data/modules/audit/xpath.rb +104 -0
- data/modules/audit/xpath/errors.txt +26 -0
- data/modules/audit/xss.rb +99 -0
- data/modules/audit/xss_event.rb +134 -0
- data/modules/audit/xss_path.rb +125 -0
- data/modules/audit/xss_script_tag.rb +112 -0
- data/modules/audit/xss_tag.rb +112 -0
- data/modules/audit/xss_uri.rb +125 -0
- data/modules/recon/allowed_methods.rb +104 -0
- data/modules/recon/backdoors.rb +131 -0
- data/modules/recon/backdoors/filenames.txt +16 -0
- data/modules/recon/backup_files.rb +177 -0
- data/modules/recon/backup_files/extensions.txt +28 -0
- data/modules/recon/common_directories.rb +138 -0
- data/modules/recon/common_directories/directories.txt +265 -0
- data/modules/recon/common_files.rb +138 -0
- data/modules/recon/common_files/filenames.txt +17 -0
- data/modules/recon/directory_listing.rb +171 -0
- data/modules/recon/grep/captcha.rb +62 -0
- data/modules/recon/grep/credit_card.rb +85 -0
- data/modules/recon/grep/cvs_svn_users.rb +73 -0
- data/modules/recon/grep/emails.rb +59 -0
- data/modules/recon/grep/html_objects.rb +53 -0
- data/modules/recon/grep/private_ip.rb +54 -0
- data/modules/recon/grep/ssn.rb +53 -0
- data/modules/recon/htaccess_limit.rb +82 -0
- data/modules/recon/http_put.rb +95 -0
- data/modules/recon/interesting_responses.rb +118 -0
- data/modules/recon/unencrypted_password_forms.rb +119 -0
- data/modules/recon/webdav.rb +126 -0
- data/modules/recon/xst.rb +107 -0
- data/path_extractors/anchors.rb +35 -0
- data/path_extractors/forms.rb +35 -0
- data/path_extractors/frames.rb +38 -0
- data/path_extractors/generic.rb +39 -0
- data/path_extractors/links.rb +35 -0
- data/path_extractors/meta_refresh.rb +39 -0
- data/path_extractors/scripts.rb +37 -0
- data/path_extractors/sitemap.rb +31 -0
- data/plugins/autologin.rb +137 -0
- data/plugins/content_types.rb +90 -0
- data/plugins/cookie_collector.rb +99 -0
- data/plugins/form_dicattack.rb +185 -0
- data/plugins/healthmap.rb +94 -0
- data/plugins/http_dicattack.rb +133 -0
- data/plugins/metamodules.rb +118 -0
- data/plugins/proxy.rb +248 -0
- data/plugins/proxy/server.rb +66 -0
- data/plugins/waf_detector.rb +184 -0
- data/profiles/comprehensive.afp +74 -0
- data/profiles/full.afp +75 -0
- data/reports/afr.rb +59 -0
- data/reports/ap.rb +55 -0
- data/reports/html.rb +179 -0
- data/reports/html/default.erb +967 -0
- data/reports/metareport.rb +139 -0
- data/reports/metareport/arachni_metareport.rb +174 -0
- data/reports/plugin_formatters/html/content_types.rb +82 -0
- data/reports/plugin_formatters/html/cookie_collector.rb +66 -0
- data/reports/plugin_formatters/html/form_dicattack.rb +54 -0
- data/reports/plugin_formatters/html/healthmap.rb +76 -0
- data/reports/plugin_formatters/html/http_dicattack.rb +54 -0
- data/reports/plugin_formatters/html/metaformatters/timeout_notice.rb +65 -0
- data/reports/plugin_formatters/html/metaformatters/uniformity.rb +71 -0
- data/reports/plugin_formatters/html/metamodules.rb +93 -0
- data/reports/plugin_formatters/html/waf_detector.rb +54 -0
- data/reports/plugin_formatters/stdout/content_types.rb +73 -0
- data/reports/plugin_formatters/stdout/cookie_collector.rb +61 -0
- data/reports/plugin_formatters/stdout/form_dicattack.rb +52 -0
- data/reports/plugin_formatters/stdout/healthmap.rb +72 -0
- data/reports/plugin_formatters/stdout/http_dicattack.rb +53 -0
- data/reports/plugin_formatters/stdout/metaformatters/timeout_notice.rb +55 -0
- data/reports/plugin_formatters/stdout/metaformatters/uniformity.rb +68 -0
- data/reports/plugin_formatters/stdout/metamodules.rb +89 -0
- data/reports/plugin_formatters/stdout/waf_detector.rb +48 -0
- data/reports/plugin_formatters/xml/content_types.rb +91 -0
- data/reports/plugin_formatters/xml/cookie_collector.rb +70 -0
- data/reports/plugin_formatters/xml/form_dicattack.rb +57 -0
- data/reports/plugin_formatters/xml/healthmap.rb +82 -0
- data/reports/plugin_formatters/xml/http_dicattack.rb +57 -0
- data/reports/plugin_formatters/xml/metaformatters/timeout_notice.rb +67 -0
- data/reports/plugin_formatters/xml/metaformatters/uniformity.rb +82 -0
- data/reports/plugin_formatters/xml/metamodules.rb +91 -0
- data/reports/plugin_formatters/xml/waf_detector.rb +58 -0
- data/reports/stdout.rb +182 -0
- data/reports/txt.rb +77 -0
- data/reports/xml.rb +231 -0
- data/reports/xml/buffer.rb +98 -0
- metadata +516 -0
data/lib/plugin.rb
ADDED
data/lib/plugin/base.rb
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
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 Plugin
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Will be extended by plugin formatters which provide plugin data formatting
|
|
16
|
+
# for the reports.
|
|
17
|
+
#
|
|
18
|
+
# Plugin formatters will be in turn ran by [Arachni::Report::Bas#format_plugin_results].
|
|
19
|
+
#
|
|
20
|
+
#
|
|
21
|
+
class Formatter
|
|
22
|
+
|
|
23
|
+
# get the output interface
|
|
24
|
+
include Arachni::UI::Output
|
|
25
|
+
|
|
26
|
+
def initialize( plugin_data )
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def run
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Arachni::Plugin::Base class
|
|
38
|
+
#
|
|
39
|
+
# An abstract class for the plugins.<br/>
|
|
40
|
+
# All plugins must extend this.
|
|
41
|
+
#
|
|
42
|
+
# @author: Tasos "Zapotek" Laskos
|
|
43
|
+
# <tasos.laskos@gmail.com>
|
|
44
|
+
# <zapotek@segfault.gr>
|
|
45
|
+
# @version: 0.1
|
|
46
|
+
# @abstract
|
|
47
|
+
#
|
|
48
|
+
class Base
|
|
49
|
+
|
|
50
|
+
# get the output interface
|
|
51
|
+
include Arachni::Module::Output
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# @param [Arachni::Framework] framework
|
|
55
|
+
# @param [Hash] options options passed to the plugin
|
|
56
|
+
#
|
|
57
|
+
def initialize( framework, options )
|
|
58
|
+
@framework = framework
|
|
59
|
+
@options = options
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
#
|
|
64
|
+
# OPTIONAL
|
|
65
|
+
#
|
|
66
|
+
def prepare( )
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#
|
|
71
|
+
# REQUIRED
|
|
72
|
+
#
|
|
73
|
+
def run( )
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# OPTIONAL
|
|
79
|
+
#
|
|
80
|
+
def clean_up( )
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def register_results( results )
|
|
85
|
+
@framework.plugin_store( self, results )
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
#
|
|
89
|
+
# REQUIRED
|
|
90
|
+
#
|
|
91
|
+
# Do not ommit any of the info.
|
|
92
|
+
#
|
|
93
|
+
def self.info
|
|
94
|
+
{
|
|
95
|
+
:name => 'Abstract plugin class',
|
|
96
|
+
:description => %q{Abstract plugin class.},
|
|
97
|
+
:author => 'Tasos "Zapotek" Laskos <tasos.laskos@gmail.com>',
|
|
98
|
+
:version => '0.1',
|
|
99
|
+
:options => [
|
|
100
|
+
# option name required? description default
|
|
101
|
+
# Arachni::OptBool.new( 'print_framework', [ false, 'Do you want to print the framework?', false ] ),
|
|
102
|
+
# Arachni::OptString.new( 'my_name_is', [ false, 'What\'s you name?', 'Tasos' ] ),
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
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
|
+
#
|
|
14
|
+
# The namespace under which all plugins exist
|
|
15
|
+
#
|
|
16
|
+
module Plugins
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Resets the namespace unloading all module classes
|
|
20
|
+
#
|
|
21
|
+
def self.reset
|
|
22
|
+
constants.each {
|
|
23
|
+
|const|
|
|
24
|
+
remove_const( const )
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module Plugin
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Holds and manages the plugins.
|
|
33
|
+
#
|
|
34
|
+
# @author: Tasos "Zapotek" Laskos
|
|
35
|
+
# <tasos.laskos@gmail.com>
|
|
36
|
+
# <zapotek@segfault.gr>
|
|
37
|
+
# @version: 0.1
|
|
38
|
+
#
|
|
39
|
+
class Manager < Arachni::ComponentManager
|
|
40
|
+
|
|
41
|
+
include Arachni::Module::Utilities
|
|
42
|
+
|
|
43
|
+
ALWAYS_ON = [ 'metamodules', 'content_types', 'healthmap' ]
|
|
44
|
+
|
|
45
|
+
#
|
|
46
|
+
# @param [Arachni::Framework] framework framework instance
|
|
47
|
+
#
|
|
48
|
+
def initialize( framework )
|
|
49
|
+
super( framework.opts.dir['plugins'], Arachni::Plugins )
|
|
50
|
+
@framework = framework
|
|
51
|
+
|
|
52
|
+
@jobs = []
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def load_defaults!
|
|
56
|
+
load( ALWAYS_ON )
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# Runs each plug-in in its own thread.
|
|
61
|
+
#
|
|
62
|
+
def run
|
|
63
|
+
i = 0
|
|
64
|
+
each {
|
|
65
|
+
|name, plugin|
|
|
66
|
+
|
|
67
|
+
@jobs << Thread.new {
|
|
68
|
+
|
|
69
|
+
exception_jail {
|
|
70
|
+
Thread.current[:name] = name
|
|
71
|
+
|
|
72
|
+
plugin_new = create( name )
|
|
73
|
+
plugin_new.prepare
|
|
74
|
+
plugin_new.run
|
|
75
|
+
plugin_new.clean_up
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
i += 1
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if i > 0
|
|
84
|
+
print_status( 'Waiting for plugins to settle...' )
|
|
85
|
+
::IO::select( nil, nil, nil, 1 )
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def create( name )
|
|
90
|
+
opts = @framework.opts.plugins[name]
|
|
91
|
+
self[name].new( @framework, prep_opts( name, self[name], opts ) )
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
# Blocks until all plug-ins have finished executing.
|
|
96
|
+
#
|
|
97
|
+
def block!
|
|
98
|
+
while( !@jobs.empty? )
|
|
99
|
+
|
|
100
|
+
print_debug
|
|
101
|
+
print_debug( "Waiting on the following (#{@jobs.size}) plugins to finish:" )
|
|
102
|
+
print_debug( job_names.join( ', ' ) )
|
|
103
|
+
print_debug
|
|
104
|
+
|
|
105
|
+
@jobs.delete_if { |j| !j.alive? }
|
|
106
|
+
::IO::select( nil, nil, nil, 1 )
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Will return false if all plug-ins have finished executing.
|
|
112
|
+
#
|
|
113
|
+
# @return [Bool]
|
|
114
|
+
#
|
|
115
|
+
def busy?
|
|
116
|
+
!@jobs.reject{ |j| j.alive? }.empty?
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
#
|
|
120
|
+
# Returns the names of the running plug-ins.
|
|
121
|
+
#
|
|
122
|
+
# @return [Array]
|
|
123
|
+
#
|
|
124
|
+
def job_names
|
|
125
|
+
@jobs.map{ |j| j[:name] }
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
#
|
|
129
|
+
# Returns all the running threads.
|
|
130
|
+
#
|
|
131
|
+
# @return [Array<Thread>]
|
|
132
|
+
#
|
|
133
|
+
def jobs
|
|
134
|
+
@jobs
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
#
|
|
138
|
+
# Kills a plug-in by name.
|
|
139
|
+
#
|
|
140
|
+
# @param [String] name
|
|
141
|
+
#
|
|
142
|
+
def kill( name )
|
|
143
|
+
job = get( name )
|
|
144
|
+
return job.kill if job
|
|
145
|
+
return nil
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
#
|
|
149
|
+
# Gets a running plug-in by name.
|
|
150
|
+
#
|
|
151
|
+
# @param [String] name
|
|
152
|
+
#
|
|
153
|
+
# @return [Thread]
|
|
154
|
+
#
|
|
155
|
+
def get( name )
|
|
156
|
+
@jobs.each { |job| return job if job[:name] == name }
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
data/lib/report.rb
ADDED
data/lib/report/base.rb
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
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 Report
|
|
13
|
+
|
|
14
|
+
class FormatterManager < ComponentManager
|
|
15
|
+
|
|
16
|
+
def paths
|
|
17
|
+
cpaths = paths = Dir.glob( File.join( "#{@lib}", "*.rb" ) )
|
|
18
|
+
return paths.reject { |path| helper?( path ) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Arachni::Report::Base class
|
|
25
|
+
#
|
|
26
|
+
# An abstract class for the reports.<br/>
|
|
27
|
+
# All reports must extend this.
|
|
28
|
+
#
|
|
29
|
+
# @author: Tasos "Zapotek" Laskos
|
|
30
|
+
# <tasos.laskos@gmail.com>
|
|
31
|
+
# <zapotek@segfault.gr>
|
|
32
|
+
# @version: 0.1
|
|
33
|
+
# @abstract
|
|
34
|
+
#
|
|
35
|
+
class Base
|
|
36
|
+
|
|
37
|
+
# get the output interface
|
|
38
|
+
include Arachni::UI::Output
|
|
39
|
+
|
|
40
|
+
# where to report false positives <br/>
|
|
41
|
+
# info about this should be included in all templates
|
|
42
|
+
REPORT_FP = 'http://github.com/Zapotek/arachni/issues'
|
|
43
|
+
|
|
44
|
+
module PluginFormatters
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#
|
|
49
|
+
# REQUIRED
|
|
50
|
+
#
|
|
51
|
+
def run( )
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# Runs plugin formatters for the running report and returns a hash
|
|
57
|
+
# with the prepared/formatted results.
|
|
58
|
+
#
|
|
59
|
+
# @param [AuditStore#plugins] plugins plugin data/results
|
|
60
|
+
#
|
|
61
|
+
def format_plugin_results( plugins )
|
|
62
|
+
|
|
63
|
+
# get the object that extends this class (i.e. the running report)
|
|
64
|
+
ancestor = self.class.ancestors[0]
|
|
65
|
+
|
|
66
|
+
# add the PluginFormatters module to the report
|
|
67
|
+
eval( "class " + ancestor.to_s + "\n module PluginFormatters end \n end" )
|
|
68
|
+
|
|
69
|
+
# get the path to the report file
|
|
70
|
+
# this is a very bad way to do it...
|
|
71
|
+
report_path = ::Kernel.caller[0].match( /^(.+?):(\d+)(?::in `(.*)')?/ )[1]
|
|
72
|
+
|
|
73
|
+
# prepare the directory of the formatters for the running report
|
|
74
|
+
lib = File.dirname( report_path ) + '/plugin_formatters/' + File.basename( report_path, '.rb' ) + '/'
|
|
75
|
+
|
|
76
|
+
@@formatters ||= {}
|
|
77
|
+
|
|
78
|
+
# initialize a new component manager to handle the plugin formatters
|
|
79
|
+
@@formatters[ancestor] ||= FormatterManager.new( lib, ancestor.const_get( 'PluginFormatters' ) )
|
|
80
|
+
|
|
81
|
+
# load all the formatters
|
|
82
|
+
@@formatters[ancestor].load( ['*'] ) if @@formatters[ancestor].empty?
|
|
83
|
+
|
|
84
|
+
# run the formatters and gather the formatted data they return
|
|
85
|
+
formatted = {}
|
|
86
|
+
@@formatters[ancestor].each_pair {
|
|
87
|
+
|name, formatter|
|
|
88
|
+
plugin_results = plugins[name]
|
|
89
|
+
next if !plugin_results || plugin_results[:results].empty?
|
|
90
|
+
|
|
91
|
+
formatted[name] = formatter.new( plugin_results.deep_clone ).run
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return formatted
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
#
|
|
98
|
+
# REQUIRED
|
|
99
|
+
#
|
|
100
|
+
# Do not ommit any of the info.
|
|
101
|
+
#
|
|
102
|
+
def self.info
|
|
103
|
+
{
|
|
104
|
+
:name => 'Report abstract class.',
|
|
105
|
+
:options => [
|
|
106
|
+
# option name required? description default
|
|
107
|
+
# Arachni::OptBool.new( 'html', [ false, 'Include the HTML responses in the report?', true ] ),
|
|
108
|
+
# Arachni::OptBool.new( 'headers', [ false, 'Include the headers in the report?', true ] ),
|
|
109
|
+
],
|
|
110
|
+
:description => %q{This class should be extended by all reports.},
|
|
111
|
+
:author => 'zapotek',
|
|
112
|
+
:version => '0.1',
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
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
|
+
#
|
|
14
|
+
# The namespace under which all modules exist
|
|
15
|
+
#
|
|
16
|
+
module Reports
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Resets the namespace unloading all module classes
|
|
20
|
+
#
|
|
21
|
+
def self.reset
|
|
22
|
+
constants.each {
|
|
23
|
+
|const|
|
|
24
|
+
remove_const( const )
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
module Report
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Arachni::Report::Manager class
|
|
33
|
+
#
|
|
34
|
+
# Holds and manages the registry of the reports.
|
|
35
|
+
#
|
|
36
|
+
# @author: Tasos "Zapotek" Laskos
|
|
37
|
+
# <tasos.laskos@gmail.com>
|
|
38
|
+
# <zapotek@segfault.gr> <br/>
|
|
39
|
+
# @version: 0.1
|
|
40
|
+
#
|
|
41
|
+
class Manager < Arachni::ComponentManager
|
|
42
|
+
|
|
43
|
+
# the extension of the Arachni Framework Report files
|
|
44
|
+
EXTENSION = '.afr'
|
|
45
|
+
|
|
46
|
+
def initialize( opts )
|
|
47
|
+
super( opts.dir['reports'], Arachni::Reports )
|
|
48
|
+
@opts = opts
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Takes care of report execution
|
|
53
|
+
#
|
|
54
|
+
# @see AuditStore
|
|
55
|
+
#
|
|
56
|
+
# @param [AuditStore] audit_store
|
|
57
|
+
#
|
|
58
|
+
def run( audit_store, run_afr = true )
|
|
59
|
+
self.each {
|
|
60
|
+
|name, report|
|
|
61
|
+
run_one( name, audit_store.deep_clone )
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# run the default report
|
|
65
|
+
run_one( 'afr', audit_store.deep_clone ) if run_afr
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def run_one( name, audit_store )
|
|
69
|
+
report = self.[](name).new( audit_store.deep_clone,
|
|
70
|
+
prep_opts( name, self.[](name), @opts.reports[name] ) )
|
|
71
|
+
|
|
72
|
+
report.run( )
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def paths
|
|
76
|
+
cpaths = paths = Dir.glob( File.join( "#{@lib}", "*.rb" ) )
|
|
77
|
+
return paths.reject { |path| helper?( path ) }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def self.reset
|
|
82
|
+
Arachni::Reports.reset
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def extension
|
|
86
|
+
return EXTENSION
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
end
|
|
92
|
+
end
|