From 35ab9bfb895b79fa80e5c19ee310005318d53d15 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Mon, 16 Apr 2007 01:41:50 +0000 Subject: [PATCH] Bug fixes and a new "hidden" service detection module git-svn-id: file:///home/svn/framework3/trunk@4685 4d416f70-5f16-0410-b530-b9f4589650da --- modules/auxiliary/scanner/dcerpc/hidden.rb | 128 ++++++++++++++++++ .../auxiliary/scanner/dcerpc/management.rb | 6 +- 2 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 modules/auxiliary/scanner/dcerpc/hidden.rb diff --git a/modules/auxiliary/scanner/dcerpc/hidden.rb b/modules/auxiliary/scanner/dcerpc/hidden.rb new file mode 100644 index 0000000000..cf6f377a4f --- /dev/null +++ b/modules/auxiliary/scanner/dcerpc/hidden.rb @@ -0,0 +1,128 @@ +## +# $Id:$ +## + +## +# 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/projects/Framework/ +## + + +require 'msf/core' + +module Msf + +class Auxiliary::Scanner::Dcerpc::RPC_HIDDEN < Msf::Auxiliary + + # Exploit mixins should be called first + include Exploit::Remote::DCERPC + + # Scanner mixin should be near last + include Auxiliary::Scanner + + def initialize + super( + 'Name' => 'Hidden DCERPC Service Discovery', + 'Version' => '$Revision: 3624 $', + 'Description' => %q{ + This module will query the endpoint mapper and make a list + of all ncacn_tcp RPC services. It will then connect to each of + these services and use the management API to list all other + RPC services accessible on this port. Any RPC service found attached + to a TCP port, but not listed in the endpoint mapper, will be displayed + and analyzed to see whether anonymous access is permitted. + }, + 'Author' => 'hdm', + 'License' => MSF_LICENSE + ) + + deregister_options('RHOST', 'RPORT') + end + + # Obtain information about a single host + def run_host(ip) + begin + + epm = dcerpc_endpoint_list() + if(not epm) + print_status("Could not contact the endpoint mapper on #{ip}") + return + end + + eports = {} + + epm.each do |ep| + next if not (ep[:port] and ep[:prot] and ep[:prot] == "tcp") + eports[ep[:port]] ||= {} + eports[ep[:port]][ep[:uuid]+'_'+ep[:vers]] = true + end + + eports.each_pair do |eport, servs| + + rport = eport + print_status("Looking for services on #{ip}:#{rport}...") + + ids = dcerpc_mgmt_inq_if_ids(rport) + return if not ids + + ids.each do |id| + if (not servs.has_key?(id[0]+'_'+id[1])) + print_status("\tHIDDEN: UUID #{id[0]} v#{id[1]}") + + conn = nil + bind = nil + call = nil + data = nil + error = nil + begin + connect(true, { 'RPORT' => eport }) + conn = true + + handle = dcerpc_handle(id[0], id[1], 'ncacn_ip_tcp', [eport]) + dcerpc_bind(handle) + bind = true + + res = dcerpc.call(0, NDR.long(0) * 128) + call = true + + if (dcerpc.last_response != nil and dcerpc.last_response.stub_data != nil) + data = dcerpc.last_response.stub_data + end + + rescue ::Interrupt + raise $! + rescue ::Exception => e + error = e.to_s + end + + if (error and error =~ /DCERPC FAULT/ and error !~ /nca_s_fault_access_denied/) + call = true + end + + status = "\t\t" + status << "CONN " if conn + status << "BIND " if bind + status << "CALL " if call + status << "DATA=#{data.unpack("H*")[0]} " if data + status << "ERROR=#{error} " if error + + print_status(status) + print_status("") + + end + end + end + + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_status("Error: #{e.to_s}") + end + end + + +end +end + diff --git a/modules/auxiliary/scanner/dcerpc/management.rb b/modules/auxiliary/scanner/dcerpc/management.rb index d78ed30db6..9b38a2b3e6 100644 --- a/modules/auxiliary/scanner/dcerpc/management.rb +++ b/modules/auxiliary/scanner/dcerpc/management.rb @@ -52,13 +52,13 @@ class Auxiliary::Scanner::Dcerpc::RPC_MGMT < Msf::Auxiliary print_status("UUID #{id[0]} v#{id[1]}") stats = dcerpc_mgmt_inq_if_stats(rport) - print_status("\t stats: " + stats.map{|i| "0x%.8x" % i}.join(", ")) + print_status("\t stats: " + stats.map{|i| "0x%.8x" % i}.join(", ")) if stats live = dcerpc_mgmt_is_server_listening(rport) - print_status("\t listening: %.8x" % live) + print_status("\t listening: %.8x" % live) if live dead = dcerpc_mgmt_stop_server_listening(rport) - print_status("\t killed: %.8x" % dead) + print_status("\t killed: %.8x" % dead) if dead princ = dcerpc_mgmt_inq_princ_name(rport) print_status("\t name: #{princ.unpack("H*")[0]}") if princ