Class: Ronin::Vulns::WebVuln

Inherits:
Vuln
  • Object
show all
Defined in:
lib/ronin/vulns/web_vuln.rb,
lib/ronin/vulns/web_vuln/http_request.rb

Overview

The base class for all web vulnerabilities.

Direct Known Subclasses

LFI, OpenRedirect, RFI, ReflectedXSS, SQLI, SSTI

Defined Under Namespace

Classes: HTTPRequest

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Vuln

vuln_type

Constructor Details

#initialize(url, query_param: nil, header_name: nil, cookie_param: nil, form_param: nil, http: nil, request_method: :get, user: nil, password: nil, headers: nil, cookie: nil, form_data: nil, referer: nil) ⇒ WebVuln

Initializes the web vulnerability.

The HTTP request mehtod for each request.

Parameters:

  • url (URI::HTTP, String)

    The URL to test or exploit.

  • query_param (String, Symbol, nil) (defaults to: nil)

    The query param to test or exploit.

  • header_name (String, Symbol, nil) (defaults to: nil)

    The HTTP Header name to test or exploit.

  • cookie_param (String, Symbol, nil) (defaults to: nil)

    The Cookie: param name to test or exploit.

  • form_param (String, Symbol, nil) (defaults to: nil)

    The form param name to test or exploit.

  • http (Ronin::Support::Network::HTTP, nil) (defaults to: nil)

    An HTTP session to use for testing the URL.

  • request_method (:copy, :delete, :get, :head, :lock, :mkcol, :move, :options, :patch, :post, :propfind, :proppatch, :put, :trace, :unlock) (defaults to: :get)
  • user (String, nil) (defaults to: nil)

    The user to authenticate as.

  • password (String, nil) (defaults to: nil)

    The password to authenticate with.

  • headers (Hash{Symbol,String => String}, nil) (defaults to: nil)

    Additional HTTP header names and values to add to the request.

  • cookie (Hash{String => String}, nil) (defaults to: nil)

    Additional Cookie header. If a Hash is given, it will be converted to a String using Ronin::Support::Network::HTTP::Cookie.

  • form_data (Hash, nil) (defaults to: nil)

    The form data that may be sent in the body of the request.

  • referer (String, nil) (defaults to: nil)

    The optional HTTP Referer header to send with each request.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ronin/vulns/web_vuln.rb', line 152

def initialize(url, query_param:    nil,
                    header_name:    nil,
                    cookie_param:   nil,
                    form_param:     nil,
                    # http keyword arguments
                    http:           nil,
                    request_method: :get,
                    user:           nil,
                    password:       nil,
                    headers:        nil,
                    cookie:         nil,
                    form_data:      nil,
                    referer:        nil)
  @url = URI(url)

  @query_param  = String(query_param)  if query_param
  @header_name  = String(header_name)  if header_name
  @cookie_param = String(cookie_param) if cookie_param
  @form_param   = String(form_param)   if form_param

  @http = http || Support::Network::HTTP.connect_uri(@url)

  @request_method = request_method
  @query_params   = @url.query_params
  @user           = user
  @password       = password
  @headers        = headers
  @cookie         = cookie
  @form_data      = form_data
  @referer        = referer
end

Instance Attribute Details

Additional Cookie header. If a Hash is given, it will be converted to a String using Ronin::Support::Network::HTTP::Cookie.

Returns:

  • (Hash{String => String}, nil)


95
96
97
# File 'lib/ronin/vulns/web_vuln.rb', line 95

def cookie
  @cookie
end

The Cookie: param name to test or exploit.

Returns:

  • (String, Symbol, nil)


52
53
54
# File 'lib/ronin/vulns/web_vuln.rb', line 52

def cookie_param
  @cookie_param
end

#form_dataHash? (readonly)

The form data that may be sent in the body of the request.

Returns:

  • (Hash, nil)


100
101
102
# File 'lib/ronin/vulns/web_vuln.rb', line 100

def form_data
  @form_data
end

#form_paramString, ... (readonly)

The form param name to test or exploit.

