You can create animated GIFs of an IP address's historical screenshots by using the Shodan API to retrieve host history and ImageMagick to process the images.
Workflow:
- Download a Shodan data file (e.g.,
screenshots.json.gz) using the Shodan CLI: shodan download screenshots.json.gz has_screenshot:true. - Use
shodan.helpers.iterate_files() to loop through the downloaded data. - Call
api.host(ip_str, history=True) to retrieve all historical banners for that IP. - Extract the
screenshot data from the opts field in the banner. - Use the
convert command from ImageMagick to compile the images into a GIF.
Note: The script requires a valid API_KEY and uses the arrow library to sort screenshots by timestamp for a smooth loop.
import arrow
import os
import shodan
import shodan.helpers as helpers
import sys
# Settings
API_KEY = 'YOUR_API_KEY'
MIN_SCREENS = 5
MAX_SCREENS = 24
api = shodan.Shodan(API_KEY)
# Iterate through the downloaded json.gz file
for result in helpers.iterate_files(sys.argv[1]):
# Get the historic info using the history=True flag
host = api.host(result['ip_str'], history=True)
screenshots = []
for banner in host['data']:
if 'opts' in banner and 'screenshot' in banner['opts']:
# Sort by time of day using arrow
timestamp = arrow.get(banner['timestamp']).time()
sort_key = timestamp.hour
screenshots.append((sort_key, banner['opts']['screenshot']['data']))
if len(screenshots) >= MAX_SCREENS:
break
if len(screenshots) >= MIN_SCREENS:
# Save individual frames to /tmp
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'))
# Create GIF using ImageMagick
os.system('convert -layers OptimizePlus -delay 5x10 /tmp/gif-image-*.jpg -loop 0 +dither -colors 256 -depth 8 data/{}.gif'.format(result['ip_str']))
os.system('rm -f /tmp/gif-image-*.jpg')
print(result['ip_str'])