Transformation Example
Linux Syslog
Hướng dẫn người dùng xây dựng và kiểm tra Transformation cho log Linux Syslog trong CMC SecOps.
Overview
Transformation xử lý các loại syslog từ Linux (RFC 5424 format):
- SSH Authentication: Login success/failure từ sshd
- Sudo Events: Privilege escalation và command execution
- Kernel/UFW Firewall: Network traffic block/allow events
- Cron Jobs: Scheduled task execution
Sample Logs
1. SSH Authentication (Failed)
{"@timestamp":"2026-03-17T09:30:15.123Z","message":"<38>1 2026-03-17T09:30:15.123Z webserver01 sshd 12345 - - Failed password for invalid user admin from 192.168.1.100 port 52341 ssh2","timestamp":"2026-03-17T09:30:15.123Z","host":"webserver01"}
2. Kernel UFW Firewall Block
{"@timestamp":"2026-03-17T09:35:22.456Z","message":"<6>1 2026-03-17T09:35:22.456Z dbserver01 kernel - - - [UFW BLOCK] IN=eth0 OUT= MAC=00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd SRC=10.0.0.5 DST=10.0.0.10 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=54321 PROTO=TCP SPT=54321 DPT=22 WINDOW=0 RES=0x00 SYN URGP=0","timestamp":"2026-03-17T09:35:22.456Z","host":"dbserver01"}
3. Cron Job Execution
{"@timestamp":"2026-03-17T10:00:01.789Z","message":"<78>1 2026-03-17T10:00:01.789Z appserver01 CRON 9876 - - (root) CMD (/usr/local/bin/backup.sh)","timestamp":"2026-03-17T10:00:01.789Z","host":"appserver01"}
4. Sudo Privilege Escalation
{"@timestamp":"2026-03-17T10:15:30.321Z","message":"<86>1 2026-03-17T10:15:30.321Z proxyserver01 sudo 5432 - - jdoe : TTY=pts/0 ; PWD=/home/jdoe ; USER=root ; COMMAND=/bin/systemctl restart nginx","timestamp":"2026-03-17T10:15:30.321Z","host":"proxyserver01"}
Transformation Configuration
#regex
#conditional
event_timestamp = .timestamp
host_hostname = ""
process_name = ""
process_pid = ""
log_level = ""
facility = ""
event_message = ""
event_action = ""
event_category = ""
event_outcome = ""
source_ip = ""
source_port = ""
destination_ip = ""
destination_port = ""
user_name = ""
target_user = ""
process_command = ""
process_working_directory = ""
network_transport = ""
event_module = "syslog"
host_str = ""
if (u, err = to_string(.host); err == null) { host_str = u }
msg_str = ""
if (m, err = to_string(.message); err == null) { msg_str = m }
if (syslog, err = parse_syslog(msg_str); err == null) {
host_hostname = to_string(syslog.hostname)
process_name = to_string(syslog.appname)
process_pid = to_string(syslog.procid)
log_level = to_string(syslog.severity)
facility = to_string(syslog.facility)
event_message = to_string(syslog.message)
}
if host_hostname == "" { host_hostname = host_str }
if process_name == "sshd" {
event_category = "authentication"
if contains(event_message, "Failed password") {
event_action = "logon_failed"
event_outcome = "failure"
if (user_m, err = parse_regex(event_message, r'for[ ](?:invalid user )?(?P<user>\S+)[ ]from'); err == null) {
user_name = user_m.user
}
if (ip_m, err = parse_regex(event_message, r'from[ ](?P<ip>\d+\.\d+\.\d+\.\d+)'); err == null) {
source_ip = ip_m.ip
}
if (port_m, err = parse_regex(event_message, r'port[ ](?P<port>\d+)'); err == null) {
source_port = port_m.port
}
}
if contains(event_message, "Accepted") {
event_action = "logon_success"
event_outcome = "success"
if (user_m, err = parse_regex(event_message, r'for[ ](?P<user>\S+)[ ]from'); err == null) {
user_name = user_m.user
}
if (ip_m, err = parse_regex(event_message, r'from[ ](?P<ip>\d+\.\d+\.\d+\.\d+)'); err == null) {
source_ip = ip_m.ip
}
if (port_m, err = parse_regex(event_message, r'port[ ](?P<port>\d+)'); err == null) {
source_port = port_m.port
}
}
if contains(event_message, "session opened") {
event_action = "session_start"
event_outcome = "success"
}
if contains(event_message, "session closed") {
event_action = "session_end"
event_outcome = "success"
}
}
if process_name == "sudo" {
event_category = "iam"
event_action = "privilege_escalation"
event_outcome = "success"
if (sudo_user_m, err = parse_regex(event_message, r'^(?P<user>\S+)\s*:'); err == null) {
user_name = sudo_user_m.user
}
if (target_m, err = parse_regex(event_message, r'USER=(?P<target>\S+)'); err == null) {
target_user = target_m.target
}
if (cmd_m, err = parse_regex(event_message, r'COMMAND=(?P<cmd>.+)$'); err == null) {
process_command = cmd_m.cmd
}
if (pwd_m, err = parse_regex(event_message, r'PWD=(?P<pwd>[^ ;]+)'); err == null) {
process_working_directory = pwd_m.pwd
}
if contains(event_message, "authentication failure") {
event_outcome = "failure"
}
if contains(event_message, "NOT in sudoers") {
event_outcome = "failure"
}
}
if process_name == "kernel" {
event_category = "network"
if contains(event_message, "UFW BLOCK") {
event_action = "firewall_block"
event_outcome = "success"
if (src_m, err = parse_regex(event_message, r'SRC=(?P<src>[0-9.]+)'); err == null) {
source_ip = src_m.src
}
if (dst_m, err = parse_regex(event_message, r'DST=(?P<dst>[0-9.]+)'); err == null) {
destination_ip = dst_m.dst
}
if (spt_m, err = parse_regex(event_message, r'SPT=(?P<spt>\d+)'); err == null) {
source_port = spt_m.spt
}
if (dpt_m, err = parse_regex(event_message, r'DPT=(?P<dpt>\d+)'); err == null) {
destination_port = dpt_m.dpt
}
if (proto_m, err = parse_regex(event_message, r'PROTO=(?P<proto>\w+)'); err == null) {
proto_str = to_string(proto_m.proto)
network_transport = downcase(proto_str)
}
}
if contains(event_message, "UFW ALLOW") {
event_action = "firewall_allow"
event_outcome = "success"
if (src_m, err = parse_regex(event_message, r'SRC=(?P<src>[0-9.]+)'); err == null) {
source_ip = src_m.src
}
if (dst_m, err = parse_regex(event_message, r'DST=(?P<dst>[0-9.]+)'); err == null) {
destination_ip = dst_m.dst
}
if (spt_m, err = parse_regex(event_message, r'SPT=(?P<spt>\d+)'); err == null) {
source_port = spt_m.spt
}
if (dpt_m, err = parse_regex(event_message, r'DPT=(?P<dpt>\d+)'); err == null) {
destination_port = dpt_m.dpt
}
if (proto_m, err = parse_regex(event_message, r'PROTO=(?P<proto>\w+)'); err == null) {
proto_str = to_string(proto_m.proto)
network_transport = downcase(proto_str)
}
}
}
if process_name == "CRON" {
event_category = "process"
event_action = "scheduled_task"
event_outcome = "success"
if (cron_user_m, err = parse_regex(event_message, r'\((?P<user>\w+)\)'); err == null) {
user_name = cron_user_m.user
}
if (cron_cmd_m, err = parse_regex(event_message, r'CMD[ ]\((?P<cmd>[^)]+)\)'); err == null) {
process_command = cron_cmd_m.cmd
}
}
if event_category == "" { event_category = "host" }
if event_action == "" { event_action = "info" }
#normalize
timestamp: format_timestamp!(parse_timestamp!(event_timestamp, "%Y-%m-%dT%H:%M:%S.%3fZ"), "%Y-%m-%d %H:%M:%S")
host.hostname: host_hostname
event.module: event_module
event.category: event_category
event.action: event_action
event.outcome: event_outcome
process.name: process_name
process.pid: process_pid
process.command_line: process_command
process.working_directory: process_working_directory
log.level: log_level
labels: {"syslog_facility": facility, "target_user": target_user}
message: event_message
source.ip: source_ip
source.port: source_port
destination.ip: destination_ip
destination.port: destination_port
user.name: user_name
network.transport: network_transport
Output (ECS Format)
1. SSH Authentication (Failed) Output
{
"timestamp": "2026-03-17 09:30:15",
"host.hostname": "webserver01",
"event.module": "syslog",
"event.category": "authentication",
"event.action": "logon_failed",
"event.outcome": "failure",
"process.name": "sshd",
"process.pid": "12345",
"log.level": "info",
"labels": {"syslog_facility": "auth", "target_user": ""},
"message": "Failed password for invalid user admin from 192.168.1.100 port 52341 ssh2",
"source.ip": "192.168.1.100",
"source.port": "52341",
"user.name": "admin"
}
2. Kernel UFW Firewall Block Output
{
"timestamp": "2026-03-17 09:35:22",
"host.hostname": "dbserver01",
"event.module": "syslog",
"event.category": "network",
"event.action": "firewall_block",
"event.outcome": "success",
"process.name": "kernel",
"log.level": "info",
"labels": {"syslog_facility": "kern", "target_user": ""},
"message": "[UFW BLOCK] IN=eth0 OUT= MAC=... SRC=10.0.0.5 DST=10.0.0.10 ... PROTO=TCP SPT=54321 DPT=22 ...",
"source.ip": "10.0.0.5",
"source.port": "54321",
"destination.ip": "10.0.0.10",
"destination.port": "22",
"network.transport": "tcp"
}
3. Cron Job Execution Output
{
"timestamp": "2026-03-17 10:00:01",
"host.hostname": "appserver01",
"event.module": "syslog",
"event.category": "process",
"event.action": "scheduled_task",
"event.outcome": "success",
"process.name": "CRON",
"process.pid": "9876",
"process.command_line": "/usr/local/bin/backup.sh",
"log.level": "info",
"labels": {"syslog_facility": "cron", "target_user": ""},
"message": "(root) CMD (/usr/local/bin/backup.sh)",
"user.name": "root"
}
4. Sudo Privilege Escalation Output
{
"timestamp": "2026-03-17 10:15:30",
"host.hostname": "proxyserver01",
"event.module": "syslog",
"event.category": "iam",
"event.action": "privilege_escalation",
"event.outcome": "success",
"process.name": "sudo",
"process.pid": "5432",
"process.command_line": "/bin/systemctl restart nginx",
"process.working_directory": "/home/jdoe",
"log.level": "info",
"labels": {"syslog_facility": "authpriv", "target_user": "root"},
"message": "jdoe : TTY=pts/0 ; PWD=/home/jdoe ; USER=root ; COMMAND=/bin/systemctl restart nginx",
"user.name": "jdoe"
}