slimm609 / checksec.sh

Checksec.sh

Home Page:https://slimm609.github.io/checksec.sh/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Different results between v2.6.0 and v2.7.0

voxik opened this issue · comments

Using checksec to check fortification of Ruby in Fedora, the check passes with v2.6.0 while it fails with v2.7.0. The main difference is that FORTIFY reports Yes for the former while No for the latter. Here are some details:

2.6.0

$ checksec --version
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

checksec v2.6.0, Brian Davis, github.com/slimm609/checksec.sh, Dec 2015
Based off checksec v1.5, Tobias Klein, www.trapkit.de, November 2011

$ checksec --file=redhat-linux-build/libruby.so.3.3.1 
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	Symbols		FORTIFY	Fortified	Fortifiable	FILE
Full RELRO      Canary found      NX enabled    DSO             No RPATH   No RUNPATH   33201 Symbols	  Yes	11		28		redhat-linux-build/libruby.so.3.3.1

$ checksec --fortify-file=redhat-linux-build/libruby.so.3.3.1 
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

* FORTIFY_SOURCE support available (libc)    : Yes
* Binary compiled with FORTIFY_SOURCE support: Yes

 ------ EXECUTABLE-FILE ------- . -------- LIBC --------
 Fortifiable library functions | Checked function names
 -------------------------------------------------------
 strlcpy_chk                    | __strlcpy_chk
 strlcpy                        | __strlcpy_chk
 strlcpy_chk                    | __strlcpy_chk
 strlcpy                        | __strlcpy_chk
 poll                           | __poll_chk
 poll                           | __poll_chk
 realpath                       | __realpath_chk
 realpath                       | __realpath_chk
 stpcpy                         | __stpcpy_chk
 stpcpy                         | __stpcpy_chk
 getlogin_r                     | __getlogin_r_chk
 getlogin_r                     | __getlogin_r_chk
 printf_chk                     | __printf_chk
 printf_chk                     | __printf_chk
 getgroups                      | __getgroups_chk
 getgroups_chk                  | __getgroups_chk
 getgroups                      | __getgroups_chk
 getgroups_chk                  | __getgroups_chk
 longjmp_chk                    | __longjmp_chk
 longjmp                        | __longjmp_chk
 longjmp_chk                    | __longjmp_chk
 longjmp                        | __longjmp_chk
 ppoll                          | __ppoll_chk
 ppoll                          | __ppoll_chk
 explicit_bzero_chk             | __explicit_bzero_chk
 explicit_bzero_chk             | __explicit_bzero_chk
 memcpy_chk                     | __memcpy_chk
 memcpy                         | __memcpy_chk
 memcpy_chk                     | __memcpy_chk
 memcpy                         | __memcpy_chk
 vfprintf_chk                   | __vfprintf_chk
 vfprintf_chk                   | __vfprintf_chk
 vsnprintf_chk                  | __vsnprintf_chk
 vsnprintf_chk                  | __vsnprintf_chk
 memmove                        | __memmove_chk
 memmove_chk                    | __memmove_chk
 memmove                        | __memmove_chk
 memmove_chk                    | __memmove_chk
 fprintf_chk                    | __fprintf_chk
 fprintf_chk                    | __fprintf_chk
 fread                          | __fread_chk
 fread                          | __fread_chk
 strlcat                        | __strlcat_chk
 strlcat                        | __strlcat_chk
 memset                         | __memset_chk
 memset_chk                     | __memset_chk
 memset                         | __memset_chk
 memset_chk                     | __memset_chk
 getcwd                         | __getcwd_chk
 getcwd                         | __getcwd_chk
 read                           | __read_chk
 read                           | __read_chk
 pread                          | __pread_chk
 pread                          | __pread_chk
 readlink                       | __readlink_chk
 readlink                       | __readlink_chk

SUMMARY:

* Number of checked functions in libc                : 83
* Total number of library functions in the executable: 35355
* Number of Fortifiable functions in the executable : 56
* Number of checked functions in the executable      : 22
* Number of unchecked functions in the executable    : 34

2.7.0

$ checksec --version
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

checksec v2.7.0, Brian Davis, github.com/slimm609/checksec.sh, Dec 2015
Based off checksec v1.5, Tobias Klein, www.trapkit.de, November 2011

$ checksec --file=redhat-linux-build/libruby.so.3.3.1 
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	Symbols		FORTIFY	Fortified	Fortifiable	FILE
Full RELRO      Canary found      NX enabled    DSO             No RPATH   No RUNPATH   33201 Symbols	  No	11		28		redhat-linux-build/libruby.so.3.3.1

$ checksec --fortify-file=redhat-linux-build/libruby.so.3.3.1 
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

* FORTIFY_SOURCE support available (libc)    : Yes
* Binary compiled with FORTIFY_SOURCE support: Yes

 ------ EXECUTABLE-FILE ------- . -------- LIBC --------
 Fortifiable library functions | Checked function names
 -------------------------------------------------------
 explicit_bzero_chk             | __explicit_bzero_chk
 fprintf_chk                    | __fprintf_chk
 fread                          | __fread_chk
 getcwd                         | __getcwd_chk
 getgroups                      | __getgroups_chk
 getgroups_chk                  | __getgroups_chk
 getlogin_r                     | __getlogin_r_chk
 longjmp                        | __longjmp_chk
 longjmp_chk                    | __longjmp_chk
 memcpy                         | __memcpy_chk
 memcpy_chk                     | __memcpy_chk
 memmove                        | __memmove_chk
 memmove_chk                    | __memmove_chk
 memset                         | __memset_chk
 memset_chk                     | __memset_chk
 poll                           | __poll_chk
 ppoll                          | __ppoll_chk
 pread                          | __pread_chk
 printf_chk                     | __printf_chk
 read                           | __read_chk
 readlink                       | __readlink_chk
 realpath                       | __realpath_chk
 stpcpy                         | __stpcpy_chk
 strlcat                        | __strlcat_chk
 strlcpy                        | __strlcpy_chk
 strlcpy_chk                    | __strlcpy_chk
 vfprintf_chk                   | __vfprintf_chk
 vsnprintf_chk                  | __vsnprintf_chk

SUMMARY:

* Number of checked functions in libc                : 83
* Total number of library functions in the executable: 14093
* Number of Fortifiable functions in the executable : 28
* Number of checked functions in the executable      : 11
* Number of unchecked functions in the executable    : 17

See here.
Try 2.7.1 from here.
After accepting Pull requests from here, it will be OK for processes as well.

Thx for all the pointers 👏

Trying with 2.7.1, these are the results now:

$ checksec --version
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

checksec v2.7.1, Brian Davis, github.com/slimm609/checksec.sh, Dec 2015
Based off checksec v1.5, Tobias Klein, www.trapkit.de, November 2011

 checksec --file=redhat-linux-build/libruby.so.3.3.1
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	Symbols		FORTIFY	Fortified	Fortifiable	FILE
Full RELRO      Canary found      NX enabled    DSO             No RPATH   No RUNPATH   33201 Symbols	  Partial	11		28		redhat-linux-build/libruby.so.3.3.1

$ checksec --fortify-file=redhat-linux-build/libruby.so.3.3.1 
WARNING: 'openssl' not found! It's required for most checks.

WARNING: Not all necessary commands found. Some tests might not work!

