Class: Arachni::Plugins::Exec

Inherits:
Arachni::Plugin::Base show all
Defined in:
components/plugins/exec.rb

Overview

Author:

Version:

  • 0.1

Constant Summary

Constants included from Arachni

BANNER, Cookie, Form, Header, JSON, Link, LinkTemplate, NestedCookie, Severity, UIForm, UIInput, VERSION, WEBSITE, WIKI, XML

Instance Attribute Summary

Attributes inherited from Arachni::Plugin::Base

#framework, #options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Arachni::Plugin::Base

#browser_cluster, distributable, distributable?, #framework_abort, #framework_pause, #framework_resume, gems, #http, #info, #initialize, is_distributable, merge, #register_results, #restore, #session, #suspend, #wait_while_framework_running, #with_browser

Methods inherited from Component::Base

author, description, fullname, #shortname, shortname, shortname=, version

Methods included from Component::Output

#depersonalize_output, #depersonalize_output?, #intercept_print_message

Methods included from UI::Output

#caller_location, #debug?, #debug_level, #debug_level_1?, #debug_level_2?, #debug_level_3?, #debug_level_4?, #debug_off, #debug_on, #disable_only_positives, #error_buffer, #error_log_fd, #error_logfile, #has_error_log?, #included, #log_error, #mute, #muted?, #only_positives, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_exception, #print_debug_level_1, #print_debug_level_2, #print_debug_level_3, #print_debug_level_4, #print_error, #print_error_backtrace, #print_exception, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, reset_output_options, #set_error_logfile, #unmute, #verbose?, #verbose_off, #verbose_on

Methods included from Component::Utilities

#read_file

Methods included from Utilities

#available_port, available_port_mutex, #bytes_to_kilobytes, #bytes_to_megabytes, #caller_name, #caller_path, #cookie_decode, #cookie_encode, #cookies_from_file, #cookies_from_parser, #cookies_from_response, #exception_jail, #exclude_path?, #follow_protocol?, #form_decode, #form_encode, #forms_from_parser, #forms_from_response, #full_and_absolute_url?, #generate_token, #get_path, #hms_to_seconds, #html_decode, #html_encode, #include_path?, #links_from_parser, #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?, #regexp_array_match, #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

Methods included from Arachni

URI, collect_young_objects, #get_long_win32_filename, jruby?, null_device, profile?, windows?

Constructor Details

This class inherits a constructor from Arachni::Plugin::Base

Class Method Details

.infoObject



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'components/plugins/exec.rb', line 107

def self.info
    {
        name:        'Exec',
        description: %q{
Calls external executables at different scan stages.

The following variables can be used in the executable string:

* `__URL__`: Target URL.
* `__URL_SCHEME__`: URL scheme (http/https).
* `__URL_HOST__`: URL host.
* `__URL_PORT__`: URL port.
* `__STAGE__`: Scan stage (pre/during/post).
* `__ISSUE_COUNT__`: Amount of logged issues.
* `__SITEMAP_SIZE__`: Amount of discovered pages.
* `__FRAMEWORK_RUNTIME__`: Scan runtime.
* `__FRAMEWORK_STATUS__`: Framework status.

**Example:**

The following:

echo "__URL__ __URL_SCHEME__ __URL_HOST__ __URL_PORT__ __STAGE__ __ISSUE_COUNT__ __SITEMAP_SIZE__ __FRAMEWORK_RUNTIME__ __FRAMEWORK_STATUS__"

Will result in:

http://testfire.net/ http testfire.net 80 post 0 2 3.906482517 cleanup

_Will not work over RPC._
},
        author:      'Tasos "Zapotek" Laskos <[email protected]>',
        version:     '0.1.1',
        options:     [
            Options::String.new( :pre,
                description: 'Executable to be called prior to the scan.'
            ),
            Options::String.new( :during,
                description: 'Executable to be called in parallel to the scan.'
            ),
            Options::String.new( :post,
                description: 'Executable to be called after the scan.'
            )
        ]
    }
end

Instance Method Details

#clean_upObject



46
47
48
49
50
51
# File 'components/plugins/exec.rb', line 46

def clean_up
    wait_while_framework_running
    exec( :post )

    register_results @data
end

#exec(stage) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'components/plugins/exec.rb', line 53

def exec( stage )
    return if options[stage].to_s.empty?

    if defined?( Arachni::RPC::Server::Framework ) &&
        framework.is_a?( Arachni::RPC::Server::Framework )
        print_error 'Cannot be executed while running as an RPC server.'
        return
    end

    @stage = stage

    data = @data[stage.to_s] = {
        'status'     => nil,
        'pid'        => nil,
        'executable' => nil,
        'stdout'     => nil,
        'stderr'     => nil,
        'runtime'    => 0
    }

    executable          = options[stage.to_sym]
    expanded_executable = format( executable )

    print_status "Running #{stage} executable: #{expanded_executable}"

    data['executable'] = expanded_executable

    t = Time.now
    data['stdout'], data['stderr'], status =
        Open3.capture3( expanded_executable )

    data['runtime'] = Time.now - t

    data['status'] = status.exitstatus
    data['pid']    = status.pid

    print_info "Status: #{data['status']}"
    print_info "PID:    #{data['pid']}"
    print_info "STDOUT: #{data['stdout']}"
    print_info "STDERR: #{data['stderr']}"
end

#format(string) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# File 'components/plugins/exec.rb', line 95

def format( string )
    @substitutions.each do |variable, value|
        next if !string.include?( variable )

        value = value.call if value.respond_to? :call

        string = string.gsub( variable, value.to_s )
    end

    string
end

#prepareObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'components/plugins/exec.rb', line 15

def prepare
    parsed_url = Arachni::URI( framework.options.url )

    @data          = {}
    @substitutions = {
        '__URL__'               => framework.options.url,
        '__URL_SCHEME__'        => parsed_url.scheme,
        '__URL_HOST__'          => parsed_url.host,
        '__URL_PORT__'          => parsed_url.port || 80,
        '__STAGE__'             => proc { @stage },
        '__ISSUE_COUNT__'       => proc do
            Arachni::Data.issues.size
        end,
        '__SITEMAP_SIZE__'      => proc do
            framework.data.sitemap.size
        end,
        '__FRAMEWORK_RUNTIME__' => proc do
            framework.statistics[:runtime]
        end,
        '__FRAMEWORK_STATUS__'  => proc do
            framework.status
        end
    }

    exec( :pre )
end

#runObject



42
43
44
# File 'components/plugins/exec.rb', line 42

def run
    exec( :during )
end