Azure Vulnerability
Management Lab

By Mohamed Ali Krichen
MS AZURE NESSUS OPENVAS LYNIS CIS-CAT DEFENDER FOR CLOUD

This is not a step-by-step deployment tutorial, but rather a documentation of what I implemented and the results I achieved. While you may be able to follow along and set up your own deployment, some components and configurations are not fully detailed here, such as the Azure resource deployment/scan tools setup/exact scanning process. Every finding has a traceable path from discovery to remediation. The methodology is simple: scan->analyze->harden->verify.

Overview

This lab covers the full vulnerability management lifecycle on two freshly deployed Azure VMs. The Ubuntu machine doubles as both a target and a scanner host. The Windows machine is a standalone target with no domain infrastructure. Both were assessed from an external Kali Linux host using credentialed scans, then hardened based on the findings, then re-scanned to confirm improvement.

You can find all the raw and detailed results of the scans performed during this project on my Github repo: github.com/dalli-krichen/azure-vulnerability-management-lab

1. Azure Infrastructure

A dedicated resource group DalliRG was created in the France Central region under an Azure Free Tier subscription. A virtual network vnet1 connects both VMs on the same private subnet, allowing them to communicate internally at 10.0.0.0/24.

Opening the NSG — Allowing the Scanner In

Azure NSGs block all inbound traffic by default. An inbound rule named Allow-Kali-Scanner was added at priority 100 to both VMs' NSGs, allowing all traffic from the Kali public IP 41.62.86.217.

Windows Local Firewall

The Azure NSG alone isn't enough for Windows — the OS-level Windows Defender Firewall also blocks inbound by default. A PowerShell rule was added to allow inbound connections from the Kali IP across all protocols.

2. Building the Scanner Stack

Lynis

Installed directly on the Ubuntu VM via apt. Lynis audits the local system from the inside — no network scan, no agent. It checks SSH config, PAM, kernel parameters, file permissions, services, and more, then produces a hardening index score.

Nessus Essentials

Downloaded from the Tenable website and installed on the Kali VM. Exposes a web interface at https://localhost:8834. Credentialed scans give Nessus OS-level access to inspect services, packages, and configuration from the inside — not just open ports.

Downloading via curl and confirming the output:

CIS-CAT Lite (v4.60)

Free compliance assessment tool from the Center for Internet Security. The zip was transferred to both VMs — SCP to Ubuntu, RDP file copy to Windows. On Ubuntu, navigating to the Assessor directory and running the CLI revealed a Java version conflict that needed fixing before it would execute. On Windows, the .bat launcher failed silently so the GUI version was used instead.

Transferring CIS-CAT to the Ubuntu VM and navigating to the Assessor directory:

Copying CIS-CAT to the Windows VM:

Running on Ubuntu — Java reflective access warnings, but the tool starts and lists available benchmarks. Ubuntu 24.04 LTS selected:

Java conflict on first attempt — wrong JDK version:

Switching to Oracle JDK resolves it:

CIS-CAT Ubuntu baseline result in the terminal — 64.66%:

CIS-CAT on Windows — GUI auto-detects the OS and prompts with the correct benchmark:

Interactive assessment running and completing on Windows:

OpenVAS via Docker

The initial plan was to run OpenVAS directly on Kali. After setup, the feed sync blocked all scans with no progress for several hours — a resource limitation on the local Kali VM.

OpenVAS on Kali — feed syncing, scans blocked:

The scanner was migrated to the Ubuntu cloud VM using Docker. The Ubuntu OS disk was first expanded from 32GB to 64GB in Azure to accommodate the container image and feeds.

Feed stuck on local Kali — the migration trigger:

Docker container running — OpenVAS login page (immauss image):

Feed successfully updated on the Docker container:

Allow Redis to use more memory, then pull and start the container
sudo sysctl vm.overcommit_memory=1
sudo docker run -d --name openvas -p 9392:9392 \
  -e PASSWORD="admin123" immauss/openvas
SSH tunnel to reach the OpenVAS web UI from a local browser
ssh -L 9392:localhost:9392 [email protected]

Creating scan tasks for both VMs:

Microsoft Defender for Cloud

Azure-native security posture management — no installation required. Enabled at the subscription level, it continuously assesses both VMs against the Microsoft Cloud Security Benchmark and surfaces actionable recommendations.