* FORTIFY_SOURCE support available (libc)    : Yes
* Binary compiled with FORTIFY_SOURCE support: Yes

 ------ EXECUTABLE-FILE ------- . -------- LIBC --------
 Fortifiable library functions | Checked function names
 -------------------------------------------------------
 explicit_bzero_chk             | __explicit_bzero_chk
 fprintf_chk                    | __fprintf_chk
 fread                          | __fread_chk
 getcwd                         | __getcwd_chk
 getgroups                      | __getgroups_chk
 getgroups_chk                  | __getgroups_chk
 getlogin_r                     | __getlogin_r_chk
 longjmp                        | __longjmp_chk
 longjmp_chk                    | __longjmp_chk
 memcpy                         | __memcpy_chk
 memcpy_chk                     | __memcpy_chk
 memmove                        | __memmove_chk
 memmove_chk                    | __memmove_chk
 memset                         | __memset_chk
 memset_chk                     | __memset_chk
 poll                           | __poll_chk
 ppoll                          | __ppoll_chk
 pread                          | __pread_chk
 printf_chk                     | __printf_chk
 read                           | __read_chk
 readlink                       | __readlink_chk
 realpath                       | __realpath_chk
 stpcpy                         | __stpcpy_chk
 strlcat                        | __strlcat_chk
 strlcpy                        | __strlcpy_chk
 strlcpy_chk                    | __strlcpy_chk
 vfprintf_chk                   | __vfprintf_chk
 vsnprintf_chk                  | __vsnprintf_chk

SUMMARY:

* Number of checked functions in libc                : 83
* Total number of library functions in the executable: 14093
* Number of Fortifiable functions in the executable : 28
* Number of checked functions in the executable      : 11
* Number of unchecked functions in the executable    : 17

So the FORTIFY changed from No to Partial.

However now I am puzzled how to interpret the results. I guess the reason for Partial is the "* Number of unchecked functions in the executable : 17". Is there something to do about them?

The coded cases can now be:

if [[ "${libc_found}" == "false" ]] || [[ "${FS_cnt_total}" == "0" ]]; then

  • N/A if not applicable (doesn't use libc or no functions)
  • Yes if Fortified=Fortifiable
  • No if Fortified=0
  • Partial if Fortified != Fortifiable (but different from zero)
    In the latter case, Fortify modes (=1, =2, =3) of operation may not be appropriate or cannot be applied.

Better Partial than No or worse Yes depends on the case!
#235 (comment)

Better Partial than No or worse Yes depends on the case!

👍

I think I start to understand what is going on. Looking back at the 2.6.0 outputs, this:

FORTIFY	Fortified	Fortifiable
Yes	11		28

correlates with the:

* Number of Fortifiable functions in the executable : 28
* Number of checked functions in the executable      : 11
* Number of unchecked functions in the executable    : 17

In 2.7, this was changed that the FORTIFY == Yes only when the result would be:

* Number of Fortifiable functions in the executable : 28
* Number of checked functions in the executable      : 28
* Number of unchecked functions in the executable    : 0

And FORTIFY == No for the following case

* Number of Fortifiable functions in the executable : 28
* Number of checked functions in the executable      : 0
* Number of unchecked functions in the executable    : 28

All in between is Partial.

Just let me explain the context why I am using checksec. This started with Fedora introducing fortification flags. My memory is a bit hazy, but I believe that either there was some issue and despite Fedora setting the fortification, Ruby was not fortified. Or maybe I just wanted to be sure that I won't mess up. Therefore I have added the checksec into the mix, while I can't say I really know what I am doing.

Based on this:

  1. I'd still rather use checksec naively, i.e. ensuring there are no changes between Ruby builds. If there are changes, make sure I know about them and asking experts for help.
  2. The output of the tool could be more helpful (and yes, it seems that the Partial intends to improve this 👍). Up until now, I had no idea what the Fortified / Fortifiable fields means and that they are actually used to derive the FORTIFY value. In retrospect, checking the Fortified / Fortifiable fields and ignoring the FORTIFY value altogether would make more sense for my case. Maybe all these fields should have been combined into one field or either the numbers or just the FORTIFY status displayed based on the --verbose / --extended flags. Alternatively, this could be better captured in documentation / manpages

Nevertheless, I am closing this ticket, because my original concern was addressed. Thank you for your support.