#!/bin/sh

#################################################################################
#
#   Lynis
# ------------------
#
# Copyright 2007-2013, Michael Boelen
# Copyright 2013-2016, CISOfy
#
# Website  : https://cisofy.com
# Blog     : http://linux-audit.com
# GitHub   : https://github.com/CISOfy/lynis
#
# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are
# welcome to redistribute it under the terms of the GNU General Public License.
# See LICENSE file for usage of this software.
#
#################################################################################
#
# Software: PHP
#
#################################################################################
#
    InsertSection "PHP"

    # Possible locations of php.ini
    PHPINILOCS="/etc/php.ini /etc/php.ini.default \
                /etc/php/cgi-php5/php.ini /etc/php/cli-php5/php.ini /etc/php/apache2-php5/php.ini \
                /etc/php/apache2-php5.4/php.ini /etc/php/apache2-php5.5/php.ini \
                /etc/php5/cgi/php.ini \
                /etc/php5/cli/php.ini \
                /etc/php5/cli-php5.4/php.ini /etc/php5/cli-php5.5/php.ini /etc/php5/cli-php5.6/php.ini \
                /etc/php5/apache2/php.ini \
                /etc/php5/fpm/php.ini \
                /private/etc/php.ini \
                /var/www/conf/php.ini \
                /usr/local/etc/php.ini /usr/local/lib/php.ini \
                /usr/pkg/etc/php.ini"

    PHPINIDIRS="/etc/php5/conf.d \
                /etc/php.d"
