Write an Automated Script to Perform a Vulnerability Scan and Log the Results

1.25 hours
  • 4 Learning Objectives

About this Hands-on Lab

When we have multiple instances of an Apache web server, we generally need to run a vulnerability scan for each of our instances on a regular basis. It’s best to write an automated script to perform this task to reduce the human error factor and get consistent results running exactly the same sets of tests on each instance. This lab does precisely that and configures the script to generate a log file containing a report. In addition to this, the script should not necessarily scan for just vulnerabilities. It should also report on the operating system, version of the operating system, version of the Apache server, status of SELinux, status of the firewall, firewall rules, etc. Why is this important? Because in addition to figuring out whether or not our system is vulnerable, we might also want to know whether or not the security mechanisms of the system are functional.

Learning Objectives

Successfully complete this lab by achieving the following learning objectives:

Define Functions to Retrieve Server Information

Create and open a file /home/cloud_user/ourScript.py.

vim /home/cloud_user/ourScript.py

Define which interpreter is to be used for the script.

import subprocess
import socket

Get Apache web server version.

def get_apache_version():       
    return subprocess.check_output(['httpd', '-v'], stdin=None, stderr=None, shell=False, universal_newlines=True)

Get SELinux status.

def get_selinux_status():
    return subprocess.check_output(['getenforce'], stdin=None, stderr=None, shell=False, universal_newlines=True)

Get the current firewall configuration for the default zone.

def get_firewall_rules():
    return subprocess.check_output(['firewall-cmd', '--list-all'], stdin=None, stderr=None, shell=False, universal_newlines=True)

Create a function to find a line containing a string in a file.

def find_line_in_file(file_path, str_to_find):
        for line in open(file_path):
                if str_to_find in line:
                        return line

Get the port number from the ssh configuration file.

sshd_config = "/etc/ssh/sshd_config"
def get_ssh_port():
    return find_line_in_file(sshd_config, "Port")

Get PermitRootLogin.

def get_root_login():
    return find_line_in_file(sshd_config, "PermitRootLogin")
Write Additional Functions to Retrieve Server Information

Get the value of PasswordAuthentication.

def get_ssh_password_config():
    return find_line_in_file(sshd_config, "PasswordAuthentication")

Get the ports in ssh_port_t.

def get_selinux_ssh_port_label():
return subprocess.check_output(['sepolicy', 'network', '-t', 'ssh_port_t'], stdin=None, stderr=None, shell=False, universal_newlines=True)

Get the public IP address of the server.

def get_server_IP():
    s = socket.socket(socket.AF_INET,   socket.SOCK_DGRAM)
    s.connect(("", 80))
    return s.getsockname()[0]

Save and quit.

Write a Function to Perform an Nmap Scan

Install Nmap.

sudo yum install nmap

Change directory to /usr/share/nmap/scripts/.

cd /usr/share/nmap/scripts/

Clone https://github.com/vulnersCom/nmap-vulners.git and https://github.com/scipag/vulscan.git

sudo git clone https://github.com/vulnersCom/nmap-vulners.git
sudo git clone https://github.com/scipag/vulscan.git
vim /home/cloud_user/ourScript.py
def vuln_scan():
    serverIP = get_server_IP() 
    return subprocess.check_output(['nmap', '--script', 'vulscan', '--script-args', 'vulscandb=scipvuldb.csv', '-sV', '-p80', serverIP], stdin=None, stderr=None, shell=False, universal_newlines=True)
Generate a Report Combining All These Functions

Log file path.

def generate_report():
    apache_version = get_apache_version()
    selinux_status = get_selinux_status()
    firewall_rules = get_firewall_rules()
    ssh_port = get_ssh_port()
    permit_root_login = get_root_login()
    permit_pass_auth = get_ssh_password_config() 
    selinux_label = get_selinux_ssh_port_label()
    nmapScan = vuln_scan()

    log_record = apache_version + "n" + selinux_status + "n" + firewall_rules + "n" + ssh_port + "n" + permit_root_login + "n" + permit_pass_auth + "n" + selinux_label + "n" + 

    text_file=open(log_file, "w")

    print("SELinux Status: " + selinux_status)
    print("Firewall - Default Zonen " +     firewall_rules)
    print("SSH Port: " + str(ssh_port))
    print("Password Authentication: " +     str(permit_pass_auth))
    print("SELinux Label: " + selinux_label)

Save and close.


Change permissions on the file.

chmod 700 /home/cloud_user/ourScript.py
sudo ./ourScript.py

Additional Resources


When dealing with more than one Apache web server instance, it's a very good idea to implement a certain degree of automation for configuration and vulnerability scans. Why? Because if we have a hundred instances, weu want to make sure we're being consistent with security checks across the board. This helps ensure consistent results. In this lab, we write a script that makes use of Nmap and vulnerability databases to report on the security status of our server. Furthermore, the same script fetches information such as SELinux status, firewall configuration, Apache version, and so on.

Please feel free to expand the script and write a unique version! Do not forget to share!

Github links:

  • https://github.com/vulnersCom/nmap-vulners.git
  • https://github.com/scipag/vulscan.git

What are Hands-on Labs

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Get Started
Who’s going to be learning?

How many seats do you need?

  • $499 USD per seat per year
  • Billed Annually
  • Renews in 12 months

Ready to accelerate learning?

For over 25 licenses, a member of our sales team will walk you through a custom tailored solution for your business.


Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!