Skip to content

Commit

Permalink
Merge pull request #198 from Yamato-Security/177-fix-allow-filtering-…
Browse files Browse the repository at this point in the history
…on-the-chart-by-rules

fix #177 Allow filtering on the Chart by Rules
  • Loading branch information
YamatoSecurity authored Oct 22, 2024
2 parents d96a545 + aca3273 commit 57bb98f
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/takajo.nim
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ when isMainModule:
const example_vt_hash_lookup = " vt-hash-lookup -a <API-KEY> --hashList case-1-MD5-hashes.txt -r 1000 -o results.csv --jsonOutput responses.json\p"
const example_vt_ip_lookup = " vt-ip-lookup -a <API-KEY> --ipList ipAddresses.txt -r 1000 -o results.csv --jsonOutput responses.json\p"

clCfg.useMulti = "Version: 2.7.0 Dev Build\pUsage: takajo.exe <COMMAND>\p\pCommands:\p$subcmds\pCommand help: $command help <COMMAND>\p\p" &
clCfg.useMulti = "Version: 2.7.0 SecTor Releaase\pUsage: takajo.exe <COMMAND>\p\pCommands:\p$subcmds\pCommand help: $command help <COMMAND>\p\p" &
examples &
example_automagic &
example_extract_credentials & example_extract_scriptblocks & example_html_report & example_html_server &
Expand Down
2 changes: 1 addition & 1 deletion src/takajopkg/htmlReport.nim
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ proc htmlReport*(output: string, quiet: bool = false, timeline: string, rulepath

# start analysis timeline
# obtain datas from SQLite
var query = sql"""select rule_title, rule_file, level, level_order, computer, min(timestamp) as start_date, max(timestamp) as end_date, count(*) as count
var query = sql"""select rule_title, rule_file, level, level_order, computer, min(datetime(timestamp, 'localtime')) as start_date, max(datetime(timestamp, 'localtime')) as end_date, count(*) as count
from timelines
group by rule_title, level, computer
order by level_order
Expand Down
25 changes: 18 additions & 7 deletions src/takajopkg/web/controllers/computers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,19 @@ proc computer*(ctx: Context) {.async.} =

let rule_title = ctx.request.queryParams.getOrDefault("rule_title", "")
if rule_title != "":
custom_query &= " AND rule_title = ?"
params.add(rule_title)
let rule_title_list = rule_title.split(",")
custom_query &= " AND rule_title IN ("
var count = 0
let rule_title_list_last = len(rule_title_list) - 1
for rule_title in rule_title_list:
#custom_query &= "'" & rule_title & "'"
custom_query &= "?"
if count != rule_title_list_last:
custom_query &= ","
count += 1
params.add(rule_title)
custom_query &= ")"


let severities = ctx.request.queryParams.getOrDefault("severities", "")
if severities != "":
Expand All @@ -61,8 +72,8 @@ proc computer*(ctx: Context) {.async.} =
severity_query &= dbQuote(severity)
custom_query &= " AND level IN (" & severity_query & ")"

echo custom_query
echo params
# echo custom_query
# echo params

#
# query to DB
Expand All @@ -71,7 +82,7 @@ proc computer*(ctx: Context) {.async.} =
let path = getDBPath(ctx)
let db = open(path , "", "", "")

var query = """select rule_title, rule_file, level, level_order, computer, min(timestamp) as start_date, max(timestamp) as end_date, count(*) as count
var query = """select rule_title, rule_file, level, level_order, computer, min(datetime(timestamp, 'localtime')) as start_date, max(datetime(timestamp, 'localtime')) as end_date, count(*) as count
from timelines
where """ & custom_query & """
group by rule_title, level, computer
Expand Down Expand Up @@ -125,8 +136,8 @@ proc sidemenu*(ctx: Context) {.async.} =
rule_title,
computer,
COUNT(computer) AS computer_total,
MIN(timestamp) AS first_date,
MAX(timestamp) AS last_date
MIN(datetime(timestamp, 'localtime')) AS first_date,
MAX(datetime(timestamp, 'localtime')) AS last_date
FROM timelines
GROUP BY level_order, rule_title, computer
ORDER BY level_order, rule_title, computer;
Expand Down
5 changes: 4 additions & 1 deletion src/takajopkg/web/controllers/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ proc computer_summary*(ctx: Context) {.async.} =


proc commonjs*(ctx: Context) {.async.} =
await ctx.staticFileResponse("js/common.js", "src/takajopkg/web/static")
await ctx.staticFileResponse("js/common.js", "src/takajopkg/web/static")

proc favicon*(ctx: Context) {.async.} =
await ctx.staticFileResponse("img/favicon.png", "src/takajopkg/web/static")
4 changes: 2 additions & 2 deletions src/takajopkg/web/controllers/summary.nim
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ proc list*(ctx: Context) {.async.} =
severity_query &= dbQuote(severity)
custom_query &= " AND level IN (" & severity_query & ")"

echo custom_query
# echo custom_query

#
# query to DB
Expand Down Expand Up @@ -118,7 +118,7 @@ proc list*(ctx: Context) {.async.} =
var dates_with_most_total_detections = db.getAllRows(sql query, params)

query = """SELECT level, level_order, rule_title, computer, COUNT(*) AS alert_count,
MIN(DATE(timestamp)) AS first_seen, MAX(DATE(timestamp)) AS last_seen
MIN(DATE(datetime(timestamp, 'localtime'))) AS first_seen, MAX(DATE(datetime(timestamp, 'localtime'))) AS last_seen
FROM timelines
GROUP BY level, rule_title, computer
ORDER BY level_order DESC
Expand Down
5 changes: 2 additions & 3 deletions src/takajopkg/web/static/computer_summary.htm
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />

<title>Computer Summary</title>


<title>Takajo Report</title>
<link rel="icon" type="image/x-icon" href="/img/favicon.png">
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet">
<script src="/js/common.js"></script>
Expand Down
185 changes: 127 additions & 58 deletions src/takajopkg/web/static/content.htm
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />

<title>Project</title>
<title>Takajo Report</title>

<script src="https://cdn.tailwindcss.com"></script>
<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<link rel="icon" type="image/x-icon" href="/img/favicon.png">
<script src="/js/common.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>

Expand Down Expand Up @@ -68,12 +69,19 @@
}

function getComputerData() {

if (document.getElementById("detection-rule-list-body").innerHTML != "" && areAllUnchecked()) {
alert('No rules are enabled.');
return
}

let first_date = document.getElementById("first_date").value;
let last_date = document.getElementById("last_date").value;
let api_endpoint = apiUrl + `computer?computer=${computer}&start_date=${first_date}&end_date=${last_date}`;
if (pastdays == true) {
api_endpoint += "&pastdays=true";
}
api_endpoint += getCheckedValues();

fetch(api_endpoint)
.then(response => {
Expand Down Expand Up @@ -165,56 +173,68 @@
}
return b[7] - a[7];
});

const tbody = document.getElementById("detection-rule-list-body")
tbody.innerHTML = ""
alerts.forEach(alert => {
const row = document.createElement("tr");

// Alert Title
const titleCell = document.createElement("td");
const titleCellA = document.createElement("a");
titleCellA.textContent = alert[0];
titleCellA.classList.add("link");
titleCellA.target = "_blank";
global_rules.forEach(rule => {
if (rule[0] == alert[0]) {
titleCellA.href = rule[1];
return;
}
if (tbody.innerHTML == "") {
alerts.forEach(alert => {
const row = document.createElement("tr");

// Checkbox
const checkboxCell = document.createElement("td");
const checkboxCellCheck = document.createElement('input');
checkboxCellCheck.type = "checkbox";
checkboxCellCheck.classList.add("rule_check");
checkboxCellCheck.checked = true;
checkboxCellCheck.value = alert[0];
checkboxCell.appendChild(checkboxCellCheck);
row.appendChild(checkboxCell);

// Alert Title
const titleCell = document.createElement("td");
const titleCellA = document.createElement("a");
titleCellA.textContent = alert[0];
titleCellA.classList.add("link");
titleCellA.target = "_blank";
global_rules.forEach(rule => {
if (rule[0] == alert[0]) {
titleCellA.href = rule[1];
return;
}
});
titleCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
titleCell.appendChild(titleCellA);
row.appendChild(titleCell);

// Severity
const severityCell = document.createElement("td");
const severityDev = document.createElement("div");
severityDev.classList.add("inline-block", "rounded-full", "bg-" + severity_color[alert[2]] + "-100", "px-2", "py-1", "text-xs", "font-semibold", "leading-4", "text-" + severity_color[alert[2]] + "-800");
severityDev.textContent = severity_message[alert[2]];
severityCell.append(severityDev)
row.appendChild(severityCell);

// Count
const countCell = document.createElement("td");
countCell.textContent = alert[7];
countCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
row.appendChild(countCell);

// First Date
const firstDateCell = document.createElement("td");
firstDateCell.textContent = formatDate(alert[5]);
firstDateCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
row.appendChild(firstDateCell);

// Last Date
const lastDateCell = document.createElement("td");
lastDateCell.textContent = formatDate(alert[6]);
lastDateCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
row.appendChild(lastDateCell);

// 行を <tbody> に追加
tbody.appendChild(row);
});
titleCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
titleCell.appendChild(titleCellA);
row.appendChild(titleCell);

// Severity
const severityCell = document.createElement("td");
const severityDev = document.createElement("div");
severityDev.classList.add("inline-block", "rounded-full", "bg-" + severity_color[alert[2]] + "-100", "px-2", "py-1", "text-xs", "font-semibold", "leading-4", "text-" + severity_color[alert[2]] + "-800");
severityDev.textContent = severity_message[alert[2]];
severityCell.append(severityDev)
row.appendChild(severityCell);

// Count
const countCell = document.createElement("td");
countCell.textContent = alert[7];
countCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
row.appendChild(countCell);

// First Date
const firstDateCell = document.createElement("td");
firstDateCell.textContent = formatDate(alert[5]);
firstDateCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
row.appendChild(firstDateCell);

// Last Date
const lastDateCell = document.createElement("td");
lastDateCell.textContent = formatDate(alert[6]);
lastDateCell.classList.add("min-w-[180px]", "py-3", "pe-3", "text-start", "text-sm", "font-semibold", "uppercase", "tracking-wider", "text-slate-700");
row.appendChild(lastDateCell);

// 行を <tbody> に追加
tbody.appendChild(row);
});
}

})
.catch(error => {
Expand Down Expand Up @@ -521,7 +541,7 @@ <h3 class="mb-8 text-sm font-medium text-slate-600">
<dl>
<dt class="text-2xl font-bold text-sky-600" id="info_num"></dt>
<dd class="text-sm font-medium text-sky-900">
Information
Informational
</dd>
</dl>
</div>
Expand All @@ -534,6 +554,8 @@ <h3 class="mb-8 text-sm font-medium text-slate-600">
<input type="text" name="last_date" id="last_date" value="" placeholder="to date" class="flatpickr-input rounded-lg border border-zinc-200 py-2 pe-3 ps-10 leading-6 placeholder-zinc-500">
<button id="fetchData" class="button relative h-10 overflow-hidden rounded-md border border-neutral-200 bg-transparent px-6 text-neutral-950 before:absolute before:bottom-0 before:left-0 before:block before:h-full before:w-full before:-translate-x-full before:bg-neutral-100 before:transition-transform hover:before:translate-x-0"><span class="relative">Search</span></button>
&nbsp;
<button id="clearData" class="button relative h-10 overflow-hidden rounded-md border border-neutral-200 bg-transparent px-6 text-neutral-950 before:absolute before:bottom-0 before:left-0 before:block before:h-full before:w-full before:-translate-x-full before:bg-neutral-100 before:transition-transform hover:before:translate-x-0"><span class="relative">Clear</span></button>
&nbsp;
<button role="link" id="pastdays-btn" class="relative after:absolute after:bottom-0 after:left-0 after:right-0 after:h-[2px] after:w-full after:origin-bottom after:scale-x-0 after:bg-neutral-800 after:transition-transform after:duration-300 after:ease-[cubic-bezier(0.65_0.05_0.36_1)] hover:after:origin-bottom hover:after:scale-x-100">past 30 days</button>
</div>
<script>
Expand All @@ -545,25 +567,38 @@ <h3 class="mb-8 text-sm font-medium text-slate-600">
document.getElementById("pastdays-btn").addEventListener('click', () => {
pastdays = true;
getComputerData();
})
});

document.getElementById("clearData").addEventListener('click', () => {
pastdays = false;
document.getElementById('first_date').value = "";
document.getElementById('last_date').value = "";
checkAllCheckboxes();
getComputerData();
});

</script>

<canvas id="chart" class="mt-10"></canvas>

<h3 class="mt-10 mb-1 text-1xl font-semibold">Detection Rule List</h3>

<button role="link" onclick="checkAllCheckboxes()" class="relative after:absolute after:bottom-0 after:left-0 after:right-0 after:h-[2px] after:w-full after:origin-bottom after:scale-x-0 after:bg-neutral-800 after:transition-transform after:duration-300 after:ease-[cubic-bezier(0.65_0.05_0.36_1)] hover:after:origin-bottom hover:after:scale-x-100">Include all rules</button>
<br>
<button role="link" onclick="uncheckAllCheckboxes()" class="relative after:absolute after:bottom-0 after:left-0 after:right-0 after:h-[2px] after:w-full after:origin-bottom after:scale-x-0 after:bg-neutral-800 after:transition-transform after:duration-300 after:ease-[cubic-bezier(0.65_0.05_0.36_1)] hover:after:origin-bottom hover:after:scale-x-100">Exclude all rules</button>

<table class="min-w-full align-middle text-sm">
<thead>
<tr class="border-b-2 border-slate-100">
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Alert Title</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Severity</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Count</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">First Date</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Last Date</th>
<th class="min-w-[40px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700"></th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Alert Title</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Severity</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Count</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">First Date</th>
<th class="min-w-[180px] py-3 pe-3 text-start text-sm font-semibold uppercase tracking-wider text-slate-700">Last Date</th>
</tr>
</thead>
<tbody id="detection-rule-list-body">
</tbody>
<tbody id="detection-rule-list-body"></tbody>
</table>

</div>
Expand Down Expand Up @@ -606,6 +641,40 @@ <h3 class="mt-10 mb-1 text-1xl font-semibold">Detection Rule List</h3>
});

});

function checkAllCheckboxes() {
const checkboxes = document.querySelectorAll('.rule_check');
checkboxes.forEach(checkbox => {
if (checkbox.type === 'checkbox') {
checkbox.checked = true;
}
});
}

function uncheckAllCheckboxes() {
const checkboxes = document.querySelectorAll('.rule_check');
checkboxes.forEach(checkbox => {
if (checkbox.type === 'checkbox') {
checkbox.checked = false;
}
});
}

function areAllChecked() {
const checkboxes = document.querySelectorAll('.rule_check');
return Array.from(checkboxes).every(checkbox => checkbox.checked);
}

function areAllUnchecked(className) {
const checkboxes = document.querySelectorAll('.rule_check');
return Array.from(checkboxes).every(checkbox => !checkbox.checked);
}

function getCheckedValues() {
const checkboxes = document.querySelectorAll('.rule_check:checked');
const values = Array.from(checkboxes).map(checkbox => checkbox.value);
return '&rule_title=' + values.map(value => `${encodeURIComponent(value)}`).join(',');
}

</script>
</body>
Expand Down
3 changes: 2 additions & 1 deletion src/takajopkg/web/static/index.htm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />

<title>Project</title>
<title>Takajo Report</title>
<link rel="icon" type="image/x-icon" href="/img/favicon.png">

<script src="https://cdn.tailwindcss.com"></script>
<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet">
Expand Down
Loading

0 comments on commit 57bb98f

Please sign in to comment.