#
#################################################################################
#
    # Test        : PHP-2211
    # Description : Check php.ini presence
    Register --test-no PHP-2211 --weight L --network NO --category security --description "Check php.ini presence"
    if [ ${SKIPTEST} -eq 0 ]; then
        LogText "Test: Checking for presence php.ini"
        PHPINIFILE=""
        PHPINI_ALLFILES=""
        for FILE in ${PHPINILOCS}; do
            LogText "Test: checking presence ${FILE}"
            if [ -f ${FILE} ]; then
                PHPINIFILE="${FILE}"
                LogText "Result: Found php.ini file (${PHPINIFILE})"
                LogText "Note: Adding file to php.ini array"
                PHPINI_ALLFILES="${PHPINI_ALLFILES} ${PHPINIFILE}"
            else
                LogText "Result: file ${FILE} not found"
            fi
        done

        # Check all known locations
        for DIR in ${PHPINIDIRS}; do
            FIND=$(ls ${DIR}/*.ini 2> /dev/null)
            if [ -z "${FIND}" ]; then
                LogText "Result: no files found for ${DIR}"
            else
                LogText "Result: found files in location ${DIR}, checking"
                for FILE in ${FIND}; do
                    if [ -f ${FILE} ]; then
                        LogText "Result: file ${FILE} exists, adding to php.ini array"
                        PHPINI_ALLFILES="${PHPINI_ALLFILES} ${FILE}"
                    fi
                done
            fi
        done

        if [ ! -z "${PHPINIFILE}" ]; then
            Display --indent 2 --text "- Checking PHP" --result "${STATUS_FOUND}" --color GREEN
            LogText "Result: using single file ${PHPINIFILE} for main php.ini tests"
            LogText "Result: using php.ini array ${PHPINI_ALLFILES} for further tests"
        else
            Display --indent 2 --text "- Checking PHP" --result "${STATUS_NOT_FOUND}" --color WHITE
            LogText "Result: no php.ini file found"
        fi
        unset DIR; unset FILE; unset FIND
    fi
#
#################################################################################
#
    # Test        : PHP-2320
    # Description : Check php disable functions option
    if [ ! "${PHPINI_ALLFILES}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PHP-2320 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check PHP disabled functions"
    if [ ${SKIPTEST} -eq 0 ]; then
        FOUND=0
        for I in ${PHPINI_ALLFILES}; do
            LogText "Test: Checking for PHP function hardening disabled_functions or suhosin.executor.func.blacklist in file ${I}"
            FIND=`grep "^disable_functions.*=" ${I}`
            if [ "${FIND}" = "" ]; then
              LogText "Result: ${I}: disabled_functions not found"
            else
              LogText "Result: ${I}: found disabled_functions"
              FOUND=1
            fi

            FIND=`grep "^suhosin.executor.func.blacklist=" ${I}`
            if [ "${FIND}" = "" ]; then
              LogText "Result: ${I}: suhosin.executor.func.blacklist not found"
            else
              LogText "Result: ${I}: found suhosin.executor.func.blacklist"
              FOUND=1
            fi
        done
        if [ ${FOUND} -eq 0 ]; then
            LogText "Result: all PHP functions can be executed"
            Display --indent 4 --text "- Checking PHP disabled functions" --result "${STATUS_NONE}" --color YELLOW
            ReportSuggestion ${TEST_NO} "Harden PHP by disabling risky functions"
            LogText "Functions of interest to research/disable: chown, diskfreespace, disk_free_space, disk_total_space, dl, exec, escapeshellarg, escapeshellcmd, fileinode, highlight_file, max_execution_time, passthru, pclose, phpinfo, popen, proc_close, proc_open, proc_get_status, proc_nice, proc_open, proc_terminate, set_time_limit, shell_exec, show_source, system)"
            AddHP 0 1
          else
            LogText "Result: one or more PHP functions are disabled/blacklisted"
            Display --indent 4 --text "- Checking PHP disabled functions" --result "${STATUS_FOUND}" --color GREEN
            AddHP 3 3
        fi
    fi
#
#################################################################################
#
    # Test        : PHP-2368
    # Description : Check php register_globals option
    # Notes       : Don't test for it if PHP version is 5.4.0 or later (it has been removed)
    if [ ! "${PHPINIFILE}" = "" -a ! "${PHPVERSION}" = "" -a ! "${EGREPBINARY}" = "" ]; then
        if [ -f "${PHPINIFILE}" ]; then
            FIND=`echo ${PHPVERSION} | ${EGREPBINARY} "^(4.|5.[0-3])"`
            if [ "${FIND}" = "" ]; then
                PREQS_MET="NO"; Debug "Found most likely PHP version 5.4.0 or higher (${PHPVERSION}) which does not use register_globals"
              else
               PREQS_MET="YES"; Debug "Found PHP version 4 or up to 5.3 (${FIND}) which we are going to scan"
            fi
          else
            Debug "File php.ini (${PHPINIFILE}) not found"
        fi
    else
      PREQS_MET="NO"
      Debug "Skipping test: php.ini not found, or PHP version empty"
      Debug "php.ini: ${PHPINIFILE}"
      Debug "version: ${PHPVERSION}"
    fi
    Register --test-no PHP-2368 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check PHP register_globals option"
    if [ ${SKIPTEST} -eq 0 ]; then
        LogText "Test: Checking PHP register_globals option"
        FIND=`egrep -i 'register_globals.*(on|yes|1)' ${PHPINIFILE} | grep -v '^;'`
        if [ ! "${FIND}" = "" ]; then
            Display --indent 4 --text "- Checking register_globals option" --result "${STATUS_WARNING}" --color RED
            ReportWarning ${TEST_NO} "M" "PHP option register_globals option is turned on, which can be a risk for variable value overwriting"
            ReportSuggestion ${TEST_NO} "Change the register_globals line to: register_globals = Off"
            LogText "Result: register_globals option is turned on, which can be a risk for variable value overwriting."
            AddHP 1 2
          else
            Display --indent 4 --text "- Checking register_globals option" --result "${STATUS_OK}" --color GREEN
            LogText "Result: No 'register_globals' found. Most likely it is in disabled state (0, no, or off), which is the default nowadays and considered the safe value."
            ReportManual ${TEST_NO}:01
            AddHP 2 2
        fi
    fi
#
#################################################################################
#
    # Test        : PHP-2372
    # Description : Check php expose_php option
    # Notes       : Extend test to check all PHP files YYY
    if [ ! "${PHPINIFILE}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PHP-2372 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check PHP expose_php option"
    if [ ${SKIPTEST} -eq 0 ]; then
        LogText "Test: Checking expose_php option"
        FIND=`egrep -i 'expose_php.*(off|no|0)' ${PHPINIFILE} | grep -v '^;'`
        if [ "${FIND}" = "" ]; then
            Display --indent 4 --text "- Checking expose_php option" --result "${STATUS_ON}" --color RED
            ReportWarning ${TEST_NO} "M" "PHP option expose_php is possibly turned on, which can reveal useful information for attackers."
            ReportSuggestion ${TEST_NO} "Change the expose_php line to: expose_php = Off"
            Report "Result: expose_php option is turned on, which can expose useful information for an attacker"
            AddHP 1 2
          else
            Display --indent 4 --text "- Checking expose_php option" --result "${STATUS_OFF}" --color GREEN
            LogText "Result: Found 'expose_php' in disabled state (0, no, or off)"
            AddHP 2 2
        fi
        #YYY Check through all files
    fi
#
#################################################################################
#
    # Test        : PHP-2374
    # Description : Check PHP enable_dl option
    # Notes       : Extend test to check all PHP files
    if [ ! "${PHPINIFILE}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PHP-2374 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check PHP enable_dl option"
    if [ ${SKIPTEST} -eq 0 ]; then
        LogText "Test: Checking PHP enable_dl option"
        FIND=$(egrep -i 'enable_dl.*(on|yes|1)' ${PHPINIFILE} | grep -v '^;')
        if [ ! -z "${FIND}" ]; then
            Display --indent 4 --text "- Checking enable_dl option" --result "${STATUS_ON}" --color YELLOW
            Report "Result: enable_dl option is turned on, which can be used to enable more modules dynamically and circumventing security controls"
            ReportSuggestion ${TEST_NO} "Change the enable_dl line to: enable_dl = Off, to disable dynamically loading new modules"
            AddHP 0 1
          else
            Display --indent 4 --text "- Checking enable_dl option" --result "${STATUS_OFF}" --color GREEN
            LogText "Result: Found 'enable_dl' in disabled state (not present, 0, no, or off)"
            AddHP 2 2
        fi
    fi
#
#################################################################################
#
    # Test        : PHP-2376
    # Description : Check PHP allow_url_fopen option
    # Notes       : Extend test to check all PHP files YYY
    if [ ! "${PHPINIFILE}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PHP-2376 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check PHP allow_url_fopen option"
    if [ ${SKIPTEST} -eq 0 ]; then
        LogText "Test: Checking PHP allow_url_fopen option"
        FIND=`egrep -i 'allow_url_fopen.*(off|no|0)' ${PHPINIFILE} | grep -v '^;'`
        if [ "${FIND}" = "" ]; then
            Display --indent 4 --text "- Checking allow_url_fopen option" --result "${STATUS_ON}" --color YELLOW
            LogText "Result: allow_url_fopen option is turned on, which can be used for riskful downloads via PHP"
            ReportSuggestion ${TEST_NO} "Change the allow_url_fopen line to: allow_url_fopen = Off, to disable downloads via PHP"
            AddHP 0 1
          else
            Display --indent 4 --text "- Checking allow_url_fopen option" --result "${STATUS_OFF}" --color GREEN
            LogText "Result: Found 'allow_url_fopen' in disabled state (0, no, or off)"
            AddHP 2 2
        fi
        #YYY Check through all files
    fi
#
#################################################################################
#
    # Test        : PHP-2378
    # Description : Check PHP allow_url_include option
    # Notes       : Extend test to check all PHP files YYY
    if [ ! "${PHPINIFILE}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PHP-2378 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description "Check PHP allow_url_include option"
    if [ ${SKIPTEST} -eq 0 ]; then
        LogText "Test: Checking PHP allow_url_include option"
        FIND=`egrep -i 'allow_url_include.*(off|no|0)' ${PHPINIFILE} | grep -v '^;'`
        if [ "${FIND}" = "" ]; then
            Display --indent 4 --text "- Checking allow_url_include option" --result "${STATUS_ON}" --color YELLOW
            Report "Result: allow_url_include option is turned on, which can be used for riskful downloads via PHP"
            ReportSuggestion ${TEST_NO} "Change the allow_url_include line to: allow_url_include = Off, to disable downloads via PHP"
            AddHP 0 1
          else
            Display --indent 4 --text "- Checking allow_url_include option" --result "${STATUS_OFF}" --color GREEN
            LogText "Result: Found 'allow_url_include' in disabled state (0, no, or off)"
            AddHP 2 2
        fi
    fi
#
#################################################################################
#

WaitForKeyPress

#
#================================================================================
# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com