Last active
July 15, 2023 14:02
-
-
Save dadevel/36e5c97a058e910d7456632208d6db9e to your computer and use it in GitHub Desktop.
Impacket Ticket Helper
This file contains 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
#!/usr/bin/env python3 | |
from argparse import ArgumentParser, Namespace | |
import base64 | |
import hashlib | |
import itertools | |
import os | |
import shlex | |
import sys | |
from impacket.krb5.ccache import CCache | |
class CustomParser(ArgumentParser): | |
def print_help(self) -> None: | |
print(self.format_help(), file=sys.stderr) | |
def error(self, message: str) -> None: | |
print(message, file=sys.stderr) | |
def main() -> None: | |
entrypoint = CustomParser() | |
parsers = entrypoint.add_subparsers(dest='command', required=True) | |
parser = parsers.add_parser('import') | |
parser.add_argument('input', nargs='?', default='', metavar='-|base64:KIRBIBLOB|KIRBIFILE') | |
parser.add_argument('output', nargs='?', default='', metavar='CCACHEFILE') | |
parser = parsers.add_parser('export') | |
parser.add_argument('input', nargs='?', default='', metavar='CCACHEFILE') | |
parser = parsers.add_parser('set') | |
parser.add_argument('input', nargs=1, default='', metavar='CCACHEFILE') | |
parser = parsers.add_parser('unset') | |
opts = entrypoint.parse_args() | |
try: | |
globals()[f'ccache_{opts.command}'](opts) | |
except Exception as e: | |
print(f"{e.__class__.__name__}: {e}", file=sys.stderr) | |
exit(1) | |
def ccache_import(opts: Namespace) -> None: | |
if not opts.input or opts.input == '-': | |
ccache = CCache() | |
ccache.fromKRBCRED(base64.b64decode(sys.stdin.buffer.read())) | |
elif opts.input.startswith('base64:') and not os.path.exists(opts.input): | |
ccache = CCache() | |
ccache.fromKRBCRED(base64.b64decode(opts.input.removeprefix('base64:'))) | |
elif opts.input.endswith('.kirbi') and os.path.exists(opts.input): | |
ccache = CCache.loadKirbiFile(opts.input) | |
else: | |
raise ValueError('invalid input') | |
if not ccache: | |
raise ValueError('invalid kirbi ticket') | |
realm, user = _extract_user_info(ccache) | |
if opts.output: | |
filename = opts.output | |
else: | |
filename = f'{user}.ccache' | |
if os.path.exists(filename): | |
newhash = hashlib.md5(ccache.getData()).hexdigest() | |
with open(filename, 'rb') as file: | |
oldhash = hashlib.md5(file.read()).hexdigest() | |
if newhash != oldhash: | |
for i in itertools.count(): | |
filename = f'{user}{i}.ccache' | |
if not os.path.exists(filename): | |
break | |
ccache.saveFile(filename) | |
print(_generate_expots(filename, realm, user)) | |
def ccache_export(opts: Namespace) -> None: | |
ccache = CCache.loadFile(opts.input or os.environ['KRB5CCNAME']) | |
if not ccache: | |
raise ValueError('invalid ccache ticket') | |
print(f'echo {base64.b64encode(ccache.toKRBCRED()).decode()}') | |
def ccache_set(opts: Namespace) -> None: | |
ccache = CCache.loadFile(opts.input[0]) | |
if not ccache: | |
raise ValueError('invalid ccache ticket') | |
realm, user = _extract_user_info(ccache) | |
print(_generate_expots(opts.input[0], realm, user)) | |
def ccache_unset(_): | |
print('unset KRB5CCNAME KRB5CCNAME_REALM KRB5CCNAME_USER') | |
def _extract_user_info(ccache: CCache) -> tuple[str, str]: | |
credential = ccache.credentials[0] | |
upn = credential['client'].prettyPrint().decode().lower() | |
user, realm = upn.split('@', maxsplit=1) | |
assert '..' not in user and '/' not in user | |
return realm, user | |
def _generate_expots(path: str, realm: str, user: str) -> str: | |
return f'export KRB5CCNAME={shlex.quote(os.path.realpath(path))} KRB5CCNAME_REALM={shlex.quote(realm)} KRB5CCNAME_USER={shlex.quote(user)}' | |
if __name__ == '__main__': | |
main() |
This file contains 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
ccache() { | |
declare result | |
python3 ~/.lib/impacket-ccache-helper.py "$@" | read -r result && eval "${result}" | |
} | |
compdef "_arguments '1:first arg:(import export set unset)' '::optional arg:_files'" ccache |
This file contains 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
prompt_ccache() { | |
if [[ -e "$KRB5CCNAME" && -n "$KRB5CCNAME_REALM" && -n "$KRB5CCNAME_USER" ]]; then | |
p10k segment +e -t "$KRB5CCNAME_REALM/$KRB5CCNAME_USER" | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment