105 |
106 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/public/templates/overview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/public/templates/process_list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
16 |
17 |
18 |
32 |
33 |
34 |
35 |
41 |
42 |
43 |
44 |
45 | {{ lang["PROCESS_H2"] }} | |
46 | {{ lang["TARGET_HOSTNAME"] }} | {{ctrl.hostname}} |
47 | {{ lang["TARGET_DATE"] }} | {{ctrl.date}} |
48 | Total | {{ctrl.data.length}} |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |

57 |
58 |
59 |
60 |
61 |
64 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | record_id |
76 | {{ lang["PROCESS_TABLE_DATE"] }} |
77 | {{ lang["PROCESS_TABLE_TYPE"] }} |
78 | {{ lang["PROCESS_TABLE_SOURCE"] }} |
79 | {{ lang["PROCESS_TABLE_VALUE"] }} |
80 |
81 |
82 |
83 |
84 | {{day_data.number}} |
85 | {{day_data.date}} |
86 | {{day_data.type}} |
87 | {{day_data.process}} |
88 | {{day_data.disp}} |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/public/templates/process_tree.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
process tree
5 |
6 |
7 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
48 | {{ lang["CORRELATION_H2"] }} | |
49 | {{ lang["TARGET_HOSTNAME"] }} | {{ctrl.hostname}} |
50 | {{ lang["TARGET_DATE"] }} | {{ctrl.date}} |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |

59 |
60 |
61 |
62 |
95 |
96 |
97 |
101 |
102 |
103 |
test
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/__tests__/index.js:
--------------------------------------------------------------------------------
1 | import expect from 'expect.js';
2 |
3 | describe('suite', () => {
4 | it('is a test', () => {
5 | expect(true).to.equal(true);
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/Utils.js:
--------------------------------------------------------------------------------
1 | var Utils = {
2 | eventid_to_type: function(event_id) {
3 | var result = "";
4 | switch (event_id) {
5 | case 1:
6 | result = "create_process";
7 | break;
8 | case 11:
9 | result = "create_file";
10 | break;
11 | case 12:
12 | case 13:
13 | case 14:
14 | result = "registry";
15 | break;
16 | case 3:
17 | result = "net_access";
18 | break;
19 | case 8:
20 | result = "remote_thread";
21 | break;
22 | case 2:
23 | result = "file_create_time";
24 | break;
25 | case 7:
26 | result = "image_loaded";
27 | break;
28 | case 19:
29 | case 20:
30 | case 21:
31 | result = "wmi";
32 | break;
33 |
34 | case 22:
35 | result = "dns";
36 | break;
37 | //case 5:
38 | // result = "process_terminated";
39 | // break;
40 |
41 | default:
42 | result = "other";
43 | break;
44 | }
45 |
46 | return result;
47 | },
48 | get_range_datetime: function(date) {
49 | var date_str = date.substr(0, 10)+"T"+date.substr(11, 12)+"Z";
50 | var base_date = new Date(date_str);
51 | var start_date = new Date(base_date.getTime());
52 | var end_date = new Date(base_date.getTime());
53 | //start_date.setHours(start_date.getHours() - Number(config.refine_time_range));
54 | //end_date.setHours(end_date.getHours() + Number(config.refine_time_range));
55 | start_date.setHours(start_date.getHours() - 1);
56 | end_date.setHours(end_date.getHours() + 1);
57 | var start_date_str = this.date_to_text(start_date);
58 | var end_date_str = this.date_to_text(end_date);
59 |
60 | return {"start_date": start_date_str, "end_date": end_date_str};
61 | },
62 | get_range_datetime2: function(date, start_time, end_time) {
63 | //var date_str = date.substr(0, 10)+"T"+date.substr(11, 12)+"Z";
64 | //var base_date = new Date(date_str);
65 | var base_date = new Date(date);
66 | var start_date = new Date(base_date.getTime());
67 | var end_date = new Date(base_date.getTime());
68 |
69 | var start_time_array = start_time.split(':');
70 | var ent_time_array = end_time.split(':');
71 |
72 | start_date.setUTCHours(parseInt(start_time_array[0]),parseInt(start_time_array[1]));
73 | end_date.setUTCHours(parseInt(ent_time_array[0]),parseInt(ent_time_array[1]),59);
74 |
75 | var start_date_str = this.date_to_text(start_date);
76 | var end_date_str = this.date_to_text(end_date);
77 |
78 | return {"start_date": start_date_str, "end_date": end_date_str};
79 | },
80 | get_range_datetime3: function(start_time, end_time) {
81 | var start_date = new Date();
82 | var end_date = new Date();
83 |
84 | start_date.setTime( start_time );
85 | end_date.setTime( end_time );
86 |
87 | var start_date_str = this.date_to_text(start_date);
88 | var end_date_str = this.date_to_text(end_date);
89 |
90 | return {"start_date": start_date_str, "end_date": end_date_str};
91 | },
92 | date_to_text: function(date) {
93 | var y = this.padding(date.getUTCFullYear(), 4, "0"),
94 | m = this.padding(date.getUTCMonth()+1, 2, "0"),
95 | d = this.padding(date.getUTCDate(), 2, "0"),
96 | h = this.padding(date.getUTCHours(), 2, "0"),
97 | min = this.padding(date.getUTCMinutes(), 2, "0"),
98 | s = this.padding(date.getUTCSeconds(), 2, "0"),
99 | millsec = this.padding(date.getUTCMilliseconds(), 3, "0");
100 |
101 | return [y, m, d].join('-') + 'T' + [h, min, s].join(':') + 'Z';
102 | },
103 | padding: function(n, d, p) {
104 | p = p || '0';
105 | return (p.repeat(d) + n).slice(-d);
106 | }
107 | }
108 |
109 | module["exports"] = Utils;
110 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/alert_data.js:
--------------------------------------------------------------------------------
1 | const Utils = require('./Utils');
2 |
3 | async function alertData(sysmon, data) {
4 | var sort_item = {};
5 | sort_item[data.sort_item] = data.sort_order;
6 | //if(data.sort_item != "event_id")sort_item[data.sort_item + ".keyword"] = data.sort_order;
7 | //else sort_item[data.sort_item] = data.sort_order;
8 |
9 | var sort = [];
10 | sort.push(sort_item);
11 |
12 | var searchObj = {
13 | "size": 10000,
14 | "query": {
15 | "bool": {
16 | "must": [{
17 | "range": {"@timestamp": data.query}
18 | }]
19 | }
20 | },
21 | "aggs": {
22 | "unique_hosts": {
23 | "terms": {
24 | "field": "computer_name.keyword",
25 | "size" : 100000
26 | }
27 | },
28 | "tabledata": {
29 | "terms": {
30 | "field": "rule.file_name.keyword",
31 | "size" : 100000
32 | },
33 | "aggs": {
34 | "hosts": {
35 | "terms": {
36 | "field": "computer_name.keyword",
37 | "size" : 100000
38 | }
39 | }
40 | }
41 | }
42 | },
43 | "sort": sort,
44 | "_source": [
45 | "record_number",
46 | "event_id",
47 | "level",
48 | "computer_name",
49 | "event_data",
50 | "@timestamp",
51 | "rule",
52 | "original_id"
53 | ]
54 | };
55 |
56 |
57 | const el_result = await sysmon.client.search({
58 | index: 'sysmon-search-alert-*',
59 | // size: 1000,
60 | body: searchObj
61 | });
62 | //console.log(JSON.stringify(searchObj) + " => " + JSON.stringify(el_result));
63 | console.log(JSON.stringify(searchObj));
64 |
65 | var results = [];
66 | var results_count = 0;
67 | var unique_hosts = [];
68 | var tabledata = [];
69 | if (el_result !== null) {
70 | if (el_result.hits != null) {
71 | results_count = el_result.hits.total;
72 | var hits = el_result.hits.hits;
73 | for (var index in hits) {
74 | var hit = hits[index]._source;
75 | var description = Utils.eventid_to_type(hit.event_id);
76 | var tmp = {
77 | "number": hit.record_number,
78 | "utc_time": hit.event_data.UtcTime,
79 | "event_id": hit.event_id,
80 | "level": hit.level,
81 | "computer_name": hit.computer_name,
82 | "user_name": hit.event_data.User,
83 | "image": hit.event_data.Image,
84 | "date": hit["@timestamp"],
85 | "rule": hit.rule,
86 | "process_guid": hit.event_data.ProcessGuid,
87 | "description": description,
88 | "rule_name": hit.rule[0].file_name,
89 | "_id" : hit.original_id
90 | };
91 | if(hit.event_id == 8){
92 | tmp["process_guid"]=hit.event_data.SourceProcessGuid;
93 | tmp["image"]=hit.event_data.SourceImage;
94 | }
95 |
96 | results.push(tmp);
97 | }
98 | }
99 | if(el_result.aggregations != null){
100 | unique_hosts = el_result.aggregations.unique_hosts.buckets;
101 | tabledata = el_result.aggregations.tabledata.buckets;
102 | }
103 | }
104 |
105 | const response = {
106 | "total": results_count,
107 | "hits": results,
108 | "unique_hosts": unique_hosts,
109 | "table_data" : tabledata
110 | };
111 | return response;
112 | }
113 |
114 | module.exports = alertData;
115 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/alert_host.js:
--------------------------------------------------------------------------------
1 | async function alertHost(sysmon, data) {
2 | var uniqueHostObj = {
3 | "size": 0,
4 | "query": {
5 | "bool": {
6 | "must": [{
7 | "range": {"@timestamp": data.query}
8 | }]
9 | }
10 | },
11 | "aggs": {
12 | "unique_hosts": {
13 | "terms": {
14 | "field": "computer_name.keyword",
15 | "size" : 100000
16 | }
17 | }
18 | }
19 | };
20 |
21 | const el_result = await sysmon.client.search({
22 | index: 'sysmon-search-alert-*',
23 | // size: 1000,
24 | body: uniqueHostObj
25 | };
26 |
27 | var unique_hosts = [];
28 | if(el_result.aggregations != null)unique_hosts = el_result.aggregations.unique_hosts.buckets;
29 | return unique_hosts;
30 | }
31 |
32 | module.exports = alertHost;
33 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/alert_rule.js:
--------------------------------------------------------------------------------
1 | const util = require('util');
2 | const sprintf = require('sprintf-js').sprintf;
3 | const path = require('path');
4 |
5 | const CONFIG_PATH = '../../../conf.js';
6 | import {conf as config} from '../../../conf.js';
7 |
8 | function padding(n, d, p) {
9 | p = p || '0';
10 | return (p.repeat(d) + n).slice(-d);
11 | };
12 |
13 | function create_rule_filename() {
14 | var date = new Date(Date.now());
15 | var year = padding(date.getFullYear(), 4, "0"),
16 | month = padding(date.getMonth()+1, 2, "0"),
17 | day = padding(date.getDate(), 2, "0"),
18 | hour = padding(date.getHours(), 2, "0"),
19 | min = padding(date.getMinutes(), 2, "0"),
20 | second = padding(date.getSeconds(), 2, "0"),
21 | millsec = padding(date.getMilliseconds(), 3, "0");
22 | var filename = sprintf(
23 | 'rule-%1$s%2$s%3$s%4$s%5$s%6$s%7$s.json', year, month, day, hour, min, second, millsec
24 | );
25 | return filename;
26 | };
27 |
28 | function create_fullpath(savepath, filename) {
29 | var conf_dir = path.join(__dirname, path.dirname(CONFIG_PATH));
30 | console.log("savepath:", savepath, "/filename:", filename, "/basedir:", conf_dir);
31 | if (path.isAbsolute(savepath)) {
32 | return path.join(savepath, filename);
33 | } else {
34 | return path.join(conf_dir, savepath, filename);
35 | }
36 | };
37 |
38 | const saveAlert = function (params) {
39 | //console.log(util.inspect(params));
40 | var filename = create_rule_filename();
41 | var fullpath = create_fullpath(config.savepath, filename);
42 | console.log(fullpath);
43 | try {
44 | const fs = require('fs');
45 | fs.writeFileSync(fullpath, JSON.stringify(params, null, 2));
46 | console.log("#---------- save search criteria/success ----------");
47 | var res = {
48 | 'status': 200,
49 | 'result': sprintf('succeeded to save rules in "%1$s".', fullpath)
50 | };
51 | console.log(res);
52 | return res;
53 | } catch (e) {
54 | console.error("#---------- save search criteria/fail ----------");
55 | console.error(util.inspect(e));
56 | return e;
57 | }
58 | }
59 |
60 | const getAlert = async function (params) {
61 | var conf_dir = path.join(__dirname, path.dirname(CONFIG_PATH));
62 | var savepath = config.savepath;
63 | if (!path.isAbsolute(savepath)) savepath = path.join(conf_dir, savepath);
64 | console.log(`savepath: ${savepath}`);
65 | const fs = require('fs').promises;
66 | const result = await fs.readdir(savepath, async function(err, files){
67 | if (err){
68 | console.error("#---------- Acquisition of file list failed ----------");
69 | console.log(err);
70 | return;
71 | }
72 | const fileList = await files.filter(async function(file){
73 | return fs.statSync(create_fullpath(config.savepath,file)).isFile();
74 | })
75 | console.log("file list: " + fileList);
76 | return fileList;
77 | });
78 | return result;
79 | }
80 |
81 | const deleteAlert = async function (params) {
82 | var deleted = 0;
83 | if(params.filename == null || params.filename == ""){
84 | deleted = -1;
85 | } else {
86 | const basename = path.basename(params.filename);
87 | const filepath = create_fullpath(config.savepath, basename);
88 |
89 | const fs = require('fs').promises;
90 | deleted = await fs.unlink(filepath)
91 | .then(result=>{return 1})
92 | .catch(err => {return -1})
93 | }
94 | const result = {
95 | data: deleted
96 | }
97 | return result;
98 |
99 | }
100 |
101 | module.exports = {
102 | saveAlert,
103 | getAlert,
104 | deleteAlert
105 | };
106 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/dashboard.js:
--------------------------------------------------------------------------------
1 | async function dashBoard(sysmon, data) {
2 | var searchObj = {
3 | "size": 0,
4 | "query": {
5 | "bool": {
6 | "must": [
7 | {"range":{"@timestamp": data.query}}
8 | ]
9 | }
10 | },
11 | "aggs": {
12 | "by_image_asc": {
13 | "terms": {
14 | "field": "statistics_data.Image.keyword",
15 | "order" : { "_count" : "asc" },
16 | "size": 100
17 | }
18 | },
19 | "by_image_desc": {
20 | "terms": {
21 | "field": "statistics_data.Image.keyword",
22 | "order" : { "_count" : "desc" },
23 | "size": 100
24 | }
25 | },
26 | "by_DestinationIp_asc": {
27 | "terms": {
28 | "field": "statistics_data.DestinationIp.keyword",
29 | "order" : { "_count" : "asc" },
30 | "size": 100
31 | }
32 | },
33 | "by_DestinationIp_desc": {
34 | "terms": {
35 | "field": "statistics_data.DestinationIp.keyword",
36 | "order" : { "_count" : "desc" },
37 | "size": 100
38 | }
39 | },
40 | "by_eventtype": {
41 | "terms": {
42 | "field": "statistics_data.EventType.keyword",
43 | "order" : { "_count" : "asc" },
44 | "size": 100
45 | }
46 | },
47 | "by_DestinationPort": {
48 | "terms": {
49 | "field": "statistics_data.DestinationPort.keyword",
50 | "order" : { "_count" : "asc" },
51 | "size": 100
52 | }
53 | }
54 | }
55 | };
56 |
57 | //const el_result = this.search_statistical(searchObj);
58 | const el_result = await sysmon.client.search({
59 | index: 'sysmon-search-statistics-*',
60 | // size: 1000,
61 | body: searchObj
62 | });
63 |
64 | var results = {};
65 | var keys=[
66 | "by_image_asc","by_image_desc","by_DestinationIp_asc","by_DestinationIp_desc","by_eventtype","by_DestinationPort"
67 | ];
68 | for (var key in keys) {
69 | if(el_result.aggregations != null && keys[key] in el_result["aggregations"]){
70 | results[keys[key]] = el_result["aggregations"][keys[key]]["buckets"];
71 | }else{
72 | results[keys[key]] = [];
73 | }
74 | }
75 |
76 | if(el_result.hits!=null) results["total"] = el_result["hits"]["total"];
77 |
78 | return results;
79 | }
80 |
81 | module.exports = dashBoard;
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/events.js:
--------------------------------------------------------------------------------
1 | async function events(sysmon, hostname, date) {
2 | var timestamp = {
3 | "range" : {"@timestamp": date}
4 | }
5 | if (typeof date === "string"){
6 | timestamp = {
7 | "match" : {"@timestamp": date}
8 | }
9 | }
10 | var host = {};
11 | host[sysmon.computer_name] = hostname;
12 | var searchObj = {
13 | "size": 0,
14 | "query": {
15 | "bool": {
16 | "must": [
17 | {"match": host},
18 | {"match": sysmon.channel},
19 | timestamp
20 | ]
21 | }
22 | },
23 | "aggs": {
24 | "group_by": {
25 | "date_histogram": {
26 | "field": "@timestamp",
27 | "interval": "1d",
28 | "format": "yyyy-MM-dd"
29 | },
30 | "aggs": {
31 | "event_id": {
32 | "terms": {
33 | "field": sysmon.event_id,
34 | "size" : 100000
35 | }
36 | }
37 | }
38 | }
39 | }
40 | };
41 |
42 | const el_result = await sysmon.client.search({
43 | index: sysmon.index,
44 | // size: 1000,
45 | body: searchObj
46 | });
47 |
48 | if (el_result){
49 | console.log(el_result);
50 | //var results = [];
51 | var hits = el_result.aggregations.group_by.buckets;
52 | var category = [
53 | "create_process",
54 | "file_create_time",
55 | "net_access",
56 | //"process_terminated",
57 | //"driver_loaded",
58 | "image_loaded",
59 | "remote_thread",
60 | //"raw_access_read",
61 | //"process_access",
62 | "create_file",
63 | "registry",
64 | //"pipe",
65 | "wmi",
66 | "dns",
67 | //"error",
68 | "other"
69 | ];
70 | var results = {"items":[], "groups":category};
71 | for (var index in hits) {
72 | var item = hits[index];
73 | var cnt = {};
74 | for(var i in category){cnt[category[i]] = 0;}
75 | for (var i in item['event_id']['buckets']) {
76 | var event = item['event_id']['buckets'][i];
77 | if (event['key'] == 1) {
78 | cnt["create_process"] += event['doc_count'];
79 | } else if (event['key'] == 2) {
80 | cnt["file_create_time"] += event['doc_count'];
81 | } else if (event['key'] == 3) {
82 | cnt["net_access"] += event['doc_count'];
83 | //} else if (event['key'] == 5) {
84 | // cnt["process_terminated"] += event['doc_count'];
85 | //} else if (event['key'] == 6) {
86 | // cnt["driver_loaded"] += event['doc_count'];
87 | } else if (event['key'] == 7) {
88 | cnt["image_loaded"] += event['doc_count'];
89 | } else if (event['key'] == 8) {
90 | cnt["remote_thread"] += event['doc_count'];
91 | //} else if (event['key'] == 9) {
92 | // cnt["raw_access_read"] += event['doc_count'];
93 | //} else if (event['key'] == 10) {
94 | // cnt["process_access"] += event['doc_count'];
95 | } else if (event['key'] == 11) {
96 | cnt["create_file"] += event['doc_count'];
97 | } else if (event['key'] == 12 || event['key'] == 13 || event['key' == 14]) {
98 | cnt["registry"] += event['doc_count'];
99 | //} else if (event['key'] == 17 || event['key'] == 18) {
100 | // cnt["pipe"] += event['doc_count'];
101 | } else if (event['key'] == 19 || event['key'] == 20 || event['key'] == 21) {
102 | cnt["wmi"] += event['doc_count'];
103 | } else if (event['key'] == 22) {
104 | cnt["dns"] += event['doc_count'];
105 | //} else if (event['key'] == 255) {
106 | // cnt["error"] += event['doc_count'];
107 | } else {
108 | cnt["other"] += event['doc_count'];
109 | }
110 |
111 | }
112 |
113 | if (typeof date === "string"){
114 | // return piechart data
115 | var data = {"count":cnt};
116 | return data;
117 | }else{
118 | results["count"] = cnt;
119 | }
120 |
121 | let gid = 0;
122 | for (let [key, value] of Object.entries(cnt)) {
123 | var tmp = {
124 | "group": gid,
125 | "x":item['key_as_string'],
126 | "y": value,
127 | "label":{
128 | "content":key,
129 | "yOffset":20
130 | }
131 | };
132 | results["items"].push(tmp);
133 | gid++;
134 | }
135 |
136 | }
137 | // return 2dgraph data
138 | return results;
139 | }
140 | return;
141 | }
142 |
143 | module.exports = events;
144 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/hosts.js:
--------------------------------------------------------------------------------
1 | async function searchHosts(sysmon, params) {
2 |
3 | var search_items_and_date_query = [{
4 | "match": sysmon.channel
5 | }];
6 | if (typeof params !== "undefined"
7 | && params !== null
8 | && Object.keys(params).length !== 0)
9 | {
10 | if ("keyword" in params
11 | && typeof params.keyword !== "undefined"
12 | && params.keyword !== "")
13 | {
14 | var wildcard = {};
15 | //wildcard[sysmon.computer_name] = "*" + params['keyword'].toLowerCase() + "*";
16 | wildcard[sysmon.computer_name] = "*" + params['keyword'] + "*";
17 | search_items_and_date_query.push({
18 | "wildcard": wildcard
19 | });
20 | }
21 | if (("fm_start_date" in params
22 | && typeof params.fm_start_date !== "undefined")
23 | || ("fm_end_date" in params
24 | && typeof params.fm_end_date !== "undefined")
25 | ){
26 | var timestamp_range = {};
27 | if ("fm_start_date" in params
28 | && typeof params.fm_start_date !== "undefined")
29 | {
30 | timestamp_range["gte"] = params.fm_start_date;
31 | }
32 |
33 | if ("fm_end_date" in params
34 | && typeof params.fm_end_date !== "undefined"
35 | ) {
36 | timestamp_range["lte"] = params.fm_end_date;
37 | }
38 |
39 | search_items_and_date_query.push({
40 | "range": { "@timestamp": timestamp_range }
41 | });
42 | }
43 | }
44 |
45 | var searchObj = {
46 | //"size": 0,
47 | "query": {
48 | "bool": {
49 | "must": search_items_and_date_query
50 | }
51 | },
52 | "aggs": {
53 | "group_by": {
54 | "date_histogram": {
55 | "field": "@timestamp",
56 | "interval": "1d",
57 | "format": "yyyy-MM-dd"
58 | },
59 | "aggs": {
60 | "computer_names": {
61 | "terms": {
62 | "size": 1000,
63 | //"field": sysmon.computer_name + ".keyword"
64 | "field": sysmon.computer_name
65 | }
66 | }
67 | }
68 | }
69 | }
70 | };
71 | console.log("[search hosts] " + JSON.stringify(searchObj));
72 |
73 | const el_result = await sysmon.client.search({
74 | index: sysmon.index,
75 | // size: 1000,
76 | body: searchObj
77 | });
78 | //console.log("result: " + JSON.stringify(el_result))
79 |
80 | var results = [];
81 | //var hits = el_result.aggregations.group_by.buckets;
82 | var hits = el_result.aggregations?el_result.aggregations.group_by.buckets:[];
83 |
84 | for (var index in hits) {
85 | var item = hits[index];
86 | var tmp = {
87 | "date": item['key_as_string'],
88 | "result": item['computer_names']['buckets']
89 | };
90 | results.push(tmp);
91 | }
92 |
93 | return results;
94 |
95 | }
96 |
97 | module.exports = searchHosts;
98 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/import_search.js:
--------------------------------------------------------------------------------
1 | const request = require('request');
2 | import {conf as config} from '../../../conf.js';
3 | const sprintf = require('sprintf-js').sprintf;
4 |
5 | async function doRequest(options) {
6 | return new Promise(function (resolve, reject) {
7 | request(options, function (err, res, body) {
8 | if (!err && res.statusCode == 200) resolve(res.body);
9 | else reject(err);
10 | });
11 | });
12 | }
13 |
14 | async function importSearchKeywords(params) {
15 | console.log(params);
16 | //var url = 'http://localhost:56020' + params.part_url;
17 | var url = 'http://' + config.import_server_url + ':' + config.import_server_port + params.part_url;
18 | var formData = {
19 | file: {
20 | value: new Buffer.from(params.contents),
21 | options: {
22 | filename: params.filename,
23 | contentType: params.contenttype
24 | }
25 | }
26 | };
27 | console.log("#---------- request to STIX/IoC analyze server ----------");
28 | const req_str = sprintf(
29 | '{ url: \'%1$s\', formData: { file: { value: <...>, options: { filename: \'%2$s\', contentType: \'%3$s\' } } } }',
30 | url, params.filename, params.contenttype
31 | );
32 | console.log(req_str);
33 | const requestOptions = {
34 | url: url,
35 | method: "POST",
36 | formData: formData,
37 | json: true
38 | };
39 | const result = await doRequest(requestOptions);
40 | /*
41 | const result = await request.post({
42 | url: url, formData: formData
43 | },
44 | function(error, response) {
45 | console.log("#---------- response from STIX/IoC analyze server ----------");
46 | if (error) {
47 | console.error(util.inspect(error));
48 | return;
49 | } else {
50 | var res = {
51 | 'status': response.statusCode,
52 | 'message': response.statusMessage,
53 | 'data': response.body
54 | };
55 | console.log(res);
56 | return res;
57 | }
58 | }
59 | );
60 | */
61 | console.log("#---------- response from STIX/IoC analyze server ----------");
62 | console.log(JSON.stringify(result));
63 | return result;
64 | }
65 |
66 | module.exports = importSearchKeywords;
67 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/sm_search.js:
--------------------------------------------------------------------------------
1 | const Utils = require('./Utils');
2 | const makeQuery = require('./make_query');
3 |
4 | function set_wildcard_value(search_items, key, params, num) {
5 | var match = {};
6 | if ("search_value_" + num in params
7 | && typeof params["search_value_" + num] !== "undefined") {
8 | match[key] = "*" + str_escape(params["search_value_" + num].toLowerCase()) + "*";
9 | search_items.push({"wildcard": match});
10 | }
11 | return search_items;
12 | }
13 |
14 | function str_escape(str) {
15 | if(str == null || typeof str === "undefined") return "";
16 | var entityMap = {
17 | "\\" : "\\\\",
18 | "\"" : "\\\"",
19 | "\'" : "\\\'"
20 | };
21 | return String(str).replace(/[\\\"\']/g, function(s) {
22 | return entityMap[s];
23 | });
24 | }
25 |
26 | async function smSearch(sysmon, params) {
27 | const search_items_and_date_query = await makeQuery(params, sysmon.map);
28 | search_items_and_date_query.push({"match":sysmon.channel});
29 |
30 | var sort_item = {};
31 | sort_item[params.sort_item] = params.sort_order;
32 |
33 | //if(params.sort_item != "winlog.event_id") sort_item[params.sort_item + ".keyword"] = params.sort_order;
34 | //else sort_item[params.sort_item] = params.sort_order;
35 |
36 | var sort = [];
37 | sort.push(sort_item);
38 |
39 | var searchObj = {
40 | "size": 10000,
41 | "query": {
42 | "bool": {"must": search_items_and_date_query}
43 | },
44 | "sort": sort,
45 | //"_source": ["record_number", "event_id", "level", "event_record_id", "computer_name", "user", "event_data", "@timestamp"]
46 | "_source": ["winlog", "log", "@timestamp"]
47 | };
48 |
49 | console.log("[smSearch] " + JSON.stringify(searchObj, null, 2));
50 |
51 | const el_result = await sysmon.client.search({
52 | index: sysmon.index,
53 | // size: 1000,
54 | body: searchObj
55 | });
56 | //console.log(JSON.stringify(el_result));
57 |
58 | var results = [];
59 | var results_count = 0;
60 | //if (el_result !== null) {
61 | if ("hits" in el_result) {
62 | results_count = el_result.hits.total;
63 | var hits = el_result.hits.hits;
64 | //console.log(JSON.stringify(hits));
65 | for (let index in hits) {
66 | var hit = hits[index]._source;
67 | var description = Utils.eventid_to_type(hit.winlog.event_id);
68 | var tmp = {
69 | "number": hit.winlog.record_id,
70 | "utc_time": hit.winlog.event_data.UtcTime,
71 | "event_id": hit.winlog.event_id,
72 | "level": hit.log.level,
73 | "computer_name": hit.winlog.computer_name,
74 | "user_name": hit.winlog.user?hit.winlog.user.name:"",
75 | "image": hit.winlog.event_data.Image,
76 | "date": hit["@timestamp"],
77 | "process_guid": hit.winlog.event_data.ProcessGuid,
78 | "description" : description,
79 | "task": hit.winlog.task,
80 | "_id" : hits[index]._id
81 | };
82 | if(hit.winlog.event_id == 8){
83 | tmp["process_guid"] = hit.winlog.event_data.SourceProcessGuid;
84 | tmp["image"] = hit.winlog.event_data.SourceImage;
85 | }
86 | results.push(tmp);
87 | }
88 | }
89 | //console.log(results);
90 | const res = {"total": results_count, "hits": results};
91 |
92 | return res;
93 | }
94 |
95 | module.exports = smSearch;
96 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/search/sm_unique_hosts.js:
--------------------------------------------------------------------------------
1 | const makeQuery = require('./make_query');
2 |
3 | async function sm_unique_hosts(sysmon, params) {
4 | var query = await makeQuery(params, sysmon.map);
5 | query.push({"match":sysmon.channel});
6 | var uniqueHostObj = {
7 | //"size": 0,
8 | "query": {
9 | "bool": {"must": query}
10 | },
11 | "aggs": {
12 | "unique_hosts": {
13 | "terms": {
14 | //"field": sysmon.computer_name + ".keyword"
15 | "field": sysmon.computer_name
16 | }
17 | }
18 | }
19 | };
20 | console.log("[search unique host] " + JSON.stringify(uniqueHostObj, null, 2))
21 | const el_result = await sysmon.client.search({
22 | index: sysmon.index,
23 | // size: 1000,
24 | body: uniqueHostObj
25 | });
26 |
27 | //console.log(JSON.stringify(el_result));
28 | if (el_result) {
29 | var unique_hosts = el_result.aggregations.unique_hosts.buckets;
30 | return unique_hosts;
31 | }
32 | return;
33 | }
34 |
35 | module.exports = sm_unique_hosts;
36 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/server/routes/test.js:
--------------------------------------------------------------------------------
1 |
2 | var fs = require('fs');
3 |
4 | const Sysmon_Search_Logic = require('./Sysmon_Search_Logic');
5 |
6 | function get_test( hostname, date ) {
7 | var obj = new Sysmon_Search_Logic('localhost', 9200);
8 |
9 | var searchObj = {
10 | "size": 1000,
11 | "query": {
12 | "bool": {
13 | "must": [{
14 | "match": { "computer_name": hostname, }
15 | },
16 | {
17 | "match": { "event_id": 1 }
18 | },
19 | {
20 | "match": { "@timestamp": date }
21 | } ]
22 | }
23 | },
24 | "sort": [{"@timestamp":"asc"}],
25 | "_source": ["record_number", "event_data"]
26 | };
27 |
28 | function get_datas(el_result) {
29 | fs.writeFile('debug.json', JSON.stringify(el_result, null, ' '));
30 | }
31 |
32 | obj.search(searchObj, get_datas);
33 | }
34 |
35 | function test() {
36 | var datas = require('./debug.json');
37 |
38 | function make_process_list(el_result) {
39 | var hits = el_result.hits.hits;
40 |
41 | var process_array = {};
42 | var p_process_array = {};
43 |
44 | for (var index in hits) {
45 | var item = hits[index]._source;
46 |
47 | var key = item['event_data']['ProcessGuid'];
48 | var pkey = item['event_data']['ParentProcessGuid'];
49 |
50 | item['index'] = index + 1;
51 | item['key'] = key;
52 | item['pkey'] = pkey;
53 |
54 | var tmp = {
55 | "index": item.index,
56 | "key": item.key,
57 | "pkey": item.pkey,
58 | "number": item.record_number,
59 | "level": item.event_data.IntegrityLevel,
60 | "curdir": item.event_data.CurrentDirectory,
61 | "image": item.event_data.Image,
62 | "cmd": item.event_data.CommandLine,
63 | "guid": item.event_data.ProcessGuid,
64 | "date": item.event_data.UtcTime,
65 | "info":{
66 | 'CurrentDirectory':item.event_data.CurrentDirectory,
67 | 'CommandLine':item.event_data.CommandLine,
68 | 'Hashes':item.event_data.Hashes,
69 | 'ParentImage':item.event_data.ParentImage,
70 | 'ParentProcessGuid':item.event_data.ParentProcessGuid,
71 | 'ParentCommandLine':item.event_data.ParentCommandLine,
72 | 'ProcessGuid':item.event_data.ProcessGuid,
73 | 'Image':item.event_data.Image
74 | }
75 | };
76 | process_array[key] = tmp;
77 | if (pkey in p_process_array) {
78 | p_process_array[pkey].push(tmp);
79 | } else {
80 | p_process_array[pkey] = [];
81 | p_process_array[pkey].push(tmp);
82 | }
83 | }
84 |
85 | return [process_array, p_process_array]
86 | }
87 |
88 | function find_root_process(cur, list, p_list) {
89 | while( true ) {
90 | var tmp_key = cur['pkey'];
91 |
92 | var tmp = {
93 | "index": -1,
94 | "key": tmp_key,
95 | "pkey": "",
96 | "number": -1,
97 | "level": '',
98 | "curdir": '',
99 | "image":cur.info.ParentImage,
100 | "guid": cur.info.ParentProcessGuid,
101 | "date": '',
102 | "info":{
103 | 'CurrentDirectory':'',
104 | 'CommandLine':cur.info.ParentCommandLine,
105 | 'ProcessGuid':cur.info.ParentProcessGuid,
106 | 'Hashes':'',
107 | 'ParentProcessGuid':'',
108 | 'ParentCommandLine':'',
109 | 'Image':cur.info.ParentImage
110 | }
111 | };
112 |
113 | if (tmp_key in p_list) {
114 | if (tmp in list) {
115 | cur = list[tmp_key];
116 | } else {
117 | return tmp;
118 | }
119 | } else {
120 | return tmp;
121 | }
122 | }
123 | }
124 |
125 | function make_process_tree(cur, list, p_list) {
126 | if(cur.current !=null && cur.current.key !=null){
127 | var key = cur.current.key;
128 | delete list[key];
129 |
130 | for (var index in p_list[key]) {
131 | var tmp = {
132 | 'current': p_list[key][index],
133 | 'parent': cur.current,
134 | 'child': []
135 | }
136 | cur.child.push(tmp);
137 | make_process_tree(tmp, list, p_list);
138 | }
139 | }
140 | }
141 |
142 | [process_array, p_process_array] = make_process_list(datas);
143 |
144 | var process_tree = [];
145 | for (var index in process_array) {
146 | console.log( "================================" );
147 | console.log( index );
148 | var item = process_array[index];
149 | var tmp = find_root_process(item, process_array, p_process_array);
150 |
151 | var root = {
152 | 'current': tmp,
153 | 'parent': null,
154 | 'child': []
155 | }
156 | make_process_tree(root, process_array, p_process_array);
157 | process_tree.push( root );
158 | }
159 | console.log( "================================" );
160 | console.log( JSON.stringify(process_tree, null, ' ') );
161 |
162 | // console.log( "================================" );
163 | // for (var index in process_array) {
164 | // console.log( index );
165 | // }
166 |
167 | //console.log( "process_array" );
168 | //console.log( process_array );
169 | //console.log( "p_process_array" );
170 | //console.log( p_process_array );
171 | }
172 |
173 | if (require.main === module) {
174 | function debug(result) {
175 | console.log("################################");
176 | console.log(JSON.stringify(result, null, '\t'));
177 | };
178 |
179 | //get_test('practice7test', '2018-02-14');
180 | //test();
181 |
182 | var obj = new Sysmon_Search_Logic('localhost', 9200);
183 | //obj.events("practice7test", debug);
184 | //obj.process_list("practice7test", "net", "2018-02-14", debug);
185 | //obj.process("practice7test", "2018-02-14", debug);
186 | //obj.process_overview("practice7test", "2017-11-14", "{B9BDBBFE-7304-5A0A-0000-00107E7F0500}", debug);
187 | //obj.child_process("practice7test", "2017-11-14", "{B9BDBBFE-7304-5A0A-0000-00107E7F0500}", debug);
188 | obj.process_start_end("practice7test", "2018-02-14", "1518570000000", "1518580859000", null, debug);
189 | }
190 |
--------------------------------------------------------------------------------
/sysmon_search_plugin/winlogbeat.yml:
--------------------------------------------------------------------------------
1 | title: Elastic Winlogbeat (from 7.x) index pattern and field mapping
2 | order: 20
3 | backends:
4 | - es-qs
5 | - es-dsl
6 | - kibana
7 | - xpack-watcher
8 | - elastalert
9 | - elastalert-dsl
10 | logsources:
11 | windows:
12 | product: windows
13 | index: winlogbeat-*
14 | windows-application:
15 | product: windows
16 | service: application
17 | conditions:
18 | winlog.channel: Application
19 | windows-security:
20 | product: windows
21 | service: security
22 | conditions:
23 | winlog.channel: Security
24 | windows-sysmon:
25 | product: windows
26 | service: sysmon
27 | conditions:
28 | winlog.channel: 'Microsoft-Windows-Sysmon/Operational'
29 | windows-dns-server:
30 | product: windows
31 | service: dns-server
32 | conditions:
33 | winlog.channel: 'DNS Server'
34 | windows-driver-framework:
35 | product: windows
36 | service: driver-framework
37 | conditions:
38 | winlog.provider_name: 'Microsoft-Windows-DriverFrameworks-UserMode/Operational'
39 | windows-dhcp:
40 | product: windows
41 | service: dhcp
42 | conditions:
43 | winlog.provider_name: 'Microsoft-Windows-DHCP-Server/Operational'
44 | defaultindex: winlogbeat-*
45 | # Extract all field names qith yq:
46 | # yq -r '.detection | del(.condition) | map(keys) | .[][]' $(find sigma/rules/windows -name '*.yml') | sort -u | grep -v ^EventID$ | sed 's/^\(.*\)/ \1: winlog.event_data.\1/g'
47 | # Keep EventID! Clean up the list afterwards!
48 | fieldmappings:
49 | EventID: winlog.event_id
50 | EventData: winlog.event_data
51 | RecordID: winlog.record_id
52 | AccessMask: winlog.event_data.AccessMask
53 | AccountName: winlog.event_data.AccountName
54 | AllowedToDelegateTo: winlog.event_data.AllowedToDelegateTo
55 | AttributeLDAPDisplayName: winlog.event_data.AttributeLDAPDisplayName
56 | AuditPolicyChanges: winlog.event_data.AuditPolicyChanges
57 | AuthenticationPackageName: winlog.event_data.AuthenticationPackageName
58 | CallingProcessName: winlog.event_data.CallingProcessName
59 | CallTrace: winlog.event_data.CallTrace
60 | CommandLine: winlog.event_data.CommandLine
61 | ComputerName: winlog.computer_name
62 | CurrentDirectory: winlog.event_data.CurrentDirectory
63 | Description: winlog.event_data.Description
64 | DestinationHostname: winlog.event_data.DestinationHostname
65 | DestinationIp: winlog.event_data.DestinationIp
66 | DestinationIsIpv6: winlog.event_data.DestinationIsIpv6
67 | DestinationPort: winlog.event_data.DestinationPort
68 | Details: winlog.event_data.Details
69 | EngineVersion: winlog.event_data.EngineVersion
70 | EventType: winlog.event_data.EventType
71 | FailureCode: winlog.event_data.FailureCode
72 | FileName: winlog.event_data.FileName
73 | GrantedAccess: winlog.event_data.GrantedAccess
74 | GroupName: winlog.event_data.GroupName
75 | GroupSid: winlog.event_data.GroupSid
76 | Hashes: winlog.event_data.Hashes
77 | HiveName: winlog.event_data.HiveName
78 | HostVersion: winlog.event_data.HostVersion
79 | Image: winlog.event_data.Image
80 | ImageLoaded: winlog.event_data.ImageLoaded
81 | ImagePath: winlog.event_data.ImagePath
82 | Imphash: winlog.event_data.Imphash
83 | IpAddress: winlog.event_data.IpAddress
84 | KeyLength: winlog.event_data.KeyLength
85 | LogonProcessName: winlog.event_data.LogonProcessName
86 | LogonType: winlog.event_data.LogonType
87 | NewProcessName: winlog.event_data.NewProcessName
88 | ObjectClass: winlog.event_data.ObjectClass
89 | ObjectName: winlog.event_data.ObjectName
90 | ObjectType: winlog.event_data.ObjectType
91 | ObjectValueName: winlog.event_data.ObjectValueName
92 | ParentCommandLine: winlog.event_data.ParentCommandLine
93 | ParentProcessGuid: winlog.event_data.ParentProcessGuid
94 | ParentProcessName: winlog.event_data.ParentProcessName
95 | ParentImage: winlog.event_data.ParentImage
96 | Path: winlog.event_data.Path
97 | PipeName: winlog.event_data.PipeName
98 | ProcessCommandLine: winlog.event_data.ProcessCommandLine
99 | ProcessGuid: winlog.event_data.ProcessGuid
100 | ProcessName: winlog.event_data.ProcessName
101 | Protocol: winlog.event_data.Protocol
102 | Properties: winlog.event_data.Properties
103 | QueryName: winlog.event_data.QueryName
104 | QueryStatus: winlog.event_data.QueryStatus
105 | QueryResults: winlog.event_data.QueryResults
106 | SecurityID: winlog.event_data.SecurityID
107 | ServiceFileName: winlog.event_data.ServiceFileName
108 | ServiceName: winlog.event_data.ServiceName
109 | ShareName: winlog.event_data.ShareName
110 | Signature: winlog.event_data.Signature
111 | Source: winlog.event_data.Source
112 | SourceHostname: winlog.event_data.SourceHostname
113 | SourceImage: winlog.event_data.SourceImage
114 | SourceIp: winlog.event_data.SourceIp
115 | SourceIsIpv6: winlog.event_data.SourceIsIpv6
116 | SourceProcessGuid: winlog.event_data.SourceProcessGuid
117 | StartAddress: winlog.event_data.StartAddress
118 | StartModule: winlog.event_data.StartModule
119 | Status: winlog.event_data.Status
120 | SubjectUserName: winlog.event_data.SubjectUserName
121 | SubjectUserSid: winlog.event_data.SubjectUserSid
122 | TargetFilename: winlog.event_data.TargetFilename
123 | TargetImage: winlog.event_data.TargetImage
124 | TargetObject: winlog.event_data.TargetObject
125 | TicketEncryptionType: winlog.event_data.TicketEncryptionType
126 | TicketOptions: winlog.event_data.TicketOptions
127 | User: winlog.event_data.User
128 | UtcTime: winlog.event_data.UtcTime
129 | WorkstationName: winlog.event_data.WorkstationName
130 |
--------------------------------------------------------------------------------
/sysmon_search_r/.kibana-plugin-helpers.json:
--------------------------------------------------------------------------------
1 | {
2 | "styleSheetToCompile": "public/app.scss"
3 | }
4 |
--------------------------------------------------------------------------------
/sysmon_search_r/conf.js:
--------------------------------------------------------------------------------
1 | var conf = {
2 | //elasticsearch server URL
3 | "elasticsearch_url": "localhost",
4 | //elasticsearch server Port
5 | "elasticsearch_port": "9200",
6 | //monitor rule file path
7 | "savepath": "/tmp/rule_files",
8 | //stixioc import server URL
9 | "import_server_url": "localhost",
10 | //stixioc import server port
11 | "import_server_port": "56020",
12 | //internal time (hour)
13 | "refine_time_range": "1",
14 | //maximum object number
15 | "max_object_num": "30",
16 | "elasticsearch_user": "elastic",
17 | "elasticsearch_password": "changeme",
18 | };
19 | exports.conf = conf;
20 |
--------------------------------------------------------------------------------
/sysmon_search_r/index.js:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path';
2 | import { existsSync } from 'fs';
3 |
4 | //import Route from './server/routes/sysmon_search';
5 |
6 | export default function (kibana) {
7 | return new kibana.Plugin({
8 | require: ['elasticsearch'],
9 | name: 'sysmon_search_r',
10 | uiExports: {
11 | app: {
12 | title: 'SysmonSearch R',
13 | description: 'An awesome Kibana plugin',
14 | main: 'plugins/sysmon_search_r/app',
15 | },
16 | },
17 |
18 | config(Joi) {
19 | return Joi.object({
20 | enabled: Joi.boolean().default(true),
21 | }).default();
22 | },
23 |
24 | init(server, options) { // eslint-disable-line no-unused-vars
25 | //Route(server);
26 | }
27 | });
28 | }
29 |
--------------------------------------------------------------------------------
/sysmon_search_r/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sysmon_search_r",
3 | "version": "0.0.0",
4 | "description": "An awesome Kibana plugin",
5 | "main": "index.js",
6 | "kibana": {
7 | "version": "kibana",
8 | "templateVersion": "1.0.0"
9 | },
10 | "dependencies": {
11 | "lodash": "^4.17.15",
12 | "query-string": "^6.10.1"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { uiModules } from 'ui/modules';
3 | import chrome from 'ui/chrome';
4 | import { render, unmountComponentAtNode } from 'react-dom';
5 |
6 | import 'ui/autoload/styles';
7 | import { Main } from './components/main';
8 |
9 | const app = uiModules.get('apps/sysmon_search_r');
10 |
11 | app.config($locationProvider => {
12 | $locationProvider.html5Mode({
13 | enabled: false,
14 | requireBase: false,
15 | rewriteLinks: false,
16 | });
17 | });
18 | app.config(stateManagementConfigProvider =>
19 | stateManagementConfigProvider.disable()
20 | );
21 |
22 | function RootController($scope, $element, $http) {
23 | const domNode = $element[0];
24 | render(
25 | ,domNode
26 | );
27 |
28 | // unmount react on controller destroy
29 | $scope.$on('$destroy', () => {
30 | unmountComponentAtNode(domNode);
31 | });
32 | }
33 | chrome.setRootController('sysmon_search_r', RootController);
34 |
35 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/app.scss:
--------------------------------------------------------------------------------
1 | #summary {
2 | padding:15px;
3 | max-width: 1280px;
4 | margin: 0 auto;
5 | }
6 |
7 | table.legend {
8 | float: left;
9 | }
10 |
11 | table.legend th {
12 | font-size:16px;
13 | padding:5px;
14 |
15 | }
16 |
17 | table.legend td {
18 | font-size:16px;
19 | padding:5px;
20 | }
21 |
22 | #piechart {
23 | float: left;
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/acceptDeleteIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/acceptDeleteIcon.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/addNodeIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/addNodeIcon.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/backIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/backIcon.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/connectIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/connectIcon.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/cross.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/cross.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/cross2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/cross2.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/deleteIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/deleteIcon.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/downArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/downArrow.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/editIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/editIcon.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/leftArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/leftArrow.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/minus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/minus.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/plus.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/rightArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/rightArrow.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/upArrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/upArrow.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/img/network/zoomExtends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/dist/img/network/zoomExtends.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/esm/index.d.ts:
--------------------------------------------------------------------------------
1 | export * from "./vis-timeline-graph2d";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/esm/index.js:
--------------------------------------------------------------------------------
1 | export * from "./vis-timeline-graph2d";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/esm/vis-timeline-graph2d.d.ts:
--------------------------------------------------------------------------------
1 | export * from "../../declarations/entry-esnext";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/esm/vis-timeline-graph2d.min.d.ts:
--------------------------------------------------------------------------------
1 | export * from "../../declarations/entry-esnext";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/index.d.ts:
--------------------------------------------------------------------------------
1 | export * from "./esm";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/index.js:
--------------------------------------------------------------------------------
1 | export * from "./esm";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/umd/index.d.ts:
--------------------------------------------------------------------------------
1 | export * from "./vis-timeline-graph2d";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/umd/index.js:
--------------------------------------------------------------------------------
1 | export * from "./vis-timeline-graph2d";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/umd/vis-timeline-graph2d.d.ts:
--------------------------------------------------------------------------------
1 | export * from "../../declarations/entry-esnext";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/dist/vis-timeline/standalone/umd/vis-timeline-graph2d.min.d.ts:
--------------------------------------------------------------------------------
1 | export * from "../../declarations/entry-esnext";
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/arrow01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/arrow01.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/file.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/file_create_time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/file_create_time.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/image_loaded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/image_loaded.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/net.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/program.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/program.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/reg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/reg.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/reg_category.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/reg_category.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/rthread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/rthread.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/search_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/search_icon.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/images/wmi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JPCERTCC/SysmonSearch/970a765fd8672f4060ff404d953acfa4e56f2ca8/sysmon_search_r/public/components/main/images/wmi.png
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/index.js:
--------------------------------------------------------------------------------
1 | export { Main } from './main';
2 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/main.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import {
4 | BrowserRouter as Router,
5 | Switch,
6 | Route,
7 | Link,
8 | Redirect
9 | } from 'react-router-dom'
10 |
11 | import { SysmonSearchTabs } from './ss_tabs';
12 | import { SysmonSummary } from './ss_summary';
13 | import { SysmonStats } from './ss_stats';
14 | import { SysmonProcess } from './ss_process';
15 | import { SysmonProcessList } from './ss_processlist';
16 | import { SysmonOverView } from './ss_overview';
17 | import { SysmonDetail } from './ss_detail';
18 | import { SysmonVisualize } from './ss_visualize';
19 |
20 | export class Main extends React.Component {
21 |
22 | constructor(props) {
23 | super(props);
24 | this.state = {};
25 | }
26 |
27 | render() {
28 | return (
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | );
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/network.css:
--------------------------------------------------------------------------------
1 | canvas {
2 | border: 1px solid lightgrey;
3 | }
4 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/pie_chart.js:
--------------------------------------------------------------------------------
1 | import * as d3 from './dist/d3.min';
2 |
3 | function segColor(c) {
4 | var color = [
5 | "#87CEFA",
6 | "#FFDEAD",
7 | "#7B68EE",
8 | "#8FBC8F",
9 | "#FF3366",
10 | "#33FFFF",
11 | "#666699",
12 | "#00FA9A",
13 | "#FF00FF",
14 | "#FFA500",
15 | //"#6B8E23",
16 | ];
17 | var pointer = c % 10;
18 | return color[pointer];
19 | }
20 |
21 | function pieChart(id, fData, legFlg, r) {
22 |
23 | function createChart(pD) {
24 | var pC = {},
25 | pieDim = {
26 | w: r,
27 | h: r
28 | };
29 | pieDim.r = Math.min(pieDim.w, pieDim.h) / 2;
30 |
31 | var piesvg = d3.select(id).append("svg")
32 | .attr("width", pieDim.w).attr("height", pieDim.h).append("g")
33 | .attr("transform", "translate(" + pieDim.w / 2 + "," + pieDim.h / 2 + ")");
34 |
35 | var arc = d3.arc().outerRadius(pieDim.r - 10).innerRadius(0);
36 |
37 | var pie = d3.pie().sort(null).value(function(d) {
38 | return d.freq;
39 | });
40 |
41 | piesvg.selectAll("path").data(pie(pD)).enter().append("path").attr("d", arc)
42 | .each(function(d) {
43 | this._current = d;
44 | })
45 | .style("fill", function(d, i) {
46 | return segColor(i);
47 | })
48 |
49 | return pC;
50 | }
51 |
52 | var keys = [];
53 | var keys = Object.keys(fData);
54 |
55 | var tF = keys.map(function(d) {
56 | return {
57 | type: d,
58 | freq: fData[d]
59 | };
60 | });
61 |
62 | //clear_graph(id);
63 | d3.select(id).selectAll("svg").remove();
64 | d3.select(id).selectAll("table").remove();
65 |
66 | var pC = createChart(tF);
67 |
68 | }
69 |
70 | module.exports = {
71 | pieChart:pieChart,
72 | segColor:segColor
73 | };
74 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/react-graph-vis.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import defaultsDeep from "lodash/fp/defaultsDeep";
3 | import isEqual from "lodash/isEqual";
4 | import differenceWith from "lodash/differenceWith";
5 | //import vis from "./dist/vis-network";
6 | //import "./dist/vis-network.css";
7 | import vis from "./dist/vis-network.min";
8 | import "./dist/vis-network.min.css";
9 | import uuid from "uuid";
10 | import PropTypes from "prop-types";
11 |
12 | class Graph extends Component {
13 | constructor(props) {
14 | super(props);
15 | const { identifier } = props;
16 | this.updateGraph = this.updateGraph.bind(this);
17 | this.state = {
18 | identifier: identifier !== undefined ? identifier : uuid.v4()
19 | };
20 | this.container = React.createRef();
21 | }
22 |
23 | componentDidMount() {
24 | this.edges = new vis.DataSet();
25 | this.edges.add(this.props.graph.edges);
26 | this.nodes = new vis.DataSet();
27 | this.nodes.add(this.props.graph.nodes);
28 | this.updateGraph();
29 | }
30 |
31 | shouldComponentUpdate(nextProps, nextState) {
32 | let nodesChange = !isEqual(this.props.graph.nodes, nextProps.graph.nodes);
33 | let edgesChange = !isEqual(this.props.graph.edges, nextProps.graph.edges);
34 | let optionsChange = !isEqual(this.props.options, nextProps.options);
35 | let eventsChange = !isEqual(this.props.events, nextProps.events);
36 |
37 | if (nodesChange) {
38 | const idIsEqual = (n1, n2) => n1.id === n2.id;
39 | const nodesRemoved = differenceWith(this.props.graph.nodes, nextProps.graph.nodes, idIsEqual);
40 | const nodesAdded = differenceWith(nextProps.graph.nodes, this.props.graph.nodes, idIsEqual);
41 | const nodesChanged = differenceWith(
42 | differenceWith(nextProps.graph.nodes, this.props.graph.nodes, isEqual),
43 | nodesAdded
44 | );
45 | this.patchNodes({ nodesRemoved, nodesAdded, nodesChanged });
46 | }
47 |
48 | if (edgesChange) {
49 | const edgesRemoved = differenceWith(this.props.graph.edges, nextProps.graph.edges, isEqual);
50 | const edgesAdded = differenceWith(nextProps.graph.edges, this.props.graph.edges, isEqual);
51 | const edgesChanged = differenceWith(
52 | differenceWith(nextProps.graph.edges, this.props.graph.edges, isEqual),
53 | edgesAdded
54 | );
55 | this.patchEdges({ edgesRemoved, edgesAdded, edgesChanged });
56 | }
57 |
58 | if (optionsChange) {
59 | this.Network.setOptions(nextProps.options);
60 | }
61 |
62 | if (eventsChange) {
63 | let events = this.props.events || {};
64 | for (let eventName of Object.keys(events)) this.Network.off(eventName, events[eventName]);
65 |
66 | events = nextProps.events || {};
67 | for (let eventName of Object.keys(events)) this.Network.on(eventName, events[eventName]);
68 | }
69 |
70 | return false;
71 | }
72 |
73 | componentDidUpdate() {
74 | this.updateGraph();
75 | }
76 |
77 | patchEdges({ edgesRemoved, edgesAdded, edgesChanged }) {
78 | this.edges.remove(edgesRemoved);
79 | this.edges.add(edgesAdded);
80 | this.edges.update(edgesChanged);
81 | }
82 |
83 | patchNodes({ nodesRemoved, nodesAdded, nodesChanged }) {
84 | this.nodes.remove(nodesRemoved);
85 | this.nodes.add(nodesAdded);
86 | this.nodes.update(nodesChanged);
87 | }
88 |
89 | updateGraph() {
90 | let defaultOptions = {
91 | physics: {
92 | stabilization: false
93 | },
94 | autoResize: false,
95 | edges: {
96 | smooth: false,
97 | color: "#000000",
98 | width: 0.5,
99 | arrows: {
100 | to: {
101 | enabled: true,
102 | scaleFactor: 0.5
103 | }
104 | }
105 | }
106 | };
107 |
108 | // merge user provied options with our default ones
109 | let options = defaultsDeep(defaultOptions, this.props.options);
110 |
111 | this.Network = new vis.Network(
112 | this.container.current,
113 | Object.assign({}, this.props.graph, {
114 | edges: this.edges,
115 | nodes: this.nodes
116 | }),
117 | options
118 | );
119 |
120 | if (this.props.getNetwork) {
121 | this.props.getNetwork(this.Network);
122 | }
123 |
124 | if (this.props.getNodes) {
125 | this.props.getNodes(this.nodes);
126 | }
127 |
128 | if (this.props.getEdges) {
129 | this.props.getEdges(this.edges);
130 | }
131 |
132 | // Add user provied events to network
133 | let events = this.props.events || {};
134 | for (let eventName of Object.keys(events)) {
135 | this.Network.on(eventName, events[eventName]);
136 | }
137 | }
138 |
139 | render() {
140 | const { identifier } = this.state;
141 | const { style } = this.props;
142 | return React.createElement(
143 | "div",
144 | {
145 | id: identifier,
146 | ref: this.container,
147 | style
148 | },
149 | identifier
150 | );
151 | }
152 | }
153 |
154 | Graph.defaultProps = {
155 | graph: {},
156 | style: { width: "100%", height: "100%" }
157 | };
158 | Graph.propTypes = {
159 | graph: PropTypes.object,
160 | style: PropTypes.object,
161 | getNetwork: PropTypes.func,
162 | getNodes: PropTypes.func,
163 | getEdges: PropTypes.func,
164 | };
165 |
166 | export default Graph;
167 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/search_rules.js:
--------------------------------------------------------------------------------
1 | import chrome from 'ui/chrome';
2 |
3 | function is_key_exist(key, keywords) {
4 | return (key in keywords && keywords[key] !== "undefined" && keywords[key] !== null);
5 | };
6 |
7 | function get_search_key_name(num) {
8 | const option_array = [
9 | '',
10 | 'IpAddress',
11 | 'Port',
12 | 'HostName',
13 | 'ProcessName',
14 | 'FileName',
15 | 'RegistryKey',
16 | 'RegistryValue',
17 | 'Hash'
18 | ];
19 | var num_obj = Number(num);
20 | if (num_obj === Number.NaN || num_obj <= 0 || num_obj >= option_array.length) return '';
21 | return option_array[num_obj];
22 | };
23 |
24 | function save_rules (keywords) {
25 | var rules = {};
26 | if (typeof keywords !== "undefined") {
27 | rules.operator = '';
28 | if (is_key_exist("search_conjunction", keywords)
29 | && (keywords.search_conjunction === 1
30 | || keywords.search_conjunction === 2)) {
31 | rules.operator = (keywords.search_conjunction === 1) ? 'AND' : 'OR';
32 | }
33 |
34 | rules.patterns = [];
35 |
36 | const search_key_prefix = "search_item_";
37 | const search_val_prefix = "search_value_";
38 |
39 | for (var keyname in keywords) {
40 | if (keyname.substr(0, search_key_prefix.length) == search_key_prefix
41 | && is_key_exist(keyname, keywords)) {
42 | var num = keyname.substr(search_key_prefix.length);
43 | var valname = search_val_prefix + num;
44 | if (is_key_exist(valname, keywords)) {
45 | var rule = {
46 | key: get_search_key_name(keywords[keyname]),
47 | value: keywords[valname]
48 | };
49 | rules.patterns.push(rule);
50 | }
51 | }
52 | }
53 |
54 | } else {
55 | alert("Invalid rule.");
56 | return ;
57 | }
58 |
59 | console.log(rules);
60 | if(rules.patterns.length===0){
61 | alert("Pattern is empty.");
62 | return;
63 | }
64 | const api = chrome.addBasePath('/api/sysmon-search-plugin/save_alert_rules');
65 | fetch(api, {
66 | method:"POST",
67 | headers: {
68 | 'kbn-xsrf': 'true',
69 | 'Content-Type': 'application/json',
70 | },
71 | body:JSON.stringify(rules)
72 | })
73 | .then((response) => response.json())
74 | .then((responseJson) => {
75 | console.log(JSON.stringify(responseJson));
76 | if(responseJson.result) alert(responseJson.result);
77 | else alert("Save failed. Please check console.");
78 | });
79 | };
80 |
81 | module.exports = {
82 | saveRules: save_rules
83 | };
84 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_detail.css:
--------------------------------------------------------------------------------
1 | div.emphasis {
2 | background-color: rgba(255,155,155,0.9);
3 | }
4 |
5 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_overview.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import chrome from 'ui/chrome'
3 |
4 | import {
5 | EuiTitle,
6 | EuiPanel,
7 | EuiButton,
8 | EuiFlexGroup,
9 | EuiFlexItem,
10 | EuiFormRow,
11 | EuiFieldText,
12 | EuiSelect,
13 | } from '@elastic/eui';
14 |
15 | const qs = require('query-string');
16 | import {GraphOverView} from './overview_network';
17 |
18 | export class SysmonOverView extends Component {
19 | constructor(props){
20 | super(props);
21 | const params = qs.parse(this.props.location.search);
22 | this.api = chrome.addBasePath("/api/sysmon-search-plugin/process_overview");
23 | this.api += "/" + params.host;
24 | this.api += "/" + params.date;
25 | this.api += "/" + params.guid;
26 | this.state = {
27 | host: params.host,
28 | date: params.date,
29 | guid: params.guid,
30 | tops:[],
31 | keyword:null,
32 | hash:null,
33 | firstflg:true,
34 | graph:{},
35 | events:null,
36 | network:null,
37 | textarea:"",
38 | layout: "LR",
39 | };
40 |
41 | this.layouts =[
42 | {value:"LR", text:"Left to Right"},
43 | {value:"UD", text:"Up to Down"},
44 | {value:"default", text:"Default"},
45 | ]
46 |
47 | this.handleChange = this.handleChange.bind(this);
48 | this.handleChangeHash = this.handleChangeHash.bind(this);
49 |
50 | }
51 |
52 | handleChange (event) {
53 | this.setState({
54 | keyword: event.target.value
55 | });
56 | }
57 |
58 | handleChangeHash (event) {
59 | this.setState({
60 | hash: event.target.value
61 | });
62 | }
63 |
64 | handleChangeLayout = event => {
65 | this.setState({ layout: event.target.value });
66 | }
67 |
68 | componentDidMount(){ this.getProcess(); }
69 |
70 | clickSearch(){ this.getProcess(); }
71 |
72 | getProcess(){
73 | fetch(this.api, {
74 | method:"GET",
75 | headers: {
76 | 'kbn-xsrf': 'true',
77 | 'Content-Type': 'application/json',
78 | },
79 | })
80 | .then((response) => response.json())
81 | .then((responseJson) => {
82 | if(responseJson) this.setState({tops:responseJson});
83 | console.log(JSON.stringify(responseJson));
84 | })
85 | .catch((error) =>{
86 | console.error(error);
87 | });
88 | }
89 |
90 | render() {
91 | //console.log(this.state)
92 |
93 | return (
94 |
95 |
96 | {this.state.guid} on {this.state.host}@{this.state.date}
97 |
98 |
99 |
100 |
101 |
102 |
107 |
108 |
109 |
110 |
111 |
112 |
115 |
116 |
117 |
118 |
119 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
135 |
136 |
137 | )
138 | }
139 | };
140 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_stats.css:
--------------------------------------------------------------------------------
1 | .vis-timeline .vis-bar {
2 | fill-opacity: 1;
3 | }
4 |
5 | .visgroup0 {
6 | fill: #87CEFA;
7 | }
8 |
9 | .visgroup1 {
10 | fill: #FFDEAD;
11 | }
12 |
13 | .visgroup2 {
14 | fill: #7B68EE;
15 | }
16 |
17 | .visgroup3 {
18 | fill: #8FBC8F;
19 | }
20 |
21 | .visgroup4 {
22 | fill: #FF3366;
23 | }
24 |
25 | .visgroup5 {
26 | fill: #33FFFF;
27 | }
28 |
29 | .visgroup6 {
30 | fill: #666699;
31 | }
32 |
33 | .visgroup7 {
34 | fill: #00FA9A;
35 | }
36 |
37 | .visgroup8 {
38 | fill: #FF00FF;
39 | }
40 |
41 | .visgroup9 {
42 | fill: #FFA500;
43 | }
44 |
45 | .visgroup10 {
46 | fill: #6B8E23;
47 | }
48 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_stats.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import moment from 'moment';
3 | import chrome from 'ui/chrome';
4 |
5 | import {
6 | EuiTitle,
7 | EuiPanel,
8 | EuiLink,
9 | EuiSpacer,
10 | EuiButton,
11 | } from '@elastic/eui';
12 |
13 | const qs = require('query-string');
14 | import Timeline from './react-visjs-timeline'
15 | import './ss_stats.css'
16 |
17 | export class SysmonStats extends Component {
18 | constructor(props){
19 | super(props);
20 | //const params = qs.parse(this.props.location.search);
21 | this.state = {
22 | //host: params.host,
23 | //date: params.date,
24 | host: this.props.host,
25 | date: this.props.date,
26 | items:[],
27 | options:{},
28 | groups:[],
29 | category:[]
30 | };
31 | this.top = chrome.addBasePath('/app/sysmon_search_r');
32 | this.summary = this.top + "/visualize&type=summary&date=" + this.props.date + "&host=" + this.props.host;
33 | this.process = this.top + "/visualize&type=process&date=" + this.props.date + "&host=" + this.props.host;
34 |
35 | }
36 |
37 | componentDidMount(){
38 | const api = chrome.addBasePath('/api/sysmon-search-plugin/events');
39 | fetch(api, {
40 | method:"POST",
41 | headers: {
42 | 'kbn-xsrf': 'true',
43 | 'Content-Type': 'application/json',
44 | },
45 | body:JSON.stringify({
46 | hostname: this.state.host,
47 | period: {
48 | "gte": moment(this.state.date).add(-1, 'M'),
49 | "lte": moment(this.state.date).add(1, 'M'),
50 | }
51 | })
52 | })
53 | .then((response) => response.json())
54 | .then((responseJson) => {
55 | console.log(JSON.stringify(responseJson));
56 | var items = responseJson["items"];
57 | var category = responseJson["groups"];
58 | var groups = [];
59 | for (let index in category){
60 | groups.push({
61 | id: index,
62 | content: category[index],
63 | className: "visgroup" + index
64 | })
65 | }
66 | var options = {
67 | style: 'bar',
68 | stack: true,
69 | barChart: {
70 | width: 40,
71 | align: 'center',
72 | }, // align: left, center, right
73 | drawPoints: false,
74 | dataAxis: {icons: false},
75 | legend: {enabled:true},
76 | start: moment(this.state.date).add(-1, 'M'),
77 | end: moment(this.state.date).add(1, 'M'),
78 | orientation: 'top',
79 | sort:true,
80 | zoomable: true
81 | };
82 |
83 | this.setState({
84 | items:items,
85 | options:options,
86 | groups:groups,
87 | category:category,
88 | });
89 | })
90 | .catch((error) =>{
91 | console.error(error);
92 | });
93 | }
94 |
95 | render() {
96 | //console.log(this.state)
97 | return (
98 |
99 |
100 | Host Statistics: {this.state.host}
101 |
102 |
103 |
104 |
105 |
112 |
113 |
114 |
115 | )
116 | }
117 |
118 | };
119 |
120 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_summary.js:
--------------------------------------------------------------------------------
1 | import React, {Component, Fragment} from 'react';
2 | import chrome from 'ui/chrome';
3 |
4 | import {
5 | EuiLink,
6 | EuiTitle,
7 | EuiText,
8 | EuiFlexGroup,
9 | EuiFlexItem,
10 | EuiPanel,
11 | EuiSpacer,
12 | EuiButton,
13 | } from '@elastic/eui';
14 |
15 | const qs = require('query-string');
16 | import {pieChart, segColor} from './pie_chart';
17 | import {SysmonProcessList} from './ss_processlist';
18 |
19 | export class SysmonSummary extends Component {
20 | constructor(props){
21 | super(props);
22 | /*
23 | const params = qs.parse(this.props.location.search)
24 | const host = this.props.host?this.props.host:params.host;
25 | const date = this.props.date?this.props.date:params.date;
26 | */
27 | this.state = {
28 | host: this.props.host,
29 | date: this.props.date,
30 | items:[],
31 | total:0,
32 | category:this.props.category,
33 | processList:null,
34 | };
35 | this.chartRef = React.createRef();
36 | this.top = chrome.addBasePath('/app/sysmon_search_r');
37 | this.stats = this.top + "/visualize&type=stats&date=" + this.props.date + "&host=" + this.props.host;
38 | this.process = this.top + "/visualize&type=process&date=" + this.props.date + "&host=" + this.props.host;
39 |
40 | this.setCategory = this.setCategory.bind(this);
41 | //this.summaryLegend = this.summaryLegend.bind(this);
42 |
43 | }
44 |
45 | componentDidMount(){
46 | const api = chrome.addBasePath('/api/sysmon-search-plugin/events');
47 | fetch(api, {
48 | method:"POST",
49 | headers: {
50 | 'kbn-xsrf': 'true',
51 | 'Content-Type': 'application/json',
52 | },
53 | body:JSON.stringify({
54 | hostname: this.state.host,
55 | period: this.state.date,
56 | })
57 | })
58 | .then((response) => response.json())
59 | .then((responseJson) => {
60 | console.log(JSON.stringify(responseJson));
61 | var item = responseJson["count"];
62 | var freqData = item;
63 | pieChart(this.chartRef, freqData, false, 300);
64 | var items = [];
65 | var total = 0;
66 | for (let [key, value] of Object.entries(item)) {
67 | items.push({
68 | "type":key,
69 | "value":value,
70 | });
71 | total+=value;
72 | }
73 | this.setState({
74 | items:items,
75 | total:total,
76 | });
77 | })
78 | .catch((error) =>{
79 | console.error(error);
80 | });
81 | }
82 |
83 | setCategory(category){
84 | const processList = (
85 |
90 | )
91 | this.setState({
92 | category:category,
93 | processList: processList,
94 | });
95 | }
96 |
97 | summaryLegend = (items, total, host, date) => {
98 | const setCategory = this.setCategory;
99 | return items.map(function(item, i){
100 | if (item.value<=0) return;
101 | let percentage = item.value / total * 100;
102 | let style= {
103 | width: "16px",
104 | height: "16px",
105 | float: "left",
106 | marginRight: "10px",
107 | background: item.value > 0?segColor(i):""
108 | };
109 | let processlist = "process_list?";
110 | processlist += "host=" + host;
111 | processlist += "&date=" + date;
112 | processlist += "&category=" + item.type;
113 | return(
114 |
115 |
116 |
117 |
118 | setCategory(item.type)}>{item.type}
119 | |
120 | {item.value} |
121 | {percentage.toFixed(2)}% |
122 |
123 | );
124 | });
125 | }
126 |
127 | render() {
128 | console.log(this.state);
129 |
130 | return (
131 |
132 |
133 |
134 |
135 | Event Summary: {this.state.host}@{this.state.date}
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | this.chartRef = cr}>
146 |
147 |
148 |
149 |
150 |
151 | Type |
152 | Count |
153 | Percentage |
154 |
155 |
156 | {this.summaryLegend(
157 | this.state.items,
158 | this.state.total,
159 | this.state.host,
160 | this.state.date,
161 | )}
162 |
163 | Total |
164 | {this.state.total} |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | {this.state.processList}
176 |
177 |
178 | )
179 | }
180 | };
181 |
182 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_tabs.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Fragment } from 'react';
2 |
3 | import {
4 | EuiTabbedContent,
5 | EuiTitle,
6 | EuiText,
7 | EuiSpacer,
8 | } from '@elastic/eui';
9 |
10 | import { SysmonEvents } from "./ss_events";
11 | import { SysmonSearch } from "./ss_search";
12 | import { SysmonAlert } from "./ss_alert";
13 |
14 | export class SysmonSearchTabs extends Component {
15 | constructor(props) {
16 | super(props);
17 |
18 | this.tabs = [
19 | {
20 | id: 'events',
21 | name: 'Events',
22 | content: (
23 |
24 | ),
25 | },
26 | {
27 | id: 'search',
28 | name: 'Search',
29 | content: (
30 |
31 | ),
32 | },
33 | {
34 | id: 'alert',
35 | name: 'Alert',
36 | content: (
37 |
38 | ),
39 | },
40 | ];
41 | }
42 |
43 | render() {
44 | return (
45 |
46 |
47 |
51 |
52 |
53 | );
54 | }
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_utils.js:
--------------------------------------------------------------------------------
1 | function splitByLength(str, length) {
2 | var resultArr = [];
3 | if (!str || !length || length < 1) return resultArr;
4 | var index = 0;
5 | var start = index;
6 | var end = start + length;
7 | while (start < str.length) {
8 | resultArr[index] = str.substring(start, end);
9 | index++;
10 | start = end;
11 | end = start + length;
12 | }
13 | return resultArr;
14 | }
15 |
16 | function local_search(data, keyword) {
17 | for (var key in data) {
18 | if (Array.isArray(data[key])) {
19 | if (local_search(data[key], keyword)) {
20 | return true;
21 | }
22 | } else if (data[key] instanceof Object) {
23 | if (local_search(data[key], keyword)) {
24 | return true;
25 | }
26 | } else {
27 | if (String(data[key]).indexOf(keyword) != -1) {
28 | return true;
29 | }
30 | }
31 | }
32 | return false;
33 | }
34 |
35 | //export default function search(data, keyword, hash) {
36 | function search(data, keyword, hash) {
37 | var flg1 = 1;
38 | var flg2 = 1;
39 | if (keyword != null && keyword !== "") {
40 | if (local_search(data, keyword)) {
41 | flg1 = 2;
42 | }
43 | } else {
44 | flg1 = 3;
45 | }
46 |
47 | if (hash != null && hash !== "") {
48 | if (data["Hashes"] != null) {
49 | if (data["Hashes"].indexOf(hash) != -1) {
50 | flg2 = 2;
51 | }
52 | }
53 | } else {
54 | flg2 = 3;
55 | }
56 |
57 | if ((flg1 == 2 && flg2 == 2) || (flg1 == 2 && flg2 == 3) || (flg1 == 3 && flg2 == 2)) {
58 | return true;
59 | } else {
60 | return false;
61 | }
62 | }
63 |
64 | module.exports = {
65 | search: search,
66 | local_search: local_search,
67 | splitByLength: splitByLength
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/sysmon_search_r/public/components/main/ss_visualize.js:
--------------------------------------------------------------------------------
1 | import React, { Component, Fragment } from 'react';
2 |
3 | import {
4 | EuiTabbedContent,
5 | } from '@elastic/eui';
6 |
7 | import { SysmonSummary } from "./ss_summary";
8 | import { SysmonStats } from "./ss_stats";
9 | import { SysmonProcess } from "./ss_process";
10 | import { SysmonSearchTabs } from "./ss_tabs";
11 |
12 | const qs = require('query-string');
13 |
14 | export class SysmonVisualize extends Component {
15 | constructor(props) {
16 | super(props);
17 | const params = qs.parse(this.props.location.search);
18 | this.tabIndex = 1;
19 | if (params.type==="stats")this.tabIndex = 2;
20 | else if (params.type==="process")this.tabIndex = 3;
21 | this.state = {
22 | host: params.host,
23 | date: params.date,
24 | type: params.type,
25 | }
26 |
27 | this.tabs = [
28 | {
29 | id: 'top',
30 | name: 'Top',
31 | content: (
32 |
33 | ),
34 | },
35 | {
36 | id: 'summary',
37 | name: 'Summary',
38 | content: (
39 |
40 | ),
41 | },
42 | {
43 | id: 'stats',
44 | name: 'Stats',
45 | content: (
46 |
47 | ),
48 | },
49 | {
50 | id: 'process',
51 | name: 'Process',
52 | content: (
53 |
54 | ),
55 | },
56 | ];
57 | }
58 |
59 | render() {
60 | return (
61 |
65 | );
66 | }
67 | }
68 |
69 |
--------------------------------------------------------------------------------
/sysmon_search_r/winlogbeat.yml:
--------------------------------------------------------------------------------
1 | title: Elastic Winlogbeat (from 7.x) index pattern and field mapping
2 | order: 20
3 | backends:
4 | - es-qs
5 | - es-dsl
6 | - kibana
7 | - xpack-watcher
8 | - elastalert
9 | - elastalert-dsl
10 | logsources:
11 | windows:
12 | product: windows
13 | index: winlogbeat-*
14 | windows-application:
15 | product: windows
16 | service: application
17 | conditions:
18 | winlog.channel: Application
19 | windows-security:
20 | product: windows
21 | service: security
22 | conditions:
23 | winlog.channel: Security
24 | windows-sysmon:
25 | product: windows
26 | service: sysmon
27 | conditions:
28 | winlog.channel: 'Microsoft-Windows-Sysmon/Operational'
29 | windows-dns-server:
30 | product: windows
31 | service: dns-server
32 | conditions:
33 | winlog.channel: 'DNS Server'
34 | windows-driver-framework:
35 | product: windows
36 | service: driver-framework
37 | conditions:
38 | winlog.provider_name: 'Microsoft-Windows-DriverFrameworks-UserMode/Operational'
39 | windows-dhcp:
40 | product: windows
41 | service: dhcp
42 | conditions:
43 | winlog.provider_name: 'Microsoft-Windows-DHCP-Server/Operational'
44 | defaultindex: winlogbeat-*
45 | # Extract all field names qith yq:
46 | # yq -r '.detection | del(.condition) | map(keys) | .[][]' $(find sigma/rules/windows -name '*.yml') | sort -u | grep -v ^EventID$ | sed 's/^\(.*\)/ \1: winlog.event_data.\1/g'
47 | # Keep EventID! Clean up the list afterwards!
48 | fieldmappings:
49 | EventID: winlog.event_id
50 | EventData: winlog.event_data
51 | RecordID: winlog.record_id
52 | AccessMask: winlog.event_data.AccessMask
53 | AccountName: winlog.event_data.AccountName
54 | AllowedToDelegateTo: winlog.event_data.AllowedToDelegateTo
55 | AttributeLDAPDisplayName: winlog.event_data.AttributeLDAPDisplayName
56 | AuditPolicyChanges: winlog.event_data.AuditPolicyChanges
57 | AuthenticationPackageName: winlog.event_data.AuthenticationPackageName
58 | CallingProcessName: winlog.event_data.CallingProcessName
59 | CallTrace: winlog.event_data.CallTrace
60 | CommandLine: winlog.event_data.CommandLine
61 | ComputerName: winlog.computer_name
62 | CurrentDirectory: winlog.event_data.CurrentDirectory
63 | Description: winlog.event_data.Description
64 | DestinationHostname: winlog.event_data.DestinationHostname
65 | DestinationIp: winlog.event_data.DestinationIp
66 | DestinationIsIpv6: winlog.event_data.DestinationIsIpv6
67 | DestinationPort: winlog.event_data.DestinationPort
68 | Details: winlog.event_data.Details
69 | EngineVersion: winlog.event_data.EngineVersion
70 | EventType: winlog.event_data.EventType
71 | FailureCode: winlog.event_data.FailureCode
72 | FileName: winlog.event_data.FileName
73 | GrantedAccess: winlog.event_data.GrantedAccess
74 | GroupName: winlog.event_data.GroupName
75 | GroupSid: winlog.event_data.GroupSid
76 | Hashes: winlog.event_data.Hashes
77 | HiveName: winlog.event_data.HiveName
78 | HostVersion: winlog.event_data.HostVersion
79 | Image: winlog.event_data.Image
80 | ImageLoaded: winlog.event_data.ImageLoaded
81 | ImagePath: winlog.event_data.ImagePath
82 | Imphash: winlog.event_data.Imphash
83 | IpAddress: winlog.event_data.IpAddress
84 | KeyLength: winlog.event_data.KeyLength
85 | LogonProcessName: winlog.event_data.LogonProcessName
86 | LogonType: winlog.event_data.LogonType
87 | NewProcessName: winlog.event_data.NewProcessName
88 | ObjectClass: winlog.event_data.ObjectClass
89 | ObjectName: winlog.event_data.ObjectName
90 | ObjectType: winlog.event_data.ObjectType
91 | ObjectValueName: winlog.event_data.ObjectValueName
92 | ParentCommandLine: winlog.event_data.ParentCommandLine
93 | ParentProcessGuid: winlog.event_data.ParentProcessGuid
94 | ParentProcessName: winlog.event_data.ParentProcessName
95 | ParentImage: winlog.event_data.ParentImage
96 | Path: winlog.event_data.Path
97 | PipeName: winlog.event_data.PipeName
98 | ProcessCommandLine: winlog.event_data.ProcessCommandLine
99 | ProcessGuid: winlog.event_data.ProcessGuid
100 | ProcessName: winlog.event_data.ProcessName
101 | Protocol: winlog.event_data.Protocol
102 | Properties: winlog.event_data.Properties
103 | QueryName: winlog.event_data.QueryName
104 | QueryStatus: winlog.event_data.QueryStatus
105 | QueryResults: winlog.event_data.QueryResults
106 | SecurityID: winlog.event_data.SecurityID
107 | ServiceFileName: winlog.event_data.ServiceFileName
108 | ServiceName: winlog.event_data.ServiceName
109 | ShareName: winlog.event_data.ShareName
110 | Signature: winlog.event_data.Signature
111 | Source: winlog.event_data.Source
112 | SourceHostname: winlog.event_data.SourceHostname
113 | SourceImage: winlog.event_data.SourceImage
114 | SourceIp: winlog.event_data.SourceIp
115 | SourceIsIpv6: winlog.event_data.SourceIsIpv6
116 | SourceProcessGuid: winlog.event_data.SourceProcessGuid
117 | StartAddress: winlog.event_data.StartAddress
118 | StartModule: winlog.event_data.StartModule
119 | Status: winlog.event_data.Status
120 | SubjectUserName: winlog.event_data.SubjectUserName
121 | SubjectUserSid: winlog.event_data.SubjectUserSid
122 | TargetFilename: winlog.event_data.TargetFilename
123 | TargetImage: winlog.event_data.TargetImage
124 | TargetObject: winlog.event_data.TargetObject
125 | TicketEncryptionType: winlog.event_data.TicketEncryptionType
126 | TicketOptions: winlog.event_data.TicketOptions
127 | User: winlog.event_data.User
128 | UtcTime: winlog.event_data.UtcTime
129 | WorkstationName: winlog.event_data.WorkstationName
130 |
--------------------------------------------------------------------------------