Timelapse GIF Creator using the Shodan API
#!/usr/bin/env python | |
# gifcreator.py | |
# | |
# Dependencies: | |
# - arrow | |
# - shodan | |
# | |
# Installation: | |
# sudo easy_install arrow shodan | |
# sudo apt-get install imagemagick | |
# | |
# Usage: | |
# 1. Download a json.gz file using the website or the Shodan command-line tool (https://cli.shodan.io). | |
# For example: | |
# shodan download --limit=100 screenshots.json.gz has_screenshot:true | |
# 2. Run the tool on the file: | |
# python gifcreator.py screenshots.json.gz | |
import arrow | |
import os | |
import shodan | |
import shodan.helpers as helpers | |
import sys | |
# Settings | |
API_KEY = '' | |
# The user has to provide at least 1 Shodan data file | |
if len(sys.argv) < 2: | |
print('Usage: {} <shodan-data.json.gz> ...'.format(sys.argv[0])) | |
sys.exit(1) | |
# GIFs are stored in the local "data" directory | |
os.mkdir('data') | |
# Setup the Shodan API object | |
api = shodan.Shodan(API_KEY) | |
# Loop over all of the Shodan data files the user provided | |
for banner in helpers.iterate_files(sys.argv[1:]): | |
# See whether the current banner has a screenshot, if it does then lets lookup | |
# more information about this IP | |
has_screenshot = helpers.get_screenshot(banner) | |
if has_screenshot: | |
ip = helpers.get_ip(banner) | |
print('Looking up {}'.format(ip)) | |
host = api.host(ip, history=True) | |
# Store all the historical screenshots for this IP | |
screenshots = [] | |
for tmp_banner in host['data']: | |
# Try to extract the image from the banner data | |
screenshot = helpers.get_screenshot(tmp_banner) | |
if screenshot: | |
# Sort the images by the time they were collected so the GIF will loop | |
# based on the local time regardless of which day the banner was taken. | |
timestamp = arrow.get(banner['timestamp']).time() | |
sort_key = timestamp.hour | |
# Add the screenshot to the list of screenshots which we'll use to create the timelapse | |
screenshots.append(( | |
sort_key, | |
screenshot['data'] | |
)) | |
# Extract the screenshots and turn them into a GIF if we've got more than a few images | |
if len(screenshots) >= 3: | |
# screenshots is a list where each item is a tuple of: | |
# (sort key, screenshot in base64 encoding) | |
# | |
# Lets sort that list based on the sort key and then use Python's enumerate | |
# to generate sequential numbers for the temporary image filenames | |
for (i, screenshot) in enumerate(sorted(screenshots, key=lambda x: x[0], reverse=True)): | |
# Create a temporary image file | |
# TODO: don't assume that all images are "jpg", use the mimetype instead | |
open('/tmp/gif-image-{}.jpg'.format(i), 'w').write(screenshot[1].decode('base64')) | |
# Create the actual GIF using the ImageMagick "convert" command | |
# The resulting GIFs are stored in the local data/ directory | |
os.system('convert -layers OptimizePlus -delay 5x10 /tmp/gif-image-*.jpg -loop 0 +dither -colors 256 -depth 8 data/{}.gif'.format(ip)) | |
# Clean up the temporary files | |
os.system('rm -f /tmp/gif-image-*.jpg') | |
# Show a progress indicator | |
print('GIF created for {}'.format(ip)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment