// ==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/[email protected]/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();
})();