#!/bin/bash
# Copyright 2020 FireEye, Inc. and Citrix Systems, Inc.
#
# This is meant to be run on a modern Linux system.
# e.g. we'll refer to `base64` rather than `b64decode`.
#
# strategy:
#
#  1. create temp directory
#  2. copy our resources into temp directory
#  3. tgz the directory
#  4. base64 directory
#  5. emit .sh script containing bootstrap and base64 blob
#  6. remove temp directory

# unset variables are errors
set -o nounset;
# any failed commands are errors
set -o errexit;

# current_directory is the path to the directory containing this script.
# ref: https://stackoverflow.com/a/4774063/87207
readonly current_directory="$( cd "$(dirname "$0")" ; pwd -P )"

# generate a version file with git metadata
version_file="$current_directory/version.sh";
if [ -f "$version_file" ]; then
    rm "$version_file";
fi
echo "#!/usr/bin/bash" > $version_file;
echo "git_tag=\"$(git describe --tags)\";" >> $version_file;
echo "git_hash=\"$(git rev-parse HEAD)\";" >> $version_file;

# not all FreeBSD/NetScaler devices have mktemp.
readonly staging_directory="/tmp/$(date +%s)";
mkdir "$staging_directory";

cp "$current_directory/ioc-scanner-CVE-2019-19781.sh" "$staging_directory/ioc-scanner-CVE-2019-19781.sh";
cp "$current_directory/version.sh" "$staging_directory/version.sh";
cp -r "$current_directory/scanners/" "$staging_directory/scanners/" >/dev/null;
cd "$staging_directory";
    tar czvf "payload.tgz" "ioc-scanner-CVE-2019-19781.sh" "./scanners/" "version.sh" >/dev/null;
cd - >/dev/null;
readonly payload=$(cat "$staging_directory/payload.tgz" | base64 -);

# FreeBSD/NetScaler has bash at /usr/bin/bash
# while linux uses /bin/bash.
# our target audience is NetScaler devices, so prefer that.
# all users should really invoke bash explicitly, like: `bash ioc-scanner.sh`
echo "#!/usr/bin/bash";
echo "# Indicator of Compromise Scanner for CVE-2019-19781 (Citrix ADC)";
echo "# Copyright 2020 FireEye, Inc. and Citrix Systems, Inc."
echo "# Build date: $(date)"
echo "# Git hash: $(git rev-parse HEAD)"
echo "#";
echo "# Usage:";
echo "#";
echo "#    bash ioc-scanner-CVE-2019-19781.sh [-v|--verbose] [root path, optional, default: /]";
echo "#";
echo "# Must be run as root when running against a live device.";
echo "# Writes status to STDERR.";
echo "# Writes results to STDOUT.";
echo "# Non-zero status upon failure.";
echo 'readonly staging_directory="/tmp/$(date +%s)";';
echo 'mkdir "$staging_directory";';
echo 'readonly payload=$(cat <<HERE';
echo "$payload";
echo "HERE";
echo ");";
echo 'if [ -f "/usr/bin/b64decode" ]; then';
echo '  # this is what FreeBSD/NetScaler will use';
echo '  echo -n "$payload" | b64decode -r > "$staging_directory/payload.tgz";';
echo 'elif [ $(uname -s) == "Darwin" ]; then';
echo '  # this is what macOS will use';
echo '  echo -n "$payload" | base64 -D - > "$staging_directory/payload.tgz";';
echo 'else';
echo '  # this is what Linux will use';
echo '  echo -n "$payload" | base64 -d - > "$staging_directory/payload.tgz";';
echo 'fi';
echo 'cd "$staging_directory" >/dev/null;';
echo '  tar xzvf "payload.tgz" >/dev/null 2>/dev/null;';
echo 'cd - >/dev/null;';
echo 'bash "$staging_directory/ioc-scanner-CVE-2019-19781.sh" "$@";';
echo 'readonly result="$?";';
echo 'rm -rf "$staging_directory";';
echo 'exit "$result";'

rm -rf "$staging_directory";