Returns:

  • (String, Symbol, nil)


57
58
59
# File 'lib/ronin/vulns/web_vuln.rb', line 57

def form_param
  @form_param
end

#header_nameString, ... (readonly)

The HTTP Header name to test or exploit.

Returns:

  • (String, Symbol, nil)


47
48
49
# File 'lib/ronin/vulns/web_vuln.rb', line 47

def header_name
  @header_name
end

#headersHash{Symbol,String => String}? (readonly)

Additional HTTP header names and values to add to the request.

Returns:

  • (Hash{Symbol,String => String}, nil)


89
90
91
# File 'lib/ronin/vulns/web_vuln.rb', line 89

def headers
  @headers
end

#httpRonin::Support::Network::HTTP? (readonly)

An HTTP session to use for testing the URL.

Returns:

  • (Ronin::Support::Network::HTTP, nil)


62
63
64
# File 'lib/ronin/vulns/web_vuln.rb', line 62

def http
  @http
end

#passwordString? (readonly)

The password to authenticate with.

Returns:

  • (String, nil)


84
85
86
# File 'lib/ronin/vulns/web_vuln.rb', line 84

def password
  @password
end

#query_paramString, ... (readonly)

The query param to test or exploit.

Returns:

  • (String, Symbol, nil)


42
43
44
# File 'lib/ronin/vulns/web_vuln.rb', line 42

def query_param
  @query_param
end

#query_paramsHash{String,Symbol => String} (readonly)

The query params to send with each request.

Returns:

  • (Hash{String,Symbol => String})


74
75
76
# File 'lib/ronin/vulns/web_vuln.rb', line 74

def query_params
  @query_params
end

#refererString? (readonly)

The optional HTTP Referer header to send with each request.

Returns:

  • (String, nil)


105
106
107
# File 'lib/ronin/vulns/web_vuln.rb', line 105

def referer
  @referer
end

#request_method:copy, ... (readonly)

The HTTP request method for each request.

Returns:

  • (:copy, :delete, :get, :head, :lock, :mkcol, :move, :options, :patch, :post, :propfind, :proppatch, :put, :trace, :unlock)


69
70
71
# File 'lib/ronin/vulns/web_vuln.rb', line 69

def request_method
  @request_method
end

#urlURI::HTTP (readonly)

The URL to test or exploit.

Returns:

  • (URI::HTTP)


37
38
39
# File 'lib/ronin/vulns/web_vuln.rb', line 37

def url
  @url
end

#userString? (readonly)

The user to authenticate as.

Returns:

  • (String, nil)


79
80
81
# File 'lib/ronin/vulns/web_vuln.rb', line 79

def user
  @user
end

Class Method Details

.scan(url, query_params: nil, header_names: nil, cookie_params: nil, form_params: nil, http: nil, **kwargs) {|vuln| ... } ⇒ Array<WebVuln>

Scans the URL for web vulnerabilities.

The HTTP request mehtod for each request.

Parameters:

  • url (URI::HTTP, String)

    The URL to scan.

  • query_params (Array<Symbol, String>, true, nil) (defaults to: nil)

    The query param name(s) to test.

  • header_names (Array<Symbol, String>, nil) (defaults to: nil)

    The header name(s) to test.

  • cookie_params (Array<Symbol, String>, true, nil) (defaults to: nil)

    The cookie param name(s) to test.

  • form_params (Array<Symbol, String>, nil) (defaults to: nil)

    The form param name(s) to test.

  • http (Ronin::Support::Network::HTTP, nil) (defaults to: nil)

    An HTTP session to use for testing the LFI.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for #initialize.

Options Hash (**kwargs):

  • :request_method (:copy, :delete, :get, :head, :lock, :mkcol, :move, :options, :patch, :post, :propfind, :proppatch, :put, :trace, :unlock)
  • :user (String, nil)

    The user to authenticate as.

  • :password (String, nil)

    The password to authenticate with.

  • :headers (Hash{String => String}, nil)

    Additional headers to send with requests.

  • :cookie (Hash{String => String}, Ronin::Support::Network::HTTP::Cookie, nil)

    Additional cookie params to send with requests.

  • :referer (String, nil)

    Optional Referer header to send with requests.

  • :form_data (Hash{String => String}, nil)

    Additional form data to send with requests.

