@@ -9,21 +9,26 @@ module LoginScanner
9
9
# This is the LoginScanner class for dealing with REDIS.
10
10
# It is responsible for taking a single target, and a list of credentials
11
11
# and attempting them. It then saves the results.
12
-
13
12
class Redis
14
13
include Metasploit ::Framework ::LoginScanner ::Base
15
14
include Metasploit ::Framework ::LoginScanner ::RexSocket
16
15
include Metasploit ::Framework ::Tcp ::Client
17
16
18
- DEFAULT_PORT = 6379
19
- LIKELY_PORTS = [ DEFAULT_PORT ]
20
- LIKELY_SERVICE_NAMES = [ 'redis' ]
21
- PRIVATE_TYPES = [ :password ]
22
- REALM_KEY = nil
17
+ DEFAULT_PORT = 6379
18
+ LIKELY_PORTS = [ DEFAULT_PORT ]
19
+ LIKELY_SERVICE_NAMES = [ 'redis' ]
20
+ PRIVATE_TYPES = [ :password ]
21
+ REALM_KEY = nil
22
+ OLD_PASSWORD_NOT_SET = /but no password is set/i
23
+ PASSWORD_NOT_SET = /without any password configured/i
24
+ WRONG_PASSWORD_SET = /^-WRONGPASS/i
25
+ INVALID_PASSWORD_SET = /^-ERR invalid password/i
26
+ OK = /^\+ OK/
23
27
24
28
# This method can create redis command which can be read by redis server
25
29
def redis_proto ( command_parts )
26
30
return if command_parts . blank?
31
+
27
32
command = "*#{ command_parts . length } \r \n "
28
33
command_parts . each do |p |
29
34
command << "$#{ p . length } \r \n #{ p } \r \n "
@@ -50,40 +55,50 @@ def attempt_login(credential)
50
55
connect
51
56
select ( [ sock ] , nil , nil , 0.4 )
52
57
53
- command = redis_proto ( [ 'AUTH' , "#{ credential . private } " ] )
54
- sock . put ( command )
55
- result_options [ :proof ] = sock . get_once
58
+ command = redis_proto ( [ 'AUTH' , credential . private . to_s ] )
56
59
57
- # No password - ( -ERR Client sent AUTH, but no password is set\r\n )
58
- # Invalid password - ( -ERR invalid password\r\n )
59
- # Valid password - (+OK\r\n)
60
-
61
- if result_options [ :proof ] && result_options [ :proof ] =~ /but no password is set/i
62
- result_options [ :status ] = Metasploit ::Model ::Login ::Status ::NO_AUTH_REQUIRED
63
- elsif result_options [ :proof ] && result_options [ :proof ] =~ /^-ERR invalid password/i
64
- result_options [ :status ] = Metasploit ::Model ::Login ::Status ::INCORRECT
65
- elsif result_options [ :proof ] && result_options [ :proof ] [ /^\+ OK/ ]
66
- result_options [ :status ] = Metasploit ::Model ::Login ::Status ::SUCCESSFUL
67
- end
60
+ sock . put ( command )
68
61
62
+ result_options [ :proof ] = sock . get_once
63
+ result_options [ :status ] = validate_login ( result_options [ :proof ] )
69
64
rescue Rex ::ConnectionError , EOFError , Timeout ::Error , Errno ::EPIPE => e
70
65
result_options . merge! (
71
66
proof : e ,
72
67
status : Metasploit ::Model ::Login ::Status ::UNABLE_TO_CONNECT
73
68
)
74
69
end
70
+
75
71
disconnect if self . sock
72
+
76
73
::Metasploit ::Framework ::LoginScanner ::Result . new ( result_options )
77
74
end
78
75
79
76
private
80
77
78
+ # Validates the login data received from Redis and returns the correct Login status
79
+ # based upon the contents Redis sent back:
80
+ #
81
+ # No password - ( -ERR Client sent AUTH, but no password is set\r\n )
82
+ # Invalid password - ( -ERR invalid password\r\n )
83
+ # Valid password - (+OK\r\n)
84
+ def validate_login ( data )
85
+ return if data . nil?
86
+
87
+ return Metasploit ::Model ::Login ::Status ::NO_AUTH_REQUIRED if data =~ OLD_PASSWORD_NOT_SET
88
+ return Metasploit ::Model ::Login ::Status ::NO_AUTH_REQUIRED if data =~ PASSWORD_NOT_SET
89
+ return Metasploit ::Model ::Login ::Status ::INCORRECT if ( data =~ INVALID_PASSWORD_SET ) == 0
90
+ return Metasploit ::Model ::Login ::Status ::INCORRECT if ( data =~ WRONG_PASSWORD_SET ) == 0
91
+ return Metasploit ::Model ::Login ::Status ::SUCCESSFUL if ( data =~ OK ) == 0
92
+
93
+ nil
94
+ end
95
+
81
96
# (see Base#set_sane_defaults)
82
97
def set_sane_defaults
83
- self . connection_timeout ||= 30
84
- self . port ||= DEFAULT_PORT
85
- self . max_send_size ||= 0
86
- self . send_delay ||= 0
98
+ self . connection_timeout ||= 30
99
+ self . port ||= DEFAULT_PORT
100
+ self . max_send_size ||= 0
101
+ self . send_delay ||= 0
87
102
end
88
103
end
89
104
end
0 commit comments