blob: dd1f72e5417158a7edeec7959e57f350fcf6f891 [file] [log] [blame]
Richard Marian Thomaiyar14fddef2018-07-13 23:55:56 +05301#!/bin/bash
2#
3# The BSD License (http://www.opensource.org/licenses/bsd-license.php)
4# specifies the terms and conditions of use for checksec.sh:
5#
6# Copyright (c) 2009-2011, Tobias Klein.
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12#
13# * Redistributions of source code must retain the above copyright
14# notice, this list of conditions and the following disclaimer.
15# * Redistributions in binary form must reproduce the above copyright
16# notice, this list of conditions and the following disclaimer in
17# the documentation and/or other materials provided with the
18# distribution.
19# * Neither the name of Tobias Klein nor the name of trapkit.de may be
20# used to endorse or promote products derived from this software
21# without specific prior written permission.
22#
23# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
30# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
33# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
34# DAMAGE.
35#
36# Name : checksec.sh
37# Version : 1.5
38# Author : Tobias Klein
39# Date : November 2011
40# Download: http://www.trapkit.de/tools/checksec.html
41# Changes : http://www.trapkit.de/tools/checksec_changes.txt
42#
43# Description:
44#
45# Modern Linux distributions offer some mitigation techniques to make it
46# harder to exploit software vulnerabilities reliably. Mitigations such
47# as RELRO, NoExecute (NX), Stack Canaries, Address Space Layout
48# Randomization (ASLR) and Position Independent Executables (PIE) have
49# made reliably exploiting any vulnerabilities that do exist far more
50# challenging. The checksec.sh script is designed to test what *standard*
51# Linux OS and PaX (http://pax.grsecurity.net/) security features are being
52# used.
53#
54# As of version 1.3 the script also lists the status of various Linux kernel
55# protection mechanisms.
56#
57# Credits:
58#
59# Thanks to Brad Spengler (grsecurity.net) for the PaX support.
60# Thanks to Jon Oberheide (jon.oberheide.org) for the kernel support.
61# Thanks to Ollie Whitehouse (Research In Motion) for rpath/runpath support.
62#
63# Others that contributed to checksec.sh (in no particular order):
64#
65# Simon Ruderich, Denis Scherbakov, Stefan Kuttler, Radoslaw Madej,
66# Anthony G. Basile, Martin Vaeth and Brian Davis.
67#
68
69# global vars
70have_readelf=1
71verbose=false
72
73# FORTIFY_SOURCE vars
74FS_end=_chk
75FS_cnt_total=0
76FS_cnt_checked=0
77FS_cnt_unchecked=0
78FS_chk_func_libc=0
79FS_functions=0
80FS_libc=0
81
82# version information
83version() {
84 echo "checksec v1.5, Tobias Klein, www.trapkit.de, November 2011"
85 echo
86}
87
88# help
89help() {
90 echo "Usage: checksec [OPTION]"
91 echo
92 echo "Options:"
93 echo
94 echo " --file <executable-file>"
95 echo " --dir <directory> [-v]"
96 echo " --proc <process name>"
97 echo " --proc-all"
98 echo " --proc-libs <process ID>"
99 echo " --kernel"
100 echo " --fortify-file <executable-file>"
101 echo " --fortify-proc <process ID>"
102 echo " --version"
103 echo " --help"
104 echo
105 echo "For more information, see:"
106 echo " http://www.trapkit.de/tools/checksec.html"
107 echo
108}
109
110# check if command exists
111command_exists () {
112 type $1 > /dev/null 2>&1;
113}
114
115# check if directory exists
116dir_exists () {
117 if [ -d $1 ] ; then
118 return 0
119 else
120 return 1
121 fi
122}
123
124# check user privileges
125root_privs () {
126 if [ $(/usr/bin/id -u) -eq 0 ] ; then
127 return 0
128 else
129 return 1
130 fi
131}
132
133# check if input is numeric
134isNumeric () {
135 echo "$@" | grep -q -v "[^0-9]"
136}
137
138# check if input is a string
139isString () {
140 echo "$@" | grep -q -v "[^A-Za-z]"
141}
142
143# check file(s)
144filecheck() {
145 # check for RELRO support
146 if readelf -l $1 2>/dev/null | grep -q 'GNU_RELRO'; then
147 if readelf -d $1 2>/dev/null | grep -q 'BIND_NOW'; then
148 echo -n -e '\033[32mFull RELRO \033[m '
149 else
150 echo -n -e '\033[33mPartial RELRO\033[m '
151 fi
152 else
153 echo -n -e '\033[31mNo RELRO \033[m '
154 fi
155
156 # check for stack canary support
157 if readelf -s $1 2>/dev/null | grep -q '__stack_chk_fail'; then
158 echo -n -e '\033[32mCanary found \033[m '
159 else
160 echo -n -e '\033[31mNo canary found\033[m '
161 fi
162
163 # check for NX support
164 if readelf -W -l $1 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then
165 echo -n -e '\033[31mNX disabled\033[m '
166 else
167 echo -n -e '\033[32mNX enabled \033[m '
168 fi
169
170 # check for PIE support
171 if readelf -h $1 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then
172 echo -n -e '\033[31mNo PIE \033[m '
173 elif readelf -h $1 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then
174 if readelf -d $1 2>/dev/null | grep -q '(DEBUG)'; then
175 echo -n -e '\033[32mPIE enabled \033[m '
176 else
177 echo -n -e '\033[33mDSO \033[m '
178 fi
179 else
180 echo -n -e '\033[33mNot an ELF file\033[m '
181 fi
182
183 # check for rpath / run path
184 if readelf -d $1 2>/dev/null | grep -q 'rpath'; then
185 echo -n -e '\033[31mRPATH \033[m '
186 else
187 echo -n -e '\033[32mNo RPATH \033[m '
188 fi
189
190 if readelf -d $1 2>/dev/null | grep -q 'runpath'; then
191 echo -n -e '\033[31mRUNPATH \033[m '
192 else
193 echo -n -e '\033[32mNo RUNPATH \033[m '
194 fi
195}
196
197# check process(es)
198proccheck() {
199 # check for RELRO support
200 if readelf -l $1/exe 2>/dev/null | grep -q 'Program Headers'; then
201 if readelf -l $1/exe 2>/dev/null | grep -q 'GNU_RELRO'; then
202 if readelf -d $1/exe 2>/dev/null | grep -q 'BIND_NOW'; then
203 echo -n -e '\033[32mFull RELRO \033[m '
204 else
205 echo -n -e '\033[33mPartial RELRO \033[m '
206 fi
207 else
208 echo -n -e '\033[31mNo RELRO \033[m '
209 fi
210 else
211 echo -n -e '\033[31mPermission denied (please run as root)\033[m\n'
212 exit 1
213 fi
214
215 # check for stack canary support
216 if readelf -s $1/exe 2>/dev/null | grep -q 'Symbol table'; then
217 if readelf -s $1/exe 2>/dev/null | grep -q '__stack_chk_fail'; then
218 echo -n -e '\033[32mCanary found \033[m '
219 else
220 echo -n -e '\033[31mNo canary found \033[m '
221 fi
222 else
223 if [ "$1" != "1" ] ; then
224 echo -n -e '\033[33mPermission denied \033[m '
225 else
226 echo -n -e '\033[33mNo symbol table found\033[m '
227 fi
228 fi
229
230 # first check for PaX support
231 if cat $1/status 2> /dev/null | grep -q 'PaX:'; then
232 pageexec=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b6) )
233 segmexec=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b10) )
234 mprotect=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b8) )
235 randmmap=( $(cat $1/status 2> /dev/null | grep 'PaX:' | cut -b9) )
236 if [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "M" && "$randmmap" = "R" ]] ; then
237 echo -n -e '\033[32mPaX enabled\033[m '
238 elif [[ "$pageexec" = "p" && "$segmexec" = "s" && "$randmmap" = "R" ]] ; then
239 echo -n -e '\033[33mPaX ASLR only\033[m '
240 elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "m" && "$randmmap" = "R" ]] ; then
241 echo -n -e '\033[33mPaX mprot off \033[m'
242 elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "M" && "$randmmap" = "r" ]] ; then
243 echo -n -e '\033[33mPaX ASLR off\033[m '
244 elif [[ "$pageexec" = "P" || "$segmexec" = "S" ]] && [[ "$mprotect" = "m" && "$randmmap" = "r" ]] ; then
245 echo -n -e '\033[33mPaX NX only\033[m '
246 else
247 echo -n -e '\033[31mPaX disabled\033[m '
248 fi
249 # fallback check for NX support
250 elif readelf -W -l $1/exe 2>/dev/null | grep 'GNU_STACK' | grep -q 'RWE'; then
251 echo -n -e '\033[31mNX disabled\033[m '
252 else
253 echo -n -e '\033[32mNX enabled \033[m '
254 fi
255
256 # check for PIE support
257 if readelf -h $1/exe 2>/dev/null | grep -q 'Type:[[:space:]]*EXEC'; then
258 echo -n -e '\033[31mNo PIE \033[m '
259 elif readelf -h $1/exe 2>/dev/null | grep -q 'Type:[[:space:]]*DYN'; then
260 if readelf -d $1/exe 2>/dev/null | grep -q '(DEBUG)'; then
261 echo -n -e '\033[32mPIE enabled \033[m '
262 else
263 echo -n -e '\033[33mDynamic Shared Object\033[m '
264 fi
265 else
266 echo -n -e '\033[33mNot an ELF file \033[m '
267 fi
268}
269
270# check mapped libraries
271libcheck() {
272 libs=( $(awk '{ print $6 }' /proc/$1/maps | grep '/' | sort -u | xargs file | grep ELF | awk '{ print $1 }' | sed 's/:/ /') )
273
274 printf "\n* Loaded libraries (file information, # of mapped files: ${#libs[@]}):\n\n"
275
276 for element in $(seq 0 $((${#libs[@]} - 1)))
277 do
278 echo " ${libs[$element]}:"
279 echo -n " "
280 filecheck ${libs[$element]}
281 printf "\n\n"
282 done
283}
284
285# check for system-wide ASLR support
286aslrcheck() {
287 # PaX ASLR support
288 if !(cat /proc/1/status 2> /dev/null | grep -q 'Name:') ; then
289 echo -n -e ':\033[33m insufficient privileges for PaX ASLR checks\033[m\n'
290 echo -n -e ' Fallback to standard Linux ASLR check'
291 fi
292
293 if cat /proc/1/status 2> /dev/null | grep -q 'PaX:'; then
294 printf ": "
295 if cat /proc/1/status 2> /dev/null | grep 'PaX:' | grep -q 'R'; then
296 echo -n -e '\033[32mPaX ASLR enabled\033[m\n\n'
297 else
298 echo -n -e '\033[31mPaX ASLR disabled\033[m\n\n'
299 fi
300 else
301 # standard Linux 'kernel.randomize_va_space' ASLR support
302 # (see the kernel file 'Documentation/sysctl/kernel.txt' for a detailed description)
303 printf " (kernel.randomize_va_space): "
304 if /sbin/sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 1'; then
305 echo -n -e '\033[33mOn (Setting: 1)\033[m\n\n'
306 printf " Description - Make the addresses of mmap base, stack and VDSO page randomized.\n"
307 printf " This, among other things, implies that shared libraries will be loaded to \n"
308 printf " random addresses. Also for PIE-linked binaries, the location of code start\n"
309 printf " is randomized. Heap addresses are *not* randomized.\n\n"
310 elif /sbin/sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 2'; then
311 echo -n -e '\033[32mOn (Setting: 2)\033[m\n\n'
312 printf " Description - Make the addresses of mmap base, heap, stack and VDSO page randomized.\n"
313 printf " This, among other things, implies that shared libraries will be loaded to random \n"
314 printf " addresses. Also for PIE-linked binaries, the location of code start is randomized.\n\n"
315 elif /sbin/sysctl -a 2>/dev/null | grep -q 'kernel.randomize_va_space = 0'; then
316 echo -n -e '\033[31mOff (Setting: 0)\033[m\n'
317 else
318 echo -n -e '\033[31mNot supported\033[m\n'
319 fi
320 printf " See the kernel file 'Documentation/sysctl/kernel.txt' for more details.\n\n"
321 fi
322}
323
324# check cpu nx flag
325nxcheck() {
326 if grep -q nx /proc/cpuinfo; then
327 echo -n -e '\033[32mYes\033[m\n\n'
328 else
329 echo -n -e '\033[31mNo\033[m\n\n'
330 fi
331}
332
333# check for kernel protection mechanisms
334kernelcheck() {
335 printf " Description - List the status of kernel protection mechanisms. Rather than\n"
336 printf " inspect kernel mechanisms that may aid in the prevention of exploitation of\n"
337 printf " userspace processes, this option lists the status of kernel configuration\n"
338 printf " options that harden the kernel itself against attack.\n\n"
339 printf " Kernel config: "
340
341 if [ -f /proc/config.gz ] ; then
342 kconfig="zcat /proc/config.gz"
343 printf "\033[32m/proc/config.gz\033[m\n\n"
344 elif [ -f /boot/config-`uname -r` ] ; then
345 kconfig="cat /boot/config-`uname -r`"
346 printf "\033[33m/boot/config-`uname -r`\033[m\n\n"
347 printf " Warning: The config on disk may not represent running kernel config!\n\n";
348 elif [ -f "${KBUILD_OUTPUT:-/usr/src/linux}"/.config ] ; then
349 kconfig="cat ${KBUILD_OUTPUT:-/usr/src/linux}/.config"
350 printf "\033[33m%s\033[m\n\n" "${KBUILD_OUTPUT:-/usr/src/linux}/.config"
351 printf " Warning: The config on disk may not represent running kernel config!\n\n";
352 else
353 printf "\033[31mNOT FOUND\033[m\n\n"
354 exit 0
355 fi
356
357 printf " GCC stack protector support: "
358 if $kconfig | grep -qi 'CONFIG_CC_STACKPROTECTOR=y'; then
359 printf "\033[32mEnabled\033[m\n"
360 else
361 printf "\033[31mDisabled\033[m\n"
362 fi
363
364 printf " Strict user copy checks: "
365 if $kconfig | grep -qi 'CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y'; then
366 printf "\033[32mEnabled\033[m\n"
367 else
368 printf "\033[31mDisabled\033[m\n"
369 fi
370
371 printf " Enforce read-only kernel data: "
372 if $kconfig | grep -qi 'CONFIG_DEBUG_RODATA=y'; then
373 printf "\033[32mEnabled\033[m\n"
374 else
375 printf "\033[31mDisabled\033[m\n"
376 fi
377 printf " Restrict /dev/mem access: "
378 if $kconfig | grep -qi 'CONFIG_STRICT_DEVMEM=y'; then
379 printf "\033[32mEnabled\033[m\n"
380 else
381 printf "\033[31mDisabled\033[m\n"
382 fi
383
384 printf " Restrict /dev/kmem access: "
385 if $kconfig | grep -qi 'CONFIG_DEVKMEM=y'; then
386 printf "\033[31mDisabled\033[m\n"
387 else
388 printf "\033[32mEnabled\033[m\n"
389 fi
390
391 printf "\n"
392 printf "* grsecurity / PaX: "
393
394 if $kconfig | grep -qi 'CONFIG_GRKERNSEC=y'; then
395 if $kconfig | grep -qi 'CONFIG_GRKERNSEC_HIGH=y'; then
396 printf "\033[32mHigh GRKERNSEC\033[m\n\n"
397 elif $kconfig | grep -qi 'CONFIG_GRKERNSEC_MEDIUM=y'; then
398 printf "\033[33mMedium GRKERNSEC\033[m\n\n"
399 elif $kconfig | grep -qi 'CONFIG_GRKERNSEC_LOW=y'; then
400 printf "\033[31mLow GRKERNSEC\033[m\n\n"
401 else
402 printf "\033[33mCustom GRKERNSEC\033[m\n\n"
403 fi
404
405 printf " Non-executable kernel pages: "
406 if $kconfig | grep -qi 'CONFIG_PAX_KERNEXEC=y'; then
407 printf "\033[32mEnabled\033[m\n"
408 else
409 printf "\033[31mDisabled\033[m\n"
410 fi
411
412 printf " Prevent userspace pointer deref: "
413 if $kconfig | grep -qi 'CONFIG_PAX_MEMORY_UDEREF=y'; then
414 printf "\033[32mEnabled\033[m\n"
415 else
416 printf "\033[31mDisabled\033[m\n"
417 fi
418
419 printf " Prevent kobject refcount overflow: "
420 if $kconfig | grep -qi 'CONFIG_PAX_REFCOUNT=y'; then
421 printf "\033[32mEnabled\033[m\n"
422 else
423 printf "\033[31mDisabled\033[m\n"
424 fi
425
426 printf " Bounds check heap object copies: "
427 if $kconfig | grep -qi 'CONFIG_PAX_USERCOPY=y'; then
428 printf "\033[32mEnabled\033[m\n"
429 else
430 printf "\033[31mDisabled\033[m\n"
431 fi
432
433 printf " Disable writing to kmem/mem/port: "
434 if $kconfig | grep -qi 'CONFIG_GRKERNSEC_KMEM=y'; then
435 printf "\033[32mEnabled\033[m\n"
436 else
437 printf "\033[31mDisabled\033[m\n"
438 fi
439
440 printf " Disable privileged I/O: "
441 if $kconfig | grep -qi 'CONFIG_GRKERNSEC_IO=y'; then
442 printf "\033[32mEnabled\033[m\n"
443 else
444 printf "\033[31mDisabled\033[m\n"
445 fi
446
447 printf " Harden module auto-loading: "
448 if $kconfig | grep -qi 'CONFIG_GRKERNSEC_MODHARDEN=y'; then
449 printf "\033[32mEnabled\033[m\n"
450 else
451 printf "\033[31mDisabled\033[m\n"
452 fi
453
454 printf " Hide kernel symbols: "
455 if $kconfig | grep -qi 'CONFIG_GRKERNSEC_HIDESYM=y'; then
456 printf "\033[32mEnabled\033[m\n"
457 else
458 printf "\033[31mDisabled\033[m\n"
459 fi
460 else
461 printf "\033[31mNo GRKERNSEC\033[m\n\n"
462 printf " The grsecurity / PaX patchset is available here:\n"
463 printf " http://grsecurity.net/\n"
464 fi
465
466 printf "\n"
467 printf "* Kernel Heap Hardening: "
468
469 if $kconfig | grep -qi 'CONFIG_KERNHEAP=y'; then
470 if $kconfig | grep -qi 'CONFIG_KERNHEAP_FULLPOISON=y'; then
471 printf "\033[32mFull KERNHEAP\033[m\n\n"
472 else
473 printf "\033[33mPartial KERNHEAP\033[m\n\n"
474 fi
475 else
476 printf "\033[31mNo KERNHEAP\033[m\n\n"
477 printf " The KERNHEAP hardening patchset is available here:\n"
478 printf " https://www.subreption.com/kernheap/\n\n"
479 fi
480}
481
482# --- FORTIFY_SOURCE subfunctions (start) ---
483
484# is FORTIFY_SOURCE supported by libc?
485FS_libc_check() {
486 printf "* FORTIFY_SOURCE support available (libc) : "
487
488 if [ "${#FS_chk_func_libc[@]}" != "0" ] ; then
489 printf "\033[32mYes\033[m\n"
490 else
491 printf "\033[31mNo\033[m\n"
492 exit 1
493 fi
494}
495
496# was the binary compiled with FORTIFY_SOURCE?
497FS_binary_check() {
498 printf "* Binary compiled with FORTIFY_SOURCE support: "
499
500 for FS_elem_functions in $(seq 0 $((${#FS_functions[@]} - 1)))
501 do
502 if [[ ${FS_functions[$FS_elem_functions]} =~ _chk ]] ; then
503 printf "\033[32mYes\033[m\n"
504 return
505 fi
506 done
507 printf "\033[31mNo\033[m\n"
508 exit 1
509}
510
511FS_comparison() {
512 echo
513 printf " ------ EXECUTABLE-FILE ------- . -------- LIBC --------\n"
514 printf " FORTIFY-able library functions | Checked function names\n"
515 printf " -------------------------------------------------------\n"
516
517 for FS_elem_libc in $(seq 0 $((${#FS_chk_func_libc[@]} - 1)))
518 do
519 for FS_elem_functions in $(seq 0 $((${#FS_functions[@]} - 1)))
520 do
521 FS_tmp_func=${FS_functions[$FS_elem_functions]}
522 FS_tmp_libc=${FS_chk_func_libc[$FS_elem_libc]}
523
524 if [[ $FS_tmp_func =~ ^$FS_tmp_libc$ ]] ; then
525 printf " \033[31m%-30s\033[m | __%s%s\n" $FS_tmp_func $FS_tmp_libc $FS_end
526 let FS_cnt_total++
527 let FS_cnt_unchecked++
528 elif [[ $FS_tmp_func =~ ^$FS_tmp_libc(_chk) ]] ; then
529 printf " \033[32m%-30s\033[m | __%s%s\n" $FS_tmp_func $FS_tmp_libc $FS_end
530 let FS_cnt_total++
531 let FS_cnt_checked++
532 fi
533
534 done
535 done
536}
537
538FS_summary() {
539 echo
540 printf "SUMMARY:\n\n"
541 printf "* Number of checked functions in libc : ${#FS_chk_func_libc[@]}\n"
542 printf "* Total number of library functions in the executable: ${#FS_functions[@]}\n"
543 printf "* Number of FORTIFY-able functions in the executable : %s\n" $FS_cnt_total
544 printf "* Number of checked functions in the executable : \033[32m%s\033[m\n" $FS_cnt_checked
545 printf "* Number of unchecked functions in the executable : \033[31m%s\033[m\n" $FS_cnt_unchecked
546 echo
547}
548
549# --- FORTIFY_SOURCE subfunctions (end) ---
550
551if !(command_exists readelf) ; then
552 printf "\033[31mWarning: 'readelf' not found! It's required for most checks.\033[m\n\n"
553 have_readelf=0
554fi
555
556# parse command-line arguments
557case "$1" in
558
559 --version)
560 version
561 exit 0
562 ;;
563
564 --help)
565 help
566 exit 0
567 ;;
568
569 --dir)
570 if [ "$3" = "-v" ] ; then
571 verbose=true
572 fi
573 if [ $have_readelf -eq 0 ] ; then
574 exit 1
575 fi
576 if [ -z "$2" ] ; then
577 printf "\033[31mError: Please provide a valid directory.\033[m\n\n"
578 exit 1
579 fi
580 # remove trailing slashes
581 tempdir=`echo $2 | sed -e "s/\/*$//"`
582 if [ ! -d $tempdir ] ; then
583 printf "\033[31mError: The directory '$tempdir' does not exist.\033[m\n\n"
584 exit 1
585 fi
586 cd $tempdir
587 printf "RELRO STACK CANARY NX PIE RPATH RUNPATH FILE\n"
588 for N in [A-Za-z]*; do
589 if [ "$N" != "[A-Za-z]*" ]; then
590 # read permissions?
591 if [ ! -r $N ]; then
592 printf "\033[31mError: No read permissions for '$tempdir/$N' (run as root).\033[m\n"
593 else
594 # ELF executable?
595 out=`file $N`
596 if [[ ! $out =~ ELF ]] ; then
597 if [ "$verbose" = "true" ] ; then
598 printf "\033[34m*** Not an ELF file: $tempdir/"
599 file $N
600 printf "\033[m"
601 fi
602 else
603 filecheck $N
604 if [ `find $tempdir/$N \( -perm -004000 -o -perm -002000 \) -type f -print` ]; then
605 printf "\033[37;41m%s%s\033[m" $2 $N
606 else
607 printf "%s%s" $tempdir/ $N
608 fi
609 echo
610 fi
611 fi
612 fi
613 done
614 exit 0
615 ;;
616
617 --file)
618 if [ $have_readelf -eq 0 ] ; then
619 exit 1
620 fi
621 if [ -z "$2" ] ; then
622 printf "\033[31mError: Please provide a valid file.\033[m\n\n"
623 exit 1
624 fi
625 # does the file exist?
626 if [ ! -e $2 ] ; then
627 printf "\033[31mError: The file '$2' does not exist.\033[m\n\n"
628 exit 1
629 fi
630 # read permissions?
631 if [ ! -r $2 ] ; then
632 printf "\033[31mError: No read permissions for '$2' (run as root).\033[m\n\n"
633 exit 1
634 fi
635 # ELF executable?
636 out=`file $2`
637 if [[ ! $out =~ ELF ]] ; then
638 printf "\033[31mError: Not an ELF file: "
639 file $2
640 printf "\033[m\n"
641 exit 1
642 fi
643 printf "RELRO STACK CANARY NX PIE RPATH RUNPATH FILE\n"
644 filecheck $2
645 if [ `find $2 \( -perm -004000 -o -perm -002000 \) -type f -print` ] ; then
646 printf "\033[37;41m%s%s\033[m" $2 $N
647 else
648 printf "%s" $2
649 fi
650 echo
651 exit 0
652 ;;
653
654 --proc-all)
655 if [ $have_readelf -eq 0 ] ; then
656 exit 1
657 fi
658 cd /proc
659 printf "* System-wide ASLR"
660 aslrcheck
661 printf "* Does the CPU support NX: "
662 nxcheck
663 printf " COMMAND PID RELRO STACK CANARY NX/PaX PIE\n"
664 for N in [1-9]*; do
665 if [ $N != $$ ] && readlink -q $N/exe > /dev/null; then
666 printf "%16s" `head -1 $N/status | cut -b 7-`
667 printf "%7d " $N
668 proccheck $N
669 echo
670 fi
671 done
672 if [ ! -e /usr/bin/id ] ; then
673 printf "\n\033[33mNote: If you are running 'checksec.sh' as an unprivileged user, you\n"
674 printf " will not see all processes. Please run the script as root.\033[m\n\n"
675 else
676 if !(root_privs) ; then
677 printf "\n\033[33mNote: You are running 'checksec.sh' as an unprivileged user.\n"
678 printf " Too see all processes, please run the script as root.\033[m\n\n"
679 fi
680 fi
681 exit 0
682 ;;
683
684 --proc)
685 if [ $have_readelf -eq 0 ] ; then
686 exit 1
687 fi
688 if [ -z "$2" ] ; then
689 printf "\033[31mError: Please provide a valid process name.\033[m\n\n"
690 exit 1
691 fi
692 if !(isString "$2") ; then
693 printf "\033[31mError: Please provide a valid process name.\033[m\n\n"
694 exit 1
695 fi
696 cd /proc
697 printf "* System-wide ASLR"
698 aslrcheck
699 printf "* Does the CPU support NX: "
700 nxcheck
701 printf " COMMAND PID RELRO STACK CANARY NX/PaX PIE\n"
702 for N in `ps -Ao pid,comm | grep $2 | cut -b1-6`; do
703 if [ -d $N ] ; then
704 printf "%16s" `head -1 $N/status | cut -b 7-`
705 printf "%7d " $N
706 # read permissions?
707 if [ ! -r $N/exe ] ; then
708 if !(root_privs) ; then
709 printf "\033[31mNo read permissions for '/proc/$N/exe' (run as root).\033[m\n\n"
710 exit 1
711 fi
712 if [ ! `readlink $N/exe` ] ; then
713 printf "\033[31mPermission denied. Requested process ID belongs to a kernel thread.\033[m\n\n"
714 exit 1
715 fi
716 exit 1
717 fi
718 proccheck $N
719 echo
720 fi
721 done
722 exit 0
723 ;;
724
725 --proc-libs)
726 if [ $have_readelf -eq 0 ] ; then
727 exit 1
728 fi
729 if [ -z "$2" ] ; then
730 printf "\033[31mError: Please provide a valid process ID.\033[m\n\n"
731 exit 1
732 fi
733 if !(isNumeric "$2") ; then
734 printf "\033[31mError: Please provide a valid process ID.\033[m\n\n"
735 exit 1
736 fi
737 cd /proc
738 printf "* System-wide ASLR"
739 aslrcheck
740 printf "* Does the CPU support NX: "
741 nxcheck
742 printf "* Process information:\n\n"
743 printf " COMMAND PID RELRO STACK CANARY NX/PaX PIE\n"
744 N=$2
745 if [ -d $N ] ; then
746 printf "%16s" `head -1 $N/status | cut -b 7-`
747 printf "%7d " $N
748 # read permissions?
749 if [ ! -r $N/exe ] ; then
750 if !(root_privs) ; then
751 printf "\033[31mNo read permissions for '/proc/$N/exe' (run as root).\033[m\n\n"
752 exit 1
753 fi
754 if [ ! `readlink $N/exe` ] ; then
755 printf "\033[31mPermission denied. Requested process ID belongs to a kernel thread.\033[m\n\n"
756 exit 1
757 fi
758 exit 1
759 fi
760 proccheck $N
761 echo
762 libcheck $N
763 fi
764 exit 0
765 ;;
766
767 --kernel)
768 cd /proc
769 printf "* Kernel protection information:\n\n"
770 kernelcheck
771 exit 0
772 ;;
773
774 --fortify-file)
775 if [ $have_readelf -eq 0 ] ; then
776 exit 1
777 fi
778 if [ -z "$2" ] ; then
779 printf "\033[31mError: Please provide a valid file.\033[m\n\n"
780 exit 1
781 fi
782 # does the file exist?
783 if [ ! -e $2 ] ; then
784 printf "\033[31mError: The file '$2' does not exist.\033[m\n\n"
785 exit 1
786 fi
787 # read permissions?
788 if [ ! -r $2 ] ; then
789 printf "\033[31mError: No read permissions for '$2' (run as root).\033[m\n\n"
790 exit 1
791 fi
792 # ELF executable?
793 out=`file $2`
794 if [[ ! $out =~ ELF ]] ; then
795 printf "\033[31mError: Not an ELF file: "
796 file $2
797 printf "\033[m\n"
798 exit 1
799 fi
800 if [ -e /lib/libc.so.6 ] ; then
801 FS_libc=/lib/libc.so.6
802 elif [ -e /lib64/libc.so.6 ] ; then
803 FS_libc=/lib64/libc.so.6
804 elif [ -e /lib/i386-linux-gnu/libc.so.6 ] ; then
805 FS_libc=/lib/i386-linux-gnu/libc.so.6
806 elif [ -e /lib/x86_64-linux-gnu/libc.so.6 ] ; then
807 FS_libc=/lib/x86_64-linux-gnu/libc.so.6
808 else
809 printf "\033[31mError: libc not found.\033[m\n\n"
810 exit 1
811 fi
812
813 FS_chk_func_libc=( $(readelf -s $FS_libc | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') )
814 FS_functions=( $(readelf -s $2 | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') )
815
816 FS_libc_check
817 FS_binary_check
818 FS_comparison
819 FS_summary
820
821 exit 0
822 ;;
823
824 --fortify-proc)
825 if [ $have_readelf -eq 0 ] ; then
826 exit 1
827 fi
828 if [ -z "$2" ] ; then
829 printf "\033[31mError: Please provide a valid process ID.\033[m\n\n"
830 exit 1
831 fi
832 if !(isNumeric "$2") ; then
833 printf "\033[31mError: Please provide a valid process ID.\033[m\n\n"
834 exit 1
835 fi
836 cd /proc
837 N=$2
838 if [ -d $N ] ; then
839 # read permissions?
840 if [ ! -r $N/exe ] ; then
841 if !(root_privs) ; then
842 printf "\033[31mNo read permissions for '/proc/$N/exe' (run as root).\033[m\n\n"
843 exit 1
844 fi
845 if [ ! `readlink $N/exe` ] ; then
846 printf "\033[31mPermission denied. Requested process ID belongs to a kernel thread.\033[m\n\n"
847 exit 1
848 fi
849 exit 1
850 fi
851 if [ -e /lib/libc.so.6 ] ; then
852 FS_libc=/lib/libc.so.6
853 elif [ -e /lib64/libc.so.6 ] ; then
854 FS_libc=/lib64/libc.so.6
855 elif [ -e /lib/i386-linux-gnu/libc.so.6 ] ; then
856 FS_libc=/lib/i386-linux-gnu/libc.so.6
857 elif [ -e /lib/x86_64-linux-gnu/libc.so.6 ] ; then
858 FS_libc=/lib/x86_64-linux-gnu/libc.so.6
859 else
860 printf "\033[31mError: libc not found.\033[m\n\n"
861 exit 1
862 fi
863 printf "* Process name (PID) : %s (%d)\n" `head -1 $N/status | cut -b 7-` $N
864 FS_chk_func_libc=( $(readelf -s $FS_libc | grep _chk@@ | awk '{ print $8 }' | cut -c 3- | sed -e 's/_chk@.*//') )
865 FS_functions=( $(readelf -s $2/exe | awk '{ print $8 }' | sed 's/_*//' | sed -e 's/@.*//') )
866
867 FS_libc_check
868 FS_binary_check
869 FS_comparison
870 FS_summary
871 fi
872 exit 0
873 ;;
874
875 *)
876 if [ "$#" != "0" ] ; then
877 printf "\033[31mError: Unknown option '$1'.\033[m\n\n"
878 fi
879 help
880 exit 1
881 ;;
882esac