# GCP - AppEngine Privesc

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

## App Engine

For more information about App Engine check:

{{#ref}}
../gcp-services/gcp-app-engine-enum.md
{{#endref}}

### `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`** の権限は **不要** な場合があります。

You can find python code examples in [https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/appengine)

By default, the name of the App service is going to be **`default`**, and there can be only 1 instance with the same name.\
To change it and create a second App, in **`app.yaml`**, change the value of the root key to something like **`service: my-second-app`**

<details>
<summary>App Engine アプリケーションをデプロイ</summary>
```bash
cd python-docs-samples/appengine/flexible/hello_world
gcloud app deploy #Upload and start application inside the folder
```
</details>

少なくとも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 を更新する方法は次の通りです：

<details>
<summary>既存の App Engine アプリケーションを更新</summary>
```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
```
</details>

もし既に AppEngine を侵害していて、権限 **`appengine.applications.update`** と使用するサービスアカウントに対する **actAs** を持っている場合、AppEngine が使用するサービスアカウントを次のように変更できます：

<details>
<summary>App Engine のサービスアカウントを更新</summary>
```bash
gcloud app update --service-account=<sa>@$PROJECT_ID.iam.gserviceaccount.com
```
</details>

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

これらの権限があれば、**App Engine インスタンスに ssh でログインする**ことが可能です（タイプは **flexible**、standard ではありません）。一部の **`list`** および **`get`** 権限は**実際には必須ではない場合があります**。

<details>
<summary>SSH で App Engine インスタンスにログイン</summary>
```bash
gcloud app instances ssh --service <app-name> --version <version-id> <ID>
```
</details>

### `appengine.applications.update`, `appengine.operations.get`

これは単にGoogleがアプリケーションをセットアップする際に使用するバックグラウンドのサービスアカウントを変更するだけだと思うので、これを悪用してサービスアカウントを盗むことはできないと思います。

<details>
<summary>アプリケーションのサービスアカウントを更新</summary>
```bash
gcloud app update --service-account=<sa_email>
```
</details>

### `appengine.versions.getFileContents`, `appengine.versions.update`

これらの権限の使い方や有用性ははっきりしない（コードを変更すると新しいバージョンが作成されるため、単にコードやそのバージョンの IAM ロールを更新できるか分からないが、おそらく可能だと思われる。バケット内のコードを変更することでできるかもしれない）。

### Write Access over the buckets

前述のとおり、appengine versions は `staging.<project-id>.appspot.com` という形式のバケット内にいくつかのデータを生成する。GCP ユーザーは `appspot.com` ドメイン名を使ってバケットを作成する権限を持たないため、このバケットを事前に奪取することはできない点に注意。

しかし、このバケットに対して読み取り＆書き込みアクセスがあれば、バケットを監視して変更が行われるたびにできるだけ速やかにコードを改変することで、AppEngine バージョンに紐づく SA（サービスアカウント）へ権限昇格することが可能になる。こうして作成されたコンテナは **バックドア化されたコードを実行する** ことになる。

詳細および **PoC は以下のページの該当情報を確認してください**：

{{#ref}}
gcp-storage-privesc.md
{{#endref}}

### Write Access over the Artifact Registry

App Engine が Artifact Registry 内に docker イメージを作成するにもかかわらず、実際にこのサービス内のイメージを変更して App Engine インスタンスを削除（つまり新しいインスタンスがデプロイされる）しても、**実行されるコードは変わらない** ことが確認された。\
バケットと同様に Race Condition attack を行えば実行されるコードを上書きできる可能性はあるが、この点はテストされていない。

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