Cvechecker

From Alpine Linux
This material is work-in-progress ...

Do not follow instructions here until this notice is removed.
(Last edited by Sertonix on 17 Nov 2023.)

cvechecker is an useful tool which helps to compare packeges installed in your distribution with the Common Vulnerabilities Exposure. Is not a bullet-proof method and you will most likely have many false positives (vulnerability is fixed with a revision-release, but the tool isn’t able to detect the revision itself), yet it is still better than nothing. The idea is to automatize security check. But, clearly, this is not (and must not be) the only way to check security. With the proper reporting in place, you are immediately warned when a new CVE has been released that might match your system. You can then take the appropriate steps (acknowledge report, verify incident, fix package or mark as false positive). Those are the steps:

  • pull in the latest CVE entries as well as software/version detection rules (Adminsitrative task only)
  • generate a list of files to scan
  • gather installed software/version information
  • output which CVE entries might affect your system
  • generate a report informing you about the CVE entries

Installation

cvechecker is available in edge main repo. If you are running a stable version of alpine, you can add the package from edge in this way:

apk install cvechecker

Configuration with sqlite

CVEChecker's installation scripts create an user and a group, both called "cvechecker", in order to have a user with minimum privileges to run cvechecker. In this folder cvechecker will creates the database (according with the cvechecker.conf, we use sqlite3. But also mysql is supported. This could be useful if you want to share only one DB with many routers/servers running Alpine)

Before use cvechecker you should configure cvechecker to use sqlite, then populate the DB with cve entries. According with our settings, /etc/cvechecker.conf would looks like:

    # Generic settings
    # 
    dbtype = "sqlite"; 
    #dbtype="mysql";
    cvecache = "/var/cvechecker/cache";
    datadir = "/usr/share/cvechecker";
    stringcmd = "/usr/bin/strings -n 3 '@file@'";
    version_url = "https://raw.github.com/sjvermeu/cvechecker/master/versions.dat";
    #userkey = "servertag";
    #
    # For Sqlite3
    #
    sqlite3: {
      localdb = "/var/cvechecker/local";
      globaldb = "/var/cvechecker/global.db";
    };
    # 
    # For MySQL
    # 
    mysql: {
      dbname = "cvechecker";
      dbuser = "cvechecker";
      dbpass = "cvecheckpass";
      dbhost = "$IPADDRESS_OF_MYSQL_SERVER";
    };


Now, you can initialize the DB with:

cvechecker -i

DB is ready. Now, we should configure cvechecker to use mysql then populate the DB with cve entries.

Configuration with MySQL

MySQL is another backend that cvechecker is able to use. Could be useful if you have several cvechecker installed in your network. In that way, you have only one "repository" of CVEs that needs to be updated.

apk add mysql mysql-client rc-service mysql setup rc-service mysql start && rc-update add mysql default /usr/bin/mysqladmin -u root password 'new-password'

create a db user for cvechecker:

mysql -u root -p mysql>CREATE DATABASE cvechecker; mysql>CREATE USER 'cvechecker'@'%' IDENTIFIED BY 'cvecheckpass'; mysql>GRANT ALL ON cvechecker.* TO 'cvechecker'@'localhost'; mysql>GRANT ALL ON cvechecker.* TO 'cvechecker'@'%'; mysql>FLUSH PRIVILEGES;

I set % because the DB and the users should allow access from other hosts. You can restrict this to allow only your domain.

You have two way to create tables into DB:

Via .sql script

Login as cvechecker into mysql:

mysql -D cvechecker -u cvechecker -p mysql>source /usr/share/cvechecker/mysql_cvechecker.sql;

DB is ready. Now, we should configure cvechecker to use mysql then populate the DB with cve entries.

Via cvechecker

After you configured the DB, you can create tables with:

cvechecker -i

But in order to make it works, you have to configure DB settings in cvechecker.conf. According with our settings, /etc/cvechecker.conf would looks like:

    # Generic settings
    # 
    #dbtype = "sqlite"; 
    dbtype="mysql";
    cvecache = "/var/cvechecker/cache";
    datadir = "/usr/share/cvechecker";
    stringcmd = "/usr/bin/strings -n 3 '@file@'";
    version_url = "https://raw.github.com/sjvermeu/cvechecker/master/versions.dat";
    #userkey = "servertag";
    #
    # For Sqlite3
    #
    sqlite3: {
      localdb = "/var/cvechecker/local";
      globaldb = "/var/cvechecker/global.db";
    };
    # 
    # For MySQL
    # 
    mysql: {
      dbname = "cvechecker";
      dbuser = "cvechecker";
      dbpass = "cvecheckpass";
      dbhost = "$IPADDRESS_OF_MYSQL_SERVER";
    };


