MaxPatrol SIEM

1.

Миньковский Евгений
MaxPatrol SIEM

2.

Agenda: что входит в курс CP
Потоки данных
Написание правил
нормализации и работа с SDK
Написание правил
корреляции и работа с SDK
Табличные списки, правила
обогащения, правила аггрегации

3.

<
Обработка
журнальных
сообщений
в PT MaxPatrol SIEM

4.

Схема работы MaxPatrol SIEM Server
Positive Technologies
MaxPatrol SIEM

5.

Профиль filemonitor, plain_parser
Профиль
Исходник
{
Login success:
"target_filesystem_type": "WINDOWS",
"inputs": {
"@GUID": {
"base_directory": "<Path_to_base_directory>",
"encoding": "UTF-8",
"filename_regex": "(<Filename_regex>)",
"parser": {
"plain_parser": {}
},
"reader": {
"string_reader": {
"end_of_line_delimiter": "\n"
}
},
"recursion_depth": 0
}
},
.....................................................................................
}
root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100
root tty1
Tue Jun 7 08:06 still logged in 0.0.0.0
root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100
Login failure:
foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100
root tty1
Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0
UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0
unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0

6.

Профиль filemonitor, plain_parser
Профиль
Исходник
{
Login success:
"target_filesystem_type": "WINDOWS",
"inputs": {
"@GUID": {
"base_directory": "<Path_to_base_directory>",
"encoding": "UTF-8",
"filename_regex": "(<Filename_regex>)",
"parser": {
"plain_parser": {}
},
"reader": {
"string_reader": {
"end_of_line_delimiter": "\n"
}
},
"recursion_depth": 0
}
},
.....................................................................................
}
root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100
root tty1
Tue Jun 7 08:06 still logged in 0.0.0.0
root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100
Login failure:
foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100
root tty1
Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0
UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0
unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0

7.

Профиль filemonitor, plain_parser
Профиль
Исходник
{
Login success:
"target_filesystem_type": "WINDOWS",
"inputs": {
"@GUID": {
"base_directory": "<Path_to_base_directory>",
"encoding": "UTF-8",
"filename_regex": "(<Filename_regex>)",
"parser": {
"plain_parser": {}
},
"reader": {
"string_reader": {
"end_of_line_delimiter": "\n"
}
},
"recursion_depth": 0
}
},
.....................................................................................
}
root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100
root tty1
Tue Jun 7 08:06 still logged in 0.0.0.0
root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100
Login failure:
foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100
root tty1
Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0
UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0
unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0

8.

Профиль filemonitor, plain_parser
«Сырое событие» (raw event)
{
}
}
"_index": "ptsiem_r_2018-02-20",
"_type": "raw",
"_id": "00000005-a8be-0e64-f000-0023deae69c7",
"_score": 2.7208266,
"_source": {
"mime": "text/csv",
"corrections": {
"expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"],
"time_zone": 10800,
"time_delta": 0
},
"tag": "filemonitor",
"site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0",
"input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4",
"recv_time": "2018-02-20T09:46:12Z",
"uuid": "00000005-a8be-0e64-f000-0023deae69c7",
"recv_ipv4": "10.0.1.49",
"body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100",
"type": "raw",
"task_id": "c769aede-836e-4214-b7f1-7168dcbf535d",
"tenant_id": "00000000-0000-0000-0000-000000000004",
"normalized": true,
"scope_id": "00000000-0000-0000-0000-000000000005"
}
Исходник
Login success:
root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100
root tty1
Tue Jun 7 08:06 still logged in 0.0.0.0
root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100
Login failure:
foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100
root tty1
Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0
UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0
unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0

9.

Профиль filemonitor, plain_parser
«Сырое событие» (raw event)
{
}
}
"_index": "ptsiem_r_2018-02-20",
"_type": "raw",
"_id": "00000005-a8be-0e64-f000-0023deae69c7",
"_score": 2.7208266,
"_source": {
"mime": "text/csv",
"corrections": {
"expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"],
"time_zone": 10800,
"time_delta": 0
},
"tag": "filemonitor",
"site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0",
"input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4",
"recv_time": "2018-02-20T09:46:12Z",
"uuid": "00000005-a8be-0e64-f000-0023deae69c7",
"recv_ipv4": "10.0.1.49",
"body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100",
"type": "raw",
"task_id": "c769aede-836e-4214-b7f1-7168dcbf535d",
"tenant_id": "00000000-0000-0000-0000-000000000004",
"normalized": true,
"scope_id": "00000000-0000-0000-0000-000000000005"
}
Исходник
Login success:
root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100
root tty1
Tue Jun 7 08:06 still logged in 0.0.0.0
root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100
Login failure:
foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100
root tty1
Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0
UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0
unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0

10.

Профиль filemonitor, plain_parser
«Сырое событие» (raw event)
{
}
}
"_index": "ptsiem_r_2018-02-20",
"_type": "raw",
"_id": "00000005-a8be-0e64-f000-0023deae69c7",
"_score": 2.7208266,
"_source": {
"mime": "text/csv",
"corrections": {
"expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"],
"time_zone": 10800,
"time_delta": 0
},
"tag": "filemonitor",
"site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0",
"input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4",
"recv_time": "2018-02-20T09:46:12Z",
"uuid": "00000005-a8be-0e64-f000-0023deae69c7",
"recv_ipv4": "10.0.1.49",
"body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100",
"type": "raw",
"task_id": "c769aede-836e-4214-b7f1-7168dcbf535d",
"tenant_id": "00000000-0000-0000-0000-000000000004",
"normalized": true,
"scope_id": "00000000-0000-0000-0000-000000000005"
}
Исходник
Login success:
root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100
root tty1
Tue Jun 7 08:06 still logged in 0.0.0.0
root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100
Login failure:
foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100
root tty1
Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0
UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0
unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0

11.

Профиль filemonitor, plain_parser
«Сырое событие» (raw event)
{
}
}
"_index": "ptsiem_r_2018-02-20",
"_type": "raw",
"_id": "00000005-a8be-0e64-f000-0023deae69c7",
"_score": 2.7208266,
"_source": {
"mime": "text/csv",
"corrections": {
"expected_datetime_formats": ["DATETIME_YYYYMMDD_HHMMSS"],
"time_zone": 10800,
"time_delta": 0
},
"tag": "filemonitor",
"site_id": "67520817-07f1-4a8b-a7d7-0e49e35a5aa0",
"input_id": "d434bcb6-b80f-42eb-ba54-56ec25ab74c4",
"recv_time": "2018-02-20T09:46:12Z",
"uuid": "00000005-a8be-0e64-f000-0023deae69c7",
"recv_ipv4": "10.0.1.49",
"body": "root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100",
"type": "raw",
"task_id": "c769aede-836e-4214-b7f1-7168dcbf535d",
"tenant_id": "00000000-0000-0000-0000-000000000004",
"normalized": true,
"scope_id": "00000000-0000-0000-0000-000000000005"
}
Исходник
Login success:
root pts/0 Wed Jun 8 03:15 still logged in 10.0.72.100
root tty1
Tue Jun 7 08:06 still logged in 0.0.0.0
root pts/0 Wed Jun 8 02:27 - 03:13 (00:45) 10.0.72.100
Login failure:
foo ssh:notty Wed Jun 8 09:50 - 09:50 (00:00) 10.0.72.100
root tty1
Mon Jun 6 13:54 - 13:54 (00:00) 0.0.0.0
UNKNOWN tty1 Wed Jun 8 09:45 - 09:45 (00:00) 0.0.0.0
unknown tty1 Wed Jun 8 09:47 - 09:47 (00:00) 0.0.0.0

