Parser Example
Linux Audit
Linux Audit
Overview
Parser xử lý các loại audit log từ Linux Audit (auditd):
- SYSCALL: System call events - theo dõi process execution
- USER_AUTH: Authentication events - xác thực PAM
- USER_LOGIN: Login events - đăng nhập SSH/console với source IP
- EXECVE: Command execution - chi tiết command line
- CRED_ACQ: Credential acquisition - lấy credentials
Sample Logs
1. SYSCALL Log
{"@timestamp":"2026-03-17T08:15:23.456Z","message":"type=SYSCALL msg=audit(1741234523.456:98765): arch=c000003e syscall=59 success=yes exit=0 a0=7ffd1234abcd a1=7ffd5678efab a2=7ffd9abcdef0 a3=0 items=2 ppid=1234 pid=5678 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=123 comm=\"sudo\" exe=\"/usr/bin/sudo\" key=\"privilege_escalation\"","timestamp":"2026-03-17T08:15:23.456Z","host":"web-server-01"}
2. USER_AUTH Log
{"@timestamp":"2026-03-17T08:16:45.789Z","message":"type=USER_AUTH msg=audit(1741234605.789:98766): pid=5679 uid=0 auid=1000 ses=123 msg='op=PAM:authentication grantors=pam_unix acct=\"root\" exe=\"/usr/bin/sudo\" hostname=? addr=? terminal=/dev/pts/0 res=success'","timestamp":"2026-03-17T08:16:45.789Z","host":"web-server-01"}
3. USER_LOGIN Log
{"@timestamp":"2026-03-17T08:18:30.123Z","message":"type=USER_LOGIN msg=audit(1741234710.123:98767): pid=5680 uid=0 auid=1001 ses=124 msg='op=login id=1001 exe=\"/usr/sbin/sshd\" hostname=192.168.1.100 addr=192.168.1.100 terminal=/dev/pts/1 res=success'","timestamp":"2026-03-17T08:18:30.123Z","host":"web-server-01"}
4. EXECVE Log
{"@timestamp":"2026-03-17T08:20:15.456Z","message":"type=EXECVE msg=audit(1741234815.456:98768): argc=3 a0=\"/bin/bash\" a1=\"-c\" a2=\"cat /etc/passwd\"","timestamp":"2026-03-17T08:20:15.456Z","host":"web-server-01"}
Parser Configuration
#regex
#conditional
event_timestamp = .timestamp
host_hostname = ""
event_type = ""
event_category = ""
event_action = ""
event_outcome = ""
event_code = ""
audit_msg_id = ""
process_pid = ""
process_ppid = ""
process_name = ""
process_executable = ""
process_tty = ""
user_id = ""
user_audit_id = ""
user_effective_id = ""
user_saved_id = ""
user_fs_id = ""
user_name = ""
group_id = ""
source_ip = ""
session_id = ""
event_module = "auditd"
host_str = ""
if (h, err = to_string(.host); err == null) { host_str = h }
host_hostname = host_str
msg_str = ""
if (m, err = to_string(.message); err == null) { msg_str = m }
if (type_m, err = parse_regex(msg_str, r'type=(?P<type>[A-Z_]+)'); err == null) {
event_code = type_m.type
}
if (msgid_m, err = parse_regex(msg_str, r'msg=audit\([\d.]+:(?P<id>\d+)\)'); err == null) {
audit_msg_id = msgid_m.id
}
if (ses_m, err = parse_regex(msg_str, r'ses=(?P<ses>\d+)'); err == null) {
session_id = ses_m.ses
}
if contains(msg_str, "type=SYSCALL") {
event_category = "process"
event_type = "start"
event_action = "syscall"
if (pid_m, err = parse_regex(msg_str, r' pid=(?P<pid>\d+)'); err == null) {
process_pid = pid_m.pid
}
if (ppid_m, err = parse_regex(msg_str, r'ppid=(?P<ppid>\d+)'); err == null) {
process_ppid = ppid_m.ppid
}
if (uid_m, err = parse_regex(msg_str, r' uid=(?P<uid>\d+)'); err == null) {
user_id = uid_m.uid
}
if (auid_m, err = parse_regex(msg_str, r'auid=(?P<auid>\d+)'); err == null) {
user_audit_id = auid_m.auid
}
if (euid_m, err = parse_regex(msg_str, r'euid=(?P<euid>\d+)'); err == null) {
user_effective_id = euid_m.euid
}
if (suid_m, err = parse_regex(msg_str, r'suid=(?P<suid>\d+)'); err == null) {
user_saved_id = suid_m.suid
}
if (fsuid_m, err = parse_regex(msg_str, r'fsuid=(?P<fsuid>\d+)'); err == null) {
user_fs_id = fsuid_m.fsuid
}
if (gid_m, err = parse_regex(msg_str, r' gid=(?P<gid>\d+)'); err == null) {
group_id = gid_m.gid
}
if (tty_m, err = parse_regex(msg_str, r'tty=(?P<tty>[^ ]+)'); err == null) {
process_tty = tty_m.tty
}
if (comm_m, err = parse_regex(msg_str, r'comm="(?P<comm>[^"]+)"'); err == null) {
process_name = comm_m.comm
}
if (comm_m2, err = parse_regex(msg_str, r'comm=(?P<comm>[^ ]+)'); err == null) {
if process_name == "" { process_name = comm_m2.comm }
}
if (exe_m, err = parse_regex(msg_str, r'exe="(?P<exe>[^"]+)"'); err == null) {
process_executable = exe_m.exe
}
if (exe_m2, err = parse_regex(msg_str, r'exe=(?P<exe>[^ ]+)'); err == null) {
if process_executable == "" { process_executable = exe_m2.exe }
}
if (success_m, err = parse_regex(msg_str, r'success=(?P<success>[^ ]+)'); err == null) {
if success_m.success == "yes" { event_outcome = "success" }
if success_m.success == "no" { event_outcome = "failure" }
}
}
if contains(msg_str, "type=USER_AUTH") {
event_category = "authentication"
event_type = "start"
event_action = "user_auth"
if (pid_m, err = parse_regex(msg_str, r'pid=(?P<pid>\d+)'); err == null) {
process_pid = pid_m.pid
}
if (uid_m, err = parse_regex(msg_str, r' uid=(?P<uid>\d+)'); err == null) {
user_id = uid_m.uid
}
if (auid_m, err = parse_regex(msg_str, r'auid=(?P<auid>\d+)'); err == null) {
user_audit_id = auid_m.auid
}
if (acct_m, err = parse_regex(msg_str, r'acct="(?P<acct>[^"]+)"'); err == null) {
user_name = acct_m.acct
}
if (exe_m, err = parse_regex(msg_str, r'exe="(?P<exe>[^"]+)"'); err == null) {
process_executable = exe_m.exe
}
if (tty_m, err = parse_regex(msg_str, r'terminal=(?P<tty>[^ ]+)'); err == null) {
process_tty = tty_m.tty
}
if (res_m, err = parse_regex(msg_str, r'res=(?P<res>\w+)'); err == null) {
if res_m.res == "success" { event_outcome = "success" }
if res_m.res == "failed" { event_outcome = "failure" }
}
}
if contains(msg_str, "type=USER_LOGIN") {
event_category = "authentication"
event_type = "start"
event_action = "user_login"
if (pid_m, err = parse_regex(msg_str, r'pid=(?P<pid>\d+)'); err == null) {
process_pid = pid_m.pid
}
if (uid_m, err = parse_regex(msg_str, r' uid=(?P<uid>\d+)'); err == null) {
user_id = uid_m.uid
}
if (auid_m, err = parse_regex(msg_str, r'auid=(?P<auid>\d+)'); err == null) {
user_audit_id = auid_m.auid
}
if (id_m, err = parse_regex(msg_str, r' id=(?P<id>\d+)'); err == null) {
user_effective_id = id_m.id
}
if (exe_m, err = parse_regex(msg_str, r'exe="(?P<exe>[^"]+)"'); err == null) {
process_executable = exe_m.exe
}
if (addr_m, err = parse_regex(msg_str, r'addr=(?P<addr>[0-9.]+)'); err == null) {
source_ip = addr_m.addr
}
if (tty_m, err = parse_regex(msg_str, r'terminal=(?P<tty>[^ ]+)'); err == null) {
process_tty = tty_m.tty
}
if (res_m, err = parse_regex(msg_str, r'res=(?P<res>\w+)'); err == null) {
if res_m.res == "success" { event_outcome = "success" }
if res_m.res == "failed" { event_outcome = "failure" }
}
}
if contains(msg_str, "type=EXECVE") {
event_category = "process"
event_type = "start"
event_action = "execve"
event_outcome = "success"
if (a0_m, err = parse_regex(msg_str, r'a0="(?P<a0>[^"]+)"'); err == null) {
process_executable = a0_m.a0
}
if (a0_m2, err = parse_regex(msg_str, r'a0=(?P<a0>[^ ]+)'); err == null) {
if process_executable == "" { process_executable = a0_m2.a0 }
}
}
if contains(msg_str, "type=CRED_ACQ") {
event_category = "iam"
event_type = "change"
event_action = "credential_acquired"
if (pid_m, err = parse_regex(msg_str, r'pid=(?P<pid>\d+)'); err == null) {
process_pid = pid_m.pid
}
if (uid_m, err = parse_regex(msg_str, r' uid=(?P<uid>\d+)'); err == null) {
user_id = uid_m.uid
}
if (auid_m, err = parse_regex(msg_str, r'auid=(?P<auid>\d+)'); err == null) {
user_audit_id = auid_m.auid
}
if (res_m, err = parse_regex(msg_str, r'res=(?P<res>\w+)'); err == null) {
if res_m.res == "success" { event_outcome = "success" }
if res_m.res == "failed" { event_outcome = "failure" }
}
}
#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.code: event_code
event.id: audit_msg_id
event.category: event_category
event.type: event_type
event.action: event_action
event.outcome: event_outcome
process.pid: process_pid
process.ppid: process_ppid
process.name: process_name
process.executable: process_executable
process.tty: process_tty
user.id: user_id
user.audit.id: user_audit_id
user.effective.id: user_effective_id
user.saved.id: user_saved_id
user.fs.id: user_fs_id
user.name: user_name
group.id: group_id
source.ip: source_ip
Output (ECS Format)
1. SYSCALL Output
{
"timestamp": "2026-03-17T08:15:23.456Z",
"host.hostname": "web-server-01",
"event.module": "auditd",
"event.code": "SYSCALL",
"event.id": "98765",
"event.category": "process",
"event.type": "start",
"event.action": "syscall",
"event.outcome": "success",
"process.pid": "5678",
"process.ppid": "1234",
"process.name": "sudo",
"process.executable": "/usr/bin/sudo",
"process.tty": "pts0",
"user.id": "0",
"user.audit.id": "1000",
"user.effective.id": "0",
"user.saved.id": "0",
"user.fs.id": "0",
"group.id": "0",
"session.id": "123"
}
2. USER_AUTH Output
{
"timestamp": "2026-03-17T08:16:45.789Z",
"host.hostname": "web-server-01",
"event.module": "auditd",
"event.code": "USER_AUTH",
"event.id": "98766",
"event.category": "authentication",
"event.type": "start",
"event.action": "user_auth",
"event.outcome": "success",
"process.pid": "5679",
"process.executable": "/usr/bin/sudo",
"process.tty": "/dev/pts/0",
"user.id": "0",
"user.audit.id": "1000",
"user.name": "root",
"session.id": "123"
}
3. USER_LOGIN Output
{
"timestamp": "2026-03-17T08:18:30.123Z",
"host.hostname": "web-server-01",
"event.module": "auditd",
"event.code": "USER_LOGIN",
"event.id": "98767",
"event.category": "authentication",
"event.type": "start",
"event.action": "user_login",
"event.outcome": "success",
"process.pid": "5680",
"process.executable": "/usr/sbin/sshd",
"process.tty": "/dev/pts/1",
"user.id": "0",
"user.audit.id": "1001",
"user.effective.id": "1001",
"source.ip": "192.168.1.100",
"session.id": "124"
}
4. EXECVE Output
{
"timestamp": "2026-03-17T08:20:15.456Z",
"host.hostname": "web-server-01",
"event.module": "auditd",
"event.code": "EXECVE",
"event.id": "98768",
"event.category": "process",
"event.type": "start",
"event.action": "execve",
"event.outcome": "success",
"process.executable": "/bin/bash"
}
Notes
VRL Functions Used
Parser chỉ sử dụng các functions được phép trong VRL Functions.md:
to_string(): Chuyển đổi giá trị sang stringparse_regex(): Parse với regex có named capture groupscontains(): Kiểm tra string có chứa substring
Event Type Detection Logic
- SYSCALL:
contains(message, "type=SYSCALL") - USER_AUTH:
contains(message, "type=USER_AUTH") - USER_LOGIN:
contains(message, "type=USER_LOGIN") - EXECVE:
contains(message, "type=EXECVE") - CRED_ACQ:
contains(message, "type=CRED_ACQ")
User ID Fields (Linux Audit)
| Field | Description |
|---|---|
| uid | Real UID - actual user ID |
| auid | Audit UID - original login user (persists across su/sudo) |
| euid | Effective UID - permission check ID |
| suid | Saved UID - previous euid before setuid |
| fsuid | Filesystem UID - file access check ID |
Event Categories (ECS)
| Audit Type | event.category | event.type | event.action |
|---|---|---|---|
| SYSCALL | process | start | syscall |
| USER_AUTH | authentication | start | user_auth |
| USER_LOGIN | authentication | start | user_login |
| EXECVE | process | start | execve |
| CRED_ACQ | iam | change | credential_acquired |
Security Use Cases
- Privilege Escalation Detection: Monitor SYSCALL with uid=0 and auid != 0
- Failed Login Tracking: USER_LOGIN/USER_AUTH with res=failed
- Command Auditing: EXECVE events show full command execution
- SSH Session Tracking: USER_LOGIN events include source.ip