NOTE: Running cvechecker -i (initialize database) it removes ALL entries in the DB.


Using CVEChecker

After the db is created, you have to pull the necessary data from the Internet:

pullcves pull

According with the manual, "This will take a very long time, so please be patient (loading over half a million CVE entries in a database is a time consuming - but one-time - activity). Future pulls will not take this much time as they will not redownload the CVE entries from all previous years (unless you ask it to)."

(If you're behind a proxy, you should set it from env variable or with wget.rc)

Could be useful to crontab this task, maybe every day. Become the cvecheker user and run "crontab -e". Insert the following to run pullcves every day at 5:00 AM

*       5       *       *       *       /usr/bin/pullcves pull

Now, make a list of executables file as well as /proc/version and allows cvechecker to verify if there are kernel-related CVE entries for your Linux kernel and software installed.

find / -type f -perm -o+x > /tmp/cvecheck.tmp cat /proc/version >> /tmp/cvecheck.tmp

Now, in /tmp/cvecheck.tmp you'll have all the binaries of your system with their version. Check if there are cve with the following:

cvechecker -b /tmp/cvecheck.tmp

If you want, you can create a report with the entries (if they are found):

cvechecker -r

Simple script that helps to do it automatically. Copy and past it, save it as run_cvecheck.sh and give it exec permissions.

    #!/bin/sh
    tempfile=/tmp/cvecheck.tmp
    EMAILADMIN=<%EMAIL ADDRESS USED FOR THIS TASK%>
    find / -type f -perm -o+x > $tempfile
    cat /proc/version >> $tempfile
    cvechecker -b $tempfile > /dev/null 2>&1 	# Run cvechecker against the software list
    cvechecker -r > $tempfile > /dev/null 2>&1	# Create a report 
    if [ -s "$tempfile" ] ; then			# If exists and non-zero, send it via email	
     mail $EMAILADMIN -s "CVE Checker" < $tempfile	
    fi ;
    rm $tempfile
Note: If you want to send emails, you have to add mailx and configure an smtp server (like ssmtp). But this information goes beyond the purpose of this doc.

In order to make the last rows sent via email, you should configure an smtp server. Widely used is ssmtp. Could be a good idea run this script as cronjob.

So, you can do the same you did with pullcves: become the cvecheker user and run "crontab -e".

*       6       *       *       *       /var/cvechecker/run_cvecheck.sh

Create Report

CVEChecker generate reports in a CSV format. Could be nice generate an html from this CSV.

This is a sample script that uses csv2xml and cvereport.xsl (two scripts that comes with cvechecker) that allows the generation of html file starting by csv.


    #!/bin/sh
    tempfile=/tmp/cvecheck.tmp
    EMAILADMIN=root@localhost
    WEBDIR=/var/www/localhost/htdocs/cvechecker/
    CONFFILE=/etc/cvechecker.conf
    DATADIR=$(awk -F'=' '/^datadir/ {print $2}' ${CONFFILE} | awk -F'"' '{print $2}');
    find / -type f -perm -o+x > $tempfile
    cat /proc/version >> $tempfile
    cvechecker -b $tempfile > /dev/null 2>&1        # Run cvechecker against the software list
    if [ -s "$tempfile" ] ; then                    # If exists and non-zero, send it via email     
        mail $EMAILADMIN -s "CVE Checker" < $tempfile
    fi ;
    # Create Report. 
    # FYI: acknowledgements.xml is an hard-coded file name.
    cvechecker -rC > $WEBDIR/report.csv
    awk -F, -f ${DATADIR}/csv2xml.awk $WEBDIR/report.csv > ${DATADIR}/acknowledgements.xml
    xsltproc ${DATADIR}/cvereport.xsl $DATADIR/acknowledgements.xml > ${WEBDIR}/report.html
    printf "done\n".

Note: the html generated is pretty ugly, because cvereport.xsl has hard-coded the css file which is stored in /usr/share/cvechecker dir. Filename is report.css You can copy the report.css file into $WEBDIR in order to have a nicer html file.