- // ==UserScript==
- // @name BTAS
- // @namespace https://github.com/Mr-Tree-S/BTAS
- // @homepageURL https://github.com/Mr-Tree-S/BTAS
- // @version 3.8.6
- // @description Blue Team Auxiliary Script
- // @author Barry, Jack, Xingyu, Mike
- // @license Apache-2.0
- // @match https://login.microsoftonline.com/*
- // @match https://security.microsoft.com/*
- // @include https://caas*.com/*
- // @include https://mss*mss.com/*
- // @icon https://avatars.githubusercontent.com/u/42169240?v=4
- // @require https://code.jquery.com/jquery-3.6.4.min.js
- // @require https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js
- // @require https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js
- // @require https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.6/purify.min.js
- // @grant GM_registerMenuCommand
- // @grant GM_unregisterMenuCommand
- // @grant GM_xmlhttpRequest
- // @grant GM_openInTab
- // @grant GM_getValue
- // @grant GM_setValue
- // @connect raw.githubusercontent.com
- // @connect myqcloud.com
- // @connect 172.18.4.200
- // @run-at document-idle
- // @grant GM_addStyle
- // ==/UserScript==
-
- var $ = window.jQuery;
-
- /**
- * This function creates and displays a flag using AJS.flag function
- * @param {string} type - The type of flag, can be one of the following: "success", "info", "warning", "error"
- * @param {string} title - The title of the flag
- * @param {string} body - The body of the flag
- * @param {string} close - The close of flag, can be one of the following: "auto", "manual", "never"
- */
- function security_microsoft() {
- var queryString = window.location.search;
- var urlParams = new URLSearchParams(queryString);
- var current_domain = urlParams.get('current');
- var customers = {};
- const cachedWebsiteContent = GM_getValue('cachedWebsiteContent', null);
- console.log(cachedWebsiteContent);
- cachedWebsiteContent.forEach((item, index) => {
- if (item && item['category'] == 'mde' && item['url']) {
- customers[item['name']] = item['url'];
- }
- });
- var customer = customers[current_domain];
- if (customer) {
- console.log('account11', customer);
- } else {
- customer = current_domain;
- }
- if (current_domain == 'none') {
- let urls = localStorage.getItem('urls').toString().split(',');
- for (var i = 0; i < urls.length; i++) {
- if (i == 0) {
- window.location.href = urls[i];
- } else {
- GM_openInTab(urls[i], {
- active: false, // 设置为 false,以在后台打开,不激活新标签页
- insert: true // 设置为 true,将新标签页插入到当前标签页之后
- });
- }
- }
- localStorage.removeItem('urls');
- }
- setTimeout(() => {
- document.getElementById('O365_MainLink_Me').click();
- console.log('account1');
- }, 9000);
- setTimeout(() => {
- var account = document.getElementById('mectrl_currentAccount_secondary').textContent;
- console.log(account, customer);
- if (
- !account.includes(customer) &&
- !customer.includes(account.split('@')[1].split('.')[0]) &&
- current_domain != 'none'
- ) {
- let urls = [];
- urlParams.forEach(function (value, key) {
- if (key.includes('url')) {
- urls.push(value);
- }
- });
- localStorage.setItem('urls', urls);
- document.getElementById('mectrl_body_signOut').click();
- } else {
- urlParams.forEach(function (value, key) {
- if (key.includes('url')) {
- GM_openInTab(value, {
- active: false, // 设置为 false,以在后台打开,不激活新标签页
- insert: true // 设置为 true,将新标签页插入到当前标签页之后
- });
- }
- });
- window.close();
- }
- }, 9900);
- }
-
- function switch_user_microsoft() {
- console.log('login.microsoft', $('#idDiv_SAOTCC_Title').text().trim());
- if ($('#login_workload_logo_text').text().trim() == '您已注销帐户') {
- window.location.href = 'https://security.microsoft.com/homepage?¤t=none';
- }
- if (document.title == '登录到您的帐户' && $('#idDiv_SAOTCC_Title').text().trim() != '输入验证码') {
- setTimeout(() => {
- var inputElement = document.querySelectorAll('.form-control')[0];
- inputElement.addEventListener('input', function (event) {
- var inputValue = inputElement.value;
- if (inputValue.includes('@')) {
- $('#idSIButton9').click();
- setTimeout(() => {
- $('#idSIButton9').click();
- }, 1500);
- }
- });
- }, 1600);
- } else {
- setTimeout(() => {
- var inputElement = document.querySelectorAll('.form-control')[0];
- inputElement.addEventListener('keyup', function (event) {
- var inputValue = inputElement.value;
- console.log(inputValue); // 打印当输入框的内容在元素失去焦点时的值
- if (inputValue.length == 6) {
- $('#idSubmit_SAOTCC_Continue').click();
- }
- });
- }, 800);
- }
- }
-
- function addCss() {
- const ss = $(`
- <style>
- .red_highlight{
- color:red;
- font-weight: bold;
- }
- .black_highlight{
- color:black;
- font-weight: bold;
- }
- .aui-dropdown2{
- max-width: 550px !important;
- }
- .aui-dropdown2 .aui-dropdown2-checkbox, .aui-dropdown2 .aui-dropdown2-radio, .aui-dropdown2 .aui-icon-container {
- padding-top: 10px;
- padding-left: 35px;
- }
- #reply{
- column-count: 2;
- }
- .aui-flag{
- border: 4px solid rgb(222,184,135) ;
- }
- .fix-button{
- background-color: rgb(222,184,135);
- color:white;
- z-index: 100;
- margin-right: 12px;
- }
-
- </style>
- `);
- $('head').append(ss);
-
- function hideAllFlag() {
- $('.aui-flag').toggle();
- }
- const button = $('<div>')
- .attr('id', 'hide-reminder')
- .addClass('aui-button toolbar-trigger fix-button aui-button-primary')
- .append($('<span>').addClass('trigger-label').text('NOTICE'))
- .click(hideAllFlag);
-
- const checkExist = setInterval(function () {
- const targetDiv = document.getElementById('aui-flag-container');
- const toolbar = $('.aui-header-secondary');
-
- if (targetDiv) {
- toolbar.prepend(button);
- clearInterval(checkExist); // 停止检查
- }
- }, 100); // 每100毫秒检查一次
- }
-
- function showFlag(type, title, body, close) {
- AJS.flag({
- type: type,
- title: DOMPurify.sanitize(title),
- body: DOMPurify.sanitize(body),
- close: close
- });
-
- // addButton('hide-reminder', 'Hide Reminder', hideAllFlag);
-
- // 为 flag 的内容区域添加滚动条样式
- const flagBody = $('#aui-flag-container > div > div');
- flagBody.css({
- 'overflow': 'auto',
- 'max-height': '150px' // 添加最大高度,超出部分将出现滚动条
- });
-
- // 为 flag 的container区域添加滚动条样式
- const flagContainer = $('#aui-flag-container');
- flagContainer.css({
- 'overflow': 'auto',
- 'overflow-x': 'hidden', //隐藏水平滚动条
- 'max-height': '90%' // 添加最大高度,超出部分将出现滚动条
- });
- }
-
- /**
- * This function shows alert message in dialog and create a copy button
- * @param {string} body - Alert Message String
- */
- function showDialog(body) {
- // avoid editor treat double backslash as breakline and avoid xss attack
- body = DOMPurify.sanitize(body.replace(/\\\\/g, '\\'));
-
- // Create custom dialog style
- const customDialogContent = AJS.$(`<section
- id="custom-dialog"
- class="aui-dialog2 aui-dialog2-large aui-layer"
- role="dialog"
- tabindex="-1"
- data-aui-modal="true"
- data-aui-remove-on-hide="true"
- aria-labelledby="dialog-show-button--heading"
- aria-describedby="dialog-show-button--description"
- hidden
- >
- <header class="aui-dialog2-header">
- <h2 class="aui-dialog2-header-main" id="dialog-show-button--heading">Description</h2>
- </header>
- <div class="aui-dialog2-content" id="dialog-show-button--description">
- <p style="word-wrap: break-word; white-space: pre-line">${body}</p>
- </div>
- <footer class="aui-dialog2-footer">
- <div class="aui-dialog2-footer-actions">
- <button id="dialog-copy-button" class="aui-button aui-button-primary">Copy</button>
- <button id="dialog-close-button" class="aui-button aui-button-link">Close</button>
- </div>
- </footer>
- </section>`);
-
- // Show the dialog
- AJS.dialog2(customDialogContent).show();
-
- // Close the dialog
- AJS.$('#dialog-close-button').on('click', function (e) {
- e.preventDefault();
- AJS.dialog2(customDialogContent).hide();
- //tippy.destroy();
- });
-
- // Init tippy instance
- tippy('#dialog-copy-button', {
- content: 'Copy Success',
- placement: 'bottom',
- trigger: 'click'
- });
-
- // Copy description text
- AJS.$('#dialog-copy-button').on('click', function () {
- const textToCopy = customDialogContent.find('#dialog-show-button--description').text().trim();
-
- // Create Clipboard instance
- const clipboard = new ClipboardJS('#dialog-copy-button', {
- text: function () {
- return textToCopy;
- }
- });
-
- // Copy success
- clipboard.on('success', function (e) {
- clipboard.destroy();
- e.clearSelection();
- });
- });
- }
-
- /**
- * This function registers a Tampermonkey search menu command
- * @param {Array} searchEngines - Search engines array containing the Jira, VT, AbuseIPDB
- */
- function registerSearchMenu() {
- console.log('#### Code registerSearchMenu run ####');
- const LogSourceDomain = $('#customfield_10223-val').text().trim() || '*';
- const Host = function () {
- let search = {
- 'Source IP(s) and Hostname(s)': $('#customfield_10206-val').text().trim(),
- 'Destination IP(s) and Hostname(s)': $('#customfield_10208-val').text().trim()
- };
- if (search['Source IP(s) and Hostname(s)']) {
- return `AND 'Source IP(s) and Hostname(s)' ~ '${search['Source IP(s) and Hostname(s)']}'`;
- } else if (search['Destination IP(s) and Hostname(s)']) {
- return `AND 'Destination IP(s) and Hostname(s)' ~ '${search['Destination IP(s) and Hostname(s)']}'`;
- } else {
- return '';
- }
- };
- let cachedEntry = GM_getValue('cachedEntry', null);
-
- let url = `${
- cachedEntry['hk']
- }/issues/?jql=text ~ "%s" AND "Log Source Domain" ~ "%D" ${Host()} ORDER BY created DESC`;
- if (window.location.href.includes(cachedEntry['macao'].split('//')[1])) {
- url = `${cachedEntry['macao']}/issues/?jql=text ~ "%s" ORDER BY created DESC`;
- }
- console.log('===url', url);
-
- const searchEngines = [
- {
- name: 'Jira',
- url: url
- },
- { name: 'VT', url: 'https://www.virustotal.com/gui/search/%s' },
- { name: 'AbuseIPDB', url: 'https://www.abuseipdb.com/check/%s' },
- {
- name: 'Base64 Decode',
- url: `https://icyberchef.com/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)&input=%b`
- }
- ];
- searchEngines.forEach((engine) => {
- GM_registerMenuCommand(engine.name, () => {
- const selectedText = window.getSelection().toString();
- const searchURL = engine.url
- .replace('%s', selectedText)
- .replace('%D', LogSourceDomain)
- .replace('%b', btoa(selectedText));
- if (selectedText.length === 0) {
- showFlag('error', 'No text selected', 'Please select some text and try again', 'auto');
- } else {
- window.open(searchURL, '_blank');
- }
- });
- });
- }
-
- /**
- * This function registers custom add/remove quick reply menus in Tampermonkey
- * Add custom reply: input custom reply and store in local
- * Remove quick reply: remove all local storage custom replies
- */
- function registerCustomQuickReplyMenu() {
- GM_registerMenuCommand('Add Custom Quick Reply', () => {
- const userInput_name = prompt('Enter saved quick reply name (the name should be unique)').toString();
- const userInput_reply = prompt('Enter a custom quick reply (<br> is used for line break)').toString();
- if (userInput_name !== null && userInput_reply !== null) {
- const key = `customReply_${userInput_name}`;
- // local save
- localStorage.setItem(key, userInput_reply);
- }
- });
-
- GM_registerMenuCommand('Remove Custom Quick Reply', () => {
- for (let i = 0; i < localStorage.length; i++) {
- const key = localStorage.key(i);
- if (key.startsWith('customReply_')) {
- localStorage.removeItem(key);
- }
- }
- showFlag('success', 'Cleared All Custom Replies', '', 'auto');
- });
- GM_registerMenuCommand('MDE Assist', () => {
- let MDE_Assist_ = localStorage.getItem('MDE_Assist');
- const MDE_Assist = prompt(
- 'Whether MDE Assist is enabled(Example:enable 1, disable 0)',
- MDE_Assist_
- ).toString();
- localStorage.setItem('MDE_Assist', MDE_Assist);
- });
- }
-
- /**
- * This function create a Quick Reply button in editor
- */
- function QuickReply() {
- const replyButton = `<button class="aui-button aui-dropdown2-trigger" aria-controls="is-radio-checked">Quick Reply</button>
- <aui-dropdown-menu id="is-radio-checked">
- <aui-section id="reply">
- <aui-item-radio interactive>Close ticket</aui-item-radio>
- <aui-item-radio interactive>Monitor ticket</aui-item-radio>
- <aui-item-radio interactive>Waiting ticket</aui-item-radio>
- <aui-item-radio interactive>Waiting Full Scan</aui-item-radio>
- <aui-item-radio interactive>Ask for Whitelist</aui-item-radio>
- <aui-item-radio interactive>Whitelist Done</aui-item-radio>
- <aui-item-radio interactive>Agent recover</aui-item-radio>
- <aui-item-radio interactive>Leaked Credentials</aui-item-radio>
- <aui-item-radio interactive>Compromised Accounts</aui-item-radio>
- <aui-item-radio interactive>Log resume</aui-item-radio>
- <aui-item-radio interactive>关闭工单</aui-item-radio>
- <aui-item-radio interactive>Haeco high severity</aui-item-radio>
- <aui-item-radio interactive>Haeco medium severity</aui-item-radio>
- <aui-item-radio interactive>Haeco low severity</aui-item-radio>
- </aui-section>
- </aui-dropdown-menu>`;
- const commentBar = $($('.aui-toolbar2-primary')[1]);
- commentBar.append(replyButton);
-
- const commentBarSection = document.querySelector('aui-section#reply');
- const replyComment = {
- 'Close ticket': 'Dear Customer,<br>Thanks for your reply, we will close this ticket.<br>Best Regards.',
- 'Monitor ticket': 'Dear Customer,<br>Thanks for your reply, we will keep monitor.<br>Best Regards.',
- 'Waiting ticket': 'Dear Customer,<br>Thanks, we look forward to hearing from you.',
- 'Waiting Full Scan':
- 'Dear Customer,<br>Full scan have been triggered , if suspicious files detected new MDE alert/ticket will be created.',
- 'Ask for Whitelist': 'Dear Customer,<br>Can we add the ticket to white list?<br>Best Regards.',
- 'Whitelist Done':
- 'Dear Customer,<br>We have informed the relevant parties to add this ticket to the white list and will close this ticket<br>Best Regards.',
- 'Haeco high severity':
- '<h2><strong><span style="color: red;" data-mce-style="color: red;"><samp>[The ticket is escalated to High Severity]</samp></span></strong></h2><br>',
- 'Haeco medium severity':
- '<h2><span style="color: rgb(255, 171, 0);" data-mce-style="color: #ffab00;"><strong><samp>[The ticket is escalated to Medium Severity]</samp></strong></span></h2><br>',
- 'Haeco low severity':
- '<h2><span style="color: rgb(76, 154, 255);" data-mce-style="color: #4c9aff;"><strong><samp>[The ticket is de-escalated to Low Severity]</samp></strong></span></h2><br>',
- 'Leaked Credentials':
- '<p>Dear Client,</p><p>Our Cyber Threat Intelligence investigated the incident and found <Number> leaked credentials related to your organization exposed in dark web. The credentials are listed below:</p><table width="962" class="mce-item-table"><tbody><tr><td width="137"><div><p><strong>EMAIL/USERNAME</strong></p></div></td><td width="137"><div><p><strong>PASSWORD TYPE</strong></p></div></td><td width="137"><div><p><strong>PASSWORD</strong></p></div></td><td width="137"><div><p><strong>SOURCE</strong></p></div></td><td width="137"><div><p><strong>PRICE</strong></p></div></td><td width="137"><div><p><strong>POSTED DATE</strong></p></div></td><td width="137"><div><p><strong>SERVICE</strong></p></div></td></tr><tr><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td></tr></tbody></table><p>[Source Detail from Kela]</p><p><SOURCE Details/Description></p><p>[Service if disclose need check]</p><p>As per our open-source investigation through passive means, we observe that:</p><p>< SERVICE> appear to be <SERVICE USAGE></p><p>[Recommendation]</p><p>We recommend confirming that the service coverage is to customers only, or whether it also includes staff and/or third-party, and evaluate if accounts with administrative privileges require a password change. We also recommend to heighten monitoring of customer login to indicate anomalies in location or timing, and review password policies and evaluate if there is a need to strengthen (e.g., mandate password rotation regularly). A further recommendation is to reach out to these account holders if the accounts are still active, and request that they change their passwords.</p><p>Please do not hesitate to reach out to us if you have any queries. Thank you.</p><p>Best Regards,<br>Cyber Threat Intelligence Team</p>',
- 'Compromised Accounts':
- '<p>Dear Client,</p><p>Our Cyber Threat Intelligence investigated the incident and found <Number> compromised accounts related to your organisation exposed in dark web. The credentials are listed below:</p><table width="962" class="mce-item-table"><tbody><tr><td width="137"><div><p><strong>EMAIL/USERNAME</strong></p></div></td><td width="137"><div><p><strong>PASSWORD TYPE</strong></p></div></td><td width="137"><div><p><strong>PASSWORD</strong></p></div></td><td width="137"><div><p><strong>SOURCE</strong></p></div></td><td width="137"><div><p><strong>PRICE</strong></p></div></td><td width="137"><div><p><strong>POSTED DATE</strong></p></div></td><td width="137"><div><p><strong>SERVICE</strong></p></div></td></tr><tr><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td><td width="137"><br data-mce-bogus="1"></td></tr></tbody></table><p>[Source Detail from Kela]</p><p><SOURCE Details/Description></p><p>[Service if disclose need check]</p><p>As per our open-source investigation through passive means, we observe that:</p><p>< SERVICE> appear to be <SERVICE USAGE> </p><p>[Recommendation]</p><p>We recommend confirming that the service coverage is to customers only, or whether it also includes staff and/or third-party, and evaluate if accounts with administrative privileges require a password change. We also recommend to heighten monitoring of customer login to indicate anomalies in location or timing, and review password policies and evaluate if there is a need to strengthen (e.g., mandate password rotation regularly). A further recommendation is to reach out to these account holders if the accounts are still active, and request that they change their passwords.</p><p>Please do not hesitate to reach out to us if you have any queries. Thank you.</p><p>Best Regards,<br>Cyber Threat Intelligence Team</p>',
- 'Log resume':
- 'Dear Customer,<br>Thanks for your reply, <br>Log resumed, we will close this ticket.<br>Best Regards.',
- 'Agent recover':
- 'Dear Customer,<br>Thanks for your reply,<br>The agent is now active and we will close this case<br>Best Regards.',
- '关闭工单': '尊敬的客户,<br>感谢您的回复,我们将关闭此工单。 <br>祝您生活愉快。<br>'
- };
-
- // Check local storage at initialization time
- function getAllCustomReply() {
- for (let i = 0; i < localStorage.length; i++) {
- const key = localStorage.key(i);
- if (key.startsWith('customReply_')) {
- const storedReply = localStorage.getItem(key).toString();
- const storeReplyName = key.split('_')[1].toString();
- replyComment[storeReplyName] = storedReply;
- $('#reply').append(`<aui-item-radio interactive>${storeReplyName}</aui-item-radio>`);
- }
- }
- }
- getAllCustomReply();
-
- try {
- if (commentBarSection !== null) {
- commentBarSection.addEventListener('change', function (e) {
- if (e.target.hasAttribute('checked')) {
- tinymce.activeEditor.setContent('');
- let replyValue = replyComment[e.target.textContent];
- tinymce.activeEditor.execCommand('mceInsertContent', false, replyValue);
- }
- });
- }
- } catch (error) {
- console.error(error);
- }
- }
-
- /**jsonView */
- function jsonToTree(data) {
- let flag = false;
- let html = '<ul class="code-java" style="list-style-type: none;margin-top: 0px;padding-left: 20px;">';
- if (Array.isArray(data)) {
- let temp = '[';
- data.forEach((element) => {
- temp += jsonToTree(element);
- });
- html += temp + '],';
- } else if (data != null && typeof data === 'object' && Object.keys(data).length !== 0) {
- flag = true;
- for (let key in data) {
- if (data.hasOwnProperty(key)) {
- html += '<li class="code-quote">"' + key + '": ';
- if (Array.isArray(data[key])) {
- let temp = '[';
- data[key].forEach((element) => {
- temp += jsonToTree(element);
- });
- html += temp + '],';
- } else if (typeof data[key] === 'object') {
- try {
- if (Object.keys(data[key]).length == 0) {
- html += '{},';
- } else {
- const str = jsonToTree(data[key]);
- html += str;
- }
- } catch (TypeError) {
- html += '"",';
- }
- } else {
- html += '"' + data[key].toString() + '",';
- }
- html += '</li>';
- }
- }
- } else {
- html += '"' + data.toString() + '",';
- }
- if (flag === true) {
- html = '{' + html + '},';
- }
- html += '</ul>';
- return html;
- }
-
- function ToWhitelist() {
- const summary = $('#summary-val').text().trim();
- var LogSourceDomain = $('#customfield_10223-val').text().trim();
- let DecoderName = $('#customfield_10807-val').text().trim().toLowerCase();
- let Component = 'Wazuh';
- if (DecoderName.includes('mde') || DecoderName.includes('m365')) {
- Component = 'MDE';
- }
- if (DecoderName.includes('cortex')) {
- Component = 'Cortex';
- }
- let whitelist = {
- summary: summary,
- LogSourceDomain: LogSourceDomain,
- Component: Component,
- MSS: window.location.href
- };
- localStorage.setItem('whitelist', JSON.stringify(whitelist));
- let cachedEntry = GM_getValue('cachedEntry', null);
- window.open(`${cachedEntry['hk']}/plugins/servlet/desk/portal/2/create/100`, '_blank');
- }
-
- /**
- * This function registers two Tampermonkey exception menu command
- * Add Exception: adds the currently selected text to an exception list stored in local storage
- * Clear Exception: clears the exception list from local storage
- */
- let exceptionKey = localStorage.getItem('exceptionKey')?.split(',') || [];
- let notifyKey = [...exceptionKey];
- function registerExceptionMenu() {
- console.log('#### Code registerExceptionMenu run ####');
- GM_registerMenuCommand('Add Exception', () => {
- const selection = window.getSelection().toString().trim();
- if (!selection) {
- showFlag('error', 'No Issue Key selected', '', 'auto');
- return;
- }
- exceptionKey.push(selection);
- localStorage.setItem('exceptionKey', exceptionKey.toString());
- showFlag('success', '', `Added <strong>${selection}</strong> successfully`, 'auto');
- });
-
- GM_registerMenuCommand('Clear Exception', () => {
- localStorage.setItem('exceptionKey', '');
- exceptionKey = notifyKey = [];
- showFlag('success', 'Cleared All Issue Key', '', 'auto');
- });
-
- GM_registerMenuCommand('JsonViewer', () => {
- var isJson = function (str) {
- try {
- JSON.parse(str);
- } catch (e) {
- showFlag('error', 'Please select json format data', '', 'auto');
- return false;
- }
- return true;
- };
- let selection = window.getSelection().toString().trim();
- if (!selection) {
- showFlag('error', 'No Issue Key selected', '', 'auto');
- return;
- } else if (isJson(selection)) {
- var jsonData = jsonToTree(JSON.parse(selection));
- /** var jsonView = document.createElement('pre');
- jsonView.textContent = JSON.stringify(jsonData,null,2);
- **/
- showDialog(jsonData, 'Json Format');
- }
- });
- }
-
- /**
- * This function creates audio and checkbox controls and adds them to the Jira share button's parent node
- * @returns {Object} Object containing references to the audio control and audio checkbox, keep checkbox, prompt checkbox
- */
- // ## In the future, the alert sound will be migrated to another server, and more fun music will be added.
- function createNotifyControls() {
- console.log('#### Code createNotifyControls run ####');
- const operationsBar = $('div.saved-search-operations.operations');
- const audioControl = $('<span></span>');
-
- function createAudioControl(parentNode) {
- const currentDate = new Date();
- const audioURL =
- currentDate.getHours() >= 9 && currentDate.getHours() < 21
- ? 'https://gitee.com/aspirepig/aspirepig/raw/master/12221.wav'
- : 'https://gitee.com/aspirepig/aspirepig/raw/master/alerts.wav';
- audioControl.html(`<audio id="myAudio" src="${audioURL}" type="audio/mpeg" controls></audio>`);
- parentNode.prepend(audioControl);
- }
-
- function createCheckbox(parentNode, localStorageKey, checkStatus) {
- const checkbox = $('<span></span>');
- const value = localStorage.getItem(localStorageKey);
- checkbox.html(
- `<input type="checkbox" name="${localStorageKey}" ${
- value == 'true' ? 'checked' : checkStatus ? 'checked' : ''
- }>${localStorageKey}`
- );
- checkbox.find('input').on('click', () => {
- localStorage.setItem(localStorageKey, checkbox.find('input').prop('checked'));
- });
- parentNode.prepend(checkbox);
- return checkbox;
- }
- createAudioControl(operationsBar);
- const audioCheckbox = createCheckbox(operationsBar, 'audioNotify', false);
- const keepCheckbox = createCheckbox(operationsBar, 'keepAudio', false);
- const promptCheckbox = createCheckbox(operationsBar, 'prompt', true);
-
- return { audioControl, audioCheckbox, keepCheckbox, promptCheckbox };
- }
-
- /**
- * Check for updates in the issues list and play a sound if new issues are found
- * @param {Object} NotifyControls - Object containing the audio control, audio checkbox, keep checkbox, prompt checkbox
- */
- function checkupdate(NotifyControls) {
- console.log('#### Code checkupdate run ####');
- const { audioControl, audioCheckbox, keepCheckbox, promptCheckbox } = NotifyControls;
- const table = $('tbody');
- if (!table.length) return;
- let cachedEntry = GM_getValue('cachedEntry', null);
-
- let Tickets = '';
- table.find('tr').each(function () {
- const summary = $(this).find('.summary p').text().trim();
- const issuekey = $(this).find('.issuekey a.issue-link').attr('data-issue-key');
- if (!notifyKey.includes(issuekey)) {
- notifyKey.push(issuekey);
- Tickets += `${summary}==${issuekey}\n`;
- }
- });
- if (Tickets || keepCheckbox.find('input').prop('checked')) {
- if (audioCheckbox.find('input').prop('checked')) {
- audioControl.find('audio').get(0).currentTime = 0;
- audioControl.find('audio').get(0).play();
- }
- }
-
- $('.aui-banner').remove();
- let overdueTickets = '';
- table.find('tr').each(function () {
- const issuekey = $(this).find('.issuekey a.issue-link').attr('data-issue-key');
- const datetime = new Date($(this).find('.updated time').attr('datetime'));
- const currentTime = new Date();
- const diffMs = currentTime - datetime;
- const diffMinutes = Math.floor(diffMs / 60000);
- if (diffMinutes > 30 && diffMinutes < 120) {
- overdueTickets += `<a href="${cachedEntry['hk']}/browse/${issuekey}" target="_blank">${issuekey}</a>, `;
- }
- });
- if (overdueTickets && promptCheckbox.find('input').prop('checked')) {
- GM_addStyle(`
- .aui-banner.aui-banner-warning {
- background-color: #ffab00 !important;
- color: black !important;
- }
- `);
- AJS.banner({
- body: `Ticket: ${overdueTickets}<br>30 minutes have passed since the ticket's status changed, please handle it as soon as possible`,
- type: 'warning'
- });
- }
- }
-
- /**
- * This function checks for specific keywords within a string
- * Advises the user to double-check and contact L2 or TL if suspicious.
- */
- function checkKeywords() {
- console.log('#### Code checkKeywords run ####');
- function check(keywords) {
- const rawLog = $('#customfield_10219-val').text().trim().toLowerCase();
- const summary = $('#summary-val').text().trim().toLowerCase();
- let Raw_Crotex_alert = $('.code-java').text().trim().toLowerCase();
-
- for (const keyword of keywords) {
- if (
- rawLog.includes(keyword['keyword'].toLowerCase()) ||
- Raw_Crotex_alert.includes(keyword['keyword'].toLowerCase()) ||
- summary.includes(keyword['keyword'].toLowerCase())
- ) {
- AJS.banner({
- body: `\"${keyword['keyword']}\" was found in the ticket, it is maybe used for "${keyword['remark']}", please double-check and contact L2 or TL if suspicious.`
- });
- }
- }
- }
- function fetchData(url, apiKey) {
- const cachedKeywordsContent = GM_getValue('cachedKeywordsContent', null);
- const cachedWebsiteContent = GM_getValue('cachedWebsiteContent', null);
- const cachedWhitehashContent = GM_getValue('cachedWhitehashContent', null);
- GM_xmlhttpRequest({
- method: 'GET',
- url: url,
- headers: {
- 'api-key': apiKey
- },
- timeout: 4000, // 超过4秒未获取到文件则使用缓存文件
- onload: function (response) {
- if (response.status === 200) {
- const data = JSON.parse(response.responseText)['data'];
-
- console.log(data);
- if (cachedKeywordsContent == null) {
- GM_setValue('cachedKeywordsContent', data['keywords']);
- }
- if (cachedWebsiteContent == null) {
- GM_setValue('cachedWebsiteContent', data['website']);
- let cachedEntry = {};
- data['website'].forEach((item, index) => {
- if (item && item['name'] == 'hk' && item['url']) {
- cachedEntry['hk'] = item['url'];
- }
- if (item && item['name'] == 'macao' && item['url']) {
- cachedEntry['macao'] = item['url'];
- }
- GM_setValue('cachedEntry', cachedEntry);
- });
- }
- if (cachedWhitehashContent == null) {
- GM_setValue('cachedWhitehashContent', data['whitehash']);
- }
- } else {
- console.error('Error fetching cachedContent:', response.status);
- }
- },
- ontimeout: function () {
- if (cachedKeywordsContent == null || cachedWebsiteContent == null || cachedWhitehashContent == null) {
- showFlag('Error', 'BTAS缓存数据获取失败', '未连接到 VPN,请连接后刷新页面', 'auto');
- }
- },
- onerror: function (error) {
- console.error('Error:', error);
- }
- });
- }
-
- const url = 'https://172.18.4.200/api/7vVKD9hF/message/';
- const apiKey = 'Tnznjha3yhJgA7YG';
- const cachedKeywordsContent = GM_getValue('cachedKeywordsContent', null);
- if (cachedKeywordsContent == null) {
- fetchData(url, apiKey);
- }
- check(cachedKeywordsContent);
- }
-
- /**
- * This function is used for checking ATT&CK field
- */
- function checkATTCK() {
- const status = $('#opsbar-transitions_more > span').text().trim();
- const attck = $('#rowForcustomfield_10220 > div > strong > label').text();
- if (status == 'Waiting for customer' && attck == '') {
- AJS.banner({ body: `The ATT&CK field is not filled in` });
- }
- }
-
- /**
- * This function is used for popping up MSS ticket considerations when clicked "Edit" and "Resolved" button or page loading.
- * Ticket Considerations file is store in cloud server
- * @param {Object} pageData - Gets the specified fields from the jira page
- */
- function ticketNotify(pageData) {
- console.log('#### Code ticketNotify run ####');
-
- function fetchOrgNotifydict() {
- // 从本地存储获取缓存的文件内容和上次更新时间
- const cachedContent = GM_getValue('cachedFileContent', null);
-
- GM_xmlhttpRequest({
- method: 'GET',
- url: 'https://172.18.4.200/api/7vVKD9hF/notifys/',
- headers: {
- 'api-key': 'Tnznjha3yhJgA7YG'
- },
- timeout: 4000, // 超过4秒未获取到文件则使用缓存文件
- onload: function (response) {
- if (response.status === 200) {
- const data = JSON.parse(response.responseText)['data'];
-
- // 本地无缓存,第一次获取文件保存到本地
- if (cachedContent == null) {
- // 更新本地存储中的文件内容和更新时间
- GM_setValue('cachedFileContent', data);
-
- checkNotify(data.items, pageData);
- }
-
- // 如果本地存储中有缓存,并且文件内容有变化
- if (cachedContent !== null && JSON.stringify(cachedContent) !== JSON.stringify(data)) {
- // 更新本地存储中的文件内容
- GM_setValue('cachedFileContent', data);
-
- // 使用最新文件
- checkNotify(data.items, pageData);
- }
-
- // 本地存在缓存,且内容相同则使用缓存文件
- if (cachedContent !== null && JSON.stringify(cachedContent) == JSON.stringify(data)) {
- checkNotify(cachedContent.items, pageData);
- }
- } else {
- console.error('Error fetching orgNotifydict:', response.status);
- }
- },
- ontimeout: function () {
- if (cachedContent !== null) {
- checkNotify(cachedContent.items, pageData);
- } else {
- showFlag('Error', '文件获取失败', '未连接到 VPN,请连接后刷新页面', 'auto');
- }
- },
- onerror: function (error) {
- console.error('Error:', error);
- }
- });
- }
- fetchOrgNotifydict();
-
- function checkNotify(Notifydict, pageData) {
- // get button path
- const buttonMap = {
- Edit: '#edit-issue',
- Resolve: '#action_id_761',
- None: ''
- };
- const searchStrings = [];
-
- // 查找并高亮指定字符串的函数
- function highlightTextInElement(selector, searchStrings) {
- const element = $(selector);
- if (element.length === 0) {
- console.error('未找到指定的元素');
- return;
- }
-
- // 获取元素文本内容
- let text = element.text().trim();
-
- // 对每个字符串进行高亮处理
- searchStrings.forEach((searchString) => {
- // 在文本中查找并替换匹配的字符串
- text = text.replace(
- new RegExp(searchString, 'gi'),
- (match) => `<span style="background-color: yellow;">${match}</span>`
- );
- });
-
- // 将替换后的文本重新设置为元素的 HTML 内容
- element.html(text);
- }
-
- function checkProperties(properties, pageData, ticketname) {
- const condition = (property) => {
- const propertyArray = property.propertiesVal.split(',');
- let isAllConditionsMet = false;
- for (const val of propertyArray) {
- try {
- if (!property.conditionOptions) {
- let isTrue = pageData[property.propertiesKey]
- .toLowerCase()
- .includes(val.trim().toLowerCase().replace('!', ''));
- if (val.trim().toLowerCase().includes('!')) {
- isTrue = !isTrue;
- }
- if (isTrue) {
- if (property.propertiesKey == 'RawLog') {
- searchStrings.push(val.trim());
- }
- isAllConditionsMet = true; // 如果任何一个属性满足条件,返回 true
- }
- }
- switch (property.conditionOptions) {
- case 'contain':
- if (pageData[property.propertiesKey].toLowerCase().includes(val.trim().toLowerCase())) {
- isAllConditionsMet = true;
- }
- break;
- case 'not contain':
- if (
- !pageData[property.propertiesKey].toLowerCase().includes(val.trim().toLowerCase())
- ) {
- isAllConditionsMet = true;
- }
- break;
- case 'equal':
- if (pageData[property.propertiesKey].toLowerCase() === val.trim().toLowerCase()) {
- isAllConditionsMet = true;
- }
- break;
- case 'not equal':
- if (pageData[property.propertiesKey].toLowerCase() !== val.trim().toLowerCase()) {
- isAllConditionsMet = true;
- }
- break;
- default:
- console.log('Unknown.');
- }
- } catch (error) {
- if (
- error.name === 'TypeError' &&
- error.message == "Cannot read properties of undefined (reading 'includes')"
- ) {
- console.warn(`${ticketname} 提醒未加条件,请检查配置`);
- }
- }
- }
- return isAllConditionsMet; // 如果所有属性都不满足条件,则返回 false
- };
- properties = JSON.parse(properties);
- return properties.reduce((acc, property) => {
- return acc && condition(property);
- }, true);
- }
- let cachedEntry = GM_getValue('cachedEntry', null);
- let projectMap = {};
- projectMap[cachedEntry['hk'].split('//')[1]] = 'HK';
- projectMap[cachedEntry['macao'].split('//')[1]] = 'MO';
-
- for (const notify of Notifydict) {
- const { ticketname, starttime, endtime, message, properties, button, status, project } = notify;
- const isInTimeRange =
- (!starttime || new Date() >= new Date(starttime)) && (!endtime || new Date() <= new Date(endtime));
- const clickButton = buttonMap[button];
-
- if (status == 'Disable' || !isInTimeRange || projectMap[window.location.host] !== project) {
- continue;
- }
-
- if (checkProperties(properties, pageData, ticketname)) {
- if (clickButton == '') {
- showFlag('warning', `${ticketname}`, `${message.replace(/\r?\n/g, '<br>')}`, 'manual');
- } else {
- $(clickButton).on('click', () => {
- showFlag('warning', `${ticketname}`, `${message.replace(/\r?\n/g, '<br>')}`, 'manual');
- });
- }
-
- let selector;
- if (project == 'HK') {
- selector = '#field-customfield_10219 > div:first-child > div:nth-child(2)';
- } else if (project == 'MO') {
- selector = '#field-customfield_10904 > div.twixi-wrap.verbose > div';
- }
- highlightTextInElement(selector, searchStrings);
- }
- }
- }
- }
- /**
- * Creates a new button and adds it to the DOM.
- * @param {string} id - The ID attribute for the new button element.
- * @param {string} text - The text content to display on the new button.
- * @param {string} onClick - The function to call when the button is clicked.
- */
- function addButton(id, text, onClick) {
- console.log(`#### Add Button: ${text} ####`);
- const toolbar = $('.aui-toolbar2-primary');
- // 重复添加的按钮不会被显示
- if ($('#' + id).length === 0) {
- const button = $('<a>')
- .attr('id', id)
- .addClass('aui-button toolbar-trigger')
- .append($('<span>').addClass('trigger-label').text(text))
- .click(onClick);
- toolbar.append($('<div>').addClass('aui-buttons pluggable-ops').append(button));
- }
- }
-
- function monitorList() {
- var summaryElements = document.querySelectorAll('.summary');
- summaryElements.forEach(function (element) {
- if (
- element.textContent.includes('WebAvailability') ||
- element.textContent.includes('SWIFT login activity and select activity detected')
- ) {
- var audio = document.getElementById('myAudio');
- audio.play();
- }
- });
- var time_to_first_response = document.querySelectorAll('.sla-tag.sla-tag-ongoing');
- time_to_first_response.forEach(function (element) {
- console.log(element.outerText.replace('min', ''), element.outerText.replace('min', '') < 30);
- if (element.outerText.includes('min') && element.outerText.replace('min', '') < 30) {
- var audio = document.getElementById('myAudio');
- audio.play();
- console.log('出现特殊情况');
- }
- });
- }
-
- /**
- * Creates three buttons on a JIRA issue page to handle Cortex XDR alerts
- * The buttons allow users to generate a description of the alerts, open the alert card page and timeline page
- */
- function cortexAlertHandler(...kwargs) {
- console.log('#### Code cortexAlertHandler run ####');
- const { LogSourceDomain, summary } = kwargs[0];
- const rawLog = $('#field-customfield_10232 > div.twixi-wrap.verbose > div > div > div > pre').text();
- /**
- * Extracts the log information and organization name from the current JIRA issue page
- * @param {Object} orgDict - A dictionary that maps organization name to navigator name
- * @returns {Object} An object that contains the organization's name, organization's navigator URL, raw log information
- */
- let orgDict = {};
- const cachedWebsiteContent = GM_getValue('cachedWebsiteContent', null);
- console.log(cachedWebsiteContent);
- if (cachedWebsiteContent != null) {
- cachedWebsiteContent.forEach((item, index) => {
- if (item && item['category'] == 'cortex' && item['url']) {
- orgDict[item['name']] = item['url'];
- }
- });
- console.log('===orgDict', orgDict);
- } else {
- alert('cachedWebsiteContent is empty,please connect VPN get information');
- }
- const orgNavigator = orgDict[LogSourceDomain];
-
- /**
- * Parse the relevant information from the raw log data
- * @param {Array} rawLog - An array of JSON strings representing the raw log data
- * @returns {Array} An array of objects containing the alert relevant information
- */
- function parseLog(rawLog) {
- let alertInfo = [];
- try {
- const { timestamp, data, rule } = JSON.parse(rawLog);
- let rule_description = rule['description'].split(':')[-1];
- const { cortex_xdr } = data;
- const { source, alert_id, name, description } = cortex_xdr;
- const isPANNGFW = source === 'PAN NGFW';
- let dotIndex = timestamp.lastIndexOf('.');
-
- dateTimeStr = timestamp.slice(0, dotIndex) + '+0800';
- const alert = { source, alert_id, name, description, dateTimeStr, rule_description };
- if (isPANNGFW) {
- const {
- action_local_ip,
- action_local_port,
- action_remote_ip,
- action_remote_port,
- action_pretty,
- alert_link
- } = cortex_xdr;
- alertInfo.push({
- ...alert,
- action_local_ip,
- action_local_port,
- action_remote_ip,
- action_remote_port,
- action_pretty,
- alert_link
- });
- } else {
- const {
- action_local_ip,
- action_file_macro_sha256,
- action_file_name,
- action_file_path,
- action_file_sha256,
- action_process_image_name,
- action_process_image_sha256,
- action_process_image_command_line,
- action_external_hostname,
- actor_process_image_name,
- actor_process_image_path,
- actor_process_image_sha256,
- actor_process_command_line,
- causality_actor_process_image_name,
- causality_actor_process_command_line,
- causality_actor_process_image_path,
- causality_actor_process_image_sha256,
- os_actor_process_image_name,
- os_actor_process_image_path,
- os_actor_process_command_line,
- os_actor_process_image_sha256,
- action_pretty,
- host_name,
- host_ip,
- user_name,
- alert_link
- } = cortex_xdr;
- const action_list = {
- action_file_name,
- action_file_path,
- action_file_sha256,
- action_process_image_name,
- action_process_image_sha256,
- action_process_image_command_line
- };
- const actor_list = {
- actor_process_image_name,
- actor_process_image_path,
- actor_process_image_sha256,
- actor_process_command_line
- };
- const causality_actor_list = {
- causality_actor_process_image_name,
- causality_actor_process_command_line,
- causality_actor_process_image_path,
- causality_actor_process_image_sha256
- };
- const os_actor_list = {
- os_actor_process_image_name,
- os_actor_process_image_path,
- os_actor_process_command_line,
- os_actor_process_image_sha256
- };
-
- function countValidProperties(obj) {
- const validPropsCount = Object.keys(obj).reduce((count, key) => {
- if (obj[key] !== undefined) {
- count++;
- }
- return count;
- }, 0);
- return validPropsCount;
- }
-
- const actionPropsCount = countValidProperties(action_list) ? countValidProperties(action_list) + 1 : 0;
- const actorPropsCount = countValidProperties(actor_list);
- const causalityPropsCount = countValidProperties(causality_actor_list);
- const osPropsCount = countValidProperties(os_actor_list);
- const maxCount = Math.max(actionPropsCount, actorPropsCount, causalityPropsCount, osPropsCount);
-
- const action_cmd_length = action_process_image_command_line
- ? action_process_image_command_line.length
- : 0;
- const actor_cmd_length = actor_process_command_line ? actor_process_command_line.length : 0;
- const causality_cmd_length = causality_actor_process_command_line
- ? causality_actor_process_command_line.length
- : 0;
- const os_cmd_length = os_actor_process_command_line ? os_actor_process_command_line.length : 0;
- const lengths = [action_cmd_length, actor_cmd_length, causality_cmd_length, os_cmd_length];
- const maxLength = Math.max(...lengths);
-
- let filename;
- let filepath;
- let sha256;
- let cmd;
-
- if (action_cmd_length === maxLength && actionPropsCount === maxCount) {
- if (!WhiteFilehash(action_file_sha256 || action_process_image_sha256)) {
- sha256 = action_file_sha256 || action_process_image_sha256;
- }
- filename = action_file_name || action_process_image_name;
- filepath = action_file_path;
- cmd = action_process_image_command_line;
- } else if (actor_cmd_length === maxLength && actorPropsCount === maxCount) {
- if (!WhiteFilehash(actor_process_image_sha256)) {
- sha256 = actor_process_image_sha256;
- }
- filename = actor_process_image_name;
- filepath = actor_process_image_path;
- cmd = actor_process_command_line;
- } else if (causality_cmd_length === maxLength && causalityPropsCount === maxCount) {
- if (!WhiteFilehash(causality_actor_process_image_sha256)) {
- sha256 = causality_actor_process_image_sha256;
- }
- filename = causality_actor_process_image_name;
- filepath = causality_actor_process_image_path;
- cmd = causality_actor_process_command_line;
- } else if (os_actor_process_image_name && osPropsCount === maxCount) {
- if (!WhiteFilehash(os_actor_process_image_sha256)) {
- sha256 = os_actor_process_image_sha256;
- }
- filename = os_actor_process_image_name;
- filepath = os_actor_process_image_path;
- cmd = os_actor_process_command_line;
- }
-
- alertInfo.push({
- ...alert,
- host_name,
- host_ip,
- alert_link,
- user_name,
- filename,
- filepath,
- cmd,
- sha256,
- action_pretty,
- action_local_ip,
- action_file_macro_sha256,
- action_external_hostname
- });
- }
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
-
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
-
- /**
- * Define three functions for handling alert information:
- * generateDescription creates a description for each alert, and displays the combined description in an alert box
- * openCard opens a new window to display the alert card page for each alert
- * openTimeline opens a new window to display the timeline page for each alert
- */
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- let {
- source,
- name,
- action_local_ip,
- action_local_port,
- action_remote_ip,
- action_remote_port,
- action_pretty,
- description,
- alert_link,
- rule_description,
- action_external_hostname
- } = info;
- let unPanNgfw = [
- 'host_name',
- 'host_ip',
- 'sha256',
- 'action_file_macro_sha256',
- 'filepath',
- 'filename',
- 'cmd',
- 'user_name',
- 'action_local_ip'
- ];
- if (description && description.includes('xdr_data')) {
- console.log(rule_description);
- description = rule_description;
- }
- if (source === 'PAN NGFW') {
- const desc = `Observed ${name}\ntimestamp: ${dateTimeStr}\nSrcip: ${action_local_ip} Srcport: ${action_local_port}\nDstip: ${action_remote_ip} Dstport: ${action_remote_port}\nAction: ${action_pretty}\n${
- LogSourceDomain === 'cityu' ? 'Cortex Portal: ' + alert_link + '\n' : ''
- }\n\nPlease help to verify if this activity is legitimate.\n`;
- alertDescriptions.push(desc);
- } else {
- let comment = '\nPlease help to verify if this activity is legitimate.\n';
- if (
- summary.toLowerCase().includes('wildfire malware') ||
- summary.toLowerCase().includes('local analysis malware')
- ) {
- comment = '\nPlease verify if the File is legitimate. IF NOT, please Remove the File.\n';
- }
- let desc = `Observed ${
- description || name
- }\ntimestamp: ${dateTimeStr} \n<span class="red_highlight">action_external_hostname: ${action_external_hostname}\n</span>action: ${action_pretty}\n`;
- for (const key of unPanNgfw) {
- console.log(key);
- if (Object.hasOwnProperty.call(info, key)) {
- const value = info[key];
- console.log(key, value);
- if (value !== undefined) {
- if (key == 'event_evidence') {
- desc += `${key}: ${value.replace(/</g, '<').replace(/>/g, '>')}\n`;
- } else {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- }
- if (info['action_file_macro_sha256'] || info['sha256']) {
- desc += `<a href="https://www.virustotal.com/gui/file/${
- info['action_file_macro_sha256'] || info['sha256']
- }">https://www.virustotal.com/gui/file/${info['action_file_macro_sha256'] || info['sha256']}</a>\n`;
- }
- alertDescriptions.push(desc + comment);
- }
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- function openCard() {
- for (const info of alertInfo) {
- const { source, alert_id } = info;
- if (orgNavigator) {
- let cardURL;
- switch (source) {
- case 'XDR Analytics':
- cardURL = `${orgNavigator}card/analytics2/${alert_id}`;
- break;
- case 'Correlation':
- cardURL = `${orgNavigator}alerts/${alert_id}`;
- break;
- default:
- cardURL = `${orgNavigator}card/alert/${alert_id}`;
- break;
- }
- window.open(cardURL, '_blank');
- } else {
- showFlag('error', '', `There is no <strong>${LogSourceDomain}</strong> Navigator on Cortex`, 'auto');
- }
- }
- }
- function openTimeline() {
- for (const info of alertInfo) {
- const { source, alert_id } = info;
- if (orgNavigator) {
- let timelineURL;
- switch (source) {
- case 'Correlation':
- showFlag(
- 'error',
- '',
- `Source of the Alert is <strong>${source}</strong>, There is no Timeline on Cortex`,
- 'auto'
- );
- break;
- default:
- timelineURL = `${orgNavigator}forensic-timeline/alert_id/${alert_id}`;
- break;
- }
- timelineURL && window.open(timelineURL, '_blank');
- } else {
- showFlag('error', '', `There is no <strong>${LogSourceDomain}</strong> Navigator on Cortex`, 'auto');
- }
- }
- }
- addButton('generateDescription', 'Description', generateDescription);
- addButton('openCard', 'Card', openCard);
- addButton('openTimeline', 'Timeline', openTimeline);
- }
-
- function HTSCAlertHandler(...kwargs) {
- console.log('#### Code HTSCAlertHandler run ####');
- const { rawLog } = kwargs[0];
- function decodeHtml(encodedString) {
- const tmpElement = document.createElement('span');
- tmpElement.innerHTML = encodedString;
- return tmpElement.innerText;
- }
-
- const parseLog = (rawLog) => {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const formatJson = log.substring(log.indexOf('{')).trim();
- // const logObj = JSON.parse(formatJson);
- const logObj = JSON.parse(formatJson.replace(/\\\(n/g, '\\n('));
- const eventEvidence = decodeHtml(logObj.event_evidence).split('End time')[0];
- const alert = {
- attackType: logObj.tag,
- hostRisk: logObj.hostRisk,
- srcIP: logObj.src_ip,
- eventEvidence,
- hostName: logObj.hostName,
- dstIP: logObj.dst_ip
- };
- acc.push(alert);
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- };
- const alertInfo = parseLog(rawLog);
- // console.info(`alertInfo: ${alertInfo}`);
-
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const { attackType, hostRisk, srcIP, hostName, dstIP, eventEvidence } = info;
- const desc = `Observed ${attackType} Attack\nhostRisk: ${hostRisk}\nSrc_IP: ${srcIP}\nhostname: ${hostName}\nDst_IP: ${dstIP}\nevent_evidence: ${eventEvidence}\n\nPlease help to verify if this activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function VMCEFAlertHandler(...kwargs) {
- const { rawLog } = kwargs[0];
-
- function parseCefLog(rawLog) {
- function cefToJson(cefLog) {
- let json = {};
- let fields = cefLog.split(' ');
-
- for (let i = 0; i < fields.length; i++) {
- let field = fields[i].split('=');
- let key = field[0];
- let value = field.slice(1).join('=');
-
- if (value) {
- if (key === 'filePath' || key === 'msg' || key === 'start' || key === 'rt') {
- let nextFieldIndex = i + 1;
- while (nextFieldIndex < fields.length && !fields[nextFieldIndex].includes('=')) {
- value += ' ' + fields[nextFieldIndex];
- nextFieldIndex++;
- }
- }
- json[key] = value;
- }
- }
- return json;
- }
-
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- // Determine whether the log is empty
- if (Object.keys(log).length !== 0) {
- // Split CEF log
- let cef_log = log.split('|');
- // Parsing CEF Header
- const cef_log_header = cef_log.slice(1, 7);
- // Parsing CEF Extends
- const cef_log_extends = cefToJson(cef_log[7]);
-
- acc.push({
- Summary: cef_log_header[4],
- // for some like "server error" tickets
- HostName: cef_log_extends.dhost ? cef_log_extends.dhost : cef_log_extends.dvchost,
- HostIp: cef_log_extends.dst,
- UserName: cef_log_extends.duser,
- FileName: cef_log_extends.fname,
- FilePath: cef_log_extends.filePath,
- Sha256: cef_log_extends.fileHash,
- Msg: cef_log_extends.msg
- });
- }
- return acc;
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- }, []);
- return alertInfo;
- }
- const alertInfo = parseCefLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const { Summary } = info;
- let desc = `Observed ${Summary}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && index != 'Summary' && index != 'CBlink') {
- desc += `${index}: ${value}\n`;
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function CBAlertHandler(...kwargs) {
- console.log('#### Code CBAlertHandler run ####');
- const { rawLog } = kwargs[0];
-
- function parseLeefLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- const cb_log = {};
- try {
- const log_obj = log.split('\t');
- log_obj.forEach((log_item) => {
- try {
- const [key, value] = log_item.split('=');
- cb_log[key] = value;
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- });
- if (log.trim() !== '') {
- acc.push({
- Summary: cb_log.watchlist_name,
- HostName: cb_log.computer_name,
- HostIp: cb_log.interface_ip,
- UserName: cb_log.username,
- CmdLine: cb_log.cmdline,
- CBlink: cb_log.link_process,
- Filepath: cb_log.path,
- Sha256: cb_log.process_sha256
- });
- }
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLeefLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const { Summary } = info;
- let desc = `Observed ${Summary}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && index != 'Summary' && index != 'CBlink') {
- desc += `${index}: ${value}\n`;
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- function openCB() {
- let CBURL = '';
- for (const info of alertInfo) {
- const { CBlink } = info;
- if (CBlink) {
- CBURL += `${CBlink}\n`;
- }
- }
- showFlag('info', 'CB URL:', `${CBURL}`, 'manual');
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- addButton('openCB', 'CB', openCB);
- }
-
- function WineventAlertHandler(...kwargs) {
- console.log('#### Code WineventAlertHandler run ####');
- let { rawLog, summary } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- summary = summary.replace(/[\[(].*?[\])]/g, '');
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const { win } = JSON.parse(log);
- raw_alert += 1;
- const { eventdata, system } = win;
- const alertHost = system.computer;
- const systemTime = system.systemTime;
- acc.push({ systemTime, summary, alertHost, eventdata });
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let desc = `Observed${info.summary}\nHost: ${info.alertHost}\n`;
- const date = new Date(info.systemTime.split('.')[0]);
- date.setHours(date.getHours() + 16);
- desc += `systemTime(<span class="red_highlight">UTC+8</span>): ${date.toISOString().split('.')[0]}\n`;
- for (const key in info.eventdata) {
- if (Object.hasOwnProperty.call(info.eventdata, key)) {
- const value = info.eventdata[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += '\n' + 'Please help to verify if this activity is legitimate.' + '\n';
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function FortigateAlertHandler(...kwargs) {
- let { rawLog, summary, LogSourceDomain } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- summary = summary.split(']')[1].trim();
- function ParseFortigateLog(rawLog) {
- const alertInfos = rawLog.reduce((acc, log) => {
- if (log == '') {
- return acc;
- }
- let jsonData = {};
- const regex = /(\w+)=(["'].*?["']|\S+)/g;
- let matchresult;
- raw_alert += 1;
- while ((matchresult = regex.exec(log)) !== null) {
- let key = matchresult[1];
- let value = matchresult[2];
- if (value.startsWith('"') && value.endsWith('"')) {
- value = value.slice(1, -1);
- } else if (value.startsWith("'") && value.endsWith("'")) {
- value = value.slice(1, -1);
- }
- jsonData[key] = value;
- }
- acc.push(jsonData);
- return acc;
- }, []);
- return [...new Set(alertInfos)];
- }
-
- const alertInfos = ParseFortigateLog(rawLog);
- function ExtractAlertInfo(ExtractAlertInfo) {
- const extract_alert_infos = alertInfos.reduce((acc, alertInfo) => {
- const {
- date,
- time,
- srcip,
- srcport,
- srccountry,
- dstip,
- dstport,
- dstcountry,
- hostname,
- url,
- referralurl,
- action,
- devname,
- user,
- cfgattr,
- msg,
- forwardedfor,
- analyticscksum,
- from,
- to,
- remip
- } = alertInfo;
- let arr = [];
- if (summary.toLowerCase().includes('infected file detected in fortigate')) {
- let vt_url;
- if (url) {
- vt_url = 'https://www.virustotal.com/gui/domain/' + url.split('/')[2];
- } else {
- vt_url = 'https://www.virustotal.com/gui/ip-address/' + srcip;
- }
- let sum = 'https://www.virustotal.com/gui/search/' + analyticscksum;
- arr.push(`<a href="${vt_url}">${vt_url}</a>`);
- arr.push(`<a href="${sum}">${sum}</a>`);
- } else if (summary.toLowerCase().includes('connection attempt')) {
- let vt_url = 'https://www.virustotal.com/gui/ip-address/' + dstip;
- arr.push(`<a href="${vt_url}">${vt_url}</a>`);
- } else if (summary.toLowerCase().includes('connection to newly registered domain')) {
- let vt_url = 'https://www.virustotal.com/gui/domain/' + hostname;
- arr.push(`<a href="${vt_url}">${vt_url}</a>`);
- } else if (summary.toLowerCase().includes('non-office hour successful vpn login')) {
- let vt_url = 'https://www.virustotal.com/gui/ip-address/' + remip;
- arr.push(`<a href="${vt_url}">${vt_url}</a>`);
- }
-
- const extract_alert_info = {
- datetime: `${date} ${time}`,
- srcip: srcip ? `${srcip}:${srcport}[${srccountry}]` : undefined,
- dstip: dstip ? `${dstip}:${dstport}[${dstcountry}]` : undefined,
- hostname: hostname,
- devname: devname,
- user: user,
- url: url,
- action: action,
- cfgattr: cfgattr,
- msg: msg,
- referralurl: referralurl,
- forwardedfor: forwardedfor || undefined,
- analyticscksum: analyticscksum,
- from: from,
- to,
- remip: remip,
- VT: arr.length > 0 ? arr : undefined
- };
- acc.push(extract_alert_info);
- return acc;
- }, []);
- return extract_alert_infos;
- }
- function ExtractAlertInfo_sonicwall(ExtractAlertInfo) {
- const extract_alert_infos = alertInfos.reduce((acc, alertInfo) => {
- acc.push({
- time: alertInfo.time,
- msg: alertInfo.msg,
- src: alertInfo.src,
- srcZone: alertInfo.srcZone,
- natSrc: alertInfo.natSrc,
- dst: alertInfo.dst,
- dstZone: alertInfo.dstZone,
- natDst: alertInfo.natDst,
- proto: alertInfo.proto
- });
- return acc;
- }, []);
- return extract_alert_infos;
- }
- let extract_alert_infos = '';
- if (LogSourceDomain == 'miramar') {
- console.log('===miramar');
- extract_alert_infos = ExtractAlertInfo_sonicwall(alertInfos);
- } else {
- extract_alert_infos = ExtractAlertInfo(alertInfos);
- }
-
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of extract_alert_infos) {
- let desc = `Observed ${summary}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined) {
- desc += `${index}: ${value}\n`;
- }
- });
- let comment = '\nPlease help to verify if this activity is legitimate.\n';
- if (summary.toLowerCase().includes('to malware ip(s)') || summary.toLowerCase().includes('to tor ip(s)')) {
- comment = '\nPlease verify if the IP is legitimate. If NOT, please block the dst ip\n';
- }
- desc += comment;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function CSAlertHandler(...kwargs) {
- let { rawLog } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- function parseCefLog(rawLog) {
- function cefToJson(cefLog) {
- let json = {};
- let fields = cefLog.split(' ');
-
- for (let i = 0; i < fields.length; i++) {
- let field = fields[i].split('=');
- let key = field[0];
- let value = field.slice(1).join('=');
-
- if (value) {
- if (key === 'filePath' || key === 'msg' || key === 'cs5' || key === 'start' || key === 'rt') {
- let nextFieldIndex = i + 1;
- while (nextFieldIndex < fields.length && !fields[nextFieldIndex].includes('=')) {
- value += ' ' + fields[nextFieldIndex];
- nextFieldIndex++;
- }
- }
- json[key] = value;
- }
- }
- return json;
- }
-
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- // Determine whether the log is empty
- if (Object.keys(log).length !== 0) {
- // Split CEF log
- let cef_log = log.split('|');
- // Parsing CEF Header
- const cef_log_header = cef_log.slice(1, 7);
- // Parsing CEF Extends
- const cef_log_extends = cefToJson(cef_log[7]);
- raw_alert += 1;
- acc.push({
- CreateTime: cef_log[0].split(' localhost ')[0],
- Summary: cef_log_header[4],
- // for some like "server error" tickets
- HostName: cef_log_extends.dhost ? cef_log_extends.dhost : cef_log_extends.dvchost,
- HostIp: cef_log_extends.dst,
- UserName: cef_log_extends.duser,
- FileName: cef_log_extends.fname,
- FilePath: cef_log_extends.filePath,
- Command: cef_log_extends.cs5,
- Sha256: cef_log_extends.fileHash,
- Msg: cef_log_extends.msg,
- CSLink: cef_log_extends.cs6 ? cef_log_extends.cs6 : cef_log_extends.cs1
- });
- }
- return acc;
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseCefLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- const { Summary } = info;
- let desc = `Observed ${Summary}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && index != 'Summary' && index != 'CSLink') {
- desc += `${index}: ${value}\n`;
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- function openCS() {
- let CSURL = '';
- let cs_url = [];
- for (const info of alertInfo) {
- const { CSLink } = info;
- if (CSLink && !cs_url.includes(CSLink)) {
- CSURL += `${CSLink.replace('hXXps', 'https').replace(/[\[\]]/g, '')}<br><br>`;
- }
- cs_url.push(CSLink);
- }
- showFlag('info', 'CS URL:', `${CSURL}`, 'manual');
- }
- addButton('generateDescription', 'Description', generateDescription);
- addButton('openCS', 'CS', openCS);
- }
-
- function SophosAlertHandler(...kwargs) {
- let { rawLog } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- log.replace(/[\[(].*?[\])]/g, '');
- const { sophos, logsource } = JSON.parse(log);
- raw_alert += 1;
- const summary = sophos.name;
- const createtime = sophos.rt.split('.')[0] + 'Z';
- const alertHost = sophos.dhost;
- const alertUser = sophos.suser;
- const alertID = sophos.id;
- const alertIP = sophos?.source_info?.ip || sophos?.data?.source_info?.ip || '';
- const alertExtraInfo = {
- 'Sha256': sophos.appSha256,
- 'Filename': sophos?.data?.fileName ? sophos.data.fileName : undefined,
- 'Processname': sophos?.data?.processName ? sophos.data.processName : undefined,
- 'Process': sophos?.data?.process ? sophos.data.process : undefined,
- 'Clean Up Result': sophos?.core_remedy_items?.items[0]?.result
- };
- acc.push({ summary, createtime, alertHost, alertIP, alertUser, alertID, logsource, alertExtraInfo });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let desc = `Observed ${info.summary}\nHost: ${info.alertHost} IP: ${info.alertIP || 'N/A'}\nUser: ${
- info.alertUser
- }\ncreatetime:(<span class="red_highlight">GMT</span>)${info.createtime}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- if (!info.summary.includes('Failed to protect computer')) {
- desc += '\n' + 'Please help to verify if this activity is legitimate.' + '\n';
- }
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- function openSophos() {
- let searchID = '';
- for (const info of alertInfo) {
- const { alertHost, alertID, logsource } = info;
- if (alertID || alertHost) {
- searchID += `<strong>[${logsource}] ${alertHost}</strong>:<br>${alertID}<br><br>`;
- }
- }
- showFlag('info', 'Host and Alert ID', `${searchID}`, 'manual');
- GM_openInTab('https://cloud.sophos.com/manage/enterprise/alerts-list', {
- active: false, // 设置为 false,以在后台打开,不激活新标签页
- insert: true // 设置为 true,将新标签页插入到当前标签页之后
- });
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- addButton('openSophos', 'Open Sophos', openSophos);
- }
-
- function SpemAlertHandler(...kwargs) {
- const { rawLog, summary } = kwargs[0];
-
- function parseLog(rawLog) {
- let logObject = {};
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- logArray = log.split(',');
- logArray[10] = 'Action:' + logArray[10];
- for (const index of logArray) {
- const [key, value] = index.split(/:(.+)/, 2);
- logObject[key] = value;
- }
- acc.push({
- 'Summary': logObject['Event Description'] !== undefined ? logObject['Event Description'] : summary,
- 'User Name': logObject['User Name'],
- 'Local Host IP': logObject['Local Host IP'],
- 'Local Port': logObject['Local Port'],
- 'Remote Host IP': logObject['Remote Host IP'],
- 'Remote Port': logObject['Remote Port'],
- 'Application': logObject['Application'],
- 'SHA-256': logObject['SHA-256'],
- 'Intrusion URL': logObject['Intrusion URL'],
- 'Action': logObject['Action']
- });
- } catch (error) {
- console.log(`Error: ${error}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- let desc = `Observed ${info['Summary']}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && value !== ' ' && index != 'Summary') {
- desc += `${index}: ${value}\n`;
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function AwsAlertHandler(...kwargs) {
- const { rawLog, summary } = kwargs[0];
- var raw_alert = 0;
- const DecoderName = $('#customfield_10807-val').text().trim().toLowerCase();
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const { aws } = JSON.parse(log);
- if (DecoderName == 'aws-guardduty') {
- let EventTime = aws.service.eventFirstSeen.split('.')[0] + 'Z';
- const action = aws.service.action;
- if (action.actionType == 'AWS_API_CALL') {
- acc.push({
- EventTime: EventTime,
- actionType: action.actionType,
- Api_Name: action?.awsApiCallAction?.api,
- userName: aws?.resource?.accessKeyDetails?.userName,
- RemoteIP: action?.awsApiCallAction?.remoteIpDetails?.ipAddressV4,
- RemoteIP_country: action?.awsApiCallAction?.remoteIpDetails?.country.countryName
- });
- } else if (action.actionType == 'KUBERNETES_API_CALL') {
- acc.push({
- EventTime: EventTime,
- actionType: action.actionType,
- userName: aws?.resource?.accessKeyDetails?.userName,
- sourceIPs: action?.kubernetesApiCallAction?.sourceIPs,
- requestUri: action?.kubernetesApiCallAction?.requestUri
- });
- } else if (action.actionType == 'PORT_PROBE') {
- acc.push({
- EventTime: EventTime,
- actionType: action.actionType,
- localPort: action?.portProbeAction?.portProbeDetails.localPortDetails.port,
- RemoteIP: action?.portProbeAction?.portProbeDetails.remoteIpDetails.ipAddressV4,
- RemoteIP_country:
- action?.portProbeAction?.portProbeDetails.remoteIpDetails.country.countryName
- });
- } else if (action.actionType == 'NETWORK_CONNECTION') {
- console.log('===', action);
- acc.push({
- EventTime: EventTime,
- actionType: action.actionType,
- localIp: action?.networkConnectionAction?.localIpDetails.ipAddressV4,
- localPortDetails: action?.networkConnectionAction?.localPortDetails.port,
- remoteIp: action?.networkConnectionAction?.remoteIpDetails.ipAddressV4,
- remotePortDetails: action?.networkConnectionAction?.remotePortDetails.port,
- instanceId: aws?.resource?.instanceDetails?.instanceId,
- platform: aws?.resource?.instanceDetails?.platform,
- remoteIpcountryName: action?.networkConnectionAction?.remoteIpDetails?.country?.countryName
- });
- }
- } else if (summary.toLowerCase().includes('multiple sms request for same source ip')) {
- let headers = aws.logEvents.message.httpRequest.headers;
- let host, content;
- headers.forEach((item) => {
- if (item.name === 'host') {
- host = item.value;
- }
- if (item.name == 'content-type') {
- content = item.value;
- }
- });
- acc.push({
- log_file: aws.log_info.log_file,
- clientIp: aws.logEvents.message.httpRequest.clientIp,
- httpMethod: aws.logEvents.message.httpRequest.httpMethod,
- uri: aws.logEvents.message.httpRequest.uri,
- host: host,
- content_type: content
- });
- } else {
- acc.push({
- EventTime: aws?.eventTime,
- EventName: aws?.eventName,
- SourceIP: aws?.sourceIPAddress || aws?.internal_ip,
- ExternalIP: aws?.external_ip,
- Domain: aws?.domain,
- User: aws?.userIdentity?.arn,
- UserAgent: aws?.userAgent,
- PrincipalId: aws?.userIdentity?.principalId,
- Result: aws?.errorCode,
- QueryType: aws?.query_type,
- Action: aws?.action,
- requestParameters: JSON.stringify(aws?.requestParameters),
- responseElements: JSON.stringify(aws?.responseElements)
- });
- }
- raw_alert += 1;
- } catch (error) {
- console.log(`Error: ${error}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let desc = `Observed ${summary.split(']')[1]}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && value !== ' ' && index != 'Summary') {
- if (index == 'EventTime') {
- desc += `EventTime(<span class="red_highlight">GMT</span>): ${value}\n`;
- } else {
- desc += `${index}: ${value}\n`;
- }
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function AzureAlertHandler(...kwargs) {
- const { rawLog } = kwargs[0];
-
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const { eventhub, azure } = JSON.parse(log);
- const { ExtendedProperties, Entities } = eventhub;
- let entities = {};
- if (Entities) {
- Entities.forEach(function (entity) {
- if (entity.Type === 'host') {
- entities['host'] = entity['HostName'];
- }
- if (entity.Type === 'network-connection') {
- entities['SourceIP'] = entity['SourceAddress']['Address'];
- }
- });
- }
- acc.push({
- AlertType: eventhub['AlertType'],
- StartTimeUtc: eventhub['StartTimeUtc'],
- Severity: eventhub['Severity'],
- Intent: eventhub['Intent'],
- Description: eventhub['Description'],
- summary: azure['ThreatDescription'] || eventhub['AlertDisplayName'],
- Protocol: azure['Protocol'],
- SourceIP: azure['SourceIp'],
- SourcePort: azure['SourcePort'],
- DestinationIp: azure['DestinationIp'],
- DestinationPort: azure['DestinationPort'],
- URL: azure['Url'],
- Action: azure['Action'],
- ExtendedProperties: JSON.stringify(ExtendedProperties, null, 4),
- ...entities,
- alerturi: eventhub['AlertUri']
- });
- } catch (error) {
- console.log(`Error: ${error}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- let desc = `Observed ${info.summary}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && value !== '' && index !== 'summary') {
- if (index == 'StartTimeUtc') {
- desc += `StartTimeUtc(<span class="red_highlight">GMT</span>): ${value.split('.')[0]}\n`;
- } else {
- desc += `${index}: ${value}\n`;
- }
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- function openAzure() {
- let AzureURL = '';
- for (const info of alertInfo) {
- const { alerturi } = info;
- if (alerturi) {
- AzureURL += `${alerturi.replace('hXXps', 'https').replace(/\[|\]/g, '')}<br><br>`;
- }
- }
- showFlag('info', 'Azure URL:', `${AzureURL}`, 'manual');
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- addButton('openAzure', 'Azure', openAzure);
- }
-
- function paloaltoAlertHandler(...kwargs) {
- const { rawLog, summary } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- let logArray = log.split(',');
- let logType = logArray[3];
- if (logType == 'GLOBALPROTECT') {
- acc.push({
- 'Createtime': logArray[1],
- 'src ip': logArray[15],
- 'user': logArray[12]
- });
- }
- if (logType == 'TRAFFIC') {
- acc.push({
- 'Createtime': logArray[1],
- 'Summary': summary.split(']')[1],
- 'Source IP': logArray[7],
- 'Destination IP': logArray[8],
- 'Destination Port': logArray[25],
- 'Destination Location': logArray[42] != 0 ? logArray[42] : logArray[39]
- });
- }
- if (logType == 'THREAT') {
- let really = false,
- malware_potential = [];
- for (let i = 0; i < logArray.length; i++) {
- if (logArray[i].includes('"') && i > 100) {
- if (really) {
- malware_potential.push(logArray[i]);
- }
- really = !really;
- }
- if (really) {
- malware_potential.push(logArray[i]);
- }
- }
- let vt_url = 'https://www.virustotal.com/gui/search/' + logArray[31].replace('"', '').split('/')[0];
- let description = `</br>Timestamp: ${logArray[0].split(' ').slice(0, 3).join(' ')}</br>
- Device: ${logArray[0].split(' ').slice(3, 5).join(' ')}</br>
- Log Details:
- <ul><li>Event Time: ${logArray[1]}</li>
- <li>Log ID: ${logArray[2]}</li>
- <li>Type: ${logArray[3]}(${logArray[4]})</li>
- <li>Severity: ${logArray[34]}</li>
- <li>Rule Triggered: ${logArray[11]}</li>
- <li>Vulnerability: ${logArray[32]}</li>
- <li>Threat ID: ${logArray[34]}</li></ul>
- Network Information:
- <ul><li>Source IP: ${logArray[7]}</li>
- <li>Destination IP: ${logArray[8]}</li>
- <li>URL/filename : ${logArray[31]}</li>
- <li>VT : <a href="${vt_url}">${vt_url}</a></li>
- <li>Source Zone: ${logArray[16]}</li>
- <li>Destination Zone: ${logArray[17]}</li>
- <li>Ingress Interface: ${logArray[18]}</li>
- <li>Egress Interface: ${logArray[19]}</li></ul>
- Traffic Details:
- <ul><li>Protocol: ${logArray[29]}</li>
- <li>Application: ${logArray[14]}</li>
- <li>Direction: ${logArray[35]}</li>
- <li>Session ID: ${logArray[36]}</li></ul>
- Vulnerability Information:</br>
- <ul><li>Exploit Type: ${logArray[69]}</li>
- <li>Attack Vector: ${logArray[111]}</li>
- <li>Affected Technology: ${logArray[112]},${logArray[113]}</li>
- <li>Malware Potential:${malware_potential}</li>
- </ul>`;
- raw_alert += 1;
- acc.push(description);
- }
- } catch (error) {
- console.error(`Error:${error}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let arr = summary.split(']');
- let desc = `Observed ${arr[arr.length - 1]}\n`;
- if (typeof info == 'string') {
- desc += info;
- } else {
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && value !== '' && index !== 'Summary') {
- desc += `${index}: ${value}\n`;
- }
- });
- }
- let comment = '\nPlease help to verify if this activity is legitimate.\n</br>';
- if (summary.toLowerCase().includes('to malware ip(s)') || summary.toLowerCase().includes('to tor ip(s)')) {
- comment = '\nPlease verify if the IP is legitimate. If NOT, please block the dst ip\n';
- }
- desc += comment;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function ImpervaincCEFAlertHandler(...kwargs) {
- const { rawLog } = kwargs[0];
-
- function parseCefLog(rawLog) {
- function cefToJson(cefLog) {
- let json = {};
- let fields = cefLog.split(' ');
-
- for (let i = 0; i < fields.length; i++) {
- let field = fields[i].split('=');
- let key = field[0];
- let value = field.slice(1).join('=');
-
- if (value) {
- if (key === 'filePath' || key === 'msg' || key === 'start' || key === 'rt' || key === 'cs1') {
- let nextFieldIndex = i + 1;
- while (nextFieldIndex < fields.length && !fields[nextFieldIndex].includes('=')) {
- value += ' ' + fields[nextFieldIndex];
- nextFieldIndex++;
- }
- }
- if (value == 'n/a') {
- json[key] = undefined;
- } else {
- json[key] = value;
- }
- }
- }
- return json;
- }
-
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- // Determine whether the log is empty
- if (Object.keys(log).length !== 0) {
- // Split CEF log
- let cef_log = log.split('|');
- let createtime = cef_log[0].split('CEF:')[0];
- // Parsing CEF Header
- const cef_log_header = cef_log.slice(1, 7);
- // Parsing CEF Extends
- const cef_log_extends = cefToJson(cef_log[7]);
-
- acc.push({
- summary: cef_log_extends.cs1,
- // for some like "server error" tickets
- createtime: createtime,
- username: cef_log_extends.duser,
- srcIP: cef_log_extends.src,
- dstIP: cef_log_extends.dst,
- dstPort: cef_log_extends.dpt,
- protocol: cef_log_extends.proto
- });
- }
- return acc;
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- }, []);
- return alertInfo;
- }
- const alertInfo = parseCefLog(rawLog);
-
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const { summary } = info;
- let desc = `Observed ${summary}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && index != 'summary' && index != 'CBlink') {
- desc += `${index}: ${value}\n`;
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function AzureGraphAlertHandler(...kwargs) {
- const { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- if (summary.toLowerCase().includes('successful azure/o365 login from malware-ip')) {
- return;
- }
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const { azure } = JSON.parse(log);
- let properties = {};
- raw_alert += 1;
- if (azure.targetResources) {
- for (const resource of azure.targetResources) {
- if (summary.toLowerCase().includes('conditional access policy updated')) {
- const { initiatedBy, targetResources, activityDateTime, activityDisplayName, result } =
- azure;
-
- const alertExtraInfo = {
- userPrincipalName: initiatedBy?.user?.userPrincipalName
- ? initiatedBy?.user?.userPrincipalName
- : undefined,
- displayName: targetResources[0]?.displayName
- ? targetResources[0]?.displayName
- : undefined,
- activityDateTime: activityDateTime ? activityDateTime : undefined,
- activityDisplayName: activityDisplayName ? activityDisplayName : undefined,
- result: result ? result : undefined
- };
- acc.push({ alertExtraInfo });
- } else {
- if (resource.type == 'User') {
- const resourceProperties = { TargetUser: resource.userPrincipalName };
- properties = { ...properties, ...resourceProperties };
- }
- for (const prop of resource.modifiedProperties) {
- properties = { ...properties, [prop['displayName']]: prop['newValue'] };
- }
- const activityDateTime = azure.activityDateTime.split('.')[0] + 'Z';
- acc.push({
- activityDateTime: activityDateTime,
- AppDisplayName: azure?.appDisplayName || azure?.initiatedBy?.app?.displayName,
- SourceUser: azure?.userPrincipalName || azure?.initiatedBy?.user?.userPrincipalName,
- IpAddress: azure?.ipAddress || azure?.initiatedBy?.user?.ipAddress,
- Location:
- azure?.location?.countryOrRegion && azure?.location?.state && azure?.location?.city
- ? `${azure?.location?.countryOrRegion}\\${azure?.location?.state}\\${azure?.location?.city}`
- : undefined,
- ...properties,
- Result: azure?.status?.failureReason || azure.result,
- AdditionalInfo: azure?.additionalDetails[0]?.value
- ? azure?.additionalDetails[0]?.value
- : undefined
- });
- }
- }
- } else {
- const activityDateTime = azure.createdDateTime;
- acc.push({
- activityDateTime: activityDateTime,
- AppDisplayName: azure?.appDisplayName || azure?.initiatedBy?.app?.displayName,
- SourceUser: azure?.userPrincipalName || azure?.initiatedBy?.user?.userPrincipalName,
- IpAddress: azure?.ipAddress || azure?.initiatedBy?.user?.ipAddress,
- Location:
- azure?.location?.countryOrRegion && azure?.location?.state && azure?.location?.city
- ? `${azure?.location?.countryOrRegion}\\${azure?.location?.state}\\${azure?.location?.city}`
- : undefined,
- ...properties,
- DeviceName: azure.deviceDetail.displayName || 'N/A',
- failureReason: azure?.status?.failureReason || azure.result
- });
- }
- } catch (error) {
- console.log(`Error: ${error}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- if (summary.toLowerCase().includes('conditional access policy updated')) {
- for (const info of alertInfo) {
- console.log(info['alertExtraInfo']['userPrincipalName']);
- let desc = `Observed the user "${
- info['alertExtraInfo']['userPrincipalName']
- }" was on (<span class="red_highlight">GMT</span>)${
- info['alertExtraInfo']['activityDateTime'].split('.')[0]
- }ZS Updated the conditional access policy "${info['alertExtraInfo']['displayName']}"\n\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (
- value !== undefined &&
- key != 'userPrincipalName' &&
- key != 'displayName' &&
- key != 'activityDateTime'
- ) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nIt is recommended that you verify that the user has permission to change the conditional access policy and that the action is a legitimate update known to the user. Thanks!\n`;
- alertDescriptions.push(desc);
- }
- } else {
- for (const info of alertInfo) {
- let desc = `Observed ${summary.split(']')[1]}\n`;
- console.log(info);
- for (const key in info) {
- if (Object.hasOwnProperty.call(info, key)) {
- const value = info[key];
- if (value !== undefined && value !== '' && key != 'summary' && key != 'alerturi') {
- if (key == 'activityDateTime') {
- desc += `activityDateTime(<span class="red_highlight">GMT</span>): ${value}\n`;
- } else {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function ProofpointAlertHandler(...kwargs) {
- const { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const BraceIndex = log.toString().indexOf('{');
- const lastBraceIndex = log.toString().lastIndexOf('}');
- // If the braces are found
- if (BraceIndex !== -1) {
- raw_alert += 1;
- console.log(`${raw_alert} iteration 'is being processed`);
- // Intercepts a substring from the beginning of the brace to the end of the string
- json_text = log.toString().substr(BraceIndex, lastBraceIndex);
- try {
- let json_alert = JSON.parse(json_text);
- if (json_alert.hasOwnProperty('messagesDelivered')) {
- for (const message of json_alert['messagesDelivered']) {
- const { subject, sender, senderIP, recipient } = message;
- const alertExtraInfo = {
- subject: subject ? subject : undefined,
- sender: sender ? sender : undefined,
- recipient: recipient ? recipient : undefined,
- senderIP: senderIP ? senderIP : undefined
- };
- acc.push({ alertExtraInfo });
- }
- } else if (json_alert['sourcetype'].includes('clicksPermitted')) {
- json_alert['clickTime'] = json_alert['clickTime'].split('.')[0];
- json_alert['threatTime'] = json_alert['threatTime'].split('.')[0];
- acc.push({ alertExtraInfo: json_alert });
- console.log('hellO');
- } else {
- const {
- subject,
- sender,
- senderIP,
- recipient,
- headerFrom,
- messageTime,
- threatsInfoMap,
- sourcetype,
- spamScore,
- phishScore,
- cluster,
- completelyRewritten,
- id,
- QID,
- GUID
- } = json_alert;
- let alertExtraInfo = {
- sourcetype: sourcetype ? sourcetype : undefined,
- messageTime: messageTime ? messageTime : undefined,
- subject: subject ? subject : undefined,
- senderIP: senderIP ? senderIP : undefined,
- sender: sender ? sender : undefined,
- recipient: recipient ? recipient : undefined,
- headerFrom: headerFrom ? headerFrom : undefined,
- spamScore: spamScore ? spamScore : undefined,
- phishScore: phishScore ? phishScore : undefined,
- cluster: cluster ? cluster : undefined,
- completelyRewritten: completelyRewritten ? completelyRewritten : undefined,
- id: id ? id : undefined,
- QID: QID ? QID : undefined,
- GUID: GUID ? GUID : undefined
- };
- alertExtraInfo = Object.assign({}, alertExtraInfo, threatsInfoMap[0]);
- acc.push({ alertExtraInfo });
- }
- } catch (error) {
- console.log('Unable to parse JSON data, handling exception: ' + error);
- var split_str = json_text
- .split('"messagesDelivered" :')[1]
- .split('"messagesBlocked" :')[0]
- .slice(1, -2);
- const json_alerts = JSON.parse(split_str);
- for (const alert of json_alerts) {
- const { subject, sender, senderIP, recipient } = alert;
- console.log(subject, recipient);
- const alertExtraInfo = {
- subject: subject ? subject : undefined,
- sender: sender ? sender : undefined,
- recipient: recipient ? recipient : undefined,
- senderIP: senderIP ? senderIP : undefined
- };
- acc.push({ alertExtraInfo });
- }
- }
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- console.log('reduce the methods iterated altogether' + num_alert + ' times');
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let desc = `Observed ${summary.split(']')[1]}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- if (key == 'messageTime' || key == 'clickTime' || key == 'threatTime') {
- desc += `${key}(<span class="red_highlight">GMT</span>): ${value.split('.')[0]}\n`;
- } else {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function ZscalerAlertHandler(...kwargs) {
- const { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const BraceIndex = log.toString().indexOf('{');
- const lastBraceIndex = log.toString().lastIndexOf('}');
-
- // If the braces are found
- if (BraceIndex !== -1) {
- raw_alert += 1;
- // Intercepts a substring from the beginning of the brace to the end of the string
- json_text = log.toString().substr(BraceIndex, lastBraceIndex);
- const json_alert = JSON.parse(json_text);
- const { PrivateIP, PublicIP, Username, Customer, Hostname } = json_alert;
- const alertExtraInfo = {
- Hostname: Hostname ? Hostname : undefined,
- PublicIP: PublicIP ? PublicIP : undefined,
- PrivateIP: PrivateIP ? PrivateIP : undefined,
- Username: Username ? Username : undefined,
- Customer: Customer ? Customer : undefined
- };
- acc.push({ alertExtraInfo });
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let desc = `Observed ${summary.split(']')[1]}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease verify if the ip is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n'); //Can achieve automatic deduplication
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function PulseAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- if (rawLog == '') {
- var rawLog = $('#customfield_10219-val').text().trim().split('\n');
- }
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- if (log.includes('PulseSecure')) {
- var firstIndex = log.indexOf('PulseSecure:');
- let time_text = '';
- if (summary.toLowerCase().includes('suspicious geolocation ip login success')) {
- time_text = log.toString().substr(0, firstIndex);
- } else {
- time_text = log.toString().substr(firstIndex + 13);
- const first_bar = time_text.indexOf(':');
- time_text = time_text.toString().substr(0, first_bar + 6);
- }
- const lastIndex = log.toString().lastIndexOf('Vendor)');
- let alert_text = log
- .toString()
- .substr(lastIndex + 7)
- .replace('[][] -', '');
- const lastIndex_ = alert_text.toString().lastIndexOf(' - ');
- alert_text = alert_text.substr(lastIndex_ + 2);
- let first = log.indexOf('- ');
- let second = log.indexOf(' - [');
- let vpn_name = log.toString().substring(first + 2, second) + ' ';
- const alert_content = '\n' + vpn_name + alert_text + ' On ' + time_text + '\n';
- acc.push(alert_content);
- raw_alert += 1;
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- let desc = `Observed ${summary.split(']')[1]}\n`;
- desc += alertInfo;
- desc += `\n\nPlease verify if the login is legitimate.\n`;
- alertDescriptions.push(desc);
- const alertMsg = [...new Set(alertDescriptions)].join('\n'); //Can achieve automatic deduplication
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function Risky_Countries_AlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const json_alert = JSON.parse(log);
- if (json_alert.hasOwnProperty('azure')) {
- const {
- createdDateTime,
- userDisplayName,
- userPrincipalName,
- ipAddress,
- appDisplayName,
- deviceDetail,
- status
- } = json_alert['azure'];
- const { failureReason, additionalDetails } = status;
- const { displayName, operatingSystem } = deviceDetail;
-
- const alertExtraInfo = {
- createdEventDateTime: createdDateTime ? createdDateTime : undefined,
- userDisplayName: userDisplayName ? userDisplayName : undefined,
- userPrincipalName: userPrincipalName ? userPrincipalName : undefined,
- appDisplayName: appDisplayName ? appDisplayName : undefined,
- ipAddress: ipAddress ? ipAddress : undefined,
- operatingSystem: operatingSystem ? operatingSystem : undefined,
- DeviceName: displayName ? displayName : 'N/A',
- failureReason: failureReason ? failureReason : undefined,
- additionalDetails: additionalDetails ? additionalDetails : undefined
- };
- acc.push({ alertExtraInfo });
- }
- if (json_alert.hasOwnProperty('office_365')) {
- let alertExtraInfo;
- if (json_alert['office_365'].hasOwnProperty('Data')) {
- console.log(JSON.parse(json_alert['office_365']['Data']));
- let data = JSON.parse(json_alert['office_365']['Data']);
- alertExtraInfo = {
- CreationEventTime: data['wsrt'] ? data['wsrt'] : undefined,
- Username: data['f3u'] ? data['f3u'] : undefined,
- Workload: data['wl'] ? data['wl'] : undefined,
- Reason: data['ad'] ? data['ad'] : undefined
- };
- } else if (!json_alert['office_365'].hasOwnProperty('ClientIP')) {
- let data = json_alert['office_365'];
- alertExtraInfo = {
- CreationEventTime: data['CreationTime'] ? data['CreationTime'] : undefined,
- Operation: data['Operation'] ? data['Operation'] : undefined,
- ResultStatus: data['ResultStatus'] ? data['ResultStatus'] : undefined,
- UserId: data['UserId'] ? data['UserId'] : undefined,
- ObjectId: data['ObjectId'] ? data['ObjectId'] : undefined,
- UserKey: data['UserKey'] ? data['UserKey'] : undefined
- };
- } else {
- const {
- CreationTime,
- Operation,
- Workload,
- ClientIP,
- UserId,
- ResultStatusDetail,
- UserAgent,
- ActorIpAddress,
- DeviceProperties,
- UserKey
- } = json_alert['office_365'];
-
- let devicename = '';
- DeviceProperties.forEach((item) => {
- if (item.Name === 'DisplayName') {
- devicename = item.Value;
- }
- });
- alertExtraInfo = {
- CreationEventTime: CreationTime ? CreationTime : undefined,
- Operation: Operation ? Operation : undefined,
- Workload: Workload ? Workload : undefined,
- UserId: UserId ? UserId : undefined,
- ClientIP: ClientIP ? ClientIP : undefined,
- ActorIpAddress: ActorIpAddress ? ActorIpAddress : undefined,
- UserAgent: UserAgent ? UserAgent : undefined,
- DeviceName: devicename ? devicename : 'N/A',
- UserKey: UserKey ? UserKey : undefined,
- ResultStatusDetail: ResultStatusDetail ? ResultStatusDetail : undefined
- };
- }
-
- acc.push({ alertExtraInfo });
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- console.log(alertInfo);
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
-
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- if (key == 'CreationEventTime') {
- desc += `CreationEventTime(<span class="red_highlight">GMT</span>): ${value}\n`;
- } else {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function Agent_Disconnect_AlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- const LogSource = $('#customfield_10204-val').text().trim().split('\n');
- function parseLog(LogSource) {
- const alertInfo = LogSource.reduce((acc, log) => {
- try {
- log = log.replace(/\s/g, '');
- if (log == 'Show' || log == 'Hide' || log.length == 0) {
- console.log('ss');
- } else {
- acc.push(log);
- console.log(log);
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- let alertInfo = [...new Set(parseLog(LogSource))];
- function generateDescription() {
- const alertDescriptions = [];
-
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}, kindly please help to check it.\n`;
- desc += `\nagent name: ${alertInfo.join(',')}`;
- alertDescriptions.push(desc);
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- function openMDE() {
- let KQL = '';
- KQL += `name=${alertInfo.join(' or name=')} \n`;
- showFlag('info', 'KQL:', `${KQL}`, 'manual');
- }
- addButton('generateDescription', 'Description', generateDescription);
- addButton('openKQL', 'KQL', openMDE);
- }
-
- function MdbAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- if (rawLog.length == 0 || rawLog.length == 1) {
- rawLog = $('#customfield_10219-val').text().trim().split('\n');
- }
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- if (log.length == 0) {
- return acc;
- }
- if (summary.toLowerCase().includes('syslog: user missed the password more than one time')) {
- let log_ = log.split(';')[1].split(' ');
- let time_host = log.split(' sshd')[0].split(' ');
- let user = '';
- if (log_.length > 7) {
- user = log_[8].split('=')[1];
- }
- let description = `Observed user<span class='black_highlight'> ${user}</span> multiple ssh login failed from ${
- log_[6].split('=')[1]
- }\nCreateTime: ${time_host
- .slice(0, time_host.length - 1)
- .join(' ')}\nHostname: <span class='black_highlight'> ${
- time_host[time_host.length - 1]
- }</span>\n`;
-
- acc.push(description);
- }
- if (summary.toLowerCase().includes('sshd: insecure connection attempt')) {
- let log_ = log.split(' ');
- console.log('log', log_);
- let description = `Observed insecure connection attempt from ${
- log_[log_.length - 3]
- }\nCreateTime: ${log_.slice(0, log_.length - 11).join(' ')}\n`;
- acc.push(description);
- }
- if (
- summary
- .toLowerCase()
- .includes('anomaly: suspected lateral movement - linux containing session opened')
- ) {
- let log_ = log.split('>')[1] + '\n';
- console.log('log', log_);
- acc.push(log_);
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- if (summary.toLowerCase().includes('anomaly: suspected lateral movement - linux containing session opened')) {
- const Log_source = $('#customfield_10204-val').text().trim();
- alertDescriptions.push(`Observed session opened on <span class='black_highlight'>${Log_source}</span>\n`);
- }
- for (const info of alertInfo) {
- alertDescriptions.push(info);
- }
- if (summary.toLowerCase().includes('sshd: insecure connection attempt')) {
- alertDescriptions.push('Kindly help to verify if the connection is legitimate\n');
- }
- if (summary.toLowerCase().includes('syslog: user missed the password more than one time')) {
- alertDescriptions.push('Kindly help to verify if the login is legitimate\n');
- }
- if (summary.toLowerCase().includes('anomaly: suspected lateral movement - linux containing session opened')) {
- alertDescriptions.push('Kindly help to verify if the session is legitimate\n');
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function AlicloudAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const BraceIndex = log.toString().indexOf('{');
- const lastBraceIndex = log.toString().lastIndexOf('}');
- if (BraceIndex !== -1) {
- raw_alert += 1;
- // Intercepts a substring from the beginning of the brace to the end of the string
- json_text = log.toString().substr(BraceIndex, lastBraceIndex);
- let time_1 = log.toString().substr(0, BraceIndex).split(' ');
- let time = time_1.slice(time_1.length - 4, time_1.length - 2).join(' ');
- time = time_1[0] + ' ' + time;
- try {
- const json_alert = JSON.parse(json_text);
- let {
- eventId,
- uuid,
- eventName,
- resourceName,
- sourceIpAddress,
- userIdentity,
- intranet_ip,
- internet_ip,
- instance_id,
- extend_content,
- detail,
- requestParameters,
- responseElements
- } = json_alert['alicloud'];
- let alertExtraInfo = {
- createTime: time,
- eventId: eventId ? eventId : undefined,
- uuid: uuid ? uuid : undefined,
- eventName: eventName ? eventName : undefined,
- InstanceId: resourceName ? resourceName : undefined,
- sourceIpAddress: sourceIpAddress ? sourceIpAddress : undefined,
- userName: userIdentity?.userName ? userIdentity?.userName : undefined,
- internet_ip: internet_ip ? internet_ip : undefined,
- intranet_ip: intranet_ip ? intranet_ip : undefined,
- instance_id: instance_id ? instance_id : undefined,
- extend_content: extend_content ? extend_content : undefined,
- responseElements: responseElements ? JSON.stringify(responseElements) : undefined
- };
- console.log('===', requestParameters, time);
-
- if (detail != undefined) {
- detail = JSON.parse(detail);
- alertExtraInfo = Object.assign({}, alertExtraInfo, detail);
- }
- if (requestParameters != undefined) {
- alertExtraInfo = Object.assign({}, alertExtraInfo, requestParameters);
- }
-
- console.log(alertExtraInfo);
- acc.push({ alertExtraInfo });
- } catch (error) {
- console.log('Unable to parse JSON data, handling exception: ' + error);
- }
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function DstAlertHandler(...kwargs) {
- var rawLog = $('#field-customfield_10904').text().trim().split('\n');
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const json_alert = JSON.parse(log);
- const { system, eventdata } = json_alert['win'];
- const alertExtraInfo = {
- computer: system?.computer ? system?.computer : undefined,
- commandLine: eventdata?.commandLine ? eventdata?.commandLine : undefined
- };
- acc.push({ alertExtraInfo });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- let desc = ``;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function ThreatMatrixAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const json_alert = JSON.parse(log);
- console.log(json_alert['threatmatrix']);
- const {
- account_telephone,
- account_login,
- application_name,
- customer_event_type,
- input_ip_address,
- event_datetime,
- input_ip_city,
- input_ip_geo,
- input_ip_isp,
- input_ip_organization,
- policy,
- tmx_risk_rating,
- request_result
- } = json_alert['threatmatrix'];
- const alertExtraInfo = {
- account_telephone: account_telephone ? account_telephone : undefined,
- account_login: account_login ? account_login : undefined,
- application_name: application_name ? application_name : undefined,
- customer_event_type: customer_event_type ? customer_event_type : undefined,
- input_ip_address: input_ip_address ? input_ip_address : undefined,
- input_ip_city: input_ip_city ? input_ip_city : undefined,
- input_ip_geo: input_ip_geo ? input_ip_geo : undefined,
- input_ip_isp: input_ip_isp ? input_ip_isp : undefined,
- input_ip_organization: input_ip_organization ? input_ip_organization : undefined,
- policy: policy ? policy : undefined,
- tmx_risk_rating: tmx_risk_rating ? tmx_risk_rating : undefined,
- request_result: request_result ? request_result : undefined,
- event_datetime: event_datetime ? event_datetime.split('.')[0] : undefined
- };
- acc.push({ alertExtraInfo });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease verify if the login is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function DarktraceAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- var breach_Url;
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const BraceIndex = log.toString().indexOf('{');
- const lastBraceIndex = log.toString().lastIndexOf('}');
- const logarray = log.toString().split(' ');
- if (BraceIndex !== -1) {
- raw_alert += 1;
- // Intercepts a substring from the beginning of the brace to the end of the string
- json_text = log.toString().substr(BraceIndex, lastBraceIndex);
- const json_alert = JSON.parse(json_text);
- let alertExtraInfo = {},
- Resource_paths = [];
- breach_Url = json_alert['breachUrl'] + '<br>' + json_alert['incidentEventUrl'];
- let year = ' 20' + $('#created-val').text().trim().split('/')[2].split(' ')[0]; //动态产生工单的年份
- let time_str = logarray.slice(0, 3).join(' ') + year;
- if (!time_str.includes(':')) {
- time_str = logarray.slice(0, 4).join(' ').replace(' ', ' ') + year;
- }
-
- if (json_alert.hasOwnProperty('model')) {
- const { device, triggeredComponents, model } = json_alert;
- let User_agent = '',
- Message;
- alertExtraInfo = {
- AlertTime: formatCurrentDateTime(time_str),
- hostname: device?.hostname ? device?.hostname : undefined,
- ip: device?.ip ? device?.ip : undefined,
- credentials: device?.credentials ? device?.credentials : undefined,
- subnetlabel: device?.ips ? device?.ips[0].subnetlabel : undefined,
- typename: device?.typename ? device?.typename : undefined,
- User_agent: User_agent ? User_agent : undefined,
- saas_info: device?.customFields?.saasinfo
- ? device.customFields.saasinfo.saas_info
- : undefined,
- Message: Message ? Message : undefined,
- description: model?.description ? model?.description.replace(/\\\n/g, ' ') : undefined
- };
- triggeredComponents[0]['triggeredFilters'].forEach((item) => {
- if (item['filterType'] == 'User agent' && item['id'] == 'O') {
- User_agent = item['arguments']['value'];
- console.log('value', item['arguments']['value']);
- } else if (item['id'] == 'C') {
- Message = item['trigger']['value'];
- } else if (
- item['filterType'].includes('IP') ||
- item['filterType'] == 'Resource Location' ||
- item['filterType'] == 'Event' ||
- item['filterType'] == 'Connection hostname'
- ) {
- alertExtraInfo[item['filterType']] = item['trigger']['value'];
- }
- });
- } else {
- const { summary, breachDevices, details } = json_alert;
- let values;
- alertExtraInfo = {
- AlertTime: formatCurrentDateTime(time_str),
- hostname: breachDevices[0]?.hostname ? breachDevices[0]?.hostname : undefined,
- host_ip: breachDevices[0]?.ip ? breachDevices[0]?.ip : undefined,
- summary: summary ? summary : undefined
- };
- details.forEach((item) => {
- if (item[0].header == 'Endpoint Details') {
- values = item[0].contents[0].values;
- item[0].contents.forEach((i) => {
- if (i.key == 'IP addresses associated with hostnames') {
- console.log(i);
- alertExtraInfo[i.type] = JSON.stringify(i.values);
- }
- });
- }
- item.forEach((ii) => {
- if (
- ii.header == 'Activity Details' ||
- ii.header == 'Details of Accessing Users' ||
- ii.header == 'Resource Access Details'
- ) {
- ii.contents.forEach((i) => {
- if (i['key'] == 'Resource paths include' || i['key'] == 'Resource path') {
- i['values'].forEach((iii) => {
- Resource_paths.push(iii);
- });
- } else if (
- i['key'].includes('Source IPs') ||
- i['key'].includes('Actors include')
- ) {
- alertExtraInfo[i.key] = JSON.stringify(i.values);
- }
- });
- }
- });
- });
- Resource_paths = [...new Set(Resource_paths)].join('\n');
- alertExtraInfo['Resource_paths'] = Resource_paths ? Resource_paths : undefined;
- alertExtraInfo['Endpoint Details'] = values ? values : undefined;
- }
- acc.push({ alertExtraInfo });
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let ss = summary.substr(lastindex + 1).split('::');
- let desc = `Observed ${ss[ss.length - 1]}\n\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease help to verify if this activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- function breachUrl() {
- showFlag('info', 'breach Url:', `${breach_Url.replace('hXXps[:]', 'https:')}`, 'manual');
- }
- addButton('generateDescription', 'Description', generateDescription);
- addButton('breachUrl', 'breachUrl', breachUrl);
- }
-
- function SangforAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- if (log.length == 0) {
- return acc;
- }
- const regex = /(\b\w+=)([^=\s].*?)(?=\s+\w+=|$)/g;
- let match;
- const matches = {};
- while ((match = regex.exec(log)) !== null) {
- let item = match[0].split('=');
- matches[item[0]] = item.slice(1, item.length).join('=');
- }
- console.log(matches);
- var pattern = /event_evidence.*?(?=suffer_classify1_id_name)/g;
- console.log(log.match(pattern));
- let logArray = log.split(' ').filter((item) => item !== ''); //Remove extra whitespace from the string
- const DecoderName = $('#customfield_10807-val').text().trim().toLowerCase();
- if (DecoderName == 'cyberark_cef') {
- let data_json = {
- 'Event time': logArray.slice(0, 3).join(' '),
- 'event_desc': matches.event_desc ? matches.event_desc : undefined,
- 'dhost': matches.dhost ? matches.dhost : undefined,
- 'dst': matches.dst ? matches.dst : undefined,
- 'duser': matches.duser ? matches.duser : undefined,
- 'shost': matches.shost ? matches.shost : undefined,
- 'src': matches.src ? matches.src : undefined,
- 'suser': matches.suser ? matches.suser : undefined
- };
- data_json[matches.cs3Label] = matches.cs3 ? matches.cs3 : undefined;
- acc.push(data_json);
- } else if (DecoderName == 'trellix_cef') {
- let data_json = {
- filePath: matches.filePath ? matches.filePath : undefined,
- rt: matches.rt ? matches.rt : undefined,
- duser: matches.duser ? matches.duser : undefined,
- msg: matches.msg ? matches.msg : undefined,
- act: matches.act ? matches.act : undefined,
- suser: matches.suser ? matches.suser.replace(/[<>]/g, '') : undefined,
- fileType: matches.fileType ? matches.fileType : undefined,
- subject: matches.subject ? matches.subject : undefined
- };
- data_json[matches.cs1Label] = matches.cs1 ? matches.cs1 : undefined;
- data_json[matches.cs4Label] = matches.cs4 ? matches.cs4 : undefined;
- data_json[matches.flexString2Label] = matches.flexString2 ? matches.flexString2 : undefined;
- acc.push(data_json);
- } else if (DecoderName == 'impervainc_cef') {
- console.log('===', matches);
- console.log('===start ', formatCurrentDateTime(parseInt(matches.start), 'impervainc_cef'));
- let data_json = {
- start_time: matches.start
- ? formatCurrentDateTime(parseInt(matches.start), 'impervainc_cef')
- : undefined,
- end_time: matches.end
- ? formatCurrentDateTime(parseInt(matches.end), 'impervainc_cef')
- : undefined,
- dhost: matches.dhost ? matches.dhost : undefined,
- AlertTime: matches.rt ? matches.rt : undefined,
- src: matches.src ? matches.src : undefined,
- sptPort: matches.spt ? matches.spt : undefined,
- dstIP: matches.dst ? matches.dst : undefined,
- dstPort: matches.dpt ? matches.dpt : undefined,
- protocol: matches.proto ? matches.proto : undefined,
- request: matches.request ? matches.request : undefined,
- requestClientApplication: matches.requestClientApplication
- ? matches.requestClientApplication
- : undefined,
- msg: matches.msg ? matches.msg : undefined
- };
- data_json[matches.cs1Label] = matches.cs1 ? matches.cs1 : undefined;
- data_json[matches.cs2Label] = matches.cs2 ? matches.cs2 : undefined;
- data_json[matches.cs3Label] = matches.cs3 ? matches.cs3 : undefined;
- data_json[matches.cs4Label] = matches.cs4 ? matches.cs4 : undefined;
- data_json[matches.cs5Label] = matches.cs5 ? matches.cs5 : undefined;
- data_json[matches.cs6Label] = matches.cs6 ? matches.cs6 : undefined;
- data_json[matches.cs7Label] = matches.cs7 ? matches.cs7 : undefined;
- data_json[matches.cs8Label] = matches.cs8 ? matches.cs8 : undefined;
- data_json[matches.cs9Label] = matches.cs9 ? matches.cs9 : undefined;
-
- acc.push(data_json);
- } else if (DecoderName == 'checkpoint_cef') {
- let data_json = {
- Signature: matches.Signature ? matches.Signature : undefined,
- cp_severity: matches.cp_severity ? matches.cp_severity : undefined,
- src: matches.src ? matches.src : undefined,
- dst: matches.dst ? matches.dst : undefined,
- origin: matches.origin ? matches.origin : undefined
- };
- data_json[matches.cs2Label] = matches.cs2 ? matches.cs2 : undefined;
- data_json[matches.cs3Label] = matches.cs3 ? matches.cs3 : undefined;
- data_json[matches.cs4Label] = matches.cs4 ? matches.cs4 : undefined;
- data_json[matches.flexNumber1Label] = matches.flexNumber1 ? matches.flexNumber1 : undefined;
- data_json[matches.flexNumber2Label] = matches.flexNumber2 ? matches.flexNumber2 : undefined;
- data_json[matches.flexString2Label] = matches.flexString2 ? matches.flexString2 : undefined;
- acc.push(data_json);
- } else if (DecoderName == 'incapsula_cef') {
- let data_json = {
- requestClientApplication: matches.requestClientApplication
- ? matches.requestClientApplication
- : undefined,
- request: matches.request ? matches.request : undefined,
- requestMethod: matches.requestMethod ? matches.requestMethod : undefined,
- postbody: matches.postbody ? matches.postbody : undefined,
- qstr: matches.qstr ? matches.qstr : undefined,
- act: matches.act ? matches.act : undefined,
- sip: matches.sip ? matches.sip : undefined,
- spt: matches.spt ? matches.spt : undefined,
- xff: matches.xff ? matches.xff : undefined,
- cpt: matches.cpt ? matches.cpt : undefined,
- src: matches.src ? matches.src : undefined
- };
- data_json[matches.cs9Label] = matches.cs9 ? matches.cs9 : undefined;
- acc.push(data_json);
- } else if (window.location.href.includes('macaumss')) {
- acc.push({
- 'Event time': logArray.slice(0, 3).join(' '),
- 'event_desc': matches.event_desc ? matches.event_desc : undefined,
- 'dev_name': matches.dev_name ? matches.dev_name : undefined,
- 'attack_ip': matches.attack_ip ? matches.attack_ip : undefined,
- 'suffer_ip': matches.suffer_ip ? matches.suffer_ip : undefined,
- 'suffer_port': matches.suffer_port ? matches.suffer_port : undefined,
- 'status_code': matches.status_code ? matches.status_code : undefined,
- 'x_forwarded_for': matches.x_forwarded_for ? matches.x_forwarded_for : undefined,
- 'event_evidence': log.match(pattern) ? log.match(pattern)[0] : undefined,
- 'attack_type_name': matches.attack_type_name ? matches.attack_type_name : undefined
- });
- } else {
- acc.push({
- 'Event time': logArray.slice(0, 3).join(' '),
- 'event_desc': matches.event_desc ? matches.event_desc : undefined,
- 'dev_name': matches.dev_name ? matches.dev_name : undefined,
- 'suffer_ip': matches.suffer_ip ? matches.suffer_ip : undefined,
- 'attack_ip': matches.attack_ip ? matches.attack_ip : undefined,
- 'event_evidence': matches.event_evidence ? matches.event_evidence : undefined,
- 'url': matches.url ? matches.url : undefined,
- 'suggest': matches.suggest ? matches.suggest : undefined
- });
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc;
- if (summary.includes('-')) {
- desc = `Observed ${summary.substr(lastindex + 1).split('-')[1]}\n`;
- } else {
- desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- }
- for (const key in info) {
- if (Object.hasOwnProperty.call(info, key)) {
- const value = info[key];
- if (value !== undefined) {
- if (key == 'event_evidence') {
- desc += `${key}: ${value.replace(/</g, '<').replace(/>/g, '>')}\n`;
- } else if (key == 'start_time' || key == 'end_time' || key == 'AlertTime') {
- desc += `${key}(<span class="red_highlight">GMT+8</span>): ${value.split('.')[0]}\n`;
- } else {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function RadwareAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const json_alert = JSON.parse(log);
- const {
- device_ip,
- device_name,
- device_abbr,
- detected_by,
- asset_name,
- asset_type,
- asset_ip,
- account_uid,
- account_name,
- acc_site_name,
- end_time,
- start_time
- } = json_alert['radware'];
-
- alertExtraInfo = {
- start_time: start_time._date_time ? start_time._date_time : undefined,
- end_time: end_time._date_time ? end_time._date_time : undefined,
- device_ip: device_ip ? device_ip : undefined,
- device_name: device_name ? device_name : undefined,
- device_abbr: device_abbr ? device_abbr : undefined,
- detected_by: detected_by ? detected_by : undefined,
- asset_name: asset_name ? asset_name : undefined,
- asset_type: asset_type ? asset_type : undefined,
- asset_ip: asset_ip ? asset_ip : undefined,
- account_uid: account_uid ? account_uid : undefined,
- account_name: account_name ? account_name : undefined,
- acc_site_name: acc_site_name ? acc_site_name : undefined
- };
- acc.push({ alertExtraInfo });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- if (key == 'start_time' || key == 'end_time') {
- desc += `${key}(<span class="red_highlight">GMT</span>): ${value.split('.')[0] + 'Z'}\n`;
- } else {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function CarbonAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const BraceIndex = log.toString().indexOf('{');
- const lastBraceIndex = log.toString().lastIndexOf('}');
- if (BraceIndex !== -1) {
- json_text = log.toString().substr(BraceIndex, lastBraceIndex);
- const json_alert = JSON.parse(json_text);
- const {
- reason,
- device_os_version,
- device_username,
- device_location,
- device_external_ip,
- device_internal_ip,
- device_name,
- process_pid,
- process_name,
- process_sha256,
- process_guid,
- process_cmdline,
- process_username,
- netconn_remote_ip,
- netconn_remote_port,
- parent_guid,
- parent_pid,
- parent_name,
- parent_sha256,
- parent_username,
- netconn_local_ip,
- netconn_local_port,
- first_event_timestamp
- } = json_alert;
- alertExtraInfo = {
- EventTime: first_event_timestamp.split('.')[0],
- device_name: device_name ? device_name : undefined,
- device_os_version: device_os_version ? device_os_version : undefined,
- device_username: device_username ? device_username : undefined,
- device_location: device_location ? device_location : undefined,
- device_external_ip: device_external_ip ? device_external_ip : undefined,
- device_internal_ip: device_internal_ip ? device_internal_ip : undefined,
- process_guid: process_guid ? process_guid : undefined,
- process_pid: process_pid ? process_pid : undefined,
- process_name: process_name ? process_name : undefined,
- process_sha256: process_sha256 ? process_sha256 : undefined,
- process_cmdline: process_cmdline ? process_cmdline : undefined,
- process_username: process_username ? process_username : undefined,
- parent_guid: parent_guid ? parent_guid : undefined,
- parent_pid: parent_pid ? parent_pid : undefined,
- parent_name: parent_name ? parent_name : undefined,
- parent_sha256: parent_sha256 ? parent_sha256 : undefined,
- parent_username: parent_username ? parent_username : undefined,
- netconn_remote_ip: netconn_remote_ip ? netconn_remote_ip : undefined,
- netconn_remote_port: netconn_remote_port ? netconn_remote_port : undefined,
- netconn_local_ip: netconn_local_ip ? netconn_local_ip : undefined,
- netconn_local_port: netconn_local_port ? netconn_local_port : undefined,
- reason: reason ? reason : undefined
- };
- raw_alert += 1;
- acc.push({ alertExtraInfo });
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (key == 'EventTime') {
- desc += `EventTime(<span class="red_highlight">GMT</span>): ${value + 'Z'}\n`;
- } else if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
-
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function MultipleAccountAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const json_alert = JSON.parse(log)['win'];
- const { targetUserName, targetDomainName, subjectUserName, subjectDomainName, subjectLogonId } =
- json_alert['eventdata'];
- const { systemTime, computer, message } = json_alert['system'];
- alertExtraInfo = {
- Eventtime: systemTime ? systemTime : undefined,
- computer: computer ? computer : undefined,
- targetUserName: targetUserName ? targetUserName : undefined,
- targetDomainName: targetDomainName ? targetDomainName : undefined,
- subjectUserName: subjectUserName ? subjectUserName : undefined,
- subjectDomainName: subjectDomainName ? subjectDomainName : undefined,
- message: message ? message.split('\r\n\r\n')[0] : undefined
- };
- acc.push({ alertExtraInfo });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- const single = [];
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const info of alertInfo) {
- let desc_ = '',
- single_ = '';
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- if (key == 'Eventtime') {
- desc_ += `${key}(<span class="red_highlight">GMT</span>): ${value.split('.')[0] + 'Z'}\n`;
- } else if (
- key == 'subjectUserName' ||
- key == 'subjectDomainName' ||
- key == 'computer' ||
- key == 'message' ||
- key == 'targetDomainName'
- ) {
- single_ += `${key}: ${value}\n`;
- } else {
- desc_ += `${key}: ${value}\n`;
- }
- }
- }
- }
- alertDescriptions.push(desc_);
- single.push(single_);
- }
- desc += [...new Set(single)].join('\n');
- desc += '\n';
- desc += [...new Set(alertDescriptions)].join('\n');
- desc += `Please verify if the activity is legitimate.\n`;
- showDialog(desc);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- /**
- * Create Description and Open MDE and MDE365 button
- * @param {...any} kwargs - Include LogSourceDomain, Labels, LogSource, TicketAutoEscalate, Status, RawLog, Summary fields
- */
- function MDE365AlertHandler(...kwargs) {
- console.log('#### Code MDE365lertHandler run ####');
- const { rawLog, LogSourceDomain, summary } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- let alertInfo_MDE = [],
- alertInfo_365 = [];
- function GMT8(params) {
- let date = new Date(params);
- date.setHours(date.getHours() + 16); // 获取当前的小时数并加上8小时
- const year = date.getUTCFullYear();
- const month = String(date.getUTCMonth() + 1).padStart(2, '0');
- const day = String(date.getUTCDate()).padStart(2, '0');
- const hours = String(date.getUTCHours()).padStart(2, '0');
- const minutes = String(date.getUTCMinutes()).padStart(2, '0');
- const seconds = String(date.getUTCSeconds()).padStart(2, '0');
-
- const formattedDate = `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;
- return formattedDate;
- }
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- let logObj = '';
- if (log != '') {
- try {
- if (log.charAt(log.length - 1) == '}') {
- const formatJson = log.substring(log.indexOf('{')).trim();
- logObj = JSON.parse(formatJson.replace(/\\\(n/g, '\\n('));
- } else {
- const formatJson = log.substring(log.indexOf('{')).trim() + '"}]}}';
- logObj = JSON.parse(formatJson.replace(/\\\(n/g, '\\n('));
- }
- if (logObj['integration'] == 'Wazuh-MDE') {
- raw_alert += 1;
- const { mde } = logObj;
- const { title, id, computerDnsName, relatedUser, evidence, alertCreationTime } = mde;
- let dotIndex = alertCreationTime.lastIndexOf('.');
-
- let dateTimeStr = GMT8(alertCreationTime.slice(0, dotIndex));
- const alert = { title, id, computerDnsName, dateTimeStr };
- const userName = relatedUser ? relatedUser.userName : 'N/A';
- let extrainfo = '';
- let processCommandLine = '';
- if (evidence) {
- const tmp = [];
- for (const evidenceItem of evidence) {
- let description = '';
-
- if (evidenceItem.entityType === 'File') {
- console.log('===', WhiteFilehash(evidenceItem.sha1));
- if (WhiteFilehash(evidenceItem.sha1) || WhiteFilehash(evidenceItem.sha256)) {
- description = `filename: ${evidenceItem.fileName}\nfilePath: ${evidenceItem.filePath}`;
- tmp.push(description);
- } else {
- description = `filename: ${evidenceItem.fileName}\nfilePath: ${evidenceItem.filePath}\nsha1: ${evidenceItem.sha1}`;
- tmp.push(description);
- }
- }
- if (evidenceItem.entityType === 'Process') {
- if (evidenceItem.processCommandLine !== undefined) {
- processCommandLine = evidenceItem.processCommandLine.replace(
- /\r\n\r\n+/g,
- '\n'
- );
- console.log(processCommandLine);
- }
- if (
- evidenceItem.processCommandLine !== undefined &&
- evidenceItem.processCommandLine.includes('EncodedCommand')
- ) {
- let cmd_length = evidenceItem.processCommandLine.split(' ').length;
- description = `Decode_Cmd: ${atob(
- evidenceItem.processCommandLine
- .split(' ')
- [cmd_length - 1].replace(/['"]/g, '')
- )}`;
- tmp.push(description);
- }
- if (WhiteFilehash(evidenceItem.sha1) || WhiteFilehash(evidenceItem.sha256)) {
- description = `cmd: ${processCommandLine}\naccount: ${evidenceItem.accountName}`;
- tmp.push(description);
- } else {
- description = `cmd: ${processCommandLine}\naccount: ${evidenceItem.accountName}\nsha1: ${evidenceItem.sha1}`;
- tmp.push(description);
- }
- }
- if (evidenceItem.entityType === 'Url') {
- description += `Url: ${evidenceItem.url}`;
- tmp.push(description);
- }
- if (evidenceItem.entityType === 'Ip') {
- description += `IP: ${evidenceItem.ipAddress}`;
- tmp.push(description);
- }
- }
- const uniqueDescriptions = Array.from(new Set(tmp));
- extrainfo = uniqueDescriptions.join('\n');
- }
- alertInfo_MDE.push({ ...alert, userName, extrainfo });
- } else {
- raw_alert += 1;
- const alerts = logObj['incidents']['alerts'][0];
- console.log(alerts);
- let entities = {};
- if (alerts !== undefined) {
- alerts['entities'].forEach(function (entity) {
- if (entity.processCommandLine !== undefined) {
- processCommandLine = entity.processCommandLine.replace(/\r\n\r\n+/g, '\n');
- console.log(processCommandLine);
- }
- if (entity['entityType'] == 'User' || entity['entityType'] == 'Mailbox') {
- entities['user'] = `${entity['domainName']}\\\\${entity['accountName']}`;
- entities['userPrincipalName'] = entity['userPrincipalName'];
- }
- if (entity['entityType'] == 'CloudApplication') {
- entities['applicationId'] = entity['applicationId'];
- entities['applicationName'] = entity['applicationName'];
- }
- if (entity['entityType'] == 'Process') {
- if (!entities['process']) {
- entities['process'] = [];
- }
- const fileEntry = {
- filename: entity['fileName'],
- filePath: entity['filePath'],
- cmd: processCommandLine
- };
- if (processCommandLine.includes('EncodedCommand')) {
- let cmd_length = processCommandLine.split(' ').length;
- fileEntry['Decode_Cmd'] = atob(
- processCommandLine.split(' ')[cmd_length - 1].replace(/['"]/g, '')
- );
- }
- if (
- Object.keys(entity).includes('sha256') &&
- (WhiteFilehash(entity['sha256']) || WhiteFilehash(entity['sha1']))
- ) {
- entities['process'].push(fileEntry);
- } else {
- fileEntry['sha256'] = entity['sha256'];
- entities['process'].push(fileEntry);
- }
- }
-
- if (entity['entityType'] == 'File') {
- if (!entities['file']) {
- entities['file'] = [];
- }
- const fileEntry = {
- filename: entity['fileName'],
- filePath: entity['filePath']
- };
- if (
- Object.keys(entity).includes('sha256') &&
- (WhiteFilehash(entity['sha256']) || WhiteFilehash(entity['sha1']))
- ) {
- entities['file'].push(fileEntry);
- } else {
- fileEntry['sha256'] = entity['sha256'];
- entities['file'].push(fileEntry);
- }
- }
-
- if (entity['entityType'] == 'Ip') {
- if (!entities['ip']) {
- entities['ip'] = [];
- }
- entities['ip'].push({
- ip: entity['ipAddress']
- });
- }
- if (entity['entityType'] == 'Url') {
- if (!entities['url']) {
- entities['url'] = [];
- }
- entities['url'].push({
- url: entity['url']
- });
- }
- });
- }
- let creationTime = GMT8(alerts.creationTime.split('.')[0]);
- let title = alerts?.title;
- if (summary.toLowerCase().includes(title.toLowerCase())) {
- title = undefined;
- }
- alertInfo_365.push({
- creationTime: creationTime,
- Title: title,
- summary: logObj['incidents'].incidentName,
- host: alerts?.devices[0]?.deviceDnsName,
- user: entities.user,
- userPrincipalName: entities.userPrincipalName,
- process: entities.process,
- file: entities.file,
- ip: entities.ip,
- url: entities.url,
- alertid: alerts?.alertId,
- incidenturi: logObj['incidents'].incidentUri,
- severity: logObj['incidents'].severity,
- description: alerts['description'],
- applicationId: entities.applicationId,
- applicationName: entities.applicationName
- });
- }
- } catch (error) {
- console.error(`Error: ${error.message}`);
- }
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertDescriptions = [];
- parseLog(rawLog);
-
- function generateDescription_MDE() {
- for (const info of alertInfo_MDE) {
- const { title, computerDnsName, userName, extrainfo, dateTimeStr } = info;
- const desc = `Observed ${title}\nalertCreationTime(<span class="red_highlight">GMT+8</span>): ${dateTimeStr}\nHost: ${computerDnsName}\nusername: ${userName}\n${extrainfo}\n\nPlease help to verify if it is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- }
- function generateDescription_365() {
- if (summary.includes('M365 Defender High Severity Alerts: Logon from a risky country involving one user')) {
- const ticketnumber = $('#key-val').text();
- for (const info of alertInfo) {
- let desc = `Dear Customer,
-
- Reasons for escalating:
-
- Observed Logon from a risky country involving one user in [time]
-
- Here is information about this login:
-
- creationTime(<span class="red_highlight"">GMT</span>): ${info.creationTime}
-
- source IP: ${info.ip[0].ip}
-
- user: ${info.user}
-
- active: Microsoft 365
-
- userPrincipalName: ${info.userPrincipalName}
-
- Device type:
-
- UserAgent:
-
- location:
-
- logging status:
-
- LoginStatus:
-
- MfaRequired:
-
- the user suddenly logged in from [Location1] but the user used to be logged in from [Location2], aberdeen. Please confirm whether the login behavior of the user is normal.if not, could block the ip.
-
-
- Suggestion: We suggest to confirm whether the behavior of this customer logging in at ${info.ip[0].ip}: is normal or not, if not, we suggest to block the IP and change the user's password and perform a full scan on the user's commonly used PCs, thank you!
-
- Severity: ${info.severity}
-
- Correlation ticket: ${ticketnumber}
-
- `;
- alertDescriptions.push(desc);
- }
- } else {
- for (const info of alertInfo_365) {
- let desc = `Observed ${info.summary}\n`;
- try {
- for (let key in info) {
- if (info.hasOwnProperty(key)) {
- if (Array.isArray(info[key])) {
- info[key].forEach((item) => {
- for (let subKey in item) {
- if (item.hasOwnProperty(subKey) && item[subKey] !== '') {
- desc += `${subKey}: ${item[subKey]}\n`;
- }
- }
- });
- } else {
- if (
- info[key] !== undefined &&
- info[key] !== ' ' &&
- key !== 'summary' &&
- key !== 'alertid' &&
- key !== 'incidenturi' &&
- key !== 'severity'
- ) {
- if (key == 'creationTime') {
- desc += `creationTime(<span class="red_highlight">GMT+8</span>): ${info[key]}\n`;
- } else {
- desc += `${key}: ${info[key]}\n`;
- }
- }
- }
- }
- }
- } catch (error) {
- console.error(`Error: ${error}`);
- }
- let MDEURL = '';
- if (LogSourceDomain == 'wkcda') {
- if (info.alertid && !MDEURL.includes(info.alertid)) {
- MDEURL += `https://security.microsoft.com/alerts/${info.alertid}<br>`;
- }
- if (info.incidenturi) {
- let incident_url = info.incidenturi.replace('hXXps[:]', 'https:') + '<br>';
- MDEURL += incident_url;
- }
- desc += `MDE URL: \n${MDEURL}\n`;
- }
-
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- }
- }
- function generateDescription() {
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- generateDescription_MDE();
- generateDescription_365();
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- function openMDE() {
- let MDEURL = '';
- for (const info of alertInfo_MDE) {
- const { id } = info;
- if (id) {
- MDEURL += `https://security.microsoft.com/alerts/${id}<br>`;
- }
- }
- for (const info of alertInfo_365) {
- const { alertid, incidenturi } = info;
- if (alertid && !MDEURL.includes(alertid)) {
- MDEURL += `https://security.microsoft.com/alerts/${alertid}<br>`;
- }
- if (incidenturi) {
- let incident_url = incidenturi.replace('hXXps[:]', 'https:') + '<br>';
- MDEURL += incident_url;
- }
- }
- showFlag('info', 'MDE URL:', `${MDEURL}`, 'manual');
- let url = 'https://security.microsoft.com/homepage?¤t=';
- url += LogSourceDomain;
- for (let i = 0; i < MDEURL.length; i++) {
- let mde_url = `&url${i}=${MDEURL[i]}`;
- url += mde_url;
- console.log(MDEURL[i]);
- }
- let MDE_Assist_ = localStorage.getItem('MDE_Assist');
- if (MDE_Assist_ != 0) {
- GM_openInTab(url, {
- active: false, // 设置为 false,以在后台打开,不激活新标签页
- insert: true // 设置为 true,将新标签页插入到当前标签页之后
- });
- }
- }
- addButton('generateDescription', 'Description', generateDescription);
- addButton('openMDE', 'MDE', openMDE);
- }
-
- function WindowsSysAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- if (log != '') {
- let log_data = {},
- sub = '';
- log.split('#010').forEach((element, index) => {
- if (element.includes('#013')) {
- element = element.replace(/#013/g, '');
- }
- if (element.includes('#009')) {
- let e = element.replace(/#009/g, '').split(':');
- log_data[e[0]] = e[1];
- }
- if (element.includes('=')) {
- let e = element.replace(/#013/g, '').split('=');
- log_data[e[0]] = e[1];
- }
- if (element.includes(':#013')) {
- sub = element.split(':')[0];
- }
- if (
- element.includes(':#009') &&
- (element.includes('Account') ||
- element.includes('Security ID') ||
- element.includes('Logon ID'))
- ) {
- let e = element.replace(/#009/g, ' ').replace(/#013/g, '').split(': ');
- log_data[sub + e[0].trim()] = e[1];
- }
- if (element.includes(':#009')) {
- let e = element.replace(/#009/g, ' ').replace(/#013/g, '').split(': ');
- log_data[e[0].trim()] = e[1];
- }
- });
- const regex = /(\S+\s+\S+\s+\S+\s+\S+\s+)(.*)/g;
- alertExtraInfo = {
- Event_time: regex.exec(log.split('#010')[0])[2],
- ComputerName: log_data.ComputerName ? log_data.ComputerName : undefined,
- EventCode: log_data.EventCode ? log_data.EventCode : undefined,
- SourceName: log_data.SourceName ? log_data.SourceName : undefined,
- CreatorAccountDomain: log_data['Creator SubjectAccount Domain']
- ? log_data['Creator SubjectAccount Domain']
- : undefined,
- CreatorAccountName: log_data['Creator SubjectAccount Name']
- ? log_data['Creator SubjectAccount Name']
- : undefined,
- Type: log_data.Type ? log_data.Type : undefined,
- Keywords: log_data.Keywords ? log_data.Keywords : undefined,
- Message: log_data.Message ? log_data.Message : undefined,
- CreatorProcessID: log_data['Creator Process ID'] ? log_data['Creator Process ID'] : undefined,
- CreatorProcessName: log_data['Creator Process Name']
- ? log_data['Creator Process Name']
- : undefined,
- NewProcessID: log_data['New Process ID'] ? log_data['New Process ID'] : undefined,
- NewProcessName: log_data['New Process Name'] ? log_data['New Process Name'] : undefined,
- ProcessCommandLine: log_data['Process Command Line']
- ? log_data['Process Command Line']
- : undefined,
- ProcessCommandLine: log_data['Process Command Line']
- ? log_data['Process Command Line']
- : undefined,
- SecurityID: log_data['Security ID'] ? log_data['Security ID'] : undefined,
- ServiceAccount: log_data['Service Account'] ? log_data['Service Account'] : undefined,
- ServiceFileName: log_data['Service File Name'] ? log_data['Service File Name'] : undefined,
- ServiceName: log_data['Service Name'] ? log_data['Service Name'] : undefined,
- ServiceStartType: log_data['Service Start Type'] ? log_data['Service Start Type'] : undefined,
- ServiceType: log_data['Service Type'] ? log_data['Service Type'] : undefined
- };
- acc.push({ alertExtraInfo });
- }
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info.alertExtraInfo) {
- if (Object.hasOwnProperty.call(info.alertExtraInfo, key)) {
- const value = info.alertExtraInfo[key];
- if (value !== undefined) {
- if (key == 'start_time' || key == 'end_time') {
- desc += `${key}(<span class="red_highlight">GMT</span>): ${value.split('.')[0] + 'Z'}\n`;
- } else {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function ClarotyAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- if (log.length == 0) {
- return acc;
- }
- const regex = /(\b\w+=)([^=\s].*?)(?=\s+\w+=|$)/g;
- let match;
- const matches = {};
- while ((match = regex.exec(log)) !== null) {
- let item = match[0].split('=');
- matches[item[0]] = item.slice(1, item.length).join('=');
- }
- raw_alert += 1;
- console.log(matches);
- let logArray = log.split(' ').filter((item) => item !== ''); //Remove extra whitespace from the string
- acc.push({
- 'Event time': logArray.slice(0, 3).join(' '),
- 'Extra information': logArray.slice(3, 8).join(' '),
- 'CtdSourceIp': matches.CtdSourceIp ? matches.CtdSourceIp : undefined,
- 'CtdDestinationIp': matches.CtdDestinationIp ? matches.CtdDestinationIp : undefined,
- 'CtdMessage': matches.CtdMessage ? matches.CtdMessage : undefined,
- 'CtdCategory': matches.CtdCategory ? matches.CtdCategory : undefined,
- 'CtdSourceZone': matches.CtdSourceZone ? matches.CtdSourceZone : undefined,
- 'CtdDestinationZone': matches.CtdDestinationZone ? matches.CtdDestinationZone : undefined,
- 'CtdAlertLink': matches.CtdAlertLink ? matches.CtdAlertLink : undefined
- });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info) {
- if (Object.hasOwnProperty.call(info, key)) {
- const value = info[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function FireeyeAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- const num_alert = $('#customfield_10300-val').text().trim();
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- if (log.length == 0) {
- return acc;
- }
- const regex = /(\b\w+=)([^=\s].*?)(?=\s+\w+=|$)/g;
- let match;
- const matches = {};
- while ((match = regex.exec(log)) !== null) {
- let item = match[0].split('=');
- matches[item[0]] = item.slice(1, item.length).join('=');
- }
- raw_alert += 1;
- let logArray = log.split(' ').filter((item) => item !== ''); //Remove extra whitespace from the string
- acc.push({
- 'Event time': logArray.slice(0, 3).join(' '),
- 'Vlan': matches.cn1 ? matches.cn1 : undefined,
- 'Sid': matches.cn2 ? matches.cn2 : undefined,
- 'CncHost': matches.cs5 ? matches.cs5 : undefined,
- 'CncPort': matches.cn3 ? matches.cn3 : undefined,
- 'Sname': matches.cs1 ? matches.cs1 : undefined,
- 'anomaly': matches.cs2 ? matches.cs2 : undefined,
- 'Link': matches.cs4 ? matches.cs4 : undefined,
- 'Channel': matches.cs6 ? matches.cs6 : undefined,
- 'request': matches.request ? matches.request : undefined,
- 'requestClientApplication': matches.requestClientApplication
- ? matches.requestClientApplication
- : undefined,
- 'requestMethod': matches.requestMethod ? matches.requestMethod : undefined,
- 'dst': matches.dst ? matches.dst : undefined,
- 'dpt': matches.dpt ? matches.dpt : undefined,
- 'src': matches.src ? matches.src : undefined,
- 'spt': matches.spt ? matches.spt : undefined,
- 'dvchost': matches.dvchost ? matches.dvchost : undefined,
- 'dvc': matches.dvc ? matches.dvc : undefined
- });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info) {
- if (Object.hasOwnProperty.call(info, key)) {
- const value = info[key];
- if (value !== undefined) {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function WebAccesslogAlertHandler(...kwargs) {
- var { summary, rawLog } = kwargs[0];
- var raw_alert = 0;
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- if (log.length == 0) {
- return acc;
- }
- const regex = /(\b\w+=)"([^"]*?)"/g;
- const regex_ = /"(.*?)"/g;
- let match;
- const matches = {};
- while ((match = regex.exec(log)) !== null) {
- let item = match[0].split('=');
- matches[item[0]] = item.slice(1, item.length).join('=');
- }
- let match_;
- const matches_ = [];
- while ((match_ = regex_.exec(log)) !== null) {
- matches_.push(match_[0]);
- }
- console.log(matches);
- console.log(matches_);
- let logArray = log.split(' ').filter((item) => item !== ''); //Remove extra whitespace from the string
- console.log(logArray);
- acc.push({
- 'Event time': logArray.slice(3, 5).join(' '),
- 'Source_IP': logArray[0] ? logArray[0] : undefined,
- // 'request_uri': matches.request_uri ? matches.request_uri : undefined,
- 'URL': matches_[0] ? matches_[0] : undefined,
- 'User-Agent': matches_[2] ? matches_[2] : undefined,
- 'upstream_status': logArray[8] ? logArray[8] : undefined,
- 'upstream_addr': matches.upstream_addr ? matches.upstream_addr : undefined,
- 'sn': matches.sn ? matches.sn : undefined,
- 'http_referrer': matches.http_referrer ? matches.http_referrer : undefined,
- 'http_cookie': matches.http_cookie ? matches.http_cookie : undefined,
- 'location': matches.location ? matches.location : undefined
- });
- } catch (error) {
- console.log(`Error: ${error.message}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
- const alertInfo = parseLog(rawLog);
- console.log(alertInfo);
- function generateDescription() {
- const alertDescriptions = [];
- for (const info of alertInfo) {
- const lastindex = summary.lastIndexOf(']');
- let desc = `Observed ${summary.substr(lastindex + 1)}\n`;
- for (const key in info) {
- if (Object.hasOwnProperty.call(info, key)) {
- const value = info[key];
- if (value !== undefined && value !== '-' && value !== '"-"') {
- desc += `${key}: ${value}\n`;
- }
- }
- }
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function FireeyeEtpAlertHandler(...kwargs) {
- const { rawLog, summary } = kwargs[0];
- var raw_alert = 0;
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- const { meta, alert, email } = JSON.parse(log)['fireeye'];
- acc.push({
- timestamp: alert['timestamp'],
- accepted: email['timestamp']['accepted'],
- last_malware: meta['last_malware'],
- alert_type: meta['alert_type'],
- status: email['status'],
- source_ip: email['source_ip'],
- rcpt_to: email['smtp']['rcpt_to'],
- mail_from: email['smtp']['mail_from'],
- etp_message_id: email['etp_message_id'],
- To: email['headers']['to'],
- From: email['headers']['from'],
- Subject: email['headers']['subject'],
- attachment: email['attachment']
- });
- raw_alert += 1;
- } catch (error) {
- console.log(`Error: ${error}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let desc = `Observed ${summary.split(']')[1]}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && value !== ' ' && index != 'Summary') {
- if (index == 'timestamp') {
- desc += `timestamp(<span class="red_highlight">GMT</span>): ${value.split('.')[0]}Z\n`;
- } else if (index == 'accepted') {
- desc += `accepted(<span class="red_highlight">GMT</span>): ${value}Z\n`;
- } else {
- desc += `${index}: ${value}\n`;
- }
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function SentinelOneAlertHandler(...kwargs) {
- const { rawLog, summary } = kwargs[0];
- var raw_alert = 0;
- function parseLog(rawLog) {
- const alertInfo = rawLog.reduce((acc, log) => {
- try {
- console.log('===sentinel_one');
- const sentinel_one = JSON.parse(log)['sentinel_one'];
- acc.push({
- timestamp: sentinel_one.threatInfo.createdAt.split('.')[0],
- accountName: sentinel_one.accountName,
- agentDomain: sentinel_one.agentDomain,
- agentIpV4: sentinel_one.agentIpV4,
- agentOsName: sentinel_one.agentOsName,
- agentMitigationMode: sentinel_one.agentMitigationMode,
- filePath: sentinel_one.threatInfo.filePath,
- sha1: sentinel_one.threatInfo.sha1,
- confidenceLevel: sentinel_one.threatInfo.filePath,
- threatName: sentinel_one.threatInfo.threatName,
- processUser: sentinel_one.threatInfo.processUser
- });
- raw_alert += 1;
- } catch (error) {
- console.log(`Error: ${error}`);
- }
- return acc;
- }, []);
- return alertInfo;
- }
-
- const alertInfo = parseLog(rawLog);
- const num_alert = $('#customfield_10300-val').text().trim();
- function generateDescription() {
- const alertDescriptions = [];
- if (raw_alert < num_alert) {
- let extra_message = `<span class="red_highlight">Number Of Alert : ${num_alert}, Raw Log Alert : ${raw_alert} Raw log information is Not Complete, Please Get More Alert Information From Elastic.</span>\n`;
- alertDescriptions.push(extra_message);
- }
- for (const info of alertInfo) {
- let desc = `Observed ${summary.split(']')[1]}\n`;
- Object.entries(info).forEach(([index, value]) => {
- if (value !== undefined && value !== ' ' && index != 'Summary') {
- if (index == 'timestamp') {
- desc += `timestamp(<span class="red_highlight">GMT</span>): ${value.split('.')[0]}Z\n`;
- } else {
- desc += `${index}: ${value}\n`;
- }
- }
- });
- desc += `\nPlease verify if the activity is legitimate.\n`;
- alertDescriptions.push(desc);
- }
- const alertMsg = [...new Set(alertDescriptions)].join('\n');
- showDialog(alertMsg);
- }
- addButton('generateDescription', 'Description', generateDescription);
- }
-
- function LHG_CS_AlertHandler(DecoderName) {
- let ORG = $('#customfield_10002-val').text().trim();
- console.log(ORG.split(' ')[ORG.split(' ').length - 1]);
- const elements = document.querySelectorAll('.user-hover.user-avatar');
- const userList = ['kitty.li', 'anson.cho', 'ray.tan', 'philip.ng'];
- console.log(elements[0].textContent.toLowerCase()); // 对每个元素执行操作
- let ClientComment = false;
- for (const dataItem of userList) {
- if (elements[0].textContent.toLowerCase().includes(dataItem.toLowerCase())) {
- ClientComment = true;
- break;
- }
- }
- //判断工单是否升级,
- if (ORG.split(' ')[ORG.split(' ').length - 1] == 'None' && DecoderName == 'crowdstrike_cef') {
- $('#opsbar-opsbar-transitions').on('click', () => {
- let userConfirmed = confirm('LHG的所有 Crowdstrike 告警均需要升级,即使是误报也需要升级');
- });
- } else {
- if (!ClientComment) {
- $('#opsbar-opsbar-transitions').on('click', () => {
- let userConfirmed = confirm(
- '只有这四个客户回复philip.ng,ray.tan,anson.cho,kitty.li,才可关单,若以上四个客户已允许close,可忽略此提示'
- );
- });
- }
- }
- }
-
- function RealMonitorMe() {
- let ORG = $('#customfield_10002-val').text().trim();
- let status = $('#opsbar-transitions_more').text().trim();
- if ($('#customfield_10302-val').text().trim().includes('\n')) {
- let rules = $('#customfield_10302-val').text().trim().split(' \n')[1].split('\n');
- if (rules.length - 1 >= 3 && status == 'Work in progress') {
- confirm(
- `检测到该工单的RuleName有${
- rules.length - 1
- }个,(如果同一张tickets出现三个告警及以上,需要往cortex群里发,如果是误报请描述原因,谢谢)`
- );
- }
- }
- const intervalId = setInterval(() => {
- var element_one = document.getElementById('opsbar-opsbar-transitions');
- var first = element_one ? element_one.textContent || element_one.innerText : null;
- if (first == 'Resolved') {
- clearInterval(intervalId);
- }
- if (first == 'Waiting for customer' && ORG.split(' ')[ORG.split(' ').length - 1] == 'None') {
- console.log('===发生了改变', first);
- confirm('请注意,该工单变为Waiting for customer,请检查该工单是否已添加ORG');
- first = 'Waiting for customer';
- clearInterval(intervalId);
- }
- }, 500);
- }
-
- function formatCurrentDateTime(dateStr, decoder_name) {
- if (dateStr) {
- var date = new Date(dateStr);
- var localOffset = date.getTimezoneOffset();
- if (decoder_name == 'impervainc_cef') {
- var targetDate = new Date(date.getTime() + (480 + localOffset) * 60000);
- } else {
- var targetDate = new Date(date.getTime() + (960 + localOffset) * 60000);
- }
- var year = targetDate.getFullYear();
- var month = ('0' + (targetDate.getMonth() + 1)).slice(-2);
- var day = ('0' + targetDate.getDate()).slice(-2);
- var hours = ('0' + targetDate.getHours()).slice(-2);
- var minutes = ('0' + targetDate.getMinutes()).slice(-2);
- var seconds = ('0' + targetDate.getSeconds()).slice(-2);
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
- }
- const pad = (num) => (num < 10 ? '0' : '') + num;
- const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
- const date_ = new Date();
-
- const day_ = date_.getDate();
- const month_ = months[date_.getMonth()];
- const year_ = date_.getFullYear().toString().slice(-2); // 取最后两位
- const hours_ = date_.getHours();
- const minutes_ = date_.getMinutes();
- const ampm = hours_ >= 12 ? 'PM' : 'AM';
- const hour = hours_ % 12 || 12; // Convert to 12-hour format and handle 0 case
-
- return `${pad(day_)}/${month_}/${year_} ${pad(hour)}:${pad(minutes_)} ${ampm}`;
- }
-
- function MonitorDev() {
- function formatDate() {
- const date = new Date();
- const day = String(date.getDate()).padStart(2, '0'); // 日期补齐两位数
- const month = date.toLocaleString('en-US', { month: 'short' }); // 获取月份缩写
- const year = String(date.getFullYear()).slice(-2); // 取年份的后两位
-
- let hours = date.getHours();
- const minutes = String(date.getMinutes()).padStart(2, '0');
- const ampm = hours >= 12 ? 'PM' : 'AM';
-
- hours = hours % 12; // 将24小时制转换为12小时制
- hours = hours ? hours : 12; // 如果是0点,将其转换为12
- hours = String(hours).padStart(2, '0'); // 补齐小时为两位数
-
- return `${day}/${month}/${year} ${hours}:${minutes} ${ampm}`;
- }
- let white = JSON.parse(localStorage.getItem('whitelist'));
-
- if (window.location.href.includes('/portal/2/create/100')) {
- const interval = setInterval(() => {
- var iframe = document.getElementById('rw_iframe');
- var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
- var element = iframeDocument.getElementById('summary');
- if (element) {
- let summary = 'Whitelist ' + white['summary'].replace('Wazuh', white['LogSourceDomain']);
- iframeDocument.getElementById('summary').value = summary;
- iframeDocument.getElementById('s2id_labels').innerHTML =
- `<ul class="select2-choices"> <li class="select2-search-choice"> <div>` +
- white['LogSourceDomain'] +
- `</div> <a href="#" class="select2-search-choice-close" tabindex="-1"></a></li><li class="select2-search-field"> <input type="text" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" class="select2-input" id="s2id_autogen1" style="width: 10px;"> </li></ul>`;
- iframeDocument.getElementById('labels').value = white['LogSourceDomain'];
- iframeDocument.getElementById('customfield_14601').value = formatDate();
- iframeDocument.getElementById('customfield_14600').value = formatDate();
- iframeDocument.getElementById('customfield_14610').value = 'Yes';
- iframeDocument.getElementById('customfield_14609').value = 'Yes';
- iframeDocument.getElementById('customfield_14608').value = 'Yes';
- clearInterval(interval);
- }
- }, 600);
- }
- let cachedEntry = GM_getValue('cachedEntry', null);
- if (window.location.href.includes('/servlet/desk/portal/2') && window.location.href.includes('DEV')) {
- window.location.href = `${cachedEntry['hk']}/browse/` + window.location.href.split('portal/2/')[1];
- localStorage.setItem('Dev_link', window.location.href.split('portal/2/')[1]);
- }
- if (window.location.href.includes(localStorage.getItem('Dev_link'))) {
- document.getElementById('edit-issue').click();
- const interval = setInterval(() => {
- const components = document.querySelector('#components-textarea');
- if (components) {
- $('#components-textarea').val(white['Component']);
- $('#components-textarea').click();
- $('#issuelinks-issues-textarea').val(white['MSS'].split('browse/')[1]);
- $('#tab-0').click();
- localStorage.removeItem('Dev_link');
- clearInterval(interval);
- }
- }, 500);
- }
- }
-
- function WhiteFilehash(filehash) {
- if (filehash == undefined) {
- return 0;
- }
- const cachedWhitehashContent = GM_getValue('cachedWhitehashContent', null);
- for (const f of cachedWhitehashContent) {
- if (filehash.includes(f['hash'].toLowerCase())) {
- console.log('命中了', filehash);
- return true;
- }
- }
- }
-
- function RealTimeMonitoring() {
- // Filter page: audio control registration and regular issues table update
- if (
- (window.location.href.includes('filter=15200') ||
- window.location.href.includes('filter=26405') ||
- window.location.href.includes('filter=13300')) &&
- !window.location.href.includes('MSS')
- ) {
- console.log('#### Code includes filter run ####');
- const NotifyControls = createNotifyControls();
- if (window.location.href.includes('filter=15200') || window.location.href.includes('filter=26405')) {
- setInterval(() => {
- notifyKey = [];
- $('.aui-button.aui-button-primary.search-button').click();
- setTimeout(() => {
- checkupdate(NotifyControls);
- }, 10000);
- }, 180000);
- }
- if (window.location.href.includes('filter=13300')) {
- setInterval(() => {
- notifyKey = [];
- $('.aui-button.aui-button-primary.search-button').click();
- setTimeout(() => {
- monitorList();
- }, 10000);
- }, 60000);
- }
- }
- if (window.location.href.includes('login.microsoftonline.com')) {
- setTimeout(() => {
- switch_user_microsoft();
- }, 2000);
- }
- if (window.location.href.includes('security.microsoft.com/homepage?¤t=')) {
- setTimeout(() => {
- security_microsoft();
- }, 3000);
- }
- // Issue page: Alert Handler
- const generation_description = setInterval(() => {
- var LogSourceDomain = $('#customfield_10223-val').text().trim();
- let rawLog = $('#field-customfield_10219 > div:first-child > div:nth-child(2)').text().trim().split('\n');
- if (rawLog == '') {
- rawLog = $('#field-customfield_10904 > div:first-child > div:nth-child(2)').text().trim().split('\n');
- }
- const summary = $('#summary-val').text().trim();
- if ($('#issue-content').length && !$('#generateDescription').length) {
- console.log('#### Code Issue page: Alert Handler ####');
- const handlers = {
- 'cortex-xdr-json': cortexAlertHandler,
- 'mde-api-json': MDE365AlertHandler,
- 'sangfor-ccom-json': HTSCAlertHandler,
- 'carbonblack': CBAlertHandler,
- 'carbonblack_cef': VMCEFAlertHandler,
- 'windows_eventchannel': WineventAlertHandler,
- 'fortigate-firewall-v5': FortigateAlertHandler,
- 'crowdstrike_cef': CSAlertHandler,
- 'sophos': SophosAlertHandler,
- 'sepm-security': SpemAlertHandler,
- 'sepm-traffic': SpemAlertHandler,
- 'vmwarecarbonblack_cef': VMCEFAlertHandler,
- 'aws-cloudtrail': AwsAlertHandler,
- 'aws-cisco-umbrella': AwsAlertHandler,
- 'm365-defender-json': MDE365AlertHandler,
- 'azureeventhub': AzureAlertHandler,
- 'azuregraphapi-json': AzureGraphAlertHandler,
- 'paloalto-firewall': paloaltoAlertHandler,
- 'impervainc_cef': SangforAlertHandler,
- 'proofpoint_tap': ProofpointAlertHandler,
- 'zscaler-zpa-json': ZscalerAlertHandler,
- 'pulse-secure': PulseAlertHandler,
- 'aws-guardduty': AwsAlertHandler,
- 'alicloud-json': AlicloudAlertHandler,
- 'darktrace-json': DarktraceAlertHandler,
- 'sangfor_cef': SangforAlertHandler,
- 'cyberark_cef': SangforAlertHandler,
- 'radware-json': RadwareAlertHandler,
- 'carbonblack_cloud': CarbonAlertHandler,
- 'windows-syslog': WindowsSysAlertHandler,
- 'claroty_cef': ClarotyAlertHandler,
- 'office-365': Risky_Countries_AlertHandler,
- 'fireeye': FireeyeAlertHandler,
- 'web-accesslog': WebAccesslogAlertHandler,
- 'checkpoint_cef': SangforAlertHandler,
- 'incapsula_cef': SangforAlertHandler,
- 'fireeye-etp-json': FireeyeEtpAlertHandler,
- 'sentinelone-json': SentinelOneAlertHandler,
- 'sonicwall': FortigateAlertHandler,
- 'trellix_cef': SangforAlertHandler
- };
- let DecoderName = $('#customfield_10807-val').text().trim().toLowerCase();
- if (DecoderName == '') {
- DecoderName = $('#customfield_10906-val').text().trim().toLowerCase();
- }
- if (DecoderName.includes('m365-defender-json')) {
- let decoder_name = [];
- DecoderName.split(' ').forEach((element, index) => {
- if (element != 'hide\n' && element != '' && element != 'show\n' && element != '\n') {
- decoder_name.push(element);
- }
- });
- if (decoder_name[0].includes('m365-defender-json\n')) {
- DecoderName = 'm365-defender-json';
- }
- }
- const handler = handlers[DecoderName];
- if (handler) {
- handler({ LogSourceDomain: LogSourceDomain, rawLog: rawLog, summary: summary });
- }
- const No_Decoder_handlers = {
- 'detect aad, o365 sign-in from risky countries': Risky_Countries_AlertHandler,
- 'successful azure/o365 login from malware-ip': Risky_Countries_AlertHandler,
- 'rarely country signin from o365': Risky_Countries_AlertHandler,
- 'agent disconnected': Agent_Disconnect_AlertHandler,
- 'suspicious geolocation ip login success': PulseAlertHandler,
- 'login success from malware ip(s)': ThreatMatrixAlertHandler,
- 'multiple account being disabled or deleted in short period of time': MultipleAccountAlertHandler,
- 'multiple sms request for same source ip': AwsAlertHandler
- };
- const Summary = $('#summary-val').text().trim();
- let No_Decoder_handler = null;
- Object.keys(No_Decoder_handlers).forEach((key) => {
- if (Summary.toLowerCase().includes(key)) {
- No_Decoder_handler = No_Decoder_handlers[key];
- }
- });
- if (No_Decoder_handler !== null) {
- No_Decoder_handler({ LogSourceDomain: LogSourceDomain, rawLog: rawLog, summary: Summary });
- }
- if (LogSourceDomain == '') {
- LogSourceDomain = $('#customfield_10846-val').text().trim();
- }
- const Log_Domain_handlers = {
- mdb: MdbAlertHandler, //这里面有点工单为decoder name:sshd
- dst: DstAlertHandler
- };
- const Log_Domain_handler = Log_Domain_handlers[LogSourceDomain];
- if (Log_Domain_handler) {
- Log_Domain_handler({ LogSourceDomain: LogSourceDomain, rawLog: rawLog, summary: summary });
- }
- clearInterval(generation_description);
- }
- }, 1000);
- // Issue page: check Keywords and ATT&CK and Org
- setTimeout(() => {
- if ($('#issue-content').length && !$('.aui-banner-error').length) {
- console.log('#### Code Issue page: check Keywords ####');
- checkKeywords();
- checkATTCK();
- }
- }, 4500);
-
- // Issue page: Edit Notify
- setTimeout(() => {
- let LogSourceDomain,
- Source,
- Labels,
- LogSource,
- DecoderName,
- TicketAutoEscalate,
- Status,
- RawLog,
- Summary,
- AgentName;
- let cachedEntry = GM_getValue('cachedEntry', null);
- if (window.location.host === cachedEntry['hk'].split('//')[1]) {
- // for HK
- LogSourceDomain = $('#customfield_10223-val').text().trim();
- Source = $('#customfield_10113-val').text().trim();
- Labels = $('.labels-wrap .labels li a span').text();
- LogSource = $('#customfield_10204-val').text().trim();
- DecoderName = $('#customfield_10807-val').text().trim().toLowerCase();
- TicketAutoEscalate = $('#customfield_12202-val').text().trim();
- Status = $('#status-val > span').text().trim();
- RawLog =
- $('#field-customfield_10219 > div:first-child > div:nth-child(2)').text().trim() ||
- $('#customfield_10219-val').text().trim() ||
- $('#field-customfield_10232 > div.twixi-wrap.verbose > div > div > div > pre').text();
- Summary = $('#summary-val').text().trim();
- AgentName = $('#customfield_10805-val').text().trim();
- } else if (window.location.host === cachedEntry['macao'].split('//')[1]) {
- // for MO
- LogSourceDomain = $('#customfield_10846-val').text().trim();
- Source = $('#customfield_10872-val').text().trim();
- Labels = $('#labels-212244-value').text().trim();
- LogSource = $('#customfield_10854-val').text().trim();
- DecoderName = $('#customfield_10906-val').text().trim();
- TicketAutoEscalate = $('#customfield_10893-val').text().trim();
- Status = $('#status-value > span').text().trim();
- RawLog = $('#field-customfield_10904 > div.twixi-wrap.verbose > div').text().trim();
- Summary = $('#summary-val').text().trim();
- AgentName = $('#customfield_10802-val').text().trim();
- }
-
- const pageData = {
- LogSourceDomain,
- Source,
- Labels,
- LogSource,
- DecoderName,
- TicketAutoEscalate,
- Status,
- RawLog,
- Summary,
- AgentName
- };
-
- // If it pops up once, it will not be reminded again
- if (
- ($('#issue-content').length &&
- !$('#generateTicketNotify').length &&
- window.location.href.includes('MSS')) ||
- window.location.href.includes('OPS')
- ) {
- addButton('towhitelist', 'WhiteList', ToWhitelist);
- ticketNotify(pageData);
- }
- }, 1000);
-
- // Issue page: Norm Alert
- setTimeout(() => {
- var LogSourceDomain = $('#customfield_10223-val').text().trim();
- let DecoderName = $('#customfield_10807-val').text().trim().toLowerCase();
- if (DecoderName == '') {
- DecoderName = $('#customfield_10906-val').text().trim().toLowerCase();
- }
- if (LogSourceDomain.includes('lhg')) {
- LHG_CS_AlertHandler(DecoderName);
- }
- }, 3500);
-
- // Issue page: Quick Reply
- setInterval(() => {
- if (document.querySelector('#reply') == null) {
- QuickReply();
- }
- }, 3000);
- }
-
- (function () {
- ('use strict');
- RealTimeMonitoring();
-
- registerSearchMenu();
- registerExceptionMenu();
- registerCustomQuickReplyMenu();
- addCss();
- MonitorDev();
- AJS.whenIType('zv').execute(function () {
- document.getElementById('opsbar-transitions_more').click();
- const interval = setInterval(() => {
- const element = document.querySelector('#action_id_761');
- if (element) {
- document.getElementById('action_id_761').click();
- clearInterval(interval);
- }
- }, 100); // 每100毫秒检查一次
- });
- AJS.whenIType('zx').execute(function () {
- document.getElementById('edit-issue').click();
- const interval = setInterval(() => {
- const tabsMenu = document.querySelector('#horizontal');
- const elements = tabsMenu.querySelectorAll('*');
- const elementsArray = Array.from(elements);
- const reviewElement = elementsArray.find((element) => element.outerText.trim() === 'Review');
- if (reviewElement) {
- const menuItem = reviewElement.querySelector('.menu-item a');
- const idValue = menuItem.id;
- const element = document.querySelector('#' + idValue);
- if (element) {
- document.getElementById(idValue).click();
- $('#customfield_17201').val(formatCurrentDateTime());
- const metaElement = document
- .querySelector('meta[name="ajs-remote-user-fullname"]')
- .getAttribute('content');
- $('#customfield_17203-field').val(metaElement);
- document.getElementById('customfield_17203-field').click();
- clearInterval(interval);
- }
- }
- }, 500);
- const intervals = setInterval(() => {
- const element1 = document.querySelector('#showing-1-of-1-matching-users');
- console.log(element1);
- if (element1) {
- document.querySelector('#showing-1-of-1-matching-users li').click();
- clearInterval(intervals);
- }
- }, 500);
- });
- RealMonitorMe();
- })();