From 9946a2c370961cd8f5041c3fc96c2bac1840144e Mon Sep 17 00:00:00 2001 From: Brian Davis Date: Sun, 2 Jun 2024 09:49:44 -0400 Subject: [PATCH] fix: fix partial check for fortify - fix partial check for fortify - remove photon tests --- .github/workflows/pull_request.yml | 2 -- Dockerfile.photon | 15 ----------- Dockerfile.ubuntu | 6 +++-- checksec | 42 +++++++++++++++--------------- docker-compose.yml | 7 ----- src/core.sh | 3 +++ src/functions/filecheck.sh | 22 ++++++++-------- src/functions/proccheck.sh | 17 +++++------- tests/test-checksec.sh | 5 +--- 9 files changed, 47 insertions(+), 72 deletions(-) delete mode 100644 Dockerfile.photon diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f4fc29b..a47457b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -20,5 +20,3 @@ jobs: fi - name: ubuntu checksec run: docker-compose run checksec-ubuntu - - name: photon checksec - run: docker-compose run checksec-photon diff --git a/Dockerfile.photon b/Dockerfile.photon deleted file mode 100644 index b81c44a..0000000 --- a/Dockerfile.photon +++ /dev/null @@ -1,15 +0,0 @@ -FROM photon:5.0 - -# Install dependencies -RUN tdnf upgrade -y && tdnf remove toybox -y && \ - tdnf install -y build-essential git rpm-build coreutils util-linux \ - make autoconf automake gcc ncurses-devel sed tar texinfo wget procps-ng grep \ - findutils gzip file which libxml2 python3 python3-pip jq clang nasm binutils && \ - pip3 install --upgrade pip && pip3 install setuptools && \ - pip3 install demjson3 && mkdir -p /zig && \ - wget https://ziglang.org/builds/zig-linux-$(uname -m)-0.12.0-dev.3667+77abd3a96.tar.xz && \ - tar xf zig-linux-$(uname -m)-0.12.0-dev.3667+77abd3a96.tar.xz -C /zig --strip-components=1 && \ - rm -rf zig-linux-$(uname -m)-0.12.0-dev.3667+77abd3a96.tar.xz - -COPY . /root -WORKDIR /root diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu index ac5c049..6102603 100644 --- a/Dockerfile.ubuntu +++ b/Dockerfile.ubuntu @@ -5,10 +5,12 @@ RUN apt-get update && apt-get -y -q upgrade && DEBIAN_FRONTEND=noninteractive ap bc bison flex build-essential git file \ libncurses-dev libssl-dev u-boot-tools wget \ xz-utils vim libxml2-utils python3 python3-pip jq \ - gcc clang gcc-multilib nasm binutils && apt-get clean \ + gcc clang nasm binutils && \ pip3 install --upgrade pip && pip3 install setuptools && \ pip3 install demjson3 && mkdir -p /zig && \ - wget https://ziglang.org/builds/zig-linux-$(uname -m)-0.12.0-dev.3667+77abd3a96.tar.xz && \ + if [ $(uname -m) == "x86_64" ]; then apt-get -y -q install gcc-multilib; fi && \ + apt-get clean && \ + wget -q https://ziglang.org/builds/zig-linux-$(uname -m)-0.12.0-dev.3667+77abd3a96.tar.xz && \ tar xf zig-linux-$(uname -m)-0.12.0-dev.3667+77abd3a96.tar.xz -C /zig --strip-components=1 && \ rm -rf zig-linux-$(uname -m)-0.12.0-dev.3667+77abd3a96.tar.xz diff --git a/checksec b/checksec index b6f5dc3..866b753 100755 --- a/checksec +++ b/checksec @@ -51,6 +51,9 @@ format="cli" SCRIPT_NAME="checksec" SCRIPT_URL="https://github.com/slimm609/checksec.sh/raw/master/${SCRIPT_NAME}" SIG_URL="https://github.com/slimm609/checksec.sh/raw/master/$(basename ${SCRIPT_NAME} .sh).sig" +# Currently unused, adding for reference +# https://github.com/gcc-mirror/gcc/blob/master/gcc/builtins.def#L1112 +# FORTIFY_FUNCTIONS=(memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk stpncpy_chk strcat_chk strcpy_chk strncat_chk strncpy_chk snprintf_chk sprintf_chk vsnprintf_chk vsprintf_chk fprintf_chk printf_chk vfprintf_chk vprintf_chk) pkg_release=false commandsmissing=false @@ -817,7 +820,7 @@ filecheck() { # check for stripped symbols in the binary IFS=" " read -r -a SYM_cnt <<< "$(${readelf} --symbols "${1}" 2> /dev/null | grep '\.symtab' | cut -d' ' -f5 | cut -d: -f1)" if ${readelf} --symbols "${1}" 2> /dev/null | grep -q '\.symtab'; then - echo_message "\033[31m${SYM_cnt[0]} Symbols\t\033[m " 'Symbols,' ' symbols="yes"' '"symbols":"yes",' + echo_message "\033[31m${SYM_cnt[0]} Symbols\t\033[m" 'Symbols,' ' symbols="yes"' '"symbols":"yes",' else echo_message '\033[32mNo Symbols\t\033[m' 'No Symbols,' ' symbols="no"' '"symbols":"no",' fi @@ -830,22 +833,22 @@ filecheck() { FS_filechk_func_libc="$(${readelf} -s "${use_dynamic}" "${FS_libc}" 2> /dev/null | sed -ne 's/.*__\(.*_chk\)@@.*/\1/p')" FS_func_libc="${FS_filechk_func_libc//_chk/}" FS_func="$(${readelf} -s "${use_dynamic}" "${1}" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d')" + # -D_FORTIFY_SOURCE=1 can be checked by the presence of printf_chk or not. + # in 1 printf is not converted to printf_chk + # in 2 and 3, it is converted. So if there is any printf_chk functions, then this confirms 2 or 3 + partial="$(${readelf} -s "${use_dynamic}" "${1}" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d' | grep -c "printf_chk")" FS_cnt_checked=$(grep -cFxf <(sort -u <<< "${FS_filechk_func_libc}") <(sort -u <<< "${FS_func}")) FS_cnt_unchecked=$(grep -cFxf <(sort -u <<< "${FS_func_libc}") <(sort -u <<< "${FS_func}")) FS_cnt_total=$((FS_cnt_unchecked + FS_cnt_checked)) - if [[ "${libc_found}" == "false" ]] || [[ "${FS_cnt_total}" == "0" ]]; then + if [[ "${libc_found}" == "false" ]] || [[ "${FS_cnt_total}" -eq "0" ]]; then echo_message "\033[32mN/A\033[m" "N/A," ' fortify_source="n/a" ' '"fortify_source":"n/a",' + elif [[ "${FS_cnt_total}" -gt "0" ]] && [[ "${FS_cnt_checked}" -gt "0" ]] && [[ ${partial} -eq "0" ]]; then + echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial" ' '"fortify_source":"partial",' + elif [[ "${FS_cnt_checked}" -eq "0" ]]; then + echo_message "\033[31mNo\033[m" "No," ' fortify_source="no" ' '"fortify_source":"no",' else - if [[ $FS_cnt_checked -eq $FS_cnt_total ]]; then - echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes" ' '"fortify_source":"yes",' - else - if [[ "${FS_cnt_checked}" == "0" ]]; then - echo_message "\033[31mNo\033[m" "No," ' fortify_source="no" ' '"fortify_source":"no",' - else - echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial" ' '"fortify_source":"partial",' - fi - fi + echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes" ' '"fortify_source":"yes",' fi echo_message "\t${FS_cnt_checked}\t" "${FS_cnt_checked}", "fortified=\"${FS_cnt_checked}\" " "\"fortified\":\"${FS_cnt_checked}\"," echo_message "\t${FS_cnt_total}\t\t" "${FS_cnt_total}" "fortify-able=\"${FS_cnt_total}\"" "\"fortify-able\":\"${FS_cnt_total}\"" @@ -1617,22 +1620,19 @@ proccheck() { Proc_FS_filechk_func_libc="$(${readelf} -s "${use_dynamic}" "${FS_libc}" 2> /dev/null | sed -ne 's/.*__\(.*_chk\)@@.*/\1/p')" Proc_FS_func_libc="${Proc_FS_filechk_func_libc//_chk/}" Proc_FS_func="$(${readelf} -s "${use_dynamic}" "${1}/exe" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d')" + Proc_Partial="$(${readelf} -s "${use_dynamic}" "${1}/exe" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d' | grep -c "printf_chk")" Proc_FS_cnt_checked=$(grep -cFxf <(sort -u <<< "${Proc_FS_filechk_func_libc}") <(sort -u <<< "${Proc_FS_func}")) Proc_FS_cnt_unchecked=$(grep -cFxf <(sort -u <<< "${Proc_FS_func_libc}") <(sort -u <<< "${Proc_FS_func}")) Proc_FS_cnt_total=$((Proc_FS_cnt_unchecked + Proc_FS_cnt_checked)) - if [[ "${libc_found}" == "false" ]] || [[ "${Proc_FS_cnt_total}" == "0" ]]; then + if [[ "${libc_found}" == "false" ]] || [[ "${Proc_FS_cnt_total}" -eq "0" ]]; then echo_message "\033[32mN/A\033[m" "N/A," ' fortify_source="n/a">' '"fortify_source":"n/a" }' + elif [[ "${Proc_FS_cnt_total}" -gt "0" ]] && [[ "${Proc_FS_cnt_checked}" -gt "0" ]] && [[ ${Proc_Partial} -eq "0" ]]; then + echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial">' '"fortify_source":"partial" }' + elif [[ "${Proc_FS_cnt_checked}" -eq "0" ]]; then + echo_message "\033[31mNo\033[m" "No," ' fortify_source="no">' '"fortify_source":"no" }' else - if [[ $Proc_FS_cnt_checked -eq $Proc_FS_cnt_total ]]; then - echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes">' '"fortify_source":"yes" }' - else - if [[ "${Proc_FS_cnt_checked}" == "0" ]]; then - echo_message "\033[31mNo\033[m" "No," ' fortify_source="no">' '"fortify_source":"no" }' - else - echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial">' '"fortify_source":"partial" }' - fi - fi + echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes">' '"fortify_source":"yes" }' fi } diff --git a/docker-compose.yml b/docker-compose.yml index 5e0ce87..f8e12d9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,13 +8,6 @@ services: image: checksec-ubuntu command: bash -c "./tests/test-checksec.sh" - checksec-photon: - build: - context: ./ - dockerfile: Dockerfile.photon - image: checksec-photon - command: bash -c "./tests/test-checksec.sh" - shellcheck: volumes: - .:/mnt diff --git a/src/core.sh b/src/core.sh index 050f20f..3e66f20 100644 --- a/src/core.sh +++ b/src/core.sh @@ -18,6 +18,9 @@ format="cli" SCRIPT_NAME="checksec" SCRIPT_URL="https://github.com/slimm609/checksec.sh/raw/master/${SCRIPT_NAME}" SIG_URL="https://github.com/slimm609/checksec.sh/raw/master/$(basename ${SCRIPT_NAME} .sh).sig" +# Currently unused, adding for reference +# https://github.com/gcc-mirror/gcc/blob/master/gcc/builtins.def#L1112 +# FORTIFY_FUNCTIONS=(memcpy_chk memmove_chk mempcpy_chk memset_chk stpcpy_chk stpncpy_chk strcat_chk strcpy_chk strncat_chk strncpy_chk snprintf_chk sprintf_chk vsnprintf_chk vsprintf_chk fprintf_chk printf_chk vfprintf_chk vprintf_chk) pkg_release=false commandsmissing=false diff --git a/src/functions/filecheck.sh b/src/functions/filecheck.sh index 465e771..877349b 100644 --- a/src/functions/filecheck.sh +++ b/src/functions/filecheck.sh @@ -124,7 +124,7 @@ filecheck() { # check for stripped symbols in the binary IFS=" " read -r -a SYM_cnt <<< "$(${readelf} --symbols "${1}" 2> /dev/null | grep '\.symtab' | cut -d' ' -f5 | cut -d: -f1)" if ${readelf} --symbols "${1}" 2> /dev/null | grep -q '\.symtab'; then - echo_message "\033[31m${SYM_cnt[0]} Symbols\t\033[m " 'Symbols,' ' symbols="yes"' '"symbols":"yes",' + echo_message "\033[31m${SYM_cnt[0]} Symbols\t\033[m" 'Symbols,' ' symbols="yes"' '"symbols":"yes",' else echo_message '\033[32mNo Symbols\t\033[m' 'No Symbols,' ' symbols="no"' '"symbols":"no",' fi @@ -137,22 +137,22 @@ filecheck() { FS_filechk_func_libc="$(${readelf} -s "${use_dynamic}" "${FS_libc}" 2> /dev/null | sed -ne 's/.*__\(.*_chk\)@@.*/\1/p')" FS_func_libc="${FS_filechk_func_libc//_chk/}" FS_func="$(${readelf} -s "${use_dynamic}" "${1}" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d')" + # -D_FORTIFY_SOURCE=1 can be checked by the presence of printf_chk or not. + # in 1 printf is not converted to printf_chk + # in 2 and 3, it is converted. So if there is any printf_chk functions, then this confirms 2 or 3 + partial="$(${readelf} -s "${use_dynamic}" "${1}" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d' | grep -c "printf_chk")" FS_cnt_checked=$(grep -cFxf <(sort -u <<< "${FS_filechk_func_libc}") <(sort -u <<< "${FS_func}")) FS_cnt_unchecked=$(grep -cFxf <(sort -u <<< "${FS_func_libc}") <(sort -u <<< "${FS_func}")) FS_cnt_total=$((FS_cnt_unchecked + FS_cnt_checked)) - if [[ "${libc_found}" == "false" ]] || [[ "${FS_cnt_total}" == "0" ]]; then + if [[ "${libc_found}" == "false" ]] || [[ "${FS_cnt_total}" -eq "0" ]]; then echo_message "\033[32mN/A\033[m" "N/A," ' fortify_source="n/a" ' '"fortify_source":"n/a",' + elif [[ "${FS_cnt_total}" -gt "0" ]] && [[ "${FS_cnt_checked}" -gt "0" ]] && [[ ${partial} -eq "0" ]]; then + echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial" ' '"fortify_source":"partial",' + elif [[ "${FS_cnt_checked}" -eq "0" ]]; then + echo_message "\033[31mNo\033[m" "No," ' fortify_source="no" ' '"fortify_source":"no",' else - if [[ $FS_cnt_checked -eq $FS_cnt_total ]]; then - echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes" ' '"fortify_source":"yes",' - else - if [[ "${FS_cnt_checked}" == "0" ]]; then - echo_message "\033[31mNo\033[m" "No," ' fortify_source="no" ' '"fortify_source":"no",' - else - echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial" ' '"fortify_source":"partial",' - fi - fi + echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes" ' '"fortify_source":"yes",' fi echo_message "\t${FS_cnt_checked}\t" "${FS_cnt_checked}", "fortified=\"${FS_cnt_checked}\" " "\"fortified\":\"${FS_cnt_checked}\"," echo_message "\t${FS_cnt_total}\t\t" "${FS_cnt_total}" "fortify-able=\"${FS_cnt_total}\"" "\"fortify-able\":\"${FS_cnt_total}\"" diff --git a/src/functions/proccheck.sh b/src/functions/proccheck.sh index b2baa02..833d939 100644 --- a/src/functions/proccheck.sh +++ b/src/functions/proccheck.sh @@ -126,21 +126,18 @@ proccheck() { Proc_FS_filechk_func_libc="$(${readelf} -s "${use_dynamic}" "${FS_libc}" 2> /dev/null | sed -ne 's/.*__\(.*_chk\)@@.*/\1/p')" Proc_FS_func_libc="${Proc_FS_filechk_func_libc//_chk/}" Proc_FS_func="$(${readelf} -s "${use_dynamic}" "${1}/exe" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d')" + Proc_Partial="$(${readelf} -s "${use_dynamic}" "${1}/exe" 2> /dev/null | awk '{ print $8 }' | sed -e 's/_*//' -e 's/@.*//' -e '/^$/d' | grep -c "printf_chk")" Proc_FS_cnt_checked=$(grep -cFxf <(sort -u <<< "${Proc_FS_filechk_func_libc}") <(sort -u <<< "${Proc_FS_func}")) Proc_FS_cnt_unchecked=$(grep -cFxf <(sort -u <<< "${Proc_FS_func_libc}") <(sort -u <<< "${Proc_FS_func}")) Proc_FS_cnt_total=$((Proc_FS_cnt_unchecked + Proc_FS_cnt_checked)) - if [[ "${libc_found}" == "false" ]] || [[ "${Proc_FS_cnt_total}" == "0" ]]; then + if [[ "${libc_found}" == "false" ]] || [[ "${Proc_FS_cnt_total}" -eq "0" ]]; then echo_message "\033[32mN/A\033[m" "N/A," ' fortify_source="n/a">' '"fortify_source":"n/a" }' + elif [[ "${Proc_FS_cnt_total}" -gt "0" ]] && [[ "${Proc_FS_cnt_checked}" -gt "0" ]] && [[ ${Proc_Partial} -eq "0" ]]; then + echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial">' '"fortify_source":"partial" }' + elif [[ "${Proc_FS_cnt_checked}" -eq "0" ]]; then + echo_message "\033[31mNo\033[m" "No," ' fortify_source="no">' '"fortify_source":"no" }' else - if [[ $Proc_FS_cnt_checked -eq $Proc_FS_cnt_total ]]; then - echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes">' '"fortify_source":"yes" }' - else - if [[ "${Proc_FS_cnt_checked}" == "0" ]]; then - echo_message "\033[31mNo\033[m" "No," ' fortify_source="no">' '"fortify_source":"no" }' - else - echo_message "\033[33mPartial\033[m" "Partial," ' fortify_source="partial">' '"fortify_source":"partial" }' - fi - fi + echo_message '\033[32mYes\033[m' 'Yes,' ' fortify_source="yes">' '"fortify_source":"yes" }' fi } diff --git a/tests/test-checksec.sh b/tests/test-checksec.sh index 1d89d4e..1559b0a 100755 --- a/tests/test-checksec.sh +++ b/tests/test-checksec.sh @@ -7,7 +7,4 @@ DIR=$( "${DIR}"/xml-checks.sh || exit 2 "${DIR}"/json-checks.sh || exit 2 - -if [ ! -f /etc/photon-release ]; then - "${DIR}"/hardening-checks.sh || exit 2 -fi +"${DIR}"/hardening-checks.sh || exit 2