This script analyzes an IP address by querying VirusTotal, Censys, Shodan, and WHOIS, then uses Gemini to assess its reputation based on the findings.

Create an alias in ~/.bash_aliases

alias tipsy="python3 tipsy.py"

Create an environment variable for Gemini API in ~/.bashrc

export GEMINI_API_KEY="<API KEY>"

Tipsy.py

import sys
import requests
import json
import os
import ipaddress

def is_valid_ip(ip_string):
try:
ipaddress.ip_address(ip_string)
return True
except ValueError:
return False

#This fucntion sends the prompt to Gemini and cleans the response to be human reable
def rizz_up_gemini():
api_key = os.environ.get('GEMINI_API_KEY')
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={api_key}"

headers = {
"Content-Type": "application/json"
}

try:
response = requests.post(url, headers=headers, json=data) # Use json=data for automatic JSON encoding
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)

gemini_response = response.json() # Parse the JSON response
# Now gemini_response is a Python dictionary containing the Gemini response

# Example: Extract the generated text
if gemini_response.get("candidates"): # Check if candidates exist in the response
for candidate in gemini_response["candidates"]:
for part in candidate["content"].get("parts", []): # Handle missing parts
generated_text = part.get("text", "") # Handle missing text
print(generated_text)

# Or if you want to store the whole JSON response
# print(json.dumps(gemini_response, indent=2)) # Print the formatted JSON (optional)
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
except json.JSONDecodeError as e:
print(f"Error decoding JSON: {e}")
print(f"Response content: {response.text}") # Print the raw response for debugging

if __name__ == "__main__":

#Get the value added to the script and put it into value_to_output var
if len(sys.argv) > 1:
value_to_output = sys.argv[1]

#Is it a valid IP
if is_valid_ip(value_to_output):
#print(f"'{value_to_output}' is a valid IP address provided as a command-line argument.")
#output_value(value_to_output)

#Send IP to TI resources
vt_url="https://www.virustotal.com/gui/search/"+value_to_output
censys_url="https://search.censys.io/hosts/"+value_to_output
shodan_url="https://www.shodan.io/search?query="+value_to_output
whois_url="https://www.whois.com/whois/"+value_to_output

#Begin Interaction with Gemini
print("Is this IP malicious?")

#AI Prompt: Summarise VT results
data = {
"contents": [{
"parts": [{"text": "According to this link is the ip malicious: "+vt_url+". give me a short answer"}]
}]
}

#Sent the prompt to Gemini
rizz_up_gemini()

#AI Prompt: Summarise Censys data
data = {
"contents": [{
"parts": [{"text": "summarise this data"+censys_url}]
}]
}

#Sent the prompt to Gemini
rizz_up_gemini()

#AI Prompt: search the web - tell me if its malicious.
data = {
"contents": [{
"parts": [{"text": "is this ip "+value_to_output+" associated with any malware or threat actors or cyber attacks?"}]
}]
}

#Sent the prompt to Gemini
rizz_up_gemini()

#Print out useful TI resources
print("Here are some useful links:")
print(vt_url)
print(censys_url)
print(shodan_url)
print(whois_url)
else:
print(f"'{value_to_output}' is not a valid IP address. Try Harder :P")


#If they didnt feed in any IP then let them know how to use it
else:
print("Usage: python tipsy.py <IP Address>")