Fixed
- Debian version comparison now stops at a NUL byte, as dpkg does. Before, such a version could break the ordering. Found by fuzzing.
- Go version comparison no longer depends on argument order when two prerelease numbers are equal but written differently, such as
rc.1andrc.01. Found by fuzzing. authorized_keyslines: after the key type, the key and comment are split on whitespace alone, as sshd does, so a stray quote can no longer pull spaces into the key. Found by fuzzing.
Added
- A Stack tab listing the databases (PostgreSQL, MySQL, MariaDB, Redis, Valkey, MongoDB, SQLite), language runtimes (Node.js, Python, Ruby, Java, PHP, Go) and servers (nginx, Apache, HAProxy, Docker, containerd) on the host. It finds them in packages, version managers such as nvm, pyenv and SDKMAN!, hand-unpacked installs, Docker containers and running processes, and says whether each listens beyond loopback. A release past its end of life is Medium, or High when it listens beyond loopback. Ubuntu's own packages are not judged by upstream dates. JSON reports carry the list as
stack. - Fuzz tests for the parsers of host content and for both version orders, run with
make fuzz. The Debian order is also checked against dpkg itself.
Fixed
- systemd unit escapes that systemd rejects, such as
\777or\UFFFFFFFF, were decoded into other bytes. They now stand for themselves, so the command the persistence checks judge matches what systemd reads. Found by CodeQL.
Added
- Each release carries its build provenance attestation as
ubuntu-sys-audit.sigstore.json, sogh attestation verify --bundlechecks a binary without a GitHub login. The bundles of v0.1.4 to v0.1.16 were attached afterwards. - A security policy (SECURITY.md) with private vulnerability reporting, plus CodeQL, Dependabot and OpenSSF Scorecard for the repository.
- systemd unit escapes that systemd rejects, such as
Added
web.tls.default_cert: the tool makes a TLS handshake without a server name to the host's own HTTPS ports, as Censys and Shodan do, and reports High when the certificate names a domain. That ties the server's address to its domains, even behind Cloudflare. No request is sent.
Changed
- When
integrity.binaries_otherlists a replaced Caddy binary, it says which Caddy build now holds the path and the usual causes. Reinstall advice names the real packages.
- When
Fixed
- Files listed with a leading
./in a package's md5sums, as in Caddy's packages up to 2.10.2, were skipped by the binary hash check. A Caddy binary swapped bycaddy upgradeis now caught, by its hash or by a version that differs from the package's.
- Files listed with a leading
Fixed
- An xcaddy build copied over the packaged
/usr/bin/caddywas labeled as Caddy's apt repository build, with advice toapt upgrade, which would remove its plugins. It is now reported as self-compiled, with advice to install custom builds beside the package.
- An xcaddy build copied over the packaged
Added
- Caddy checks. The version, Go toolchain and plugins are read from the binary without running it, including xcaddy builds and a Caddy in a container. Builds other than Ubuntu's are compared against Go's vulnerability database. The admin API on a non-loopback address is Critical, configuration that sets it is High, and directory listing is Medium. Caddy's site roots join the webshell scan.
Added
--cve CVE-ID,...answers single CVEs for the host from Canonical's CVE OVAL feed, including ones with no fix released yet. An affected host gets the CVE's priority as severity, and exit code 2 marks hosts a High or Critical CVE reaches.
Added
- Commands that run automatically from logrotate scripts, network hooks (ifupdown, networkd-dispatcher, NetworkManager, dhclient, pppd),
/etc/anacrontab,/etc/cron.yearlyand/etc/xdg/autostart.
Fixed
- The notice that reading BPF filters made the kernel load
af_packet_diagnever appeared, because the check looked for the wrong module name.
- Commands that run automatically from logrotate scripts, network hooks (ifupdown, networkd-dispatcher, NetworkManager, dhclient, pppd),
Added
- systemd persistence: generators, transient units, lingering users and their user units, units that set
LD_PRELOAD,LD_LIBRARY_PATHorLD_AUDIT, and drop-ins that replace a packaged unit'sExecStart.
Changed
- Exec lines are read the way systemd reads them, including continuations, quotes and escapes.
- systemd persistence: generators, transient units, lingering users and their user units, units that set
Added
- Name resolution tampering:
/etc/hostsentries that override Ubuntu's domains, NSS modules outside package management and TCP Wrappers rules that run commands. - Tunnel interfaces with the programs holding them, IP forwarding nothing explains, and unusual default routes.
- More exposed services (etcd, the Kubernetes API, RabbitMQ, Prometheus, rsync, RDP, CUPS, SNMP) and kernel parameters (
rp_filter,send_redirects, IPv6 redirects and source routes).
- Name resolution tampering:
Added
- Firewall gaps: ufw allowing incoming traffic by default, public IPv6 listeners ufw leaves unfiltered, and containers publishing ports around it.
- Rarely used network protocols that are loaded or can be auto-loaded, and unprivileged user namespaces.
Fixed
- ARM hosts got Intel and AMD microcode advice for unmitigated CPU vulnerabilities. They now get kernel and firmware advice.
Changed
- The project is released under the MIT License. Building requires Go 1.27.3.
Changed
- The TUI figure is now a hooded hacker that reacts when a Critical or High finding turns up.
Added
- An animated opening screen and a figure beside the check list in the TUI. Any key skips the opening screen, which costs no scan time.
Added
- LXD checks. The snap, which USN data does not cover, is compared against Canonical's LXD advisories and its branch's latest version. Unsupported branches, an API on a non-loopback address and containers that can escape to the host are reported.
- Exit code 3 when a check did not finish, so an incomplete scan no longer looks clean.
Fixed
- Missed detections and false alarms found in a review, including sshd_config parsing (
=andMatchblocks), password fields in/etc/passwd, sudo's!authenticate, binaries in/binon hosts without merged/usr, and empty or wrong-release OVAL data. - File handling a local user could abuse: files are type-checked before opening, so FIFOs and devices are never opened, and
-oonly creates new files where the sudo user can write.
Changed
- Releases are built with the latest Go, gated on govulncheck, and carry build provenance attestations.
Added
- MPTCP enabled is reported as Medium, with the commands to turn it off and a warning when sockets use it.
Fixed
- From 22.04 on,
systemd-udevdis a symlink toudevadm, so every host with udev got a Critical masquerading process finding. A packaged symlink to the running packaged binary is now exempt, while one made by an attacker is still reported.
- From 22.04 on,
Fixed
- The scan screen overflowed small terminals.
Added
- First release: a read-only security audit for Ubuntu 18.04 to 26.04 as one static binary, with a terminal UI and text and JSON output for runs over SSH. It checks missing CVE fixes against Canonical's USN data, port 53 listeners, BPFDoor-style packet filters, webshells, tampered binaries, persistence, accounts, SSH and filesystem issues, and never runs a program from the host.