こんにちわ。ヤスムラです。
前回メール本文をSlackに通知するGASを作ってみましたが、今回は応用編でメール本文から必要な部分だけを抜き取ってSlackに投稿してみたいと思います。
基本編を見ていない方は以下からお読み下さい。
必要な部分のみ抽出する方法
今回は正規表現を使って本文から必要な単語だけ抽出します。正規表現を使えば文字列のパターンマッチングを使って該当する文字列を抽出することが出来ます。使い方については以下サイトを参考にさせて頂きました。特に正規表現をチェックするサイトがとても役に立ちました。
今回通知するメール
今回はMicrosofot Defender for Endpoint(以下MDfE)から通知される脆弱性情報のメールを分解してSlackに通知されるようにしたいと思います。
MDfEから脆弱性情報を通知させる方法は以下記事を参考にして下さい。
使用するGAS
今回使用するGASはこちらです(☆の部分は適宜変更して下さい)
function myFunction(){
const labelname = 'complete' //☆ラベル名(事前に同じラベルを作成)
const subject = "New vulnerabilities notification from Microsoft Defender for Endpoint" //☆件名
let query = 'subject:' + subject + ',-label:' + labelname;
//対象メールの二次元配列を取得&Slack通知
let gmail = getGmail(query,labelname);
}
function getGmail(query,labelname) {
//☆Slack通知用Webhook
const webhookurl = 'https://hooks.slack.com/hogehoge';
//Gmailの履歴からマッチするメールを一覧化
let threads = GmailApp.search(query);
//let gmailInfo = new Array();
//一覧化したメールの件数分繰り返し
threads.forEach(function(thread) {
// スレッド内のメール一覧を取得
let messages = thread.getMessages();
// 対象メールに処理済ラベルを追加(次回以降通知させないようにするため)
const label = GmailApp.getUserLabelByName(labelname);
for (let n in messages) {
thread.addLabel(label);
}
//メールを一つずつ取り出す
messages.forEach(function(message) {
//メール本文
let plainBody = message.getPlainBody();
Logger.log(plainBody);
// メール本文からCVEを抽出
let cve = plainBody.match(/Vulnerability Name: (.*)/g);
let cve_allStaffs = cve.join("\n"); //配列を改行させる
let cve_replace = cve_allStaffs.replace(/Vulnerability Name: /g, ""); //不要な文字を除去
Logger.log(cve_replace)
//配列の数を取得
const counta = cve.length
let severity_cvss = plainBody.match(/Severity: ([\s\S]*?)Exposed devices/g);
let severity_cvss_array = severity_cvss.map((value) => {return value.replace(/Severity:/g, "").replace(/CVSS:/g, " / ").replace(/Exposed devices/g, "").replace(/\s/g, "")});
let severity_cvss_array_join = severity_cvss_array.join("\n"); //配列を改行させる
Logger.log(severity_cvss);
// メール本文からcvssを抽出
let cvss = plainBody.match(/CVSS: ([\s\S]*)Exposed devices/g);
Logger.log(cvss);
// メール本文から対象デバイス数を抽出
let device = plainBody.match(/Exposed devices: (.*)/);
Logger.log(device);
// メール本文からソフトウェア名を抽出
let software = plainBody.match(/Affected products: (.*)/);
Logger.log(software);
// メール本文からMicrofostDefenderのリンクURLを取得[対象ユーザの確認]
let executionuser = plainBody.match(/View recommendations >>([\s\S]*)Go to related vulnerabilities/s);
Logger.log(executionuser);
//Slackの投稿メッセージ作成
let blocks = [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "[脆弱性情報]\n以下脆弱性に該当する社内PCが検知されました\n社内IT担当は影響度と利用者を確認の上、必要に応じて対応願います\n\n"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*ソフトウェア名*\n" + software.splice(1) + "\n"
},
{
"type": "mrkdwn",
"text": "*対象デバイス数*\n" + device.splice(1) + "\n"
},
{
"type": "mrkdwn",
"text": "*CVE番号*\n" + cve_replace
},
{
"type": "mrkdwn",
"text": "*驚異/脆弱性スコア*\n" + severity_cvss_array_join
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "IT管理者は以下リンクから詳細確認願います\n" + executionuser[1] + "\n"
}
},
];
let payload = {'blocks': blocks};
let options = {'method' : 'POST', 'payload': JSON.stringify(payload)};
//Slack投稿
UrlFetchApp.fetch(webhookurl, options);
});
});
return(gmailInfo);
}
スクリプトの内容を簡単に説明するとまず以下の部分でメール本文をプレーンテキストで抽出します。
次に抽出した本文から使いたい部分を正規表現で抽出します。
あとは抽出した文字をSlackに通知させるように配置して完了です。
手順
スクリプトの内容以外は基本編と同じなのでそちら参考にGASとSlackを設定して下さい。うまくいけば以下のような通知BOTを作れるはずです。
注意点
当然ですがメール本文の内容が少しでも変わってしまうと、スクリプトが正しく動かなくなってしまうのでそこだけ注意です。あと今回のMDfEのアラートであればPower Automateでも似たようなことが出来るようです。あいにく当方は検証していませんが気になる方は以下参考にしてみて下さい。
まとめ
API連携でSlack通知できればそれが一番確実なんですが、どうしてもメール通知しか出来ないサービスはあります。またSlack標準のメール機能だと「本文全体が通知される」&「折りたたんだ状態で表示される」ので見にくいんですがこの方法なら必要な情報だけ表示させることが出来ます。
このやり方を理解すれば、いろんなメールに応用出来るのでぜひ色々試してみて下さい。
最後に、当方は副業情シスとして活動もしています。以下サイトに詳細記載しておりますので、もしご興味がある方いればお気軽にお問い合わせ(またはDM等)ご連絡お待ちしております。
また本記事について質問や・誤り等あればご連絡いただければ幸いです。
コメント