{"id":16995777,"url":"https://github.com/qtc-de/kutil","last_synced_at":"2025-04-12T05:41:13.653Z","repository":{"id":57438495,"uuid":"282125048","full_name":"qtc-de/kutil","owner":"qtc-de","description":"A command line utility to work with Kerberos ticket caches (MIT format)","archived":false,"fork":false,"pushed_at":"2020-08-08T16:18:10.000Z","size":84,"stargazers_count":7,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-20T06:48:34.962Z","etag":null,"topics":["kerberos","kerberos-authentication","kerberos-tickets","manipulation","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qtc-de.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-24T04:45:21.000Z","updated_at":"2024-11-08T02:53:00.000Z","dependencies_parsed_at":"2022-08-29T02:01:20.128Z","dependency_job_id":null,"html_url":"https://github.com/qtc-de/kutil","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qtc-de%2Fkutil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qtc-de%2Fkutil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qtc-de%2Fkutil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qtc-de%2Fkutil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qtc-de","download_url":"https://codeload.github.com/qtc-de/kutil/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248525162,"owners_count":21118617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kerberos","kerberos-authentication","kerberos-tickets","manipulation","python3"],"created_at":"2024-10-14T03:50:06.054Z","updated_at":"2025-04-12T05:41:13.611Z","avatar_url":"https://github.com/qtc-de.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"### kutil\n\n----\n\n*kutil* is a command line utility to work with Kerberos ticket cache files (MIT format).\nIt supports different operations like merging, splitting and modifying ticket caches.\nA detailed list of all supported operations can be found in the [operations section](#supported-operations).\n\n![](https://github.com/qtc-de/kutil/workflows/master%20Python%20CI/badge.svg?branch=master)\n![](https://github.com/qtc-de/kutil/workflows/develop%20Python%20CI/badge.svg?branch=develop)\n\n\n### Table of Contents\n\n----\n\n- [Installation](#installation)\n- [Supported Operations](#supported-operations)\n  * [Credential Modifications](#credential-modifications) \n    + [Change Principal](#change-principal)\n    + [Change Realm](#change-realm)\n    + [Change Service](#change-service)\n    + [Change SPN](#change-spn)\n    + [Change Target](#change-Target)\n  * [Ticket Cache Modifications](#ticket-cache-modifications)\n    + [Clear Duplicates](#clear-duplicates)\n    + [Change Default Principal](#change-default-principal)\n    + [Delete Credential](#delete-credential)\n    + [Merge Ticket Caches](#merge-ticket-caches)\n    + [Split Ticket Caches](#split-ticket-caches)\n  * [Miscellaneous](#miscellaneous)\n    + [Decrypt Credential](#decrypt-credential)\n    + [Hash Password](#hash-password)\n    + [List Ticket Cache](#list-ticket-cache)\n- [Why Modifying Tickets](#why-modifying-tickets)\n- [Modifying Encrypted Ticket Content](#modifying-encrypted-ticket-content)\n- [Acknowledgements](#acknowledgements)\n\n\n### Installation\n\n----\n\n*kutil* can be build and installed as a *pip* package. The following\ncommand installs *kutil* for your current user profile:\n\n```console\n$ pip3 install kutil\n```\n\nYou can also build *kutil* from source and install it directly by using\nthe following commands:\n\n```console\n$ git clone https://github.com/qtc-de/kutil\n$ cd kutil\n$ pip3 install -r requirements.txt\n$ python3 setup.py sdist\n$ pip3 install dist/*\n```\n\nAdditionally, *kutil* ships a [bash-completion](./kutil/resources/bash_completion.d/kutil) script.\nThe completion script is installed automatically, but relies on the [completion-helpers](https://github.com/qtc-de/completion-helpers)\npackage. If *completion-helpers* is already installed, autocompletion for *kutil* should\nwork after installing the pip package. Otherwise, you may need to copy the completion\nscript manually:\n\n```console\n$ cp kutil/resources/bash_completion.d/kutil ~/.bash_completion.d\n```\n\n\n### Supported Operations\n\n----\n\n```console\n$ kutil --help\nusage: kutil [-h] [--aes-user username] [--aes-realm realm] [--aes-host hostname] [-c] [-d principal] [--delete index] [--decrypt key] [--hash password] [-i number] [-l] [-m path] [-o path] [-p PRINCIPAL]\n             [--prefix PREFIX] [-r REALM] [-s SERVICE] [--spn SPN] [--split] [-t TARGET]\n             [ticket]\n\nkutil is a command line utility to work with Kerberos ticket cache files (MIT format). It can be used to merge different Kerberos tickets into a single ticket cache, to split or delete credentials from a ticket\ncache or to modify the unencrypted portions of an existing ticket.\n\npositional arguments:\n  ticket                Kerberos ticket to operate on (default: /tmp/krb5cc_1000)\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --aes-user username   username for AES hash generation\n  --aes-realm realm     realm for AES hash generation\n  --aes-host hostname   hostname for AES hash generation\n  -c, --clear           clear duplicate credentials\n  -d principal, --default principal\n                        update default principal of ccache\n  --delete index        delete credential with specified index\n  --decrypt key         decrypt credential selected by index\n  --hash password       generate hashes for specified password\n  -i number, --index number\n                        ticket index for updates (default: 0)\n  -l, --list            list ticket contents\n  -m path, --merge path\n                        merge specified ticket into main ticket (can be used multiple times)\n  -o path, --out path   filename of the output ticket (default: ticket param)\n  -p PRINCIPAL, --principal PRINCIPAL\n                        update principal of credential selected by index\n  --prefix PREFIX       filename prefix for split operation (default: cc_split_)\n  -r REALM, --realm REALM\n                        update the target realm of credential selected by index\n  -s SERVICE, --service SERVICE\n                        update service type (e.g. HTTP) of credential selected by index\n  --spn SPN             update service SPN (e.g. service/target@realm) of credential slected by index\n  --split               split ticket cache into seperate tickets\n  -t TARGET, --target TARGET\n                        update target server of credential selected by index\n```\n\n\n#### Credential Modifications\n\nOperations that modify credentials stored inside a Kerberos ticket cache.\n\n##### Change Principal\n\nChanges the client principal for the credential specified by ``--index`` (default 0):\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --principal smeyer@example.lab\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating principal of credential with index 0\n[+]     Old principal: 'administrator@EXAMPLE.LAB'\n[+]     New principal: 'smeyer@example.lab'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\tfor client smeyer@example.lab, renew until 07/22/30 07:00:40\n```\n\n##### Change Realm\n\nChanges the *realm* of the server principal for the credential specified by ``--index`` (default 0):\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --realm MODIFIED.LAB\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating realm of credential with index 0\n[+]     Old realm: 'EXAMPLE.LAB'\n[+]     New realm: 'MODIFIED.LAB'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@MODIFIED.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n##### Change Service\n\nChanges the *service type* of the server principal for the credential specified by ``--index`` (default 0):\n\n```console\n$ klist \nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --service LDAP\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating service of credential with index 0\n[+]     Old service: 'http'\n[+]     New service: 'LDAP'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  LDAP/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n##### Change SPN\n\nChanges the target *SPN* of a credential specified by ``--index`` (default 0). This is basically\nan alternative to the ``--realm``, ``--service`` and ``--target`` parameters where you can specify\nall options in one.\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --spn LDAP/dc01.example.lab@EXAMPLE.LAB\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating SPN of credential with index 0\n[+]     Old SPN: 'http/dev01.example.lab@EXAMPLE.LAB'\n[+]     New SPN: 'LDAP/dc01.example.lab@EXAMPLE.LAB'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  LDAP/dc01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n##### Change Target\n\nChange the target host of the server principal in the credential specified by ``--index`` (default 0):\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --target dev02.example.lab\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating target of credential with index 0\n[+]     Old target: 'dev01.example.lab'\n[+]     New target: 'dev02.example.lab'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev02.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n\n#### Ticket Cache Modifications\n\nOperations that modify the Kerberos ticket cache.\n\n##### Clear Duplicates\n\nClears duplicate tickets from the ticket cache.\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --clear\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Removing duplicate credentials from '/tmp/krb5cc_1000'.\n[+] 1 duplicate credentials removed.\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n##### Change Default Principal\n\nChanges the default principal of a ticket cache.\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --default smeyer@EXAMPLE.LAB\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating default principal.\n[+]     Old default principal: 'administrator@EXAMPLE.LAB'\n[+]     New default principal: 'smeyer@EXAMPLE.LAB'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: smeyer@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\tfor client administrator@EXAMPLE.LAB, renew until 07/22/30 07:00:40\n```\n\n##### Delete Credential\n\nDeletes a credential from the cache specified by an index.\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  LDAP/dc01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --delete 1\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Deleting credential with index 1.\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  LDAP/dc01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n##### Merge Ticket Caches\n\nMerges different Kerberos ticket caches.\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  LDAP/dc01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --merge administrator.ccache \n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Kerberos ticket cache 'administrator.ccache' loaded.\n[+] Adding 1 credential(s) to '/tmp/krb5cc_1000'\n[+] Saving ticket as '/tmp/krb5cc_1000'\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  LDAP/dc01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n##### Split Ticket Caches\n\nSplit credentials of a Kerberos ticket cache into separate files.\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  LDAP/dc01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --split\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Splitting /tmp/krb5cc_1000 into 2 separate tickets.\n[+] Ticket cc_split_1 created.\n[+] Ticket cc_split_2 created.\n```\n\n\n#### Miscellaneous\n\nOther functions that can be useful when working with Kerberos tickets.\n\n##### Decrypt Credential\n\nDecrypts the credential specified by the ``--index`` parameter (default 0). Requires\nthe Kerberos hash for the corresponding credential.\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil --decrypt 139a228822914d0d20e13920b219121\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] \n[+] PAC Info Buffer:\n[+]     ulType: 1\n[+]     cbBufferSize: 456 bytes\n[+]     Offset: 72 bytes\n[+] \n[+] Authorization Data:\n[+]     CommonHeader:                   \n[...]\n```\n\n##### Hash Password\n\nComputes Kerberos password hashes (NTLM, AES128, AES256) of the specified password.\nThis can be useful for the *decrypt* operation, as it requires the hashed password for a credential.\n\n```console\n$ kutil --hash password\n[+] Generating hashes...\n[+]    NTLM\t\t: 8846F7EAEE8FB117AD06BDD830B7586C\n[-] Notice: --aes-user or --aes-host and --aes-realm need to be supplied for AES hash calculation.\n```\n\nFor computing *AES hashes* a username or computername and the corresponding realm are required:\n\n```console\n$ kutil --hash password --aes-user smeyer --aes-realm example.lab\n[+] Generating hashes...\n[+]    NTLM\t\t    : 8846F7EAEE8FB117AD06BDD830B7586C\n[+]    AES 128\t\t: 8266333A9E151D16FAE6AD5AEF0DEF4D\n[+]    AES 256\t\t: 608504D6D78351369EAC5D9AB7B2F90D0BC2EA451C8BF76C91D3CA716D9F7887\n```\n\n##### List Ticket Cache\n\nList contents of the ticket cache.\n\n```console\n$ kutil --list\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Primary Principal: b'administrator@EXAMPLE.LAB'\n[+] Credentials: \n[+] [0]\n[+] \tClient: b'administrator@EXAMPLE.LAB'\n[+] \tServer: b'http/dev01.example.lab@EXAMPLE.LAB'\n[+] \tKey: (0x17)b'6c4f65644771724c416767427743454e'\n[+] \tTimes: \n[+] \t\tAuth : 2020-07-24T07:00:40\n[+] \t\tStart: 2020-07-24T07:00:40\n[+] \t\tEnd  : 2030-07-22T07:00:40\n[+] \t\tRenew: 2030-07-22T07:00:40\n[+] \tSubKey: 0\n[+] \tFlags: 0x50a00000\n[+] \tAddresses: 0\n[+] \tAuth Data: 0\n[+] \tTicket: b'618203b9308203b5a003020105a10d1b0b4558414d504c452e4c4142a2243022a003020101a11b30191b04687474701b1164657630312e6578616d706c652e6c6162a382037730820373a003020117a103020102a282036504820361ef0967adc54dd1d8fb35e980fabe346e8e95bd1555b44f23f9500731487a3d96cc2dbf759ce37ff1bd5aded25a04cae751b80735e4f225e66ae9bee021b52676af1c593afa9372d075bd01462a3a48ba855112140b4375da212d389089aceab517efb1cacab386017e086c91fb51b899accfa7ca67cea511bc56c0e6b0c1c0a888426273178ea938a266bfd0ada3c520b039eeb26373003cc85ae7b8473a78da36a78f80af9e347b02f691d16a16eb3b3a36542661cad526f59312d149e562e43b75add5a7d651ac50c703cea34d19d4a4e4e68d5e7526b5a8983518a799d3de73818e383244f1d5acb5ef5e4d0886800e7ba5e1879a47846835c4701ebec34801993e9cbee45daca2b64544ab946e312db4286e19667df02da546a8f48faecbb369ea8d1ce8e17a542c1593c872f76ae47acca2b9e26b0285348b0059a256454390abe6149bb89e86213104969923b64ee04625cb789a7fdecf21e9577f2390c728a3d12e968e5430e882a3f9cf4895a0b4809c319c942e7c587cd6b59468c67417b515e089ff833db666494f36acf7f27d5a11f914e898630d1af6a2d73f9897adc3190c53c4ad84efec15908fdd91464e03e00344c16a28fe26bca801f138f961e979bdefb09c1c32e0a433ad19696133db7c76b447105bce5043580be21c6fbc627ccdc61b1e7f7f0b1df36fd9390978687a5edfeca033d45d485c0fb5c469a1fae918f0030d5d76dff7957446f077b8db034a36ce557a87a30123b06414e80077bc6bb743156ccf435b16ec5f032bdcfdabc82bbdba39de67b2658615a8248606f4185aa4a229bcbce4376cf8b5313001fd6b1d8597de543a7da621c0bfb70b3ad1db4c2421272ddd041f0b01f1026a401cc32228af87da479a6488020578d1bfef02d6724dafeb8fa65a0573de9e22d78c3838bf97145cf901a9f5c904a3b1760b0ea8671d66a25e0da13039969b15ee9b6f3aa88200133e199643e730b9afcffc4cd76f308ce33bdae83c82e130e3ec688ec9b427611d0af9a8cde958e254015ce89ca71798410f7d36ac65f01733109f6c894f6e5ed15f090d1f0e3b024fdd4a4ade9eedf9d5bf1386ed7256d1f30406f73596ed6eb8801ef075620f230d66c39f6c1ff6ef55aa85aeb763a231be64fcd492e131f877068331a683355f1a9c36a455143246e920ed08c030cc544146d2f51ecd4c7548994590906357e1'\n[+] \tSecond Ticket: b''\n```\n\n\n### Why Modifying Tickets\n\n----\n\nA legitimate question is why it should be useful to modify the unencrypted portions of *Kerberos tickets*?\nActually, this was the initial functionality of *kutil* and the other functions were build later on.\nSo lets look at a scenario where changing tikcet contents can be useful.\n\nImagine you encounter an *HTTP Server* that is configured for *Kerberos Authentication* and you want to access\nit with *Firefox*. Furthermore, let us assume that you have no valid credentials for a domain account, but\nmanaged to obtain a service ticket (*TGS*) for a domain user. Therefore, your ticket cache could look like this:\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: smeyer@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  HTTP/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\nAfter configuring *Firefox* for *Kerberos Authentication* with the corresponding domain, you will notice\nthat *Firefox* refuses to use the *TGS* and tries to access the webserver without authentication. The\nreason for this behavior is that *GSSAPI* is quite picky when it comes down to comparing principal\nnames.\n\nBy hooking the ``gss_import_name`` function, you can verify that *Firefox* searches for a\ncredential matching the principal name ``HTTP@dev01.example.lab``. This format is called \n``NT-SRV-HST`` and does not contain the *realm* name explicitly (obviously, as *Firefox* could only\nguess the actual *realm* of the domain). The credential inside the *ccache*, on the other hand,\nis stored in the ``NT-SRV-INST`` format, that contains the *realm* name explicitly.\n\nThe *GSSAPI* documentation says, that the different principal name types do not matter during credential\nlookups. However, this is only partially true as the explicit realm from the ``NT-SRV-INST`` type\nseems to conflict with the missing realm in the ``NT-SRV-HST`` type. This is the reason why *Firefox*\ndoes not find the corresponding credential and tries to access the webserver unauthenticated.\n\nSolving the issue can be done in different ways. Initiall when I encountered this problem I hooked\nthe ``gss_import_name`` function and changed the ``NT-SRV-HST`` lookup into the ``NT-SRV-INST`` form.\nHowever, with *kutil* where is an easier option. As mentioned above, the only conflicting part between\nthe two different principal name types is the explicit *realm* definition. By simply removing the\n*realm* of the ``NT-SRV-INST`` type, *Firefox* will find the credential. The (probably) easiest\nsolution is therefore:\n\n```console\n$ kutil -r ''\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating realm of credential with index 0\n[+]     Old realm: 'EXAMPLE.LAB'\n[+]     New realm: ''\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: smeyer@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  HTTP/dev01.example.lab@\n\trenew until 07/22/30 07:00:40\n```\n\nApart from this very specific example, changing the *service type* of a ticket can be quite useful.\n*GSSAPI* uses case sensitive comparison when looking up credentials. A lookup for ``HTTP/dev01.example.lab@EXAMPLE.LAB``\ndoes therefore not find the credential ``http/dev01.example.lab@EXAMPLE.LAB``. This can be annoying, but with *kutil*\nit is easy to change:\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  http/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil -s HTTP\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating service of credential with index 0\n[+]     Old service: 'http'\n[+]     New service: 'HTTP'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  HTTP/dev01.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\nFinally, [this great article](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html#solving-a-sensitive-problem)\non Kerberos constrained delegation demonstrates that ``S4U2Self`` can be quite useful to bypass limitations of\n*Silver Tickets*. To utilize this, it is required to change the target host of a ``S4U2Self`` ticket. This can, again,\nbe easily done with *kutil*:\n\n```console\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  cifs/serviceA$@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n$ kutil -t servicea.example.lab\n[+] Kerberos ticket cache '/tmp/krb5cc_1000' loaded.\n[+] Updating target of credential with index 0\n[+]     Old target: 'serviceA$'\n[+]     New target: 'servicea.example.lab'\n[+] Saving ticket as '/tmp/krb5cc_1000'.\n$ klist\nTicket cache: FILE:/tmp/krb5cc_1000\nDefault principal: administrator@EXAMPLE.LAB\n\nValid starting     Expires            Service principal\n07/24/20 07:00:40  07/22/30 07:00:40  cifs/servicea.example.lab@EXAMPLE.LAB\n\trenew until 07/22/30 07:00:40\n```\n\n\n### Modifying Encrypted Ticket Content\n\n-----\n\nAs *kutil* does already implement ticket decryption, one could also think about modifying the\nencrypted portions of Kerberos tickets. However, once you have credentials for decrypting tickets\nyou could also just generate a new one using [ticketer.py](https://github.com/SecureAuthCorp/impacket/blob/master/examples/ticketer.py). Therefore, modifying the encrypted\ncontents seems to be of limited use. That being said, modifying the unencrypted portions seemed\nalso not to be very useful until I encounterd the above described situation. So maybe this will\nbe implemented in future.\n\n\n\n### Acknowledgements\n\n-----\n\n*kutil* does heavily rely on the [impacket](https://github.com/SecureAuthCorp/impacket) library. Furthermore, certain portions were copied\nfrom other resources on *GitHub* (see comments in the source code). Thanks to all for sharing\nyour code :)\n\n\n*Copyright 2020, Tobias Neitzel and the kutil contributors.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqtc-de%2Fkutil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqtc-de%2Fkutil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqtc-de%2Fkutil/lists"}