12.

Профиль filemonitor, offset_parser
Профиль
«Сырое событие» (raw event)
{
.....................................................................................
"inputs": {
"@GUID": {
.....................................................................................
"encoding": "UTF-16BE",
"filename_regex": "(.+.AUD)",
"parser": {
"offset_parser": {
"offsets": [
{ "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" },
{ "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA"
},
{ "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID"
},
{ "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" },
{ "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" },
{ "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" },
{ "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" },
{ "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" },
{ "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" },
{ "begin_pos": 64, "length": 16, "name": "SLGLTRM"
},
{ "begin_pos": 80, "length": 24, "name": "SLGUSER"
},
{ "begin_pos": 104,"length": 40, "name": "SLGTC"
},
.....................................................................................
{
"SLGTYPE.SLGFTYP": "2",
"SLGTYPE.AREA": "AU",
"SLGTYPE.SUBID": "W",
"SLGDATTIM.DATE": "20150205",
"SLGDATTIM.TIME": "074639",
"SLGMAND": "700",
"SLGUSER": "HANNIBAL
"SLGTC": "SESSION_MANAGER
",
",
"SLGREPNA": "/1BCDWB/DBTSL1T
",
"SLGLTRM2": "NEF-KISEL-IA
",
"SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt"
}

13.

Профиль filemonitor, offset_parser
Профиль
«Сырое событие» (raw event)
{
.....................................................................................
"inputs": {
"@GUID": {
.....................................................................................
"encoding": "UTF-16BE",
"filename_regex": "(.+.AUD)",
"parser": {
"offset_parser": {
"offsets": [
{ "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" },
{ "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA"
},
{ "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID"
},
{ "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" },
{ "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" },
{ "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" },
{ "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" },
{ "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" },
{ "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" },
{ "begin_pos": 64, "length": 16, "name": "SLGLTRM"
},
{ "begin_pos": 80, "length": 24, "name": "SLGUSER"
},
{ "begin_pos": 104,"length": 40, "name": "SLGTC"
},
.....................................................................................
{
"SLGTYPE.SLGFTYP": "2",
"SLGTYPE.AREA": "AU",
"SLGTYPE.SUBID": "W",
"SLGDATTIM.DATE": "20150205",
"SLGDATTIM.TIME": "074639",
"SLGMAND": "700",
"SLGUSER": "HANNIBAL
"SLGTC": "SESSION_MANAGER
",
",
"SLGREPNA": "/1BCDWB/DBTSL1T
",
"SLGLTRM2": "NEF-KISEL-IA
",
"SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt"
}

14.

Профиль filemonitor, offset_parser
Профиль
«Сырое событие» (raw event)
{
.....................................................................................
"inputs": {
"@GUID": {
.....................................................................................
"encoding": "UTF-16BE",
"filename_regex": "(.+.AUD)",
"parser": {
"offset_parser": {
"offsets": [
{ "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" },
{ "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA"
},
{ "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID"
},
{ "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" },
{ "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" },
{ "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" },
{ "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" },
{ "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" },
{ "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" },
{ "begin_pos": 64, "length": 16, "name": "SLGLTRM"
},
{ "begin_pos": 80, "length": 24, "name": "SLGUSER"
},
{ "begin_pos": 104,"length": 40, "name": "SLGTC"
},
.....................................................................................
{
"SLGTYPE.SLGFTYP": "2",
"SLGTYPE.AREA": "AU",
"SLGTYPE.SUBID": "W",
"SLGDATTIM.DATE": "20150205",
"SLGDATTIM.TIME": "074639",
"SLGMAND": "700",
"SLGUSER": "HANNIBAL
"SLGTC": "SESSION_MANAGER
",
",
"SLGREPNA": "/1BCDWB/DBTSL1T
",
"SLGLTRM2": "NEF-KISEL-IA
",
"SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt"
}

15.

Профиль filemonitor, offset_parser
Профиль
«Сырое событие» (raw event)
{
.....................................................................................
"inputs": {
"@GUID": {
.....................................................................................
"encoding": "UTF-16BE",
"filename_regex": "(.+.AUD)",
"parser": {
"offset_parser": {
"offsets": [
{ "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" },
{ "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA"
},
{ "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID"
},
{ "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" },
{ "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" },
{ "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" },
{ "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" },
{ "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" },
{ "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" },
{ "begin_pos": 64, "length": 16, "name": "SLGLTRM"
},
{ "begin_pos": 80, "length": 24, "name": "SLGUSER"
},
{ "begin_pos": 104,"length": 40, "name": "SLGTC"
},
.....................................................................................
{
"SLGTYPE.SLGFTYP": "2",
"SLGTYPE.AREA": "AU",
"SLGTYPE.SUBID": "W",
"SLGDATTIM.DATE": "20150205",
"SLGDATTIM.TIME": "074639",
"SLGMAND": "700",
"SLGUSER": "HANNIBAL
"SLGTC": "SESSION_MANAGER
",
",
"SLGREPNA": "/1BCDWB/DBTSL1T
",
"SLGLTRM2": "NEF-KISEL-IA
",
"SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt"
}

16.

Профиль filemonitor, offset_parser
Профиль
«Сырое событие» (raw event)
{
.....................................................................................
"inputs": {
"@GUID": {
.....................................................................................
"encoding": "UTF-16BE",
"filename_regex": "(.+.AUD)",
"parser": {
"offset_parser": {
"offsets": [
{ "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" },
{ "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA"
},
{ "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID"
},
{ "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" },
{ "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" },
{ "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" },
{ "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" },
{ "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" },
{ "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" },
{ "begin_pos": 64, "length": 16, "name": "SLGLTRM"
},
{ "begin_pos": 80, "length": 24, "name": "SLGUSER"
},
{ "begin_pos": 104,"length": 40, "name": "SLGTC"
},
.....................................................................................
{
"SLGTYPE.SLGFTYP": "2",
"SLGTYPE.AREA": "AU",
"SLGTYPE.SUBID": "W",
"SLGDATTIM.DATE": "20150205",
"SLGDATTIM.TIME": "074639",
"SLGMAND": "700",
"SLGUSER": "HANNIBAL
"SLGTC": "SESSION_MANAGER
",
",
"SLGREPNA": "/1BCDWB/DBTSL1T
",
"SLGLTRM2": "NEF-KISEL-IA
",
"SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt"
}

17.

Профиль filemonitor, offset_parser
Профиль
«Сырое событие» (raw event)
{
.....................................................................................
"inputs": {
"@GUID": {
.....................................................................................
"encoding": "UTF-16BE",
"filename_regex": "(.+.AUD)",
"parser": {
"offset_parser": {
"offsets": [
{ "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" },
{ "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA"
},
{ "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID"
},
{ "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" },
{ "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" },
{ "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" },
{ "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" },
{ "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" },
{ "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" },
{ "begin_pos": 64, "length": 16, "name": "SLGLTRM"
},
{ "begin_pos": 80, "length": 24, "name": "SLGUSER"
},
{ "begin_pos": 104,"length": 40, "name": "SLGTC"
},
.....................................................................................
{
"SLGTYPE.SLGFTYP": "2",
"SLGTYPE.AREA": "AU",
"SLGTYPE.SUBID": "W",
"SLGDATTIM.DATE": "20150205",
"SLGDATTIM.TIME": "074639",
"SLGMAND": "700",
"SLGUSER": "HANNIBAL
"SLGTC": "SESSION_MANAGER
",
",
"SLGREPNA": "/1BCDWB/DBTSL1T
",
"SLGLTRM2": "NEF-KISEL-IA
",
"SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt"
}

18.

Профиль filemonitor, offset_parser
Профиль
«Сырое событие» (raw event)
{
.....................................................................................
"inputs": {
"@GUID": {
.....................................................................................
"encoding": "UTF-16BE",
"filename_regex": "(.+.AUD)",
"parser": {
"offset_parser": {
"offsets": [
{ "begin_pos": 0, "length": 2, "name": "SLGTYPE.SLGFTYP" },
{ "begin_pos": 2, "length": 4, "name": "SLGTYPE.AREA"
},
{ "begin_pos": 6, "length": 2, "name": "SLGTYPE.SUBID"
},
{ "begin_pos": 8, "length": 16, "name": "SLGDATTIM.DATE" },
{ "begin_pos": 24, "length": 12, "name": "SLGDATTIM.TIME" },
{ "begin_pos": 36, "length": 4, "name": "SLGDATTIM.DUMMY" },
{ "begin_pos": 40, "length": 10, "name": "SLGPROC.UNIXPID" },
{ "begin_pos": 50, "length": 10, "name": "SLGPROC.TASKTNO" },
{ "begin_pos": 60, "length": 4, "name": "SLGPROC.SLGTTYP" },
{ "begin_pos": 64, "length": 16, "name": "SLGLTRM"
},
{ "begin_pos": 80, "length": 24, "name": "SLGUSER"
},
{ "begin_pos": 104,"length": 40, "name": "SLGTC"
},
.....................................................................................
{
"SLGTYPE.SLGFTYP": "2",
"SLGTYPE.AREA": "AU",
"SLGTYPE.SUBID": "W",
"SLGDATTIM.DATE": "20150205",
"SLGDATTIM.TIME": "074639",
"SLGMAND": "700",
"SLGUSER": "HANNIBAL
"SLGTC": "SESSION_MANAGER
",
",
"SLGREPNA": "/1BCDWB/DBTSL1T
",
"SLGLTRM2": "NEF-KISEL-IA
",
"SLGDATA": "12349&ASC&C:\\SAP\\tsl1t_new.txt"
}

19.

Схема работы MaxPatrol SIEM Server
Positive Technologies
MaxPatrol SIEM

20.

<
MaxPatrol SIEM
Правила
нормализации

21.

Примеры журнальных сообщений
TEXT (Syslog)
<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length
JSON
XML
{
"TimeVal": "2015-07-21 07:10:59",
"DoorIndex": 10,
"Contents": "Доступ предоставлен",
"OwnerName": "мастер Йода",
"NumCom": 4828116
}
<Event
xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Windows Server Update Services" />
<EventID Qualifiers="0">501</EventID>
<Level>4</Level>
<Task>1</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2016-05-14T17:06:59.000Z" />
<EventRecordID>8156</EventRecordID>
<Channel>Application</Channel>
<Computer>something.example.com</Computer>
<Security />
</System>
<EventData>
<Data>Update Services Service Started</Data>
</EventData>
</Event>

22.

TEXT (Syslog)
CEF — попытка унификации формата
CEF:Version|Device Vendor|Device Product|
Device Version|Signature ID|Name|Severity|Extension
<6>CEF:0|Stonesoft|Firewall|5.3.10|70018|Connection_Allowed|0|
spt=27302 deviceExternalId=fw-int-ptk2 node 2 dst=172.2.8.26 app=DNS (UDP) rt=Mar 10
2016 11:09:58 deviceFacility=Packet filter act=Allow deviceInboundInterface=129
proto=17 dpt=53 src=172.2.1.26 dvc=172.2.2.250 dvchost=172.2.2.250 cs1Label=RuleId
cs1=236.6

23.

JSON
Tabular
{
"TimeVal":"2015-07-21 07:10:59.000",
"DoorIndex":10,
"Contents":"Доступ предоставлен",
"OwnerName":"Ганнибал Барка",
"NumCom":4828116
}

24.

EventLog: XML -> JSON via RapidXML
<Event xmlns=" http://schemas.microsoft.com/w...">
<System>
<Provider Name="Windows Server Update S..." />
<EventID Qualifiers="0">501</EventID>
<Level>4</Level>
<Task>1</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2016-05-14T17:..." />
<EventRecordID>8156</EventRecordID>
<Channel>Application</Channel>
<Computer>something.example.com</Computer>
<Security />
</System>
<EventData>
<Data>Update Services Service Started</Data>
</EventData>
</Event>
{
"Event": {
"xmlns":
"http://schemas.microsoft.com/win/2004/08/events/event",
"System": {
"Provider": {
"Name": "Windows Server Update Services"
},
"EventID": {
"Qualifiers": "0",
"text": "501"
},
"Level": "4",
"Task": "1",
"Keywords": "0x80000000000000",
"TimeCreated": {
"SystemTime": "2016-05-14T17:06:59.000000000Z"
},
"EventRecordID": "8156",
"Channel": "Application",
"Computer": "something.example.com",
"Security": null
},
"EventData": {
"Data": "Update Services Service Started"
}}}

25.

TEXT — пишем формулу нормализации
#<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length
TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?}
{$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?}
{NUMBER?}{":"?}{$origin_id_ip=IPV4|
$origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|}
{":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?}
{object.name="SSH2"|object.name="SSH"} {NUMBER}:
{reason="Invalid modulus length"}'

26.

TEXT — пишем формулу нормализации
#<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length
TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?}
{$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?}
{NUMBER?}{":"?}{$origin_id_ip=IPV4|
$origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|}
{":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?}
{object.name="SSH2"|object.name="SSH"} {NUMBER}:
{reason="Invalid modulus length"}'

27.

TEXT — пишем формулу нормализации
#<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length
TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?}
{$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?}
{NUMBER?}{":"?}{$origin_id_ip=IPV4|
$origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|}
{":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?}
{object.name="SSH2"|object.name="SSH"} {NUMBER}:
{reason="Invalid modulus length"}'

28.

TEXT — пишем формулу нормализации
#<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length
TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?}
{$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?}
{NUMBER?}{":"?}{$origin_id_ip=IPV4|
$origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|}
{":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?}
{object.name="SSH2"|object.name="SSH"} {NUMBER}:
{reason="Invalid modulus length"}'

29.

TEXT — пишем формулу нормализации
#<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length
TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?}
{$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?}
{NUMBER?}{":"?}{$origin_id_ip=IPV4|
$origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|}
{":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?}
{object.name="SSH2"|object.name="SSH"} {NUMBER}:
{reason="Invalid modulus length"}'

30.

TEXT — пишем формулу нормализации
#<191>11908: Feb 8 10:47:35.220: SSH2 2: Invalid modulus length
TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?}
{$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?}
{NUMBER?}{":"?}{$origin_id_ip=IPV4|
$origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|}
{":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?}
{object.name="SSH2"|object.name="SSH"} {NUMBER}:
{reason="Invalid modulus length"}'

31.

TEXT — пишем формулу нормализации
{$предопределенные=МАКРОСЫ}
{WORD}
[a-zA-Z0-9_]+
{WORDDASH}
[a-zA-Z0-9_-]+
{STRING}
{LITERAL}
\S
{DATETIME}
Operator Guide
{DURATION}
[hhh]hh:mm:ss,+
{IPV4} {IPV6}
{HOSTNAME}
RFC-1034,1035,+
{NTUSER}
tudor\edward
{CSV} {CSV(',','"')}
{KEYVALUE} {KEYVALUE(';','=')}
{REST}

32.

TEXT — пишем формулу нормализации
TEXT = '{"<"NUMBER">"?} {NUMBER?}{":"?} {DATETIME?}
{$ip=IPV4|$ip=IPV6|$hostname=HOSTNAME|}{":"?}
{NUMBER?}{":"?}{$origin_id_ip=IPV4|
$origin_id_ip=IPV6|$origin_id_hostname=HOSTNAME|}
{":"?} {"*"|"."|}{time=DATETIME}: {WORD":"?}
{object.name="SSH2"|object.name="SSH"} {NUMBER}:
{reason="Invalid modulus length"}'
if ($origin_id_ip == "127.0.0.1" or $origin_id_ip == "0.0.0.0")
then
$origin_id_ip = null
endif
event_src.hostname = coalesce($hostname, $origin_id_hostname)
event_src.ip = coalesce($ip, $origin_id_ip)

33.

JSON: TABULAR
# {"TimeVal":"2015-07-21 07:10:59.000", "DoorIndex":10,
# "Contents":"Доступ предоставлен",
# "OwnerName":"Ганнибал Барка", "NumCom":4828116}
TABULAR = "TimeVal, DoorIndex, Contents, OwnerName, NumCom"
COND = $Contents == "Доступ предоставлен"
subject = "system"
action = "allow"
status = "success"
object = "account"
time = $TimeVal
msgid = $Contents

34.

JSON: TABULAR
# { "TimeVal":"2015-07-21 07:10:59.000",
#
"DoorIndex":10,
#
"Contents":"Доступ предоставлен",
#
"OwnerName":"Ганнибал Барка",
#
"NumCom":4828116}
TABULAR = "TimeVal, DoorIndex, Contents, OwnerName, NumCom"
COND = $Contents == "Доступ предоставлен"
time = $TimeVal
msgid = $Contents

35.

JSON: EVENTLOG, raw (после RapidXML)
{
"Event": {
"xmlns": http://example.com/.../event",
"System": {
"Provider": {
"Name": "WSUS"
},
"EventID": {
"Qualifiers": "0",
"text": "501"
},
"Level": "4",
"Task": "1",
"Keywords": "0x80000000000000",
"TimeCreated": {
"SystemTime": "2016-05-14T17:06:59"
},
"EventRecordID": "8156",
"Channel": "Application",
"Computer": "example",
"Security": null
},
"EventData": {
"Data": "Update Services Service Started"
}
}
}

36.

JSON: EVENTLOG, raw (после RapidXML)
"Event": {
"xmlns": http://example.com/.../event",
"System": {
"Provider": {
"Name": "WSUS"
},
"EventID": {
"Qualifiers": "0",
"text": "501"
},
"Level": "4",
"Task": "1",
"Keywords": "0x80000000000000",
"TimeCreated": {
"SystemTime": "2016-05-14T17:06:59"
},
"EventRecordID": "8156",
"Channel": "Application",
"Computer": "example",
"Security": null
},
"EventData": {
"Data": "Update Services Service Started"
}
}
}
EVENTLOG = 'EventID.text="501"'
COND = $Channel=="Application" and
$Provider["Name"]=="WSUS"

37.

JSON: EVENTLOG, formula.xp
EVENTLOG = 'EventID.text="501"'
COND = $Channel=="Application" and object.name = "Update Services"
$Provider["Name"]=="WSUS"
action = "start"
object = "service"
status = "success"
msgid = $EventID["text"]
time = $TimeCreated["SystemTime"]

38.

JSON:"PT_Microsoft_Windows_WMI_Win32_
LoggedOnUser"
JSON = 'TargetInstance.__CLASS="Win32_LoggedOnUser"'
time = win_ticks_to_datetime($TIME_CREATED)
subject.domain = lower($Win32_Account['Domain'])
subject.name = lower($Win32_Account['Name'])
subject.id = $Win32_Account['SID']

39.

JSON:"PT_Microsoft_Windows_WMI_Win32_
LoggedOnUser"
JSON = 'TargetInstance.__CLASS="Win32_LoggedOnUser"'
time = win_ticks_to_datetime($TIME_CREATED)
subject.domain = lower($Win32_Account['Domain'])
subject.name = lower($Win32_Account['Name'])
subject.id = $Win32_Account['SID']

40.

Нормализация: Вложенные сообщения
{
"unixtime": 1466648875,
"timegenerated": "2016-06-23 02:27:25.000",
"objectname": "DC1-DC-02",
"objectdisplayname": "DC1-DC-02",
"objectpath": "DC1-DC-02.ptsecurity.ru",
"objectfullname": "Microsoft.Windows.Server.2008.AD.DomainControllerRole:DC1-DC-02.example.com;DC1-DC-02",
"publishername": "Health Service Script",
"number": 17,
"category": 0,
"eventuser": "N/A",
"channel": "Operations Manager",
"level": 4,
"loggingcomputer": "DC1-DC-02.ptsecurity.ru",
"eventdata": "<DataItem type=\"System.XmlData\" time=\"2016-06-23T05:27:25.1476913+03:00\"
sourceHealthServiceId=\"52DE6561-458F-28F5-4C75-CCE269716AB5\"><eventdata
xmlns=\"http://schemas.microsoft.com/win/2004/08/events/event\"><Data>AD Monitor Trusts</Data><Data>The script
'AD Monitor Trusts' completed successfully in 0 seconds.</Data></eventdata></DataItem>",
"eventparameters": "<Param>AD Monitor Trusts</Param><Param>The script 'AD Monitor Trusts' completed
successfully in 0 seconds.</Param>",
"rulename": "AD_Monitor_Trusts_Pass_through_2",
"rulecategory": "EventCollection",
"ruleenabled": 2,
"ruleguaranteeddelivery": 0,
"rulepriority": 1,
"ruleremotable": 0
}

41.

XML
TABULAR =
"{time=timegenerated},
{subject.name=objectpath},
{subject.group=publishername},
number,
{event_src.subsys=channel},
{event_src.hostname=loggingcomputer},
eventdata,
{datafield2=rulename}"
COND = $publishername == "Health Service
Script" and $number == 17
submessage("XML","Event_data",$eventdata)
submessage("TEXT","Script_info",$script_info)
subformula "Event_data"
XML = 'DataItem'
$script_info = $DataItem / eventdata / Data
[1] #Имя скрипта и временя выполнения
endsubformula

42.

XML
<DataItem type="System.XmlData" time="2016-06-23..." sourceHealthServiceId="...">
<eventdata xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<Data>AD Monitor Trusts</Data>
<Data>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Data>
</eventdata>
</DataItem>
submessage("XML","Event_data",$eventdata)
submessage("TEXT","Script_info",$script_info)
subformula "Event_data"
XML = 'DataItem'
$script_info = $DataItem / eventdata / Data [1] #Имя скрипта и временя выполнения
endsubformula
subformula "Script_info"
TEXT = 'The script {$script=STRING+} completed successfully in {datafield3=NUMBER}
seconds.'
endsubformula

43.

Нормализация: Вложенные сообщения
<DataItem type="System.XmlData" time="2016-06-23..." sourceHealthServiceId="...">
<eventdata xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<Data>AD Monitor Trusts</Data>
<Data>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Data>
</eventdata>
</DataItem>
submessage("XML","Event_data",$eventdata)
submessage("TEXT","Script_info",$script_info)
subformula "Event_data"
XML = 'DataItem'
$script_info = $DataItem / eventdata / Data [1] #Имя скрипта и временя выполнения
endsubformula
subformula "Script_info"
TEXT = 'The script {$script=STRING+} completed successfully in {datafield3=NUMBER}
seconds.'
endsubformula

44.

Нормализация: Вложенные сообщения
<DataItem type="System.XmlData" time="2016-06-23..." sourceHealthServiceId="...">
<eventdata xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<Data>AD Monitor Trusts</Data>
<Data>The script 'AD Monitor Trusts' completed successfully in 0 seconds.</Data>
</eventdata>
</DataItem>
submessage("XML","Event_data",$eventdata)
submessage("TEXT","Script_info",$script_info)
subformula "Event_data"
XML = 'DataItem'
$script_info = $DataItem / eventdata / Data [1] #Имя скрипта и временя выполнения
endsubformula
subformula "Script_info"
TEXT = 'The script {$script=STRING+} completed successfully in {datafield3=NUMBER}
seconds.'
endsubformula

45.

Функции
Математика, логика
+, -, *, mod, div
and, or, not
>, <, >=, <=, ==, !=
in_list, in_subnet, in_active_set
Другое
coalesce($one,$two,$three) — вернуть первое не пустое значение
match($one,"*.sw?") — истина, если шаблон найден в переменной $one

46.

Функции
Условные переходы
$access_success = ["100", "101", "200", "201", "202", "203", "206", "302", "304"]
$access_failure = ["301", "302", "305", "307", "308", "400", "401", "403", "404",
"405", "406", "407", "413", "415", "418", "423", "429", "431", "495",
"496", "497", "500", "501", "502", "503", "504", "505", "507", "508"]
if in_list($access_success, object.state) then
status = "success"
elif in_list($access_failure, string(object.state)) then
status = "failure"
else
#Остановка работы формулы если неизвестный HTTP код
submessage('TEXT', 'break', 'a')
endif
subformula "break"
TEXT = "b"
endsubformula

47.

Функции
Условные переходы
reason = switch object.state
...
case "400" "Bad Request"
case "401" "Unauthorized"
case "403" "Forbidden"
case "404" "Not Found"
...
endswitch

48.

TEXT — пишем формулу нормализации
#login success
#root pts/0
Wed Jun 8 02:27 - 03:13
(00:45) 10.0.72.100
#login failure
#foo ssh:notty Wed Jun 8 09:50 - 09:50
(00:00) 10.0.72.100
TEXT = '{$tmp_user_name=WORDDASH} {datafield1=STRING} {WORD}
{$MM=WORD}{$DD=NUMBER}{$HH=NUMBER}:{$minutes=NUMBER} {"-"?} {NUMBER?}{":"?}{NUMBER?}
{"("?}{$duration_minutes=NUMBER?}{":"?}{$duration_seconds=NUMBER?}{")"?} {"still logged
in"?} {$event_src.ip=IPV4}'
if $duration_minutes == 0 and $duration_seconds == 0 then
status = "failure"
else
status = "success"
endif
time = $MM+" "+string($DD)+" "+string($HH)+":"+string($minutes)+":"+"00"
if $duration_minutes != null and $duration_seconds != null then
duration = $duration_minutes*60 + $duration_seconds
endif

49.

Функции
Преобразование
типов, конвертация
string
number (may_be_number)
number8 (may_be_number8)
number16 (may_be_number16)
float (may_be_float)
bool
ipv4 (may_be_ipv4)
ipv6 (may_be_ipv6)
macaddr (may_be_macaddr)
duration (may_be_duration)
datetime (may_be_datetime)
epoch_to_datetime
epoch_ms_to_datetime
win_ticks_to_datetime
Синтаксический разбор строк
keyvalue
csv
$kv=keyvalue("a=b,c=d","'","=")
Преобразование строк
year, month, day, hour, minute, second, timezone —
извлечение подстрок
strip("$123.00","$",".00") -> "123"
find_substr("$123.00",".") -> 4
length("$123.00") -> 7
substr("$123.00",0,4) -> "$123"
upper, lower

50.

Локализация
Поле text не входит в таксономию события. Да-да, совсем-совсем
...\formulas\Checkpoint\Endpoint_security\Security_console\Assign_policy\i18n\i18n_ru.xml
<?xml version="1.0" encoding="utf-8"?>
<Localization locale="ru">
<EventDescriptions>
<EventDescription
id="PT_Checkpoint_Endpoint_Security_console_Assign_policy_lang">Политика {object.name}
была добавлена в группу {object.group} на узле {event_src.ip}</EventDescription>
</EventDescriptions>
</Localization>
C:\Program Files\Positive Technologies\MaxPatrol SIEM Server\langs\ru.lang
id = "PT_Checkpoint_Endpoint_Security_console_Assign_policy_lang"; Политика {object.name}
была добавлена в группу {object.group} на узле {event_src.ip}
Поле text в браузере:
Политика Deny Hackers была добавлена в группу Networks на узле 192.0.2.123

51.

<
MaxPatrol SIEM
Правила корреляции

52.

Правила корреляции

53.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
rule Together:
One -> Other
event Login_success:
key: subject.name, subject.domain
filter {
correlation_name == null and
subject.name != null and … }
on One { … }
event Login_failure:
key: subject.name, subject.domain
filter { … }
on Other { … }
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m
emit { … }
on Login_failure {
$count.subevents = $count.subevents + 1
}
on Login_success {
$subject.name = subject.name
$subject.domain = subject.domain
$count.subevents = $count.subevents + 1
}
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
}

54.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
rule Together:
One -> Other
event Login_success:
key: subject.name, subject.domain
filter {
correlation_name == null and
subject.name != null and … }
on One { … }
event Login_failure:
key: subject.name, subject.domain
filter { … }
on Other { … }
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m
emit { … }
on Login_failure {
$count.subevents = $count.subevents + 1
}
on Login_success {
$subject.name = subject.name
$subject.domain = subject.domain
$count.subevents = $count.subevents + 1
}
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
}

55.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
rule Together:
One -> Other
on One { … }
event Login_success:
key:
subject.name, subject.domain
filter {
correlation_name == null and
subject.name != null and
category.generic == "Access" and
category.high == "Authentication" and
subject == "account" and
action == "login" and
status == "success"
}
on Other { … }
emit { … }
event Login_failure:
key: subject.name, subject.domain
filter { … }
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m

56.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
rule Together:
One -> Other
on One { … }
event Login_success:
key:
subject.name, subject.domain
filter {
correlation_name == null and
subject.name != null and
category.generic == "Access" and
category.high == "Authentication" and
subject == "account" and
action == "login" and
status == "success"
}
on Other { … }
emit { … }
event Login_failure:
key: subject.name, subject.domain
filter { … }
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m

57.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
event Login_success:
key:
subject.name, subject.domain
filter {
correlation_name == null and
subject.name != null and
category.generic == "Access" and
category.high == "Authentication" and
subject == "account" and
action == "login" and
status == "success"
rule Together:
One -> Other
on One { … }
on Other { … }
emit { … }
}
event Login_failure:
key: subject.name, subject.domain
filter { … }
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m

58.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
rule Together:
One -> Other
on One { … }
on Other { … }
emit { … }
event Login_success:
key: subject.name, subject.domain
filter {
correlation_name == null and
subject.name != null and … }
event Login_failure:
key: subject.name, subject.domain
filter { … }
rule Bruteforce_success_by_user:
(Login_failure[5,] -> Login_success) within 5m
on Login_failure {
$count.subevents = $count.subevents + 1
}
on Login_success {
$subject.name = subject.name
$subject.domain = subject.domain
$count.subevents = $count.subevents + 1
}
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"

}

59.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
rule Together:
One -> Other
on One { … }
on Other { … }
emit { … }
event Login_success:
key: subject.name, subject.domain
filter {
correlation_name == null and
subject.name != null and … }
event Login_failure:
key: subject.name, subject.domain
filter { … }
rule Bruteforce_success_by_user:
(Login_failure[5,] -> Login_success) within 5m
on Login_failure {
$count.subevents = $count.subevents + 1
}
on Login_success {
$subject.name = subject.name
$subject.domain = subject.domain
$count.subevents = $count.subevents + 1
}
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"

}

60.

XP — eXtraction and Processing. Корреляция
event One:
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success)
within 5m
event Other:
on Login_failure {
$count.subevents = $count.subevents + 1
}
rule Together:
One -> Other
on Login_success {
$subject.name = subject.name
$subject.domain = subject.domain
$count.subevents = $count.subevents + 1
}
on One { … }
on Other { … }
emit { … }
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
$category.generic = "Attacks & Recon"
$category.high = "Attack"
$category.low = "Bruteforce"

}

61.

XP — eXtraction and Processing. Корреляция
event One:
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m
on Login_failure { … }
event Other:
rule Together:
One -> Other
on One { … }
on Login_success { … }
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
on Other { … }
$category.generic = "Attacks & Recon"
$category.high = "Attack"
$category.low = "Bruteforce"
emit { … }
$subject = "account"
$action = "initiate"
$object = "attack"
$status = "success"
$object.name = "Bruteforce"
$id = "PT_SIEM_Bruteforce_success_by_user"
$importance = "medium"
}

62.

XP — eXtraction and Processing. Корреляция
event One:
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m
on Login_failure { … }
event Other:
rule Together:
One -> Other
on One { … }
on Login_success { … }
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
on Other { … }
$category.generic = "Attacks & Recon"
$category.high = "Attack"
$category.low = "Bruteforce"
emit { … }
$subject = "account"
$action = "initiate"
$object = "attack"
$status = "success"
$object.name = "Bruteforce"
$id = "PT_SIEM_Bruteforce_success_by_user"
$importance = "medium"
}

63.

XP — eXtraction and Processing. Корреляция
event One:
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m
on Login_failure { … }
event Other:
rule Together:
One -> Other
on One { … }
on Login_success { … }
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
on Other { … }
$category.generic = "Attacks & Recon"
$category.high = "Attack"
$category.low = "Bruteforce"
emit { … }
$subject = "account"
$action = "initiate"
$object = "attack"
$status = "success"
$object.name = "Bruteforce"
$id = "PT_SIEM_Bruteforce_success_by_user"
$importance = "medium"
}

64.

XP — eXtraction and Processing. Корреляция
event One:
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within
5m
event Other:
on Login_failure { … }
rule Together:
One -> Other
on One { … }
on Login_success { … }
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
on Other { … }
$category.generic = "Attacks & Recon"
$category.high = "Attack"
$category.low = "Bruteforce"
emit { … }
$subject = "account"
$action = "initiate"
$object = "attack"
$status = "success"
$object.name = "Bruteforce"
$id = "PT_SIEM_Bruteforce_success_by_user"
$importance = "medium"
}

65.

XP — eXtraction and Processing. Корреляция
event One:
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m
on Login_failure { … }
event Other:
rule Together:
One -> Other
on One { … }
on Login_success { … }
emit {
$correlation_name = "Bruteforce_success_by_user"
$correlation_type = "incident"
on Other { … }
$category.generic = "Attacks & Recon"
$category.high = "Attack"
$category.low = "Bruteforce"
emit { … }
$subject = "account"
$action = "initiate"
$object = "attack"
$status = "success"
$object.name = "Bruteforce"
$id = "PT_SIEM_Bruteforce_success_by_user"
$importance = "medium"
}

66.

XP — eXtraction and Processing. Корреляция
event One:
event Other:
rule Together:
One -> Other
# Checkpoint (ssh, opsec)
# Cisco ACS
# Cisco IOS (ssh, telnet, web)
# Cisco Nexus (ssh)
# Juniper Junos (ssh, telnet)
# UNIX-like
# Windows
on One { … }
on Other { … }
emit { … }
event Login_success:
key: subject.name, subject.domain
filter { … }
event Login_failure:
key: subject.name, subject.domain
filter { … }
rule Bruteforce_success_by_user: (Login_failure[5,] -> Login_success) within 5m
on Login_failure { … }
on Login_success { … }
emit { … }

67.

Если события не было…
event One:
event Other:
rule Together:
One -> Other
on One { … }
on Other { … }
emit { … }
event Infected_object_detect:
key:
event_src.ip, event_src.host, object.path
filter { … }
event Infected_object_clean:
key:
event_src.ip, event_src.host, object.path
filter { … }
rule Infected_object_detect_and_not_clean_on_event_src_host:
(Infected_object_detect -> not Infected_object_clean) timer 5m

68.

Если события не было…
event One:
event Other:
rule Together:
One -> Other
on One { … }
on Other { … }
emit { … }
event Infected_object_detect:
key:
event_src.ip, event_src.host, object.path
filter { … }
event Infected_object_clean:
key:
event_src.ip, event_src.host, object.path
filter { … }
rule Infected_object_detect_and_not_clean_on_event_src_host:
(Infected_object_detect -> not Infected_object_clean) timer 5m

69.

Если события не было…
event One:
event Other:
Правило сложения отрицаний
Оператор ?
rule Together:
One -> Other
on One { … }
on Other { … }
rule Session_request_to_network_device_from_unauthorized_host:
(SessionStart ->
(not LoginFail or not LoginSuccess) ->
SessionClose?) timer 2m
emit { … }
Между SessionStart и возможным SessionClose
не было ни LoginFail ни LoginSuccess

70.

Если обработать надо первое
событие в последовательности
Конструкция as
event Checkpoint_connection:
key: evet_src.host
filter { … }
rule Port_lookup: (
((Checkpoint_connection
as First_checkpoint_connection
-> Checkpoint_connection[9])
with different dst.ip) or
((Junos_connection
as First_junos_connection
-> Junos_connection[9])
with different dst.ip) or
((Netflow_connection
as First_netflow_connection
-> Netflow_connection[9])
with different dst.ip) or
((Cisco_fw_connection
as First_cisco_fw_connection
-> Cisco_fw_connection[9])
with different dst.ip) or
((Cisco_ios_in_connection as First_cisco_ios_in_connection -> Cisco_ios_in_connection[9]) with different dst.ip) or
((Cisco_ios_out_connection as First_cisco_ios_out_connection -> Cisco_ios_out_connection[9]) with different assigned_src_ip))
within 2h
on First_checkpoint_connection { … }
on First_junos_connection { … }
on First_netflow_connection { … }

71.

Если одинаковые события должны
отличаться некоторым параметром
Если одинаковые события должны отличаться некоторым параметром
Конструкция with different
(Антитеза оператору key из директивы event)
rule Port_lookup: (
((Checkpoint_connection
as First_checkpoint_connection
-> Checkpoint_connection[9])
with different dst.ip) or
((Junos_connection
as First_junos_connection
-> Junos_connection[9])
with different dst.ip) or
((Netflow_connection
as First_netflow_connection
-> Netflow_connection[9])
with different dst.ip) or
((Cisco_fw_connection
as First_cisco_fw_connection
-> Cisco_fw_connection[9])
with different dst.ip) or
((Cisco_ios_in_connection as First_cisco_ios_in_connection -> Cisco_ios_in_connection[9]) with different dst.ip) or
((Cisco_ios_out_connection as First_cisco_ios_out_connection -> Cisco_ios_out_connection[9]) with different assigned_src_ip))
within 2h
on First_checkpoint_connection { … }
on First_junos_connection { … }
on First_netflow_connection { … }

72.

Если в обработчике нужна подстановка
(ключ->значение)
Конструкция switch case … case … endswitch
rule Port_lookup: (
((Checkpoint_connection
as First_checkpoint_connection
-> Checkpoint_connection[9])
with different dst.ip) or
((Junos_connection
as First_junos_connection
-> Junos_connection[9])
with different dst.ip) or
((Netflow_connection
as First_netflow_connection
-> Netflow_connection[9])
with different dst.ip) or
((Cisco_fw_connection
as First_cisco_fw_connection
-> Cisco_fw_connection[9])
with different dst.ip) or
((Cisco_ios_in_connection as First_cisco_ios_in_connection -> Cisco_ios_in_connection[9]) with different dst.ip) or
((Cisco_ios_out_connection as First_cisco_ios_out_connection -> Cisco_ios_out_connection[9]) with different assigned_src_ip))
within 2h
on First_checkpoint_connection {
$src.ip = src.ip
$protocol = upper(protocol)
$dst.port = dst.port
$start_time = time
$object.name = switch dst.port
case 20
"FTP lookup"
case 21
"FTP lookup"
case 22
"SSH lookup"
case 23
"Telnet lookup"
case 25
"SMTP lookup“
endswitch
}

73.

Если в описании события надо найти
параметр в списке
Конструкция in_list
event Netflow_connection:
key:
src.ip, protocol, dst.port
filter {
src.ip != null and
event_src.subsys == "netflow" and
(
(
upper(protocol) == "TCP" and
in_list([20, 21, 194, 530, 161, 162, 135, 1433, 1434, 3299, 25, 389, 636, 445, 1025, 23, 22, 80, 8080,
443, 53, 1521, 1528, 2483, 2484, 3389, 110, 143, 139, 137, 113, 465, 993, 995, 3306], dst.port)
)
or
(
upper(protocol) == "UDP" and
in_list([67, 530, 161, 162, 1434, 389, 636, 80, 8080, 443, 53, 3389, 113], dst.port)
)
)
}
rule Port_lookup: (
((Checkpoint_connection
as First_checkpoint_connection
-> Checkpoint_connection[9])
with different dst.ip) or
((Junos_connection
as First_junos_connection
-> Junos_connection[9])
with different dst.ip) or
((Netflow_connection
as First_netflow_connection
-> Netflow_connection[9])
with different dst.ip) or …

74.

Если надо поместить в инцидент все
подобные события за промежуток времени
Конструкция timer
event TeamViewer_detect:
key:
event_src.host
filter {
correlation_name == null and
category.generic == "Configuration Management" and
category.high == "System Configuration Management" and
in_list(["OS Service Detection","OS Service Modification", "OS Service
Resumption"],category.low) and
match(object.name,"*TeamViewer*") != false and
status=="success" and
not in_active_set("authorized_to_run_team_viewer_hosts_list", event_src.host)
}
rule TeamViewer_service_detect: TeamViewer_detect+ timer 10m

75.

Табличный список
―Разделяются на списки
• для правил обогащения и
• для правил корреляции
―Записи могут быть постоянными и
временными
―Записи могут редактироваться из UI
практически «на лету»
―При превышении максимального
размера усекаются до типичного

76.

Табличный список
Список может
импортироваться/экспортироваться в
формате CSV
"object"
"малина"
"крыжовник"
"ромашка"
"подснежник"
"банан"
"киви"
"клубника"
"черника"

77.

Табличный список: справочник
Список может импортироваться/экспортироваться в формате CSV
query GetSmth()
from TableList
event One:
filter {exec_query}
event Other:
rule Attention:
One -> Other
on One { … }
on Other { … }
emit { … }
query Get_File_Extension($extension) from Cryptor_file_extensions {
extension == $extension
}
event File_modified:
key:
event_src.host, subject.name, subject.domain, datafield3
filter {
(
id == "PT_Positive_Technologies_Endpoint_Monitor_filemonitor_FileDataModified" or
id == "PT_Positive_Technologies_Endpoint_Monitor_filemonitor_FileOverwritten" or
id == "PT_Positive_Technologies_Endpoint_Monitor_filemonitor_FileRenamed"
) and
object.type == "file" and
status == "success" and
exec_query(
"Get_File_Extension",
[lower(string(regex(object.name, "(\.\w+)$", 1)))]
)
}
rule Endpoint_monitor_Mass_file_modification:
(File_modified[100] with different object.name) within 60s

78.

Табличный список: хранение данных
Пример: применение табличного списка для хранения промежуточных
данных
Здесь правило Cisco_FW_Bruteforce_success_from_src_to_dst_by_user_with_tables пишет в список,
а правило Cisco_FW_Execute_show_run_after_success_bruteforce читает из него

79.

Табличный список: хранение данных
Пример: чтение из таблицы
query GetSmth()
from TableList
event One:
filter
{exec_query}
event Other:
rule Attention:
One -> Other
on One { … }
on Other { … }
insert_into { … }
emit { … }
rule Cisco_FW_Bruteforce_success_from_src_to_dst_by_user_with_tables:
(Account_login_failed[5,] -> Account_login_success) within 5m
on Account_login_success {
$dst.ip = event_src.ip
$dst.hostname = event_src.hostname
$dst.host = event_src.host
$dst.asset = event_src.asset
$src.ip = src.ip
$src.hostname = src.hostname
$src.host = src.host
$src.asset = src.asset
$subject.name = subject.name
$event_src.vendor = event_src.vendor
$event_src.title = event_src.title
}
insert_into Success_bruteforce_on_host_table {
host = $dst.host
user = $subject.name
}

80.

Табличный список: хранение данных
Пример: чтение из таблицы
query GetSmth()
from TableList
event One:
filter
{exec_query}
event Other:
rule Attention:
One -> Other
on One { … }
on Other { … }
insert_into { … }
emit { … }
query Host_user_check($host, $user) from Success_bruteforce_on_host_table
host == $host and
user == $user
}
event Cisco_ASA_show_run:
key:
event_src.host
filter {
event_src.host != null and
subject.name != null and
id == "PT_Cisco_ASA_FWSM_PIX_syslog_111009_user_executed_show" and
match(object.value, "show running-config*") and
exec_query("Host_user_check", [event_src.host, subject.name])
}
rule Cisco_FW_Execute_show_run_after_success_bruteforce: Cisco_ASA_show_run
{

81.

Табличный список: агрегатные функции
Пример: возврат ассоциативного массива из табличного списка
query GetSmth()
from TableList
qhandler
event One:
filter {exec_query}
event Other:
rule Attention:
One -> Other
init { exec_query }
on One { … }
on Other { … }
emit { … }
query PositiveQuery ($check_url) from PositiveTable {
Url == $check_url and
Url
Port
Status
Port == 22 and
Status == "Open"
192.0.2.10
22
Open
}
192.0.2.11
22
Open
qhandler {
192.0.2.12
22
Open
$get_max_duration = max(Duration)
$get_min_duration = min(Duration)
$get_avg_duration = avg(Duration)
$get_count = count()
}
...
rule Example: Event
# Присваивание переменным максимального, минимального и среднего времени
# открытия порта 22 для переданного в запрос IP-адреса узла
init {
$get_duration = exec_query("PositiveQuery", [dst.ip])
$max_duration = $get_duration["$get_max_duration"]
$min_duration = $get_duration["$get_min_duration"]
$avg_duration = $get_duration["$get_avg_duration"]
$count = $get_duration["$get_count"]
}
PositiveTable
Duration
41
33
67

82.

Табличный список: агрегатные функции
Перечень агрегатных функций
Функция
Возвращаемое значение
min(<Имя столбца>)
Наименьший элемент в результатах запросов
max(<Имя столбца>)
Наибольший элемент в результатах запросов
avg(<Имя столбца>)
Среднее значение элементов, округленное до целого
median(<Имя столбца>)
Значение медианного элемента. При четном числе элементов
выбирается нижнее медианное значение
sum(<Имя столбца>)
Суммы всех элементов результатов запроса
count()
Количество элементов в результатах запроса
<Имя столбца>
Первый элемент из результатов запроса

83.

Табличный список
Полный синтаксис запроса query: limit и skip
query <Название запроса>(<Аргументы запроса>)
from <Название табличного списка> {
<Условие запроса>
}
qhandler {
<Ключ 1> = <Функция 1>(<Имя столбца 1>)
<Ключ 2> = <Функция 2>(<Имя столбца 2>)
...
}
limit <Максимальное число возвращаемых строк>
skip <Количество строк, исключаемых из результата>

84.

<
MaxPatrol SIEM
Правила обогащения

85.

Схема работы MaxPatrol SIEM Server
Positive Technologies
MaxPatrol SIEM
Версия XX.X
Руководство разработчика

86.

Правила обогащения
Структура правила обогащения
query <Название запроса>(<Аргументы>)
from <Название табличного списка> {
<Условие запроса>
}
event <Название события>:
filter {
<Условие отбора события>
}
enrichment <Название правила обогащения>
enrich <Название события>
enrich_fields {
<Блок операторов enrich_fields>
}
insert_into <Название табл. списка> {
<Блок операторов insert_into>

87.

Правила обогащения
Структура правила обогащения
query <Название запроса>(<Аргументы>)
from <Название табличного списка> {
<Условие запроса>
}
event <Название события>:
filter {
<Условие отбора события>
}
enrichment <Название правила обогащения>
enrich <Название события>
enrich_fields {
<Блок операторов enrich_fields>
}
insert_into <Название табл. списка> {
<Блок операторов insert_into>
Директива event —
объявление события для
обогащения

88.

Правила обогащения
Структура правила обогащения
query <Название запроса>(<Аргументы>)
from <Название табличного списка> {
<Условие запроса>
}
event <Название события>:
filter {
<Условие отбора события>
}
enrichment <Название правила обогащения>
enrich <Название события>
enrich_fields {
<Блок операторов enrich_fields>
}
insert_into <Название табл. списка> {
<Блок операторов insert_into>
Директива enrichment —
Название правила обогащения

89.

Правила обогащения
Структура правила обогащения
query <Название запроса>(<Аргументы>)
from <Название табличного списка> {
<Условие запроса>
}
event <Название события>:
filter {
<Условие отбора события>
}
enrichment <Название правила обогащения>
enrich <Название события>
enrich_fields {
<Блок операторов enrich_fields>
}
insert_into <Название табл. списка> {
<Блок операторов insert_into>
Директива enrich —
Обработчик события

90.

Правила обогащения
Структура правила обогащения
query <Название запроса>(<Аргументы>)
from <Название табличного списка> {
<Условие запроса>
}
event <Название события>:
filter {
<Условие отбора события>
}
enrichment <Название правила обогащения>
enrich <Название события>
enrich_fields {
<Блок операторов enrich_fields>
}
insert_into <Название табл. списка> {
<Блок операторов insert_into>
Директива query —
Объявление запроса к
табличному списку

91.

Правила обогащения
Структура правила обогащения
Структура правила корреляции
query <Название запроса>(<Аргументы>)
from <Название табличного списка> {
<Условие запроса>
}
event <Название события>:
filter {
<Условие отбора события>
}
enrichment <Название правила обогащения>
enrich <Название события>
enrich_fields {
<Блок операторов enrich_fields>
}
insert_into <Название табл. списка> {
<Блок операторов insert_into>
query <Название запроса>(<Аргументы>)
from <Название табличного списка> {
<Условие запроса>
}
event <Название события>:
filter {
<Условие отбора события>
exec_query(
<Название табл. списка>,
<список аргументов>)
}
rule <Название правила корреляции>
on <Название события> {
<Блок операторов обработчика>
}
insert_into <Название табл. списка> {
<Блок операторов insert_into>
}

92.

Правила обогащения: запись в таблицу
Инструкция insert_into
Арифметические операции при вставке в данных табличный список
enrichment <Название правила обогащения>
enrich <Название события>
insert_into <Название табличного списка> {
<Имя столбца-ключа> = <Значение ключа>
insert_min(<Имя столбца 1>, <Значение для записи 1>)
insert_max(<Имя столбца 2>, <Значение для записи 2>)
insert_inc(<Имя столбца 3>)
insert_dec(<Имя столбца 4>)
}

93.

Арифметические операции при вставке
Перечень агрегатных функций
Функция
Возвращаемое значение
insert_min(<Имя столбца>, $f)
Сравниваются два значения: указанное во втором аргументе
функции и содержащееся в ячейке столбца, указанного в первом
аргументе. В ячейку заносится меньшее из значений
insert_max(<Имя столбца>, $f)
Сравниваются два значения: указанное во втором аргументе
функции и содержащееся в ячейке столбца, указанного в первом
аргументе. В ячейку заносится большее из значений
insert_inc(<Имя столбца>)
Значение ячейки указанного столбца увеличивается на единицу
insert_dec(<Имя столбца>)
Значение ячейки указанного столбца уменьшается на единицу

94.

Табличный список: агрегатные функции
Пример: возврат ассоциативного массива из табличного списка
query GetSmth()
from TableList
qhandler
event One:
filter {…}
enrichment Example
enrich One:
enrich_fields {
exec_query
}
insert_into Table {

}
query PositiveQuery ($check_url) from PositiveTable {
Url == $check_url and
Port == 22 and
Status == "Open"
Url
Port
}
qhandler {
$get_max_duration = max(Duration)
192.0.2.10
22
$get_min_duration = min(Duration)
192.0.2.11
22
$get_avg_duration = avg(Duration)
$get_count = count()
192.0.2.12
22
}
enrichment Example
enrich Event:
enrich_fields {
$get_duration = exec_query("PositiveQuery", [dst.ip])
$max_duration = $get_duration["$get_max_duration"]
$min_duration = $get_duration["$get_min_duration"]
$avg_duration = $get_duration["$get_avg_duration"]
$count = $get_duration["$get_count"]
datafield1 = "Url_" + string(dst.ip)
datafield2 = "Max_duration_" + string($max_duration)
}
PositiveTable
Status
Duration
Open
41
Open
33
Open
67

95.

Табличный список: агрегатные функции
Перечень агрегатных функций
Функция
Возвращаемое значение
min(<Имя столбца>)
Наименьший элемент в результатах запросов
max(<Имя столбца>)
Наибольший элемент в результатах запросов
avg(<Имя столбца>)
Среднее значение элементов, округленное до целого
median(<Имя столбца>)
Значение медианного элемента. При четном числе элементов
выбирается нижнее медианное значение
sum(<Имя столбца>)
Суммы всех элементов результатов запроса
count()
Количество элементов в результатах запроса
<Имя столбца>
Первый элемент из результатов запроса

96.

Табличный список
Полный синтаксис запроса query: limit и skip
query <Название запроса>(<Аргументы запроса>)
from <Название табличного списка> {
<Условие запроса>
}
qhandler {
<Ключ 1> = <Функция 1>(<Имя столбца 1>)
<Ключ 2> = <Функция 2>(<Имя столбца 2>)
...
}
limit <Максимальное число возвращаемых строк>
skip <Количество строк, исключаемых из результата>

97.

Узнай больше о Позитиве
t.me/
positive_technologies
habrahabr.ru/
company/pt
t.me/
positive_investing
vk.com/
ptsecurity
t.me/
POSIdev

98.

[email protected]
ptsecurity.com

99.

<
Спасибо!
English     Русский Правила