Lucene search
K

Windows Gather Service Info Enumeration

🗓️ 06 Nov 2012 23:30:04Reported by Keith Faber, Kx499Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 41 Views

This module queries and displays service name, configuration info, and allows optional search for credentials, path, or start type

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Post
  include Msf::Post::Windows::Services

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Gather Service Info Enumeration',
        'Description' => %q{
          This module will query the system for services and display name and
          configuration info for each returned service. It allows you to
          optionally search the credentials, path, or start type for a string
          and only return the results that match. These query operations are
          cumulative and if no query strings are specified, it just returns all
          services.  NOTE: If the script hangs, windows firewall is most likely
          on and you did not migrate to a safe process (explorer.exe for
          example).
        },
        'License' => MSF_LICENSE,
        'Author' => ['Keith Faber', 'Kx499'],
        'Platform' => ['win'],
        'SessionTypes' => %w[meterpreter powershell shell],
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [],
          'SideEffects' => []
        }
      )
    )
    register_options([
      OptString.new('CRED', [ false, 'String to search credentials for' ]),
      OptString.new('PATH', [ false, 'String to search path for' ]),
      OptEnum.new('TYPE', [true, 'Service startup option', 'All', ['All', 'Auto', 'Manual', 'Disabled' ]])
    ])
  end

  def run
    credential_count = {}
    qcred = datastore['CRED'] || nil
    qpath = datastore['PATH'] || nil

    if datastore['TYPE'] == 'All'
      qtype = nil
    else
      qtype = datastore['TYPE'].downcase
      print_status("Start Type Filter: #{qtype}")
    end

    if qcred
      qcred = qcred.downcase
      print_status("Credential Filter: #{qcred}")
    end

    if qpath
      qpath = qpath.downcase
      print_status("Executable Path Filter: #{qpath}")
    end

    results_table = Rex::Text::Table.new(
      'Header' => 'Services',
      'Indent' => 1,
      'SortIndex' => 0,
      'Columns' => ['Name', 'Credentials', 'Command', 'Startup']
    )

    print_status('Listing Service Info for matching services, please wait...')

    services = service_list

    vprint_status("Found #{services.length} Windows services")

    services.each do |srv|
      srv_conf = {}

      # make sure we got a service name
      if srv[:name].blank?
        print_error("Problem retrieving service information - no name found for service: #{srv}")
        next
      end

      begin
        srv_conf = service_info(srv[:name])

        next unless srv_conf && srv_conf[:startname] && srv_conf[:path]

        # filter service based on provided filters
        next if qcred && !srv_conf[:startname].downcase.include?(qcred)
        next if qpath && !srv_conf[:path].downcase.include?(qpath)

        # There may not be a 'Startup', need to check nil
        start_type = srv_conf[:starttype]
        start_type = start_type.blank? ? '' : START_TYPE[start_type].to_s

        next if qtype && !start_type.downcase.include?(qtype)

        # count the occurance of specific credentials services are running as
        service_cred = srv_conf[:startname].upcase
        unless service_cred.empty?
          if credential_count.key?(service_cred)
            credential_count[service_cred] += 1
          else
            credential_count[service_cred] = 1
            # let the user know a new service account has been detected for possible lateral
            # movement opportunities
            print_good("New service credential detected: #{srv[:name]} is running as '#{srv_conf[:startname]}'")
          end
        end

        results_table << [
          srv[:name],
          srv_conf[:startname],
          start_type,
          srv_conf[:path]
        ]
      rescue RuntimeError => e
        print_error("An error occurred enumerating service: #{srv[:name]}: #{e}")
      end
    end

    print_status("Found #{results_table.rows.size} Windows services matching filters")

    return if results_table.rows.empty?

    print_line("\n#{results_table}")

    p = store_loot('windows.services', 'text/plain', session, results_table.to_s, 'windows_services.txt', 'Windows Services')
    print_good("Loot file stored in: #{p}")
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

12 Sep 2022 19:11Current
10High risk
Vulners AI Score10
41