Last active
December 15, 2021 21:17
-
-
Save achillean/963eea552233d9550101 to your computer and use it in GitHub Desktop.
Create GIFs from a Shodan json.gz file using the API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Dependencies: | |
# - arrow | |
# - shodan | |
# - ImageMagick | |
# | |
# 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). | |
# shodan download screenshots.json.gz has_screenshot:true | |
# 2. Run the tool on the file: | |
# python gifcreator.py screenshots.json.gz | |
# 3. The GIFs will be stored in the local "data" directory | |
import arrow | |
import os | |
import shodan | |
import shodan.helpers as helpers | |
import sys | |
# Settings | |
API_KEY = '' | |
MIN_SCREENS = 5 # Number of screenshots that Shodan needs to have in order to make a GIF | |
MAX_SCREENS = 24 | |
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') | |
# We need to connect to the API to lookup the historical host information | |
api = shodan.Shodan(API_KEY) | |
for result in helpers.iterate_files(sys.argv[1]): | |
# Get the historic info | |
host = api.host(result['ip_str'], history=True) | |
# Count how many screenshots this host has | |
screenshots = [] | |
for banner in host['data']: | |
if 'opts' in banner and 'screenshot' in banner['opts']: | |
timestamp = arrow.get(banner['timestamp']).time() | |
sort_key = timestamp.hour | |
screenshots.append(( | |
sort_key, | |
banner['opts']['screenshot']['data'] | |
)) | |
if len(screenshots) >= MAX_SCREENS: | |
break | |
# Extract the screenshots and turn them into a GIF if we've got the necessary | |
# amount of images. | |
if len(screenshots) >= MIN_SCREENS: | |
for (i, screenshot) in enumerate(sorted(screenshots, key=lambda x: x[0], reverse=True)): | |
open('/tmp/gif-image-{}.jpg'.format(i), 'w').write(screenshot[1].decode('base64')) | |
os.system('convert -layers OptimizePlus -delay 5x10 /tmp/gif-image-*.jpg -loop 0 +dither -colors 256 -depth 8 data/{}.gif'.format(result['ip_str'])) | |
# Clean up the temporary files | |
os.system('rm -f /tmp/gif-image-*.jpg') | |
# Show a progress indicator | |
print result['ip_str'] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment