From ac526be452c6e09d179680e3aa5e587ac47d5619 Mon Sep 17 00:00:00 2001 From: pyllyukko Date: Wed, 14 Feb 2024 21:12:55 +0200 Subject: [PATCH 1/3] Added initial version of a Kerberos plugin --- default.prf | 1 + include/binaries | 1 + plugins/plugin_krb5_phase1 | 121 +++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 plugins/plugin_krb5_phase1 diff --git a/default.prf b/default.prf index ec043417..0e90fa04 100644 --- a/default.prf +++ b/default.prf @@ -144,6 +144,7 @@ plugin=software plugin=system-integrity plugin=systemd plugin=users +plugin=krb5 # Disable a particular plugin (will overrule an enabled plugin) #disable-plugin=authentication diff --git a/include/binaries b/include/binaries index a2b4895a..b65d5159 100644 --- a/include/binaries +++ b/include/binaries @@ -196,6 +196,7 @@ iptables-save) IPTABLESSAVEBINARY="${BINARY}"; LogText " Found known binary: iptables-save (firewall) - ${BINARY}" ;; istat) ISTATBINARY="${BINARY}"; LogText " Found known binary: istat (file information) - ${BINARY}" ;; journalctl) JOURNALCTLBINARY="${BINARY}"; LogText " Found known binary: journalctl (systemd journal) - ${BINARY}" ;; + kadmin.local) KADMINLOCALBINARY="${BINARY}"; LogText " Found known binary: kadmin.local (krb5) - ${BINARY}" ;; kldstat) KLDSTATBINARY="${BINARY}"; LogText " Found known binary: kldstat (kernel modules) - ${BINARY}" ;; kstat) KSTATBINARY="${BINARY}"; LogText " Found known binary: kstat (kernel statistics) - ${BINARY}" ;; launchctl) LAUNCHCTL_BINARY="${BINARY}"; SERVICE_MANAGER="launchd"; LogText " Found known binary: launchctl (launchd client) - ${BINARY}" ;; diff --git a/plugins/plugin_krb5_phase1 b/plugins/plugin_krb5_phase1 new file mode 100644 index 00000000..5a480dcb --- /dev/null +++ b/plugins/plugin_krb5_phase1 @@ -0,0 +1,121 @@ +#!/bin/sh + +######################################################################### +# +# * DO NOT REMOVE * +#----------------------------------------------------- +# PLUGIN_AUTHOR="pyllyukko" +# PLUGIN_CATEGORY=security +# PLUGIN_DATE=2024-02-14 +# PLUGIN_DESC=Kerberos +# PLUGIN_NAME=krb5 +# PLUGIN_REQUIRED_TESTS= +# PLUGIN_VERSION=0.1 +#----------------------------------------------------- +# +######################################################################### +# + + # Test for the prerequisites first + if [ -n "${KADMINLOCALBINARY}" ] + then + PREQS_MET="YES" + # Make sure krb5 debugging doesn't mess up the output + unset KRB5_TRACE + PRINCS="$(${KADMINLOCALBINARY} listprincs | ${TRBINARY:-tr} '\n' ' ')" + if [ -z "${PRINCS}" ] + then + PREQS_MET="NO" + fi + else + PREQS_MET="NO" + fi + + # Test : KRB5-0001 + # Description : Check that Kerberos principals have passwords that expire + Register --test-no KRB5-0001 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check that Kerberos principals have passwords that expire" --progress + if [ ${SKIPTEST} -eq 0 ]; then + for I in ${PRINCS} + do + FIND="$(${KADMINLOCALBINARY} getprinc "${I}" | ${GREPBINARY} '^Password expiration date:')" + if [ "${FIND}" = "Password expiration date: [never]" ] + then + LogText "Result: Kerberos principal ${I} has a password/key that never expires" + fi + done + fi +# +################################################################################# +# + + # Test : KRB5-0002 + # Description : Check last password change for Kerberos principals + Register --test-no KRB5-0002 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check last password change for Kerberos principals" --progress + if [ ${SKIPTEST} -eq 0 ]; then + for I in ${PRINCS} + do + FIND="$(${KADMINLOCALBINARY} getprinc "${I}" | ${SEDBINARY} -n '/^Last password change:\s\+/s/^Last password change:\s\+//p')" + if [ "${FIND}" = "[never]" ] + then + LogText "Result: Kerberos principal ${I} has a password/key that has never been changed" + else + J="$(date -d "${FIND}" +%s)" + if [ ${J} -lt $((NOW - 60 * 60 * 24 * 365)) ] + then + LogText "Result: Kerberos principal ${I} has had a password/key change over a year ago" + fi + fi + done + fi + +# +################################################################################# +# + + # Test : KRB5-0003 + # Description : Check that Kerberos principals have a policy associated to them + Register --test-no KRB5-0003 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check that Kerberos principals have a policy associated to them" --progress + if [ ${SKIPTEST} -eq 0 ]; then + for I in ${PRINCS} + do + FIND="$(${KADMINLOCALBINARY} getprinc "${I}" | ${GREPBINARY} '^Policy:')" + if [ "${FIND}" = "Policy: [none]" ] + then + LogText "Result: Kerberos principal ${I} does not have a policy associated to it" + fi + done + fi + +# +################################################################################# +# + + # Test : KRB5-0004 + # Description : Check various attributes for Kerberos principals + Register --test-no KRB5-0004 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check various attributes for Kerberos principals" --progress + if [ ${SKIPTEST} -eq 0 ]; then + for I in ${PRINCS} + do + J="$(${KADMINLOCALBINARY} getprinc "${I}" | ${SEDBINARY} -n 's/^Attributes:\s\+\(.\+\)$/\1/p')" + if ContainsString "^K/M@" "${I}" || \ + ContainsString "^kadmin/admin@" "${I}" || \ + ContainsString "^kadmin/changepw@" "${I}" || \ + ContainsString "^krbtgt/" "${I}" + then + if ! ContainsString "\bLOCKDOWN_KEYS\b" "${J}" + then + LogText "Result: Sensitive Kerberos principal ${I} does not have the lockdown_keys attribute" + fi + fi + done + fi + +# +################################################################################# +# + +unset PRINCS +unset I +unset J + +#EOF From 4d5b41cb4e92365c27b4e738ba70f8d9f4cf9f8a Mon Sep 17 00:00:00 2001 From: pyllyukko Date: Thu, 22 Feb 2024 11:59:02 +0200 Subject: [PATCH 2/3] plugin_krb5_phase1: Added few more tests * Check that admin principals have disallow_tgt_based attribute * Check that regular user principals have requires_pre_auth and disallow_svr attributes * Check for weak crypto * Use kdb5_util for this --- include/binaries | 1 + plugins/plugin_krb5_phase1 | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/binaries b/include/binaries index b65d5159..46359b3c 100644 --- a/include/binaries +++ b/include/binaries @@ -197,6 +197,7 @@ istat) ISTATBINARY="${BINARY}"; LogText " Found known binary: istat (file information) - ${BINARY}" ;; journalctl) JOURNALCTLBINARY="${BINARY}"; LogText " Found known binary: journalctl (systemd journal) - ${BINARY}" ;; kadmin.local) KADMINLOCALBINARY="${BINARY}"; LogText " Found known binary: kadmin.local (krb5) - ${BINARY}" ;; + kdb5_util) KDB5UTILBINARY="${BINARY}"; LogText " Found known binary: kdb5_util (krb5) - ${BINARY}" ;; kldstat) KLDSTATBINARY="${BINARY}"; LogText " Found known binary: kldstat (kernel modules) - ${BINARY}" ;; kstat) KSTATBINARY="${BINARY}"; LogText " Found known binary: kstat (kernel statistics) - ${BINARY}" ;; launchctl) LAUNCHCTL_BINARY="${BINARY}"; SERVICE_MANAGER="launchd"; LogText " Found known binary: launchctl (launchd client) - ${BINARY}" ;; diff --git a/plugins/plugin_krb5_phase1 b/plugins/plugin_krb5_phase1 index 5a480dcb..625a3bc9 100644 --- a/plugins/plugin_krb5_phase1 +++ b/plugins/plugin_krb5_phase1 @@ -10,14 +10,14 @@ # PLUGIN_DESC=Kerberos # PLUGIN_NAME=krb5 # PLUGIN_REQUIRED_TESTS= -# PLUGIN_VERSION=0.1 +# PLUGIN_VERSION=0.2 #----------------------------------------------------- # ######################################################################### # # Test for the prerequisites first - if [ -n "${KADMINLOCALBINARY}" ] + if [ -n "${KADMINLOCALBINARY}" ] && [ -n "${KDB5UTILBINARY}" ] then PREQS_MET="YES" # Make sure krb5 debugging doesn't mess up the output @@ -106,10 +106,39 @@ then LogText "Result: Sensitive Kerberos principal ${I} does not have the lockdown_keys attribute" fi + elif ContainsString "/admin@" "${I}" + then + if ! ContainsString "\bDISALLOW_TGT_BASED\b" "${J}" + then + LogText "Result: Kerberos admin principal ${I} does not have the disallow_tgt_based attribute" + fi + elif ContainsString "^[^/$]+@" "${I}" + then + if ! ContainsString "\bREQUIRES_PRE_AUTH\b.+\bDISALLOW_SVR\b" "${J}" + then + LogText "Result: Regular Kerberos user principal ${I} does not have the requires_pre_auth and/or the disallow_svr attribute" + fi fi done fi +# +################################################################################# +# + + # Test : KRB5-0005 + # Description : Check for weak crypto + Register --test-no KRB5-0005 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check for weak crypto" --progress + if [ ${SKIPTEST} -eq 0 ]; then + FIND=$(${KDB5UTILBINARY} tabdump keyinfo | ${AWKBINARY} '$4 ~ /(des|arcfour|cbc|sha1)/{print$1,$4}') + while read I J + do + LogText "Result: Kerberos principal ${I} has a key with weak cryptographic algorithm ${J}" + done << EOF +${FIND} +EOF + fi + # ################################################################################# # From 5182ce31fb5e3dc6a73952a43f13447670ebd2b0 Mon Sep 17 00:00:00 2001 From: pyllyukko Date: Wed, 15 May 2024 21:51:44 +0300 Subject: [PATCH 3/3] Changed the Kerberos plugin into a category According to @mboelen's recommendations: https://github.com/CISOfy/lynis/pull/1456#issuecomment-2110761098 --- db/languages/en | 1 + .../tests_kerberos | 92 +++++++++++++------ lynis | 2 +- 3 files changed, 67 insertions(+), 28 deletions(-) rename plugins/plugin_krb5_phase1 => include/tests_kerberos (53%) diff --git a/db/languages/en b/db/languages/en index 52ace1f7..689cc57e 100644 --- a/db/languages/en +++ b/db/languages/en @@ -63,6 +63,7 @@ SECTION_USB_DEVICES="USB Devices" SECTION_USERS_GROUPS_AND_AUTHENTICATION="Users, Groups and Authentication" SECTION_VIRTUALIZATION="Virtualization" SECTION_WEBSERVER="Software: webserver" +SECTION_KERBEROS="Kerberos" STATUS_ACTIVE="ACTIVE" STATUS_CHECK_NEEDED="CHECK NEEDED" STATUS_DEBUG="DEBUG" diff --git a/plugins/plugin_krb5_phase1 b/include/tests_kerberos similarity index 53% rename from plugins/plugin_krb5_phase1 rename to include/tests_kerberos index 625a3bc9..494a01b1 100644 --- a/plugins/plugin_krb5_phase1 +++ b/include/tests_kerberos @@ -1,22 +1,14 @@ #!/bin/sh -######################################################################### -# -# * DO NOT REMOVE * -#----------------------------------------------------- -# PLUGIN_AUTHOR="pyllyukko" -# PLUGIN_CATEGORY=security -# PLUGIN_DATE=2024-02-14 -# PLUGIN_DESC=Kerberos -# PLUGIN_NAME=krb5 -# PLUGIN_REQUIRED_TESTS= -# PLUGIN_VERSION=0.2 -#----------------------------------------------------- +InsertSection "${SECTION_KERBEROS}" + # ######################################################################### # - # Test for the prerequisites first + # Test : KRB-1000 + # Description : Check that Kerberos principals have passwords that expire + Register --test-no KRB-1000 --weight L --network NO --description "Check for Kerberos KDC tools" if [ -n "${KADMINLOCALBINARY}" ] && [ -n "${KDB5UTILBINARY}" ] then PREQS_MET="YES" @@ -30,10 +22,16 @@ else PREQS_MET="NO" fi + if [ "${PREQS_MET}" = "YES" ]; then + Display --indent 2 --text "- Check for Kerberos KDC and principals" --result "${STATUS_FOUND}" --color GREEN + else + Display --indent 2 --text "- Check for Kerberos KDC and principals" --result "${STATUS_NOT_FOUND}" --color WHITE + fi - # Test : KRB5-0001 + # Test : KRB-1010 # Description : Check that Kerberos principals have passwords that expire - Register --test-no KRB5-0001 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check that Kerberos principals have passwords that expire" --progress + Register --test-no KRB-1010 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check that Kerberos principals have passwords that expire" + FOUND=0 if [ ${SKIPTEST} -eq 0 ]; then for I in ${PRINCS} do @@ -41,59 +39,84 @@ if [ "${FIND}" = "Password expiration date: [never]" ] then LogText "Result: Kerberos principal ${I} has a password/key that never expires" + FOUND=1 fi done fi + if [ ${FOUND} -eq 1 ]; then + Display --indent 4 --text "- Principals without expiring password" --result "${STATUS_WARNING}" --color RED + ReportSuggestion "${TEST_NO}" "Make sure all your Kerberos principals have expiring passwords" + else + Display --indent 4 --text "- Principals without expiring password" --result "${STATUS_OK}" --color GREEN + fi # ################################################################################# # - # Test : KRB5-0002 + # Test : KRB-1020 # Description : Check last password change for Kerberos principals - Register --test-no KRB5-0002 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check last password change for Kerberos principals" --progress + Register --test-no KRB-1020 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check last password change for Kerberos principals" if [ ${SKIPTEST} -eq 0 ]; then + FOUND=0 for I in ${PRINCS} do FIND="$(${KADMINLOCALBINARY} getprinc "${I}" | ${SEDBINARY} -n '/^Last password change:\s\+/s/^Last password change:\s\+//p')" if [ "${FIND}" = "[never]" ] then LogText "Result: Kerberos principal ${I} has a password/key that has never been changed" + FOUND=1 else J="$(date -d "${FIND}" +%s)" if [ ${J} -lt $((NOW - 60 * 60 * 24 * 365)) ] then LogText "Result: Kerberos principal ${I} has had a password/key change over a year ago" + FOUND=1 fi fi done + if [ ${FOUND} -eq 1 ]; then + Display --indent 4 --text "- Principals with late password change" --result "${STATUS_WARNING}" --color RED + ReportSuggestion "${TEST_NO}" "Enforce frequent password/key change for your Kerberos principals" + else + Display --indent 4 --text "- Principals with late password change" --result "${STATUS_OK}" --color GREEN + fi fi # ################################################################################# # - # Test : KRB5-0003 + # Test : KRB-1030 # Description : Check that Kerberos principals have a policy associated to them - Register --test-no KRB5-0003 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check that Kerberos principals have a policy associated to them" --progress + Register --test-no KRB5-1030 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check that Kerberos principals have a policy associated to them" if [ ${SKIPTEST} -eq 0 ]; then + FOUND=0 for I in ${PRINCS} do FIND="$(${KADMINLOCALBINARY} getprinc "${I}" | ${GREPBINARY} '^Policy:')" if [ "${FIND}" = "Policy: [none]" ] then LogText "Result: Kerberos principal ${I} does not have a policy associated to it" + FOUND=1 fi done + if [ ${FOUND} -eq 1 ]; then + Display --indent 4 --text "- Principals without associated policy" --result "${STATUS_WARNING}" --color RED + ReportSuggestion "${TEST_NO}" "Make sure all your Kerberos principals have a policy associated to them" + else + Display --indent 4 --text "- Principals without associated policy" --result "${STATUS_OK}" --color GREEN + fi fi # ################################################################################# # - # Test : KRB5-0004 + # Test : KRB-1040 # Description : Check various attributes for Kerberos principals - Register --test-no KRB5-0004 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check various attributes for Kerberos principals" --progress + Register --test-no KRB5-1040 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check various attributes for Kerberos principals" if [ ${SKIPTEST} -eq 0 ]; then + FOUND=0 for I in ${PRINCS} do J="$(${KADMINLOCALBINARY} getprinc "${I}" | ${SEDBINARY} -n 's/^Attributes:\s\+\(.\+\)$/\1/p')" @@ -105,38 +128,53 @@ if ! ContainsString "\bLOCKDOWN_KEYS\b" "${J}" then LogText "Result: Sensitive Kerberos principal ${I} does not have the lockdown_keys attribute" + FOUND=1 fi elif ContainsString "/admin@" "${I}" then if ! ContainsString "\bDISALLOW_TGT_BASED\b" "${J}" then LogText "Result: Kerberos admin principal ${I} does not have the disallow_tgt_based attribute" + FOUND=1 fi elif ContainsString "^[^/$]+@" "${I}" then if ! ContainsString "\bREQUIRES_PRE_AUTH\b.+\bDISALLOW_SVR\b" "${J}" then LogText "Result: Regular Kerberos user principal ${I} does not have the requires_pre_auth and/or the disallow_svr attribute" + FOUND=1 fi fi done + if [ ${FOUND} -eq 1 ]; then + Display --indent 4 --text "- Checking principals for various attributes" --result "${STATUS_WARNING}" --color RED + ReportSuggestion "${TEST_NO}" "Harden your Kerberos principals with appropriate attributes" + else + Display --indent 4 --text "- Checking principals for various attributes" --result "${STATUS_OK}" --color GREEN + fi fi # ################################################################################# # - # Test : KRB5-0005 + # Test : KRB-1050 # Description : Check for weak crypto - Register --test-no KRB5-0005 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check for weak crypto" --progress + Register --test-no KRB-1050 --preqs-met ${PREQS_MET} --weight L --network NO --description "Check for weak crypto" if [ ${SKIPTEST} -eq 0 ]; then FIND=$(${KDB5UTILBINARY} tabdump keyinfo | ${AWKBINARY} '$4 ~ /(des|arcfour|cbc|sha1)/{print$1,$4}') - while read I J - do - LogText "Result: Kerberos principal ${I} has a key with weak cryptographic algorithm ${J}" - done << EOF + if [ -n "${FIND}" ]; then + while read I J + do + LogText "Result: Kerberos principal ${I} has a key with weak cryptographic algorithm ${J}" + done << EOF ${FIND} EOF + Display --indent 4 --text "- Principals with weak crypto" --result "${STATUS_WARNING}" --color RED + ReportSuggestion "${TEST_NO}" "Remove weak (des|arcfour|cbc|sha1) cryptographic keys from principals" + else + Display --indent 4 --text "- Principals with weak crypto" --result "${STATUS_OK}" --color GREEN + fi fi # diff --git a/lynis b/lynis index ee6cc596..95135e92 100755 --- a/lynis +++ b/lynis @@ -1018,7 +1018,7 @@ ${NORMAL} if [ "${TEST_GROUP_TO_CHECK}" = "all" ]; then LogText "Info: perform tests from all categories" - INCLUDE_TESTS="boot_services kernel memory_processes authentication shells \ + INCLUDE_TESTS="boot_services kernel memory_processes authentication kerberos shells \ filesystems usb storage storage_nfs nameservices dns ports_packages networking printers_spoolers \ mail_messaging firewalls webservers ssh snmp databases ldap php squid logging \ insecure_services banners scheduling accounting time crypto virtualization containers \