3. Establishing the Baseline

Before touching any configuration, all five tools were run in sequence to capture the exact pre-hardening state.

Lynis — Ubuntu

Baseline hardening index: 60/100. Key deficiencies: no firewall active, no intrusion detection, no password complexity policy, no audit trail, no malware scanner, and several unnecessary kernel modules loaded. Lynis flags these as WARNINGs and SUGGESTIONs in the output.

Lynis warnings and suggestions grep — the specific items to address:

CIS-CAT — Ubuntu Benchmark

Assessed against the CIS Level 1 Server benchmark for Ubuntu 24.04. Baseline: 64.66% — 82 controls failing out of 232 scored.

CIS-CAT — Windows Benchmark

Assessed against both the CIS Enterprise Benchmark and IG1 controls. Enterprise baseline: 22.43%. Low but expected — 261 of 370 controls require Active Directory GPO and are not applicable to a standalone machine.

Nessus — Ubuntu (Credentialed)

The uncredentialed scan found little beyond open ports. The credentialed scan, logged in via SSH, surfaced actionable findings around SSH cipher suites and MAC algorithms.

Nessus — Windows (Credentialed)

Key Medium finding: SMB Signing not required (CVSS 5.3). Without mandatory signing, an attacker on the network could perform SMB relay attacks — capturing and replaying authentication traffic without cracking a password.

OpenVAS — Both VMs

Scans ran against both internal IPs — 20 to 30 minutes each. Both tasks completed: Ubuntu returned 3 Low findings, Windows returned 1 Medium.

Microsoft Defender for Cloud — Baseline

24 Low-severity recommendations at baseline across missing monitoring agents, NSG exposure, and guest configuration gaps. Zero critical or high alerts.

4. Closing the Gaps

Every change below is directly linked to a finding from the baseline scans. Nothing was changed speculatively — each fix has a source tool, a severity, and a before/after verification.

Ubuntu — SSH Hardening

The default SSH config on Ubuntu 24.04 is permissive: root login allowed, password auth enabled, no session limits, X11 forwarding on. A drop-in config at /etc/ssh/sshd_config.d/hardening.conf overrides these cleanly without touching the main file.

