Advertisement
Haxguy

HTB Titanic - Crack pbkdf2

Feb 27th, 2025
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.81 KB | Cybersecurity | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import hashlib
  4. import binascii
  5. import sys
  6. import time
  7. import select
  8.  
  9. def derive_pbkdf2(password: bytes, salt: bytes, rounds: int, length: int) -> bytes:
  10.     return hashlib.pbkdf2_hmac(
  11.         hash_name='sha256',
  12.         password=password,
  13.         salt=salt,
  14.         iterations=rounds,
  15.         dklen=length
  16.     )
  17.  
  18. # All "pbkdf2$50000$50" users
  19. hashes = [
  20.  
  21. # Enter in username, passwd_hex, and salt_hex
  22.     {
  23.         "username": "admin",
  24.         "passwd_hex": "86a6137c28fda328c8e6abbcb53e4ac534dc9c010bb40468ce4b8f4bf882c0c1c1d2396d45e7ee16bc592260e74c8bbdd6f2",
  25.         "salt_hex":   "5d3f4c5b71ae98ebdc2520449f6c56f8",
  26.         "iterations": 50000,
  27.         "dklen": 50
  28.     },
  29.     {
  30.         "username": "user1",
  31.         "passwd_hex": "7f2acfe2bdc0afe9cbb54aac932230de2a1032e8bfcd5706308cabd41f75151b51278207c2c6141321655612c1c54ad24fac",
  32.         "salt_hex":   "e9facc6971e7440b5e04f10765e833d1",
  33.         "iterations": 50000,
  34.         "dklen": 50
  35.     }
  36.  
  37. # Add others as needed...
  38. ]
  39.  
  40. # Convert from hex to bytes
  41. for h in hashes:
  42.     h["passwd_bytes"] = binascii.unhexlify(h["passwd_hex"])
  43.     h["salt_bytes"]   = binascii.unhexlify(h["salt_hex"])
  44.     h["cracked"]      = False
  45.  
  46. wordlist = "/usr/share/wordlists/rockyou.txt"
  47. time_limit_seconds = 600  # 10 minutes per user
  48.  
  49. print(f"[+] Will spend up to {time_limit_seconds}s (={time_limit_seconds/60:.1f} min) per hash.")
  50. print("[+] Press 's' + Enter at any time to skip the current hash.\n")
  51.  
  52. def crack_one_hash(user_hash, wordlist_path, time_limit):
  53.     """
  54.    Attempt to crack a single user's PBKDF2-HMAC-SHA256 within 'time_limit' seconds.
  55.    Returns the plaintext password or None if not found / skipped / timed out.
  56.    """
  57.     user   = user_hash["username"]
  58.     target = user_hash["passwd_bytes"]
  59.     start_time = time.time()
  60.  
  61.     print(f"[*] Cracking {user} for up to {time_limit} seconds... (Press 's' + Enter to skip)")
  62.  
  63.     try:
  64.         with open(wordlist_path, "r", encoding="utf-8", errors="ignore") as f:
  65.             for line in f:
  66.                 # 1) Check if user wants to skip
  67.                 if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
  68.                     key_press = sys.stdin.read(1)
  69.                     if key_press.lower() == 's':
  70.                         print(f"[-] User pressed 's' to skip {user}. Moving on.\n")
  71.                         return None
  72.  
  73.                 # 2) Check time limit
  74.                 if (time.time() - start_time) > time_limit:
  75.                     print(f"[-] Time limit reached for {user}. Moving on.\n")
  76.                     return None
  77.  
  78.                 pwd_str = line.strip()
  79.                 if not pwd_str:
  80.                     continue
  81.  
  82.                 pwd_bytes = pwd_str.encode('utf-8')
  83.                 derived = derive_pbkdf2(
  84.                     password=pwd_bytes,
  85.                     salt=user_hash["salt_bytes"],
  86.                     rounds=user_hash["iterations"],
  87.                     length=user_hash["dklen"]
  88.                 )
  89.                 if derived == target:
  90.                     print(f"[!] SUCCESS: {user}'s password is '{pwd_str}'\n")
  91.                     return pwd_str
  92.  
  93.     except FileNotFoundError:
  94.         print(f"[!] Wordlist not found: {wordlist_path}")
  95.         return None
  96.  
  97.     # If finished dictionary with no match
  98.     print(f"[!] Dictionary exhausted for {user}, no match.\n")
  99.     return None
  100.  
  101. # ------------------------------------------------
  102. # Main Loop: process each user sequentially
  103. # ------------------------------------------------
  104. for user_hash in hashes:
  105.     if user_hash["cracked"]:
  106.         continue
  107.  
  108.     found_pass = crack_one_hash(user_hash, wordlist, time_limit_seconds)
  109.     if found_pass:
  110.         user_hash["cracked"] = True
  111.  
  112. print("[+] Done. Any user not shown as cracked wasn't found within time or dictionary.")
  113.  
  114.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement