Class: Arachni::Session

Inherits:
Object show all
Includes:
UI::Output, Utilities
Defined in:
lib/arachni/session.rb

Overview

Session management class

Handles logins, provided log-out detection, stores and executes login sequences and provided general webapp session related helpers.

Author:

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utilities

#cookie_encode, #cookies_from_document, #cookies_from_file, #cookies_from_response, #exception_jail, #exclude_path?, #extract_domain, #form_decode, #form_encode, #form_parse_request_body, #forms_from_document, #forms_from_response, #get_path, #hash_keys_to_str, #html_decode, #html_encode, #include_path?, #links_from_document, #links_from_response, #normalize_url, #page_from_response, #page_from_url, #parse_query, #parse_set_cookie, #parse_url_vars, #path_in_domain?, #path_too_deep?, #remove_constants, #seed, #skip_path?, #to_absolute, #uri_decode, #uri_encode, #uri_parse, #uri_parser, #url_sanitize

Methods included from UI::Output

#debug?, #debug_off, #debug_on, #disable_only_positives, #flush_buffer, #mute, #muted?, old_reset_output_options, #only_positives, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_pp, #print_error, #print_error_backtrace, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, reset_output_options, #set_buffer_cap, #uncap_buffer, #unmute, #verbose, #verbose?

Constructor Details

#initialize(opts = Arachni::Options.instance) ⇒ Session

Returns a new instance of Session.



78
79
80
# File 'lib/arachni/session.rb', line 78

def initialize( opts = Arachni::Options.instance )
    @opts = opts
end

Instance Attribute Details

#login_check(&block) ⇒ Block

A block used to check whether or not we’re logged in to the webapp.

The block should return true on success, false on failure.

The proc should expect 2 parameters, the first one being a hash of HTTP options and the second one an optional block.

If a block has been set, the check should work async and pass the result to the block, otherwise it should simply return the result.

The result of the check should be true or false.

A good example of this can be found in #set_login_check.

Returns:

  • (Block)

See Also:



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

def 
  @login_check
end

#login_formElement::Form

Sets a login form and generates a login sequence from it.

The form must be kosher, best be generated by one of the Element::Form helpers, Parser or #find_login_form.

Once you get the right form you need to update it with the appropriate values before passing it to this accessor.

Returns:



76
77
78
# File 'lib/arachni/session.rb', line 76

def 
  @login_form
end

#login_sequence(&block) ⇒ Block

A block used to login to the webapp.

The block should log the framework into the webapp and return true on success, false on failure.

Parameters:

  • block (Block)

    if a block has been given it will be set as the login sequence

Returns:

  • (Block)


42
43
44
# File 'lib/arachni/session.rb', line 42

def 
  @login_sequence
end

#optsOptions (readonly)

Returns options.

Returns:



32
33
34
# File 'lib/arachni/session.rb', line 32

def opts
  @opts
end

Instance Method Details

#can_login?Bool

Returns true if there is log-in capability, false otherwise.

Returns:

  • (Bool)

    true if there is log-in capability, false otherwise



158
159
160
# File 'lib/arachni/session.rb', line 158

def can_login?
    @login_sequence && @login_check
end

Tries to find the main session (login/ID) cookie.

Parameters:

  • block (Block)

    block to be passed the cookie



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/arachni/session.rb', line 92

def cookie( &block )
    return block.call( @session_cookie ) if @session_cookie
    fail 'No login-check has been configured.' if !

    cookies.each do |cookie|
        logged_in?( cookies: { cookie.name => '' } ) do |bool|
            next if bool
            block.call( @session_cookie = cookie )
        end
    end
end

#cookiesArray<Element::Cookie>

Returns session cookies.

Returns:



83
84
85
# File 'lib/arachni/session.rb', line 83

def cookies
    http.cookies.select{ |c| c.session? }
end

#ensure_logged_inBool?

Returns true if logged-in, false otherwise, nil if there’s no log-in capability.

Returns:

  • (Bool, nil)

    true if logged-in, false otherwise, nil if there’s no log-in capability



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/arachni/session.rb', line 164

