#!/usr/bin/env sh
|
#
|
# honggfuzz stackhash blacklist file create script
|
# -----------------------------------------
|
#
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
# you may not use this file except in compliance with the License.
|
# You may obtain a copy of the License at
|
#
|
# http://www.apache.org/licenses/LICENSE-2.0
|
#
|
# Unless required by applicable law or agreed to in writing, software
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# See the License for the specific language governing permissions and
|
# limitations under the License.
|
|
set -e # fail on unhandled error
|
set -u # fail on undefined variable
|
#set -x # debug
|
|
readonly tmpFile=$(pwd)/.hf.bl.txt
|
declare -a sysTools=("perl" "cut" "sort" "paste" "wc" "tr" "cat")
|
|
usage() {
|
cat <<_EOF
|
|
Usage: $(basename $0) [options]
|
OPTIONS:
|
-i|--input : input crash(es) directory / file
|
-B|--bl-file : output file to save found hashes (merge if exists)
|
-e|--ext : file extension of fuzzer files (e.g. fuzz)
|
-a|--arch : arch fuzzer have run against ('MAC' or 'LINUX')
|
|
INFO:
|
* Blacklist file sort mode only requires [-B/--bl-file] argument
|
* Hashes gather mode requires all argument to be set
|
_EOF
|
exit 1
|
}
|
|
command_exists () {
|
type "$1" &> /dev/null ;
|
}
|
|
# Check that system tools exist
|
for i in "${sysTools[@]}"
|
do
|
if ! command_exists $i; then
|
echo "[-] '$i' command not found"
|
exit 1
|
fi
|
done
|
|
INPUT_DIR=""
|
BL_FILE=""
|
FILE_EXT=""
|
ARCH=""
|
|
nArgs=$#
|
while [[ $# > 1 ]]
|
do
|
arg="$1"
|
case $arg in
|
-i|--input)
|
INPUT_DIR="$2"
|
shift
|
;;
|
-B|--bl-file)
|
BL_FILE="$2"
|
shift
|
;;
|
-e|--ext)
|
FILE_EXT="$2"
|
shift
|
;;
|
-a|--arch)
|
ARCH="$2"
|
shift
|
;;
|
*)
|
echo "[-] Invalid argument '$1'"
|
usage
|
;;
|
esac
|
shift
|
done
|
|
gatherMode=false
|
|
# Sort only mode
|
if [[ "$BL_FILE" == "" ]]; then
|
echo "[-] Missing blacklist file"
|
usage
|
fi
|
|
# Hashes gather mode
|
if [ $nArgs -gt 2 ]; then
|
if [[ "$INPUT_DIR" == "" || ! -e "$INPUT_DIR" ]]; then
|
echo "[-] Missing or invalid input directory"
|
usage
|
fi
|
|
if [[ "$FILE_EXT" == "" ]]; then
|
echo "[-] Missing file extension"
|
usage
|
fi
|
|
if [[ "$ARCH" != "MAC" && "$ARCH" != "LINUX" ]]; then
|
echo "[-] Invalid architecture, expecting 'MAC' or 'LINUX'"
|
usage
|
fi
|
|
if [[ "$ARCH" == "LINUX" ]]; then
|
STACKHASH_FIELD=5
|
elif [[ "$ARCH" == "MAC" ]]; then
|
STACKHASH_FIELD=6
|
else
|
echo "[-] Unsupported architecture"
|
exit 1
|
fi
|
gatherMode=true
|
fi
|
|
# save old data
|
if [ -f $BL_FILE ]; then
|
cat $BL_FILE > $tmpFile
|
oldCount=$(cat $BL_FILE | wc -l | tr -d " ")
|
else
|
oldCount=0
|
fi
|
|
if $gatherMode; then
|
echo "[*] Processing files from '$INPUT_DIR' ..."
|
find $INPUT_DIR -type f -iname "*.$FILE_EXT" | while read -r FILE
|
do
|
fileName=$(basename $FILE)
|
if ! echo $fileName | grep -qF ".STACK."; then
|
echo "[!] Skipping '$FILE'"
|
continue
|
fi
|
stackHash=$(echo $fileName | cut -d '.' -f$STACKHASH_FIELD)
|
|
# We don't want to lose crashes where unwinder failed
|
if [[ "$stackHash" != "0" && ! "$stackHash" =~ ^badbad.* ]]; then
|
echo $stackHash >> $tmpFile
|
fi
|
done
|
fi
|
|
# sort hex values
|
echo "[*] Sorting blacklist file entries"
|
perl -lpe '$_=hex' $tmpFile | \
|
paste -d" " - $tmpFile | sort -nu | cut -d" " -f 2- \
|
> $BL_FILE
|
|
entries=$(cat $BL_FILE | wc -l | tr -d " ")
|
echo "[*] $BL_FILE contains $entries blacklisted stack hashes"
|
|
rm $tmpFile
|