Module: Msf::Auxiliary::Redis

Includes:
Report, Scanner, Exploit::Remote::Tcp
Defined in:
lib/msf/core/auxiliary/redis.rb

Overview

This module provides methods for working with redis

Defined Under Namespace

Classes: RESPParser

Constant Summary collapse

REDIS_UNAUTHORIZED_RESPONSE =
/(?<auth_response>ERR operation not permitted|NOAUTH Authentication required)/i

Instance Attribute Summary

Attributes included from Exploit::Remote::Tcp

#sock

Instance Method Summary collapse

Methods included from Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot

Methods included from Metasploit::Framework::Require

optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines

Methods included from Scanner

#add_delay_jitter, #check, #fail_with, #has_check?, #has_fatal_errors?, #peer, #run, #scanner_handle_fatal_errors, #scanner_progress, #scanner_show_progress, #seppuko!

Methods included from Exploit::Remote::Tcp

#chost, #cleanup, #connect, #connect_timeout, #cport, #disconnect, #handler, #lhost, #lport, #peer, #print_prefix, #proxies, #rhost, #rport, #set_tcp_evasions, #shutdown, #ssl, #ssl_cipher, #ssl_verify_mode, #ssl_version

Instance Method Details

#initialize(info = {}) ⇒ Object

Initializes an instance of an auxiliary module that interacts with Redis



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/msf/core/auxiliary/redis.rb', line 19

def initialize(info = {})
  super
  register_options(
    [
      Opt::RPORT(6379),
      OptString.new('PASSWORD', [false, 'Redis password for authentication test', 'foobared'])
    ]
  )

  register_advanced_options(
    [
      OptInt.new('READ_TIMEOUT', [true, 'Seconds to wait while reading redis responses', 2])
    ]
  )
end

#parse_redis_response(response) ⇒ Object



79
80
81
82
# File 'lib/msf/core/auxiliary/redis.rb', line 79

def parse_redis_response(response)
  parser = RESPParser.new(response)
  parser.parse
end

#printable_redis_response(response_data, convert_whitespace = true) ⇒ Object



84
85
86
# File 'lib/msf/core/auxiliary/redis.rb', line 84

def printable_redis_response(response_data, convert_whitespace = true)
  Rex::Text.ascii_safe_hex(response_data, convert_whitespace)
end

#read_timeoutObject



35
36
37
# File 'lib/msf/core/auxiliary/redis.rb', line 35

def read_timeout
  datastore['READ_TIMEOUT']
end

#redis_command(*commands) ⇒ Object



49
50
51
52
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
# File 'lib/msf/core/auxiliary/redis.rb', line 49

def redis_command(*commands)
  command_string = printable_redis_response(commands.join(' '))
  unless (command_response = send_redis_command(*commands))
    vprint_error("No response to '#{command_string}'")
    return
  end
  if match = command_response.match(REDIS_UNAUTHORIZED_RESPONSE)
    auth_response = match[:auth_response]
    fail_with(::Msf::Module::Failure::BadConfig, "#{peer} requires authentication but Password unset") unless datastore['Password']
    vprint_status("Requires authentication (#{printable_redis_response(auth_response, false)})")
    if (auth_response = send_redis_command('AUTH', datastore['PASSWORD']))
      unless auth_response =~ /\+OK/
        vprint_error("Authentication failure: #{printable_redis_response(auth_response)}")
        return
      end
      vprint_status("Authenticated")
      unless (command_response = send_redis_command(*commands))
        vprint_error("No response to '#{command_string}'")
        return
      end
    else
      vprint_status("Authentication failed; no response")
      return
    end
  end

  vprint_status("Redis command '#{command_string}' got '#{printable_redis_response(command_response)}'")
  command_response
end

#report_redis(version) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/msf/core/auxiliary/redis.rb', line 39

def report_redis(version)
  report_service(
    host: rhost,
    port: rport,
    proto: 'tcp',
    name: 'redis',
    info: "version #{version}"
  )
end