Class: Ronin::Vulns::SSTI

Inherits:
WebVuln show all
Defined in:
lib/ronin/vulns/ssti.rb,
lib/ronin/vulns/ssti/test_expression.rb

Overview

Represents a Server Side Template Injection (SSTI) vulnerability.

Defined Under Namespace

Classes: TestExpression

Constant Summary collapse

ESCAPES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

List of common Server Side Template Injection (SSTI) escapes.

[
  nil, # does not escape the expression
  ->(expression) { "{{#{expression}}}"    },
  ->(expression) { "${#{expression}}"     },
  ->(expression) { "${{#{expression}}}"   },
  ->(expression) { "\#{#{expression}}"    },
  ->(expression) { "<%= #{expression} %>" }
]

Instance Attribute Summary collapse

Attributes inherited from WebVuln

#cookie, #cookie_param, #form_data, #form_param, #header_name, #headers, #http, #password, #query_param, #query_params, #referer, #request_method, #url, #user

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from WebVuln

#exploit, #exploit_cookie, #exploit_form_data, #exploit_headers, #exploit_query_params, #original_value, #random_value, #request, scan_cookie_params, scan_form_params, scan_headers, scan_query_params, test, #to_curl, #to_http, #to_s

Constructor Details

#initialize(url, escape: nil, test_expr: self.class.random_test, **kwargs) ⇒ SSTI

Initializes the Server Side Template Injection (SSTI) vulnerability.

Parameters:

  • url (String, URI::HTTP)

    The URL to exploit.

  • escape (Proc, nil) (defaults to: nil)

    How to escape a given payload. Either a proc that will accept a String and return a String, or nil to indicate that the payload will not be escaped.

  • test_expr (TestExpression) (defaults to: self.class.random_test)

    The test payload and expected result to check for when testing the URL for SSTI.



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/ronin/vulns/ssti.rb', line 70

def initialize(url, escape: nil,
                    test_expr: self.class.random_test,
                    **kwargs)
  super(url,**kwargs)

  @escape    = escape
  @test_expr = test_expr

  unless @test_expr
    raise(ArgumentError,"must specify both a test expression")
  end
end

Instance Attribute Details

#escapeProc? (readonly)

How to escape the payload so that it's executed.

Returns:

  • (Proc, nil)

    The proc that will accept a String and return a String, or nil to indicate that the payload will not be escaped.



48
49
50
# File 'lib/ronin/vulns/ssti.rb', line 48

def escape
  @escape
end

#test_exprTestExpression (readonly)

The test expression to use when testing the URL for SSTI.

Returns:



53
54
55
# File 'lib/ronin/vulns/ssti.rb', line 53

def test_expr
  @test_expr
end

Class Method Details

.random_testTestExpression

Generates a random N*M SSTI test.

Returns:



89
90
91
92
93
94
95
96
97
# File 'lib/ronin/vulns/ssti.rb', line 89

def self.random_test
  int1 = rand(1_000..1_999)
  int2 = rand(1_000..1_999)

  string  = "#{int1}*#{int2}"
  result  = (int1 * int2).to_s

  return TestExpression.new(string,result)
end

.scan(url, escape: ESCAPES, **kwargs) {|vuln| ... } ⇒ Array<SSTI>

Scans the URL for Server Side Template Injection (SSTI) vulnerabilities.

Parameters:

  • url (URI::HTTP, String)

    The URL to scan.

  • escape (Array<Proc>, Proc, nil) (defaults to: ESCAPES)

    The escape method to use. If escape: is not given, then all escapes in ESCAPES will be tested..

  • kwargs (Hash{Symbol => Object})

    Additional keyword arguments for #initialize.

Options Hash (**kwargs):

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

    The query param name(s) to test.

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

    The header name(s) to test.

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

    The cookie param name(s) to test.

  • :form_params (Array<Symbol, String>, 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.

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

    Additional headers to send with requests.

  • :cookie (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 vulnerability.

Yield Parameters:

  • vuln (SSTI)

    A discovered SSTI vulnerability in the URL.

Returns:

  • (Array<SSTI>)

    All discovered SSTI vulnerabilities.



148
149
150
151
152
153
154
155
156
# File 'lib/ronin/vulns/ssti.rb', line 148

def self.scan(url, escape: ESCAPES, **kwargs,&block)
  vulns = []

  Array(escape).each do |escape_char|
    vulns.concat(super(url, escape: escape_char, **kwargs, &block))
  end

  return vulns
end

.vuln_typeSymbol

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method is abstract.
Note:

This is used internally to map an vulnerability class to a printable type.

Returns the type or kind of vulnerability.

Returns:

  • (Symbol)


197
198
199
# File 'lib/ronin/vulns/ssti.rb', line 197

def self.vuln_type
  :ssti
end

Instance Method Details

#encode_payload(payload) ⇒ String

Escapes the payload using #escape.

Parameters:

  • payload (String)

Returns:

  • (String)


165
166
167
168
169
# File 'lib/ronin/vulns/ssti.rb', line 165

def encode_payload(payload)
  if @escape then @escape.call(payload)
  else            payload
  end
end

#vulnerable?Boolean

Determine whether the URL is vulnerable to Server Side Template Injection (SSTI).

Returns:

  • (Boolean)


177
178
179
180
181
182
# File 'lib/ronin/vulns/ssti.rb', line 177

def vulnerable?
  response = exploit(@test_expr.string)
  body     = response.body

  return body.include?(@test_expr.result)
end