def ensure_logged_in
    return if !can_login?
    return true if logged_in?

    print_bad 'The scanner has been logged out.'
    print_info 'Trying to re-login...'

    

    if !logged_in?
        print_bad 'Could not re-login.'
        false
    else
        print_ok 'Logged-in successfully.'
        true
    end
end

#find_login_form(opts = {}, &block) ⇒ Object

Finds a login forms based on supplied location, collection and criteria.

Parameters:

  • opts (Hash) (defaults to: {})
  • block (Block)

    if a block and a :url are given, the request will run async and the block will be called with the result of this method.

Options Hash (opts):

  • :requires_password (Bool)

    Does the login form include a password field? (Defaults to true)

  • :action (Array, Regexp)

    Regexp to match or String to compare against the form action.

  • :inputs (String, Array, Hash, Symbol)

    Inputs that the form must contain.

  • :forms (Array<Element::Form>)

    Collection of forms to look through.

  • :pages (Page, Array<Page>)

    Pages to look through.

  • :url (String)

    URL to fetch and look for forms.



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
152
153
154
155
# File 'lib/arachni/session.rb', line 119

def ( opts = {}, &block )
    async = block_given?

    requires_password = (opts[:requires_password].nil? ? true : opts[:requires_password])

    find = proc do |cforms|
        cforms.select do |f|
            next if requires_password && !f.requires_password?

            oks   = []

            if action = opts[:action]
                oks << !!(action.is_a?( Regexp ) ? f.action =~ action : f.action == action)
            end

            if inputs = opts[:inputs]
                oks << f.has_inputs?( inputs )
            end

            oks.count( true ) == oks.size
        end.first
    end

    forms = if opts[:pages]
                [opts[:pages]].flatten.map { |p| p.forms }.flatten
            elsif opts[:forms]
                opts[:forms]
            elsif url = opts[:url]
                if async
                    page_from_url( url ) { |p| block.call find.call( p.forms ) }
                else
                    page_from_url( url ).forms
                end
            end

    find.call( forms || [] ) if !async
end

#has_login_check?Bool

Returns true if a login check exists, false otherwise.

Returns:

  • (Bool)

    true if a login check exists, false otherwise



215
216
217
# File 'lib/arachni/session.rb', line 215

def 
    !!
end

#has_login_sequence?Bool

Returns true if a login sequence exists, false otherwise.

Returns:

  • (Bool)

    true if a login sequence exists, false otherwise



193
194
195
# File 'lib/arachni/session.rb', line 193

def 
    !!
end

#httpHTTP

Returns http interface.

Returns:

  • (HTTP)

    http interface



274
275
276
# File 'lib/arachni/session.rb', line 274

def http
    HTTP
end

#logged_in?(http_opts = {}, &block) ⇒ Bool?

Uses the block in #login_check to check in we’re logged in to the webapp.

Parameters:

  • http_opts (Hash) (defaults to: {})

    extra HTTP options to use for the check

  • block (Block)

    if a block has been provided the check will be async and the result will be passed to it, otherwise the method will return the result.

Returns:

  • (Bool, nil)

    true if we’re logged-in, false if not, nil if no #login_sequence has been set.



210
211
212
# File 'lib/arachni/session.rb', line 210

def logged_in?( http_opts = {}, &block )
    .call( http_opts, block ) if 
end

#loginBool?

Uses the block in #login_sequence to login to the webapp.

Returns:

  • (Bool, nil)

    true if login was successful, false if not, nil if no #login_sequence has been set.



188
189
190
# File 'lib/arachni/session.rb', line 188

def 
    .call if 
end

#set_login_check(url, pattern) ⇒ Object

Sets a login check using the provided url and regexp.

Parameters:

  • url (String, #to_s)

    URL to request

  • pattern (String, Regexp)

    pattern to match against the body of the response



261
262
263
264
265
266
267
268
269
270
271
# File 'lib/arachni/session.rb', line 261

def ( url, pattern )
     do |opts, block|
        bool = nil
        http.get( url.to_s, opts.merge( async: !!block ) ) do |res|
            bool = !!res.body.match( pattern )
            block.call( bool ) if block
        end

        bool
    end
end