Yields:

  • (vuln)

    If a block is given it will be yielded each discovered web vulnerability.

Yield Parameters:

  • vuln (WebVuln)

    A discovered web vulnerability in the URL.

Returns:

  • (Array<WebVuln>)

    All discovered web vulnerabilities.



414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/ronin/vulns/web_vuln.rb', line 414

def self.scan(url, query_params:  nil,
                   header_names:  nil,
                   cookie_params: nil,
                   form_params:   nil,
                   http:          nil,
                   **kwargs,
                   &block)
  url    = URI(url)
  http ||= Support::Network::HTTP.connect_uri(url)
  vulns  = []

  if (query_params.nil? && header_names.nil? && cookie_params.nil? && form_params.nil?)
    vulns.concat(scan_query_params(url, http: http, **kwargs,&block))
  else
    if query_params
      vulns.concat(
        case query_params
        when true
          scan_query_params(url, http: http, **kwargs,&block)
        else
          scan_query_params(url,query_params, http: http, **kwargs,&block)
        end
      )
    end

    if header_names
      vulns.concat(
        scan_headers(url,header_names, http: http, **kwargs,&block)
      )
    end

    if cookie_params
      vulns.concat(
        case cookie_params
        when true
          scan_cookie_params(url, http: http, **kwargs,&block)
        else
          scan_cookie_params(url,cookie_params, http: http, **kwargs,&block)
        end
      )
    end

    if form_params
      vulns.concat(
        scan_form_params(url,form_params, http: http, **kwargs,&block)
      )
    end
  end

  return vulns
end

Scans the URL and the Cookie header params.

Parameters:

  • url (URI::HTTP, String)

    The URL to scan.

  • cookie_params (Array<Symbol, String>, nil) (defaults to: nil)

    The cookie param name(s) to test. If not given, then the URL will be requested and the Set-Cookie params from the response will be tested instead.

  • http (Ronin::Support::Network::HTTP, nil) (defaults to: nil)

    An HTTP session to use when testing for web vulnerabilities.

Yields:

  • (vuln)

    If a block is given it will be yielded each discovered web vulnerability.

Yield Parameters:

  • vuln (Web)

    A discovered web vulnerability in the URL and one of the Cookie header params.

Returns:

  • (Array<Web>)

    All discovered web vulnerabilities.



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/ronin/vulns/web_vuln.rb', line 291

def self.scan_cookie_params(url,cookie_params=nil, http: nil, **kwargs)
  url    = URI(url)
  http ||= Support::Network::HTTP.connect_uri(url)

  unless cookie_params
    cookie_params = Set.new

    http.get_cookies(url.request_uri).each do |set_cookie|
      cookie_params.merge(set_cookie.params.keys)
    end
  end

  vulns = []

  cookie_params.each do |cookie_param|
    vuln = new(url, cookie_param: cookie_param, http: http, **kwargs)

    if vuln.vulnerable?
      yield vuln if block_given?
      vulns << vuln
    end
  end

  return vulns
end

.scan_form_params(url, form_params, http: nil, **kwargs) {|vuln| ... } ⇒ Array<Web>

Scans the URL and the form params.

Parameters:

  • url (URI::HTTP, String)

    The URL to scan.

  • form_params (Array<Symbol, String>, nil)

    The form param name(s) to test.

  • http (Ronin::Support::Network::HTTP, nil) (defaults to: nil)

    An HTTP session to use when testing for web vulnerabilities.

Yields:

  • (vuln)

    If a block is given it will be yielded each discovered web vulnerability.

Yield Parameters:

  • vuln (Web)

    A discovered web vulnerability in the URL and one of the form params.

Returns:

  • (Array<Web>)

    All discovered web vulnerabilities.



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/ronin/vulns/web_vuln.rb', line 339

