diff --git a/linux-exploit-suggester.sh b/linux-exploit-suggester.sh index 1990b9d..6ca507d 100755 --- a/linux-exploit-suggester.sh +++ b/linux-exploit-suggester.sh @@ -55,8 +55,8 @@ opt_skip_more_checks=false opt_skip_pkg_versions=false ARGS= -SHORTOPTS="hVfbsu:k:dp:g" -LONGOPTS="help,version,full,fetch-binaries,fetch-sources,uname:,kernel:,show-dos,pkglist-file:,short,kernelspace-only,userspace-only,skip-more-checks,skip-pkg-versions,cvelist-file:,checksec" +SHORTOPTS="hVfbsu:k:n:v:a:dp:g" +LONGOPTS="help,version,full,fetch-binaries,fetch-sources,uname:,kernel:,os-name:,os-version:,arch:,show-dos,pkglist-file:,short,kernelspace-only,userspace-only,skip-more-checks,skip-pkg-versions,cvelist-file:,checksec" ## exploits database declare -a EXPLOITS @@ -248,7 +248,7 @@ EOF EXPLOITS[((n++))]=$(cat <=2.6.0,ver<=2.6.30 -Tags: ubuntu=8.10,RHEL=4|5 +Tags: ubuntu=8.10,RHEL=4|5,centos=4|5 Rank: 1 exploit-db: 9545 Comments: /proc/sys/vm/mmap_min_addr needs to equal 0 @@ -310,9 +310,20 @@ exploit-db: 10018 EOF ) +EXPLOITS[((n++))]=$(cat <=2.2,ver<2.5,x86 +Tags: RHEL=7 +Rank: 1 +src-url: https://dl.packetstormsecurity.net/0304-exploits/ptrace-kmod.c +exploit-db: 3 +author: Wojciech Purczynski +EOF +) + EXPLOITS[((n++))]=$(cat <=2.6.26,ver<=2.6.34 +Reqs: pkg=linux-kernel,ver>=2.6.26,ver<=2.6.34,x86_64 Tags: debian=6.0{kernel:2.6.(32|33|34|35)-(1|2|trunk)-amd64},ubuntu=(10.04|10.10){kernel:2.6.(32|35)-(19|21|24)-server} Rank: 1 bin-url: https://web.archive.org/web/20111103042904/http://tarantula.by.ru/localroot/2.6.x/kmod2 @@ -1634,6 +1645,8 @@ usage() { echo " -V | --version - print version of this script" echo " -h | --help - print this help" echo " -k | --kernel - provide kernel version" + echo " -n | --os-name - provide distro name" + echo " -v | --os-version - provide distro version" echo " -u | --uname - provide 'uname -a' string" echo " --skip-more-checks - do not perform additional checks (kernel config, sysctl) to determine if exploit is applicable" echo " --skip-pkg-versions - skip checking for exact userspace package version (helps to avoid false negatives)" @@ -1682,8 +1695,11 @@ getPkgList() { # take package listing from provided file & detect if it's 'rpm -qa' listing or 'dpkg -l' or 'pacman -Q' listing of not recognized listing if [ "$opt_pkglist_file" = "true" -a -e "$pkglist_file" ]; then + # if distro name is provided, use file as is + if [ "$opt_distro_name" = "true" ]; then + PKG_LIST="$(cat "$pkglist_file")" # ubuntu/debian package listing file - if [ $(head -1 "$pkglist_file" | grep 'Desired=Unknown/Install/Remove/Purge/Hold') ]; then + elif [ $(head -1 "$pkglist_file" | grep 'Desired=Unknown/Install/Remove/Purge/Hold') ]; then PKG_LIST=$(cat "$pkglist_file" | awk '{print $2"-"$3}' | sed 's/:amd64//g') OS="debian" @@ -1846,7 +1862,7 @@ checkRequirement() { fi elif [[ "$IN" =~ ^x86_64$ ]] && [ "$ARCH" == "x86_64" -o "$ARCH" == "" ]; then return 0 - elif [[ "$IN" =~ ^x86$ ]] && [ "$ARCH" == "i386" -o "$ARCH" == "i686" -o "$ARCH" == "" ]; then + elif [[ "$IN" =~ ^x86$ ]] && [ "$ARCH" == "x86" -o "$ARCH" == "i386" -o "$ARCH" == "i686" -o "$ARCH" == "" ]; then return 0 elif [[ "$IN" =~ ^CONFIG_.*$ ]]; then @@ -2096,6 +2112,21 @@ while true; do KERNEL="$1" opt_kernel_version=true ;; + -a|--arch) + shift + ARCH="$1" + opt_arch=true + ;; + -n|--os-name) + shift + OS="$1" + opt_distro_name=true + ;; + -v|--os-version) + shift + DISTRO="$1" + opt_distro_version=true + ;; -d|--show-dos) opt_show_dos=true ;; @@ -2140,39 +2171,55 @@ if ((BASH_VERSINFO[0] < 4)); then exitWithErrMsg "Script needs Bash in version 4.0 or newer. Aborting." fi -# exit if both --kernel and --uname are set -[ "$opt_kernel_version" = "true" ] && [ $opt_uname_string = "true" ] && exitWithErrMsg "Switches -u|--uname and -k|--kernel are mutually exclusive. Aborting." +# --uname mode is not applicable when one of -k | -n | -v | -a switches are set +if [ $opt_uname_string = "true" ]; then + [ "$opt_kernel_version" = "true" ] && exitWithErrMsg "Switches -u|--uname and -k|--kernel are mutually exclusive. Aborting." + [ "$opt_distro_name" = "true" ] && exitWithErrMsg "Switches -u|--uname and -n|--os-name are mutually exclusive. Aborting." + [ "$opt_distro_version" = "true" ] && exitWithErrMsg "Switches -u|--uname and -v|--os-version are mutually exclusive. Aborting." + [ "$opt_arch" = "true" ] && exitWithErrMsg "Switches -u|--uname and -a|--arch are mutually exclusive. Aborting." +fi # exit if both --full and --short are set [ "$opt_full" = "true" ] && [ $opt_summary = "true" ] && exitWithErrMsg "Switches -f|--full and -g|--short are mutually exclusive. Aborting." -# --cvelist-file mode is standalone mode and is not applicable when one of -k | -u | -p | --checksec switches are set +# --cvelist-file mode is standalone mode and is not applicable when one of -k | -n | -v | -a | -u | -p | --checksec switches are set if [ "$opt_cvelist_file" = "true" ]; then [ ! -e "$CVELIST_FILE" ] && exitWithErrMsg "Provided CVE list file does not exists. Aborting." [ "$opt_kernel_version" = "true" ] && exitWithErrMsg "Switches -k|--kernel and --cvelist-file are mutually exclusive. Aborting." + [ "$opt_distro_name" = "true" ] && exitWithErrMsg "Switches -n|--os-name and --cvelist-file are mutually exclusive. Aborting." + [ "$opt_distro_version" = "true" ] && exitWithErrMsg "Switches -v|--os-version and --cvelist-file are mutually exclusive. Aborting." + [ "$opt_arch" = "true" ] && exitWithErrMsg "Switches -a|--arch and --cvelist-file are mutually exclusive. Aborting." [ "$opt_uname_string" = "true" ] && exitWithErrMsg "Switches -u|--uname and --cvelist-file are mutually exclusive. Aborting." [ "$opt_pkglist_file" = "true" ] && exitWithErrMsg "Switches -p|--pkglist-file and --cvelist-file are mutually exclusive. Aborting." fi -# --checksec mode is standalone mode and is not applicable when one of -k | -u | -p | --cvelist-file switches are set +# --checksec mode is standalone mode and is not applicable when one of -k | -n | -v | -a | -u | -p | --cvelist-file switches are set if [ "$opt_checksec_mode" = "true" ]; then [ "$opt_kernel_version" = "true" ] && exitWithErrMsg "Switches -k|--kernel and --checksec are mutually exclusive. Aborting." + [ "$opt_distro_name" = "true" ] && exitWithErrMsg "Switches -n|--os-name and --checksec are mutually exclusive. Aborting." + [ "$opt_distro_version" = "true" ] && exitWithErrMsg "Switches -v|--os-version and --checksec are mutually exclusive. Aborting." + [ "$opt_arch" = "true" ] && exitWithErrMsg "Switches -a|--arch and --checksec are mutually exclusive. Aborting." [ "$opt_uname_string" = "true" ] && exitWithErrMsg "Switches -u|--uname and --checksec are mutually exclusive. Aborting." [ "$opt_pkglist_file" = "true" ] && exitWithErrMsg "Switches -p|--pkglist-file and --checksec are mutually exclusive. Aborting." fi # extract kernel version and other OS info like distro name, distro version, etc. 3 possibilities here: -# case 1: --kernel set -if [ "$opt_kernel_version" == "true" ]; then +# case 1: --kernel | --os-name | --os-version | --arch set +if [ "$opt_kernel_version" == "true" ] || + [ "$opt_distro_name" == "true" ] || + [ "$opt_distro_version" == "true" ] || + [ "$opt_arch" == "true" ]; then + # TODO: add kernel version number validation - [ -z "$KERNEL" ] && exitWithErrMsg "Unrecognized kernel version given. Aborting." - ARCH="" - OS="" + [ -z "$KERNEL" ] && + [ -z "$OS" ] && + [ -z "$DISTRO" ] && + [ -z "$ARCH" ] && exitWithErrMsg "Kernel version, arch, distro name and/or distro version must be given. Aborting." # do not perform additional checks on current machine opt_skip_more_checks=true - # do not consider current OS + # get package file contents and extract OS if not provided already getPkgList "" "$PKGLIST_FILE" # case 2: --uname set @@ -2207,7 +2254,7 @@ elif [ "$opt_checksec_mode" = "true" ]; then exit 0 -# case 5: no --uname | --kernel | --cvelist-file | --checksec set +# case 5: no --uname | --kernel | --os-name | --os-version | --cvelist-file | --checksec set else # --pkglist-file NOT provided: take all info from current machine