Skip to content

Commit

Permalink
GITBOOK-526: change request with no subject merged in GitBook
Browse files Browse the repository at this point in the history
  • Loading branch information
carlospolop authored and gitbook-bot committed Jan 17, 2024
1 parent 7d43b2d commit 3972795
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 35 deletions.
3 changes: 3 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
* [GCP - Cloud Functions Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-functions-post-exploitation.md)
* [GCP - Storage Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-storage-post-exploitation.md)
* [GCP - KMS Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-kms-post-exploitation.md)
* [GCP - App Engine Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-app-engine-post-exploitation.md)
* [GCP - Privilege Escalation](pentesting-cloud/gcp-security/gcp-privilege-escalation/README.md)
* [GCP - Apikeys Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-apikeys-privesc.md)
* [GCP - AppEngine Privesc](pentesting-cloud/gcp-pentesting/gcp-privilege-escalation/gcp-appengine-privesc.md)
Expand All @@ -103,6 +104,7 @@
* [GCP - Network Docker Escape](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-network-docker-escape.md)
* [GCP - local privilege escalation ssh pivoting](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-local-privilege-escalation-ssh-pivoting.md)
* [GCP - Persistence](pentesting-cloud/gcp-security/gcp-persistence/README.md)
* [GCP - App Engine Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-app-engine-persistence.md)
* [GCP - Cloud Functions Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-cloud-functions-persistence.md)
* [GCP - Storage Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-storage-persistence.md)
* [GCP - Secret Manager Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-secret-manager-persistence.md)
Expand Down Expand Up @@ -135,6 +137,7 @@
* [GCP - Storage Enum](pentesting-cloud/gcp-security/gcp-services/gcp-storage-enum.md)
* [GCP to Workspace Pivoting](pentesting-cloud/gcp-security/gcp-to-workspace-pivoting.md)
* [GCP - Unauthenticated Enum & Access](pentesting-cloud/gcp-security/gcp-unaunthenticated-enum-and-access/README.md)
* [GCP - App Engine Unauthenticated Enum](pentesting-cloud/gcp-security/gcp-unaunthenticated-enum-and-access/gcp-app-engine-unauthenticated-enum.md)
* [GCP - Cloud Functions Unauthenticated Enum](pentesting-cloud/gcp-security/gcp-unaunthenticated-enum-and-access/gcp-cloud-functions-unauthenticated-enum.md)
* [GCP - Storage Unauthenticated Enum](pentesting-cloud/gcp-security/gcp-unaunthenticated-enum-and-access/gcp-storage-unauthenticated-enum/README.md)
* [GCP - Public Buckets Privilege Escalation](pentesting-cloud/gcp-security/gcp-unaunthenticated-enum-and-access/gcp-storage-unauthenticated-enum/gcp-public-buckets-privilege-escalation.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ Other ways to support HackTricks:

</details>

## App Engine

For more information about App Engine check:

{% content-ref url="../gcp-services/gcp-app-engine-enum.md" %}
[gcp-app-engine-enum.md](../gcp-services/gcp-app-engine-enum.md)
{% endcontent-ref %}

### `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`

Those are the needed permissions to **deploy an App using `gcloud` cli**. Maybe the **`get`** and **`list`** ones could be **avoided**.
Expand All @@ -36,14 +44,6 @@ It's **possible to indicate the Service Account to use** but by default, the App

The URL of the application is something like `https://<proj-name>.oa.r.appspot.com/` or `https://<service_name>-dot-<proj-name>.oa.r.appspot.com`

### `logging.views.access`

With this permission it's possible to **see the logs of the App**:

```bash
gcloud app logs tail -s <name>
```

### `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`

With these permissions, it's possible to **login via ssh in App Engine instances** of type **flexible** (not standard). Some of the **`list`** and **`get`** permissions **could not be really needed**.
Expand All @@ -62,13 +62,16 @@ gcloud app update --service-account=<sa_email>
```
{% endcode %}

### `appengine.memcache.addKey`, `appengine.memcache.getKey`, `appengine.memcache.update`
### `appengine.versions.getFileContents`, `appengine.versions.update`

These permissions looks interesting to access App memcache.
Not sure how to use these permissions or if they are useful (note that when you change the code a new version is created so I don't know if you can just update the code or the IAM role of one, but I guess you should be able to, maybe changing the code inside the bucket??).

### `appengine.versions.getFileContents`, `appengine.versions.update`
### Write Access over the buckets

Even with write access over the buckets where the source code is located **it WASN'T possible to execute arbitrary code by modifying the source code and the `manifest.json`**.\
Maybe if you are monitoring the bucket and detect the moment where a new version is created and the source code and manifest is uploaded, it might be possible to change them so the new version uses the backdoored ones??

Not sure how to use these permissions or if they are useful (note that when you cange the code a new version is created so I don't know if you can just update the code or the IAM role of one, but I gues you shuold be able to, maybe changing the code inside the bucket??).
It also looks like container layers are stored in the bucket, maybe changing those?

<details>

Expand Down
75 changes: 54 additions & 21 deletions pentesting-cloud/gcp-pentesting/gcp-services/gcp-app-engine-enum.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,55 @@ Other ways to support HackTricks:

</details>

## App Engine Configurations <a href="#reviewing-app-engine-configurations" id="reviewing-app-engine-configurations"></a>
## Basic Information <a href="#reviewing-app-engine-configurations" id="reviewing-app-engine-configurations"></a>

Google [App Engine](https://cloud.google.com/appengine/) is **another** [**"serverless"**](https://about.gitlab.com/topics/serverless/) offering for hosting applications, with a focus on scalability, and enables developers to **build and deploy web applications and APIs** without having to worry about managing infrastructure.
\
Google Cloud Platform's (GCP) App Engine is a fully managed, **serverless platform** for developing and **hosting web applications at scale**. It's designed to **simplify your development process** and make it easy to manage applications, offering several key features and benefits:

1. **Serverless Architecture**: App Engine automatically handles the infrastructure, including server provisioning, configuration, and scaling. This allows developers to focus on writing code without worrying about the underlying hardware.
2. **Automatic Scaling**: App Engine can automatically scale your application in response to the amount of traffic it receives. It scales up to handle increased traffic and scales down when traffic decreases, helping optimize cost and performance.
3. **Language and Runtime Support**: It supports popular programming languages such as Java, Python, Node.js, Go, Ruby, PHP, and .NET. You can run your applications in a standard or a flexible environment. The standard environment is more restrictive but highly optimized for specific languages, while the flexible environment allows for more customization.
4. **Integrated Services**: App Engine integrates with many other GCP services, like Cloud SQL, Cloud Storage, Cloud Datastore, and more. This integration simplifies the architecture of cloud-based applications.
5. **Versioning and Traffic Splitting**: You can easily deploy multiple versions of your application and then split traffic among them for A/B testing or gradual rollouts.
6. **Application Insights**: App Engine provides built-in services such as logging, user authentication, and a suite of developer tools for monitoring and managing applications.
7. **Security**: It offers built-in security features like application versioning, SSL/TLS certificates for secure connections, and identity and access management.

### Firewall

A simple **firewall** can be configured for the instances running the Apps with the following options:

<figure><img src="../../../.gitbook/assets/image (3) (1) (2).png" alt=""><figcaption></figcaption></figure>

The default service account used by these Apps is **`<proj-name>@appspot.gserviceaccount.com`** and the SAs inside APP Engine instance **runs with cloud-platform scope (among others).**
### SA

The default service account used by these Apps is **`<proj-name>@appspot.gserviceaccount.com`** which have **Editor** role over the project and the SAs inside APP Engine instance **runs with cloud-platform scope (among others).**

### Storage

The source code and metadata is **automatically stored in buckets** with names such as `<proj-id>.appspot.com` and `staging.<proj-id>.appspot.com` and `<country>.<proj-id>.appspot.com`&#x20;

**Every file** of the App is stored with the **sha1 of the content as filename**:

<figure><img src="../../../.gitbook/assets/image (4) (6).png" alt=""><figcaption></figcaption></figure>

Inside the **`ae`** folder from `staging.<proj-id>.appspot.com`, **one folder per version exist** with the **source code** files and **`manifest.json`** file that **describes the components** of the App:

{% code overflow="wrap" %}
```json
{"requirements.txt":{"sourceUrl":"https://storage.googleapis.com/staging.onboarding-host-98efbf97812843.appspot.com/a270eedcbe2672c841251022b7105d340129d108","sha1Sum":"a270eedc_be2672c8_41251022_b7105d34_0129d108"},"main_test.py":{"sourceUrl":"https://storage.googleapis.com/staging.onboarding-host-98efbf97812843.appspot.com/0ca32fd70c953af94d02d8a36679153881943f32","sha1Sum":"0ca32fd7_0c953af9_4d02d8a ...
```
{% endcode %}

### URLs & Regions

The **default** web page will be exposed in the URL **`<project-uniq-name>.appspot.com`** although the URL of older versions will be slightly different, like **`https://20240117t001540-dot-<project-uniq-name>.uc.r.appspot.com`** (note the initial timestamp).

It might look like it's only possible to deploy 1 app engine web application per region, but it's possible to indicate **`service: <servicename>`** in the **`app.yml`** and create a new service (a new web). The format of the URL for this new web will be **`<servicename>-dot-<project-uniq-name>.appspot.com`**.

### Enumeration

{% hint style="danger" %}
Everytime you uploads a new code to the App, **a new version is created**. **All versions are stored** and they even have an **URL to access them**. So modifying the code of an old version could be a **great persistence tecnique**.
Every time you uploads a new code to the App, **a new version is created**. **All versions are stored** and they even have an **URL to access them**. So modifying the code of an old version could be a **great persistence technique**.
{% endhint %}

As with Cloud Functions, **there is a chance that the application will rely on secrets that are accessed at run-time via environment variables**. These variables are stored in an **`app.yaml`** file which can be accessed as follows:
Expand Down Expand Up @@ -67,30 +102,28 @@ gcloud app ssl-certificates list
gcloud app ssl-certificates describe <name>
```

### Storage

The source code is **automatically stored in buckets** with names such as `<proj-id>.appspot.com` or `staging.<proj-id>.appspot.com`
### Privilege Escalation

**Every file** of the App is stored with the **sha1 of the content as filename**:
{% content-ref url="../gcp-privilege-escalation/gcp-appengine-privesc.md" %}
[gcp-appengine-privesc.md](../gcp-privilege-escalation/gcp-appengine-privesc.md)
{% endcontent-ref %}

<figure><img src="../../../.gitbook/assets/image (4) (6).png" alt=""><figcaption></figcaption></figure>
### Unauthenticated Enum

Inside the **`ae`** folder, **one folder per version exist** with a **`manifest.json`** file that **describes the components** of the App:
{% content-ref url="../../gcp-security/gcp-unaunthenticated-enum-and-access/gcp-app-engine-unauthenticated-enum.md" %}
[gcp-app-engine-unauthenticated-enum.md](../../gcp-security/gcp-unaunthenticated-enum-and-access/gcp-app-engine-unauthenticated-enum.md)
{% endcontent-ref %}

{% code overflow="wrap" %}
```json
{"requirements.txt":{"sourceUrl":"https://storage.googleapis.com/staging.onboarding-host-98efbf97812843.appspot.com/a270eedcbe2672c841251022b7105d340129d108","sha1Sum":"a270eedc_be2672c8_41251022_b7105d34_0129d108"},"main_test.py":{"sourceUrl":"https://storage.googleapis.com/staging.onboarding-host-98efbf97812843.appspot.com/0ca32fd70c953af94d02d8a36679153881943f32","sha1Sum":"0ca32fd7_0c953af9_4d02d8a ...
```
{% endcode %}
### Post Exploitation

{% hint style="warning" %}
A principal capable of **writting this bucket** will be able to **overwrite** the code and make the app **execute arbitrary code**. (TODO: test this)
{% endhint %}
{% content-ref url="../../gcp-security/gcp-post-exploitation/gcp-app-engine-post-exploitation.md" %}
[gcp-app-engine-post-exploitation.md](../../gcp-security/gcp-post-exploitation/gcp-app-engine-post-exploitation.md)
{% endcontent-ref %}

### Privesc
### Persistence

{% content-ref url="../gcp-privilege-escalation/gcp-appengine-privesc.md" %}
[gcp-appengine-privesc.md](../gcp-privilege-escalation/gcp-appengine-privesc.md)
{% content-ref url="../../gcp-security/gcp-persistence/gcp-app-engine-persistence.md" %}
[gcp-app-engine-persistence.md](../../gcp-security/gcp-persistence/gcp-app-engine-persistence.md)
{% endcontent-ref %}

<details>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# GCP - App Engine Persistence

<details>

<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

Other ways to support HackTricks:

* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>

## App Engine

For more information about App Engine check:

{% content-ref url="../../gcp-pentesting/gcp-services/gcp-app-engine-enum.md" %}
[gcp-app-engine-enum.md](../../gcp-pentesting/gcp-services/gcp-app-engine-enum.md)
{% endcontent-ref %}

### Modify code

If yoi could just modify the code of a running version or create a new one yo could make it run your backdoor and mantain persistence.

### Old version persistence

**Every version of the web application is going to be run**, if you find that an App Engine project is running several versions, you could **create a new one** with your **backdoor** code, and then **create a new legit** one so the last one is the legit but there will be a **backdoored one also running**.

<details>

<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

Other ways to support HackTricks:

* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ For more info about Cloud Functions check:

### Persistence Techniques

* **Modify the code** of the Cloud Function
* **Modify the code** of the Cloud Function, even just the `requirements.txt`
* **Allow anyone** to call a vulnerable Cloud Function or a backdoor one
* **Trigger** a Cloud Function when something happens to infect something

Expand Down
Loading

0 comments on commit 3972795

Please sign in to comment.