Default Ubuntu SSH config before hardening
Include /etc/ssh/sshd_config.d/*.conf
KbdInteractiveAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
Drop-in hardening config — replaces all defaults above
sudo tee /etc/ssh/sshd_config.d/hardening.conf << 'EOF'
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PermitEmptyPasswords no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
MaxAuthTries 3
MaxSessions 2
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
TCPKeepAlive no
LogLevel VERBOSE
PrintLastLog yes
Banner /etc/issue.net
MACs hmac-sha2-256,hmac-sha2-512,[email protected],[email protected]
AllowUsers dalli
EOF

Since password auth was being disabled, key-based login had to be set up first. ED25519 key pair generated on Windows:

Public key added to Ubuntu's authorized_keys and confirmed:

Password auth disabled in the config, sshd restarted, change verified:

Ubuntu — UFW Firewall

UFW was installed but not enabled — Lynis flagged FIRE-4512. Default-deny inbound, SSH only from the Kali IP, full access from the VNet subnet.

UFW rules — default deny, whitelist only known sources
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 41.62.86.217 to any port 22
sudo ufw allow from 10.0.0.0/24
sudo ufw --force enable

Ubuntu — Password Policy

CIS requires minimum 14-character passwords with complexity and 24-password history. Configured via PAM's pwquality module and /etc/login.defs.

Password complexity in /etc/security/pwquality.conf
minlen = 14
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
maxrepeat = 3
enforce_for_root
Password aging in /etc/login.defs
PASS_MAX_DAYS 365
PASS_MIN_DAYS 7
PASS_WARN_AGE 14
UMASK 027

Ubuntu — fail2ban, Unused Protocols, auditd, rkhunter

fail2ban: 3-attempt ban, 1-hour duration on SSH. Kernel protocols dccp, sctp, rds, tipc blacklisted via modprobe. auditd installed with custom rules on sensitive files. rkhunter installed with initial baseline.

auditd rules targeting sensitive files and execve syscalls
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/ssh/sshd_config -p wa -k sshd
-w /var/log/auth.log -p wa -k auth
-a always,exit -F arch=b64 -S execve -k exec

Ubuntu — Kernel Hardening

Persistent sysctl settings at /etc/sysctl.d/hardening.conf. Disabling TCP timestamps directly remediates the OpenVAS TCP Timestamps finding (CVSS 2.6). ICMP broadcast disabled remediates the ICMP Timestamp finding (CVSS 2.1).

Key sysctl settings applied on every boot
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.log_martians = 1
kernel.randomize_va_space = 2
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2

Lynis intermediate check after SSH and firewall hardening — already at 76 before the remaining steps:

CIS-CAT reports saved locally after baseline and after hardening — both HTML files present:

Windows — Round 1: Core Security Controls

CONTEXT 261 of 370 CIS Enterprise controls assume a domain-joined machine with Group Policy. Since this is a standalone Azure VM, those controls are not applicable.
Enable auditing across all key subcategories
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Account Lockout" /success:enable /failure:enable
auditpol /set /subcategory:"Sensitive Privilege Use" /success:enable /failure:enable
auditpol /set /subcategory:"System Integrity" /success:enable /failure:enable
Require SMB signing on both server and workstation — fixes Nessus Medium (CVSS 5.3)
reg add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" /v RequireSecuritySignature /t REG_DWORD /d 1 /f
reg add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v RequireSecuritySignature /t REG_DWORD /d 1 /f

Additional Round 1: LmCompatibilityLevel set to 5 (NTLMv2 only), LM hash storage disabled, Windows Firewall enabled on all profiles, AutoRun disabled, 15-minute screen lock, UAC fully enforced, WDigest auth disabled, RemoteRegistry and Print Spooler stopped.

Windows — Round 2: Second Pass

CIS-CAT re-run after Round 1 — score at 30.27%. A second targeted script addressed remaining failures, pushing it to 62.16%.

Force TLS security layer and NLA on RDP — fixes OpenVAS deprecated TLS (CVSS 4.3)
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v UserAuthentication /t REG_DWORD /d 1 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v SecurityLayer /t REG_DWORD /d 2 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v MinEncryptionLevel /t REG_DWORD /d 3 /f

Additional Round 2: 11 unnecessary services disabled, firewall logging on all profiles, NTLM session security hardened, mDNS and LLMNR disabled, WinRM hardened, LSA Protection enabled, Defender hardened via policy.

Defender for Cloud — Fixes Applied

5. Verifying the Fixes

All five tools re-run after hardening. Every result maps directly to the baseline — same scan config, same targets.

Lynis — Ubuntu After

Hardening index improved from 60 to 78 — an 18-point gain. Remaining gap is Azure infrastructure constraints: no separate /tmp partition, no AppArmor profiles, no bootloader password, platform-managed NTP.

CIS-CAT — Ubuntu After

Overall score improved from 64.66% to 87.07%. Host-Based Firewall jumped from 0% to 92%, Logging from ~40% to 88%.

CIS-CAT — Windows After

Enterprise benchmark improved from 22.43% to 62.16% across two rounds. System Services and Advanced Audit Policy both reached 100%.

OpenVAS — Both VMs After

Zero Critical, High, Medium, or Low findings on either VM. Every baseline finding fully remediated.

Nessus — Post-Hardening Credential Setup

Password auth was disabled on Ubuntu during hardening, so the Nessus credential had to switch from password to SSH public key with sudo privilege escalation.

Nessus — Windows After

A new High finding appeared post-hardening: SWEET32 (CVSS 7.5) on RDP port 3389. Not present before — it surfaced because the RDP hardening changes altered cipher negotiation, making the 3DES birthday attack vulnerability visible. The fix (disabling 3DES/RC4 via SCHANNEL) is documented as a known residual risk, not applied within this lab scope.

Nessus — Ubuntu After

15 total findings — all INFO severity. Zero Medium, High, or Critical. Nothing actionable.

Microsoft Defender for Cloud — After

Secure Score reached 25%, 45 of 63 MCSB controls passing, zero security alerts. Recommendation count went from 24 to 26 — the two new items are Defender preview recommendations added by Azure over time, not regressions.

6. The Full Picture

Finding → Fix → Verification

What Worked

Limitations & Residual Risks