def self.scan_form_params(url,form_params, http: nil, **kwargs)
  url    = URI(url)
  http ||= Support::Network::HTTP.connect_uri(url)

  vulns = []

  form_params.each do |form_param|
    vuln = new(url, form_param: form_param, http: http, **kwargs)

    if vuln.vulnerable?
      yield vuln if block_given?
      vulns << vuln
    end
  end

  return vulns
end

.scan_headers(url, header_names, http: nil, **kwargs) {|vuln| ... } ⇒ Array<Web>

Scans the URL and request headers.

Parameters:

  • url (URI::HTTP, String)

    The URL to scan.

  • header_names (Array<String, Symbol>)

    The header name(s) to test.

  • http (Ronin::Support::Network::HTTP, nil) (defaults to: nil)

    An HTTP session to use when testing for web vulnerabilities.

Yields:

  • (vuln)

    If a block is given it will be yielded each discovered web vulnerability.

Yield Parameters:

  • vuln (Web)

    A discovered web vulnerability in the URL and one of the header names.

Returns:

  • (Array<Web>)

    All discovered web vulnerabilities.



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/ronin/vulns/web_vuln.rb', line 248

def self.scan_headers(url,header_names, http: nil, **kwargs)
  url    = URI(url)
  http ||= Support::Network::HTTP.connect_uri(url)

  vulns = []

  header_names.each do |header_name|
    vuln = new(url, header_name: header_name, http: http, **kwargs)

    if vuln.vulnerable?
      yield vuln if block_given?
      vulns << vuln
    end
  end

  return vulns
end

.scan_query_params(url, query_params = nil, http: nil, **kwargs) {|vuln| ... } ⇒ Array<Web>

Scans the query parameters of the URL.

Parameters:

  • url (URI::HTTP, String)

    The URL to scan.

  • query_params (Array<Symbol, String>, nil) (defaults to: nil)

    The query param name(s) to test. If no query param(s) are given, then all query params in the URL will be scanned.

  • http (Ronin::Support::Network::HTTP, nil) (defaults to: nil)

    An HTTP session to use when testing for web vulnerabilities.

Yields:

  • (vuln)

    If a block is given it will be yielded each discovered web vulnerability.

Yield Parameters:

  • vuln (Web)

    A discovered web vulnerability in the URL's query params.

Returns:

  • (Array<Web>)

    All discovered web vulnerabilities.



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/ronin/vulns/web_vuln.rb', line 207

def self.scan_query_params(url,query_params=nil, http: nil, **kwargs)
  url    = URI(url)
  http ||= Support::Network::HTTP.connect_uri(url)

  query_params ||= url.query_params.keys
  vulns          = []

  query_params.each do |param|
    vuln = new(url, query_param: param, http: http, **kwargs)

    if vuln.vulnerable?
      yield vuln if block_given?
      vulns << vuln
    end
  end

  return vulns
end

.test(url, **kwargs) ⇒ WebVuln?

Tests the URL for a web vulnerability and returns the first found vulnerability.

The HTTP request mehtod for each request.

Parameters:

  • url (URI::HTTP, String)

    The URL to test.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for scan.

Options Hash (**kwargs):

  • :query_params (Array<Symbol, String>, true, nil)

    The query param name(s) to test.

  • :header_names (Array<Symbol, String>, nil)

    The header name(s) to test.

  • :cookie_params (Array<Symbol, String>, true, nil)

    The cookie param name(s) to test.

  • :form_params (Array<Symbol, String>, nil)

    The form param name(s) to test.

  • :http (Ronin::Support::Network::HTTP, nil)

    An HTTP session to use for testing the LFI.

  • :request_method (:copy, :delete, :get, :head, :lock, :mkcol, :move, :options, :patch, :post, :propfind, :proppatch, :put, :trace, :unlock)
  • :user (String, nil)

    The user to authenticate as.

  • :password (String, nil)

    The password to authenticate with.

  • :headers (Hash{String => String}, nil)

    Additional headers to send with requests.

  • :cookie (Hash{String => String}, Ronin::Support::Network::HTTP::Cookie, nil)

    Additional cookie params to send with requests.

  • :referer (String, nil)

    Optional Referer header to send with requests.

  • :form_data (Hash{String => String}, nil)

    Additional form data to send with requests.

Returns:

  • (WebVuln, nil)

    The first discovered web vulnerability or nil if no vulnerabilities were discovered.



518
519
520
521
522
523
524
# File 'lib/ronin/vulns/web_vuln.rb', line 518

def self.test(url,**kwargs)
  scan(url,**kwargs) do |vuln|
    return vuln
  end

  return nil
end

Instance Method Details

#encode_payload(payload) ⇒ String

Place holder method for applying additional encoding to the payload.

Parameters:

  • payload (#to_s)

    The payload to encode.

Returns:

  • (String)

    The encoded payload.



645
646
647
# File 'lib/ronin/vulns/web_vuln.rb', line 645

def encode_payload(payload)
  payload.to_s
end

#exploit(payload, **kwargs) ⇒ Net::HTTPResponse

Exploits the web vulnerability by sending an HTTP request.

Parameters:

  • payload (String)

    The payload for the web vulnerability.

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for Ronin::Support::Network::HTTP#request.

Returns:

  • (Net::HTTPResponse)


661
662
663
664
665
666
667
668
669
670
671
# File 'lib/ronin/vulns/web_vuln.rb', line 661

def exploit(payload,**kwargs)
  payload = encode_payload(payload)

  request(
    query_params: exploit_query_params(payload),
    cookie:       exploit_cookie(payload),
    headers:      exploit_headers(payload),
    form_data:    exploit_form_data(payload),
    **kwargs
  )
end

The exploit cookie params with the payload injected.

Parameters:

  • payload (#to_s)

    The payload to use for the exploit.

Returns:

  • (Hash{String,Symbol => String}, Ronin::Support::Network::HTTP::Cookie, nil)

    The #cookie with the payload injected. If #cookie_param is not set, then the unmodified #cookie will be returned.



602
603
604
605
606
607
608
609
610
611
612
# File 'lib/ronin/vulns/web_vuln.rb', line 602

def exploit_cookie(payload)
  if @cookie_param
    if @cookie
      @cookie.merge(@cookie_param.to_s => payload)
    else
      {@cookie_param.to_s => payload}
    end
  else
    @cookie
  end
end

#exploit_form_data(payload) ⇒ Hash{String,Symbol => String}?

The exploit form data with the payload injected.

Parameters:

  • payload (#to_s)

    The payload to use for the exploit.

Returns:

  • (Hash{String,Symbol => String}, nil)

    The #form_data with the payload injected. If #form_param is not set, then the unmodified #form_data will be returned.



624
625
626
627
628
629
630
631
632
633
634
# File 'lib/ronin/vulns/web_vuln.rb', line 624

def exploit_form_data(payload)
  if @form_param
    if @form_data
      @form_data.merge(@form_param.to_s => payload)
    else
      {@form_param.to_s => payload}
    end
  else
    @form_data
  end
end

#exploit_headers(payload) ⇒ Hash{String,Symbol => String}?

The exploit headers with the payload injected.

Parameters:

  • payload (#to_s)

    The payload to use for the exploit.

Returns:

  • (Hash{String,Symbol => String}, nil)

    The #headers with the payload injected. If #header_name is not set, then the unmodified #headers will be returned.



580
581
582
583
584
585
586
587
588
589
590
# File 'lib/ronin/vulns/web_vuln.rb', line 580

def exploit_headers(payload)
  if @header_name
    if @headers
      @headers.merge(@header_name.to_s => payload)
    else
      {@header_name.to_s => payload}
    end
  else
    @headers
  end
end

#exploit_query_params(payload) ⇒ Hash{String,Symbol => String}

The exploit query params with the payload injected.

Parameters:

  • payload (#to_s)

    The payload to use for the exploit.

Returns:



558
559
560
561
562
563
564
565
566
567
568
# File 'lib/ronin/vulns/web_vuln.rb', line 558

def exploit_query_params(payload)
  if @query_param
    if @query_params
      @query_params.merge(@query_param.to_s => payload)
    else
      {@query_param.to_s => payload}
    end
  else
    @query_params
  end
end

#original_valueString?

The original value of the vulnerable query param, header, cookie param, or form param.

Returns:

  • (String, nil)


679
680
681
682
683
684
685
686
687
688
689
# File 'lib/ronin/vulns/web_vuln.rb', line 679

def original_value
  if @query_param
    @url.query_params[@query_param]
  elsif @header_name
    @headers[@header_name] if @headers
  elsif @cookie_param
    @cookie[@cookie_param] if @cookie
  elsif @form_param
    @form_data[@form_param] if @form_data
  end
end

#random_value(length = 4) ⇒ String

Returns a random value.

Parameters:

  • length (Integer) (defaults to: 4)

    The desired length of the String.

Returns:

  • (String)

    The random value.



700
701
702
# File 'lib/ronin/vulns/web_vuln.rb', line 700

def random_value(length=4)
  Chars::ALPHA.random_string(length)
end

#request(**kwargs) ⇒ Net::HTTPResponse

Performs a normal request for the URL to test.

Parameters:

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for Ronin::Support::Network::HTTP#request.

Returns:

  • (Net::HTTPResponse)


535
536
537
538
539
540
541
542
543
544
545
546
# File 'lib/ronin/vulns/web_vuln.rb', line 535

def request(**kwargs)
  @http.request(
    @request_method, @url.path, user:         @user,
                                password:     @password,
                                query_params: @query_params,
                                cookie:       @cookie,
                                referer:      @referer,
                                headers:      @headers,
                                form_data:    @form_data,
                                **kwargs
  )
end

#to_curl(payload = 'PAYLOAD') ⇒ String

Converts the HTTP request to a curl command.

Parameters:

  • payload (#to_s) (defaults to: 'PAYLOAD')

    The optional payload to include in the curl command.

Returns:

  • (String)


734
735
736
737
738
739
740
741
742
743
744
745
746
747
# File 'lib/ronin/vulns/web_vuln.rb', line 734

def to_curl(payload='PAYLOAD')
  payload = encode_payload(payload)

  HTTPRequest.new(
    @url, request_method: @request_method,
          user:           @user,
          password:       @password,
          referer:        @referer,
          query_params:   exploit_query_params(payload),
          cookie:         exploit_cookie(payload),
          headers:        exploit_headers(payload),
          form_data:      exploit_form_data(payload)
  ).to_curl
end

#to_http(payload = 'PAYLOAD') ⇒ String

Converts the HTTP request to a raw HTTP request.

Parameters:

  • payload (#to_s) (defaults to: 'PAYLOAD')

    The optional payload to include in the HTTP request.

Returns:

  • (String)


757
758
759
760
761
762
763
764
765
766
767
768
769
770
# File 'lib/ronin/vulns/web_vuln.rb', line 757

def to_http(payload='PAYLOAD')
  payload = encode_payload(payload)

  HTTPRequest.new(
    @url, request_method: @request_method,
          user:           @user,
          password:       @password,
          referer:        @referer,
          query_params:   exploit_query_params(payload),
          cookie:         exploit_cookie(payload),
          headers:        exploit_headers(payload),
          form_data:      exploit_form_data(payload)
  ).to_http
end

#to_sString

Converts the web vulnerability into a String.

Returns:

  • (String)

    The String form of #url.



722
723
724
# File 'lib/ronin/vulns/web_vuln.rb', line 722

def to_s
  @url.to_s
end

#vulnerable?Boolean

This method is abstract.

Determines if the #url is vulnerable.

Returns:

  • (Boolean)

    Indicates whether the URL is vulnerable.

Raises:

  • (NotImplementedError)


712
713
714
# File 'lib/ronin/vulns/web_vuln.rb', line 712

def vulnerable?
  raise(NotImplementedError,"#{self.inspect} did not implement ##{__method__}")
end