-
Notifications
You must be signed in to change notification settings - Fork 37
/
Copy pathkeyscanner.py
executable file
·195 lines (181 loc) · 6.5 KB
/
keyscanner.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#!/usr/bin/python2
# coding: utf-8
# ssh hostkey grabber/search-shodan-for tool.
# useful for identifying static keys for fun.
# References/Based-On:
# http://www.iodigitalsec.com/ssh-fingerprint-and-hostkey-with-paramiko-in-python/
# https://shodan.readthedocs.org/en/latest/
# https://github.com/ojarva/python-sshpubkeys
# imports here...
from sshpubkeys import SSHKey # ssh key shit
import paramiko # for ssh bullshit
import argparse # for args and shit
import hashlib # for hashing shit
import socket # so we can connect to shit
import shodan # shodan all the shit
import base64 # base64 encryptin' shit liekpro
import socks # for tor support
import sys # exits and shit
# globals.
SHODAN_API_KEY = "" # change this
# colours. don't change these
RED = "\x1b[1;31m"
GREEN = "\x1b[1;32m"
CLEAR = "\x1b[0m"
CYAN = "\x1b[1;36m"
BLUE = "\x1b[1;34m"
YELLOW = "\x1b[1;33m"
# for debugging. True or False.
DEBUG = True # if somethings going wierd just enable debug
def msg_info(msg): # informational.
print "%s{i} %s%s" %(CYAN, msg, CLEAR)
def msg_status(msg): # statuses and shit
print "%s{*} %s%s" %(BLUE, msg, CLEAR)
def msg_success(msg): # for the wins
print "%s{+} %s%s" %(GREEN, msg, CLEAR)
def msg_fail(msg): # when shit breaks catastrophically, we return False
print "%s{!} %s%s" %(RED, msg, CLEAR)
return False
def msg_debug(msg): # for debug messages
if DEBUG == True:
print "%s{>} %s%s" %(YELLOW, msg, CLEAR)
else:
pass
def pubkey_to_fingerprint(pubkey): # done
# converts pubkey in ssh-rsa BASE64SHIT to fingerprint
try:
msg_debug("Creating SSH key fingerprint")
ssh = SSHKey(pubkey)
fingerprint = ssh.hash()
return fingerprint
except Exception, e:
msg_debug(e)
msg_fail("ssh fingerprint generation failed.")
def grab_pubkey(host, port, tor=False): # done
# connect to a remote host/port and get a ssh public key
try:
msg_debug("Creating socket()")
if tor == False:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
else:
msg_debug("Using Tor, so using a socks socket thing")
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 9050, True)
s = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM)
except Exception, e:
msg_debug(e)
return msg_fail("Failed to create socket!")
try:
msg_status("Connecting to %s:%s" %(host, port))
s.connect((host, int(port)))
except Exception, e:
msg_debug(e)
return msg_fail("Failed to connect!")
try:
msg_debug("Creating SSH client")
trans = paramiko.Transport(s)
trans.start_client()
except Exception, e:
msg_debug(e)
return msg_fail("Failed to start SSH client")
try:
msg_status("Connected... Grabbing SSH key now")
binary_key = trans.get_remote_server_key()
except Exception, e:
msg_debug(e)
return msg_fail("Grabbing SSH key failure!")
# the next 3 lines are bad and I should feel bad. fuck ssh.
pubkey_data = base64.encodestring(binary_key.__str__()).replace('\n', '')
pubkey_type = binary_key.get_name()
pubkey = "%s %s" %(pubkey_type, pubkey_data)
return pubkey
def remote_query(host, port, tor=False): # done
pubkey = grab_pubkey(host, port, tor)
if pubkey != False:
fingerprint = pubkey_to_fingerprint(pubkey)
msg_info("SSH Fingerprint: %s" %(fingerprint))
if fingerprint != None:
do_shodan(fingerprint)
else:
msg_status("Fingerprint was none, skipping shodan...")
else:
msg_status("Pubkey grab failed, right? Lets move on...")
def list_query(hosts, tor=False):
hostlist = open(hosts, "r").readlines()
for target in hostlist:
target = target.strip()
if ":" in target:
host = target.split(":")[0]
port = target.split(":")[1]
remote_query(host=host, port=port, tor=tor)
else:
remote_query(host=target, port=22, tor=tor)
def local_query(keyfile): # done
msg_status("Running query using %s" %(keyfile))
try:
msg_debug("Opening file for reading...")
f = open(keyfile, "rb")
except Exception, e:
msg_debug(e)
return msg_fail("File open failed.")
try:
pubkey = f.read()
except Exception, e:
msg_debug(e)
return msg_fail("File read failed.")
fingerprint = pubkey_to_fingerprint(pubkey)
msg_info("SSH Fingerprint: %s" %(fingerprint))
do_shodan(fingerprint)
def do_shodan(fingerprint):
# run shodan query.
try:
api = shodan.Shodan(SHODAN_API_KEY)
except Exception, e:
msg_debug(e)
return msg_fail("Shodan API (Key?) failed.")
try:
msg_status("Querying Shodan now...")
results = api.search(fingerprint)
except Exception, e:
msg_debug(e)
return msg_fail("Shodan query failure :(")
try:
msg_success("Hits Found: %s" %(results['total']))
if results['total'] > 0:
msg_info("Printing IP's now...")
for result in results['matches']:
print result['ip_str']
else:
pass
except Exception, e:
msg_debug(e)
return msg_fail("Some fucking shit broke.")
def main():
# args: -f (file), -i (ip), -p (port)
parser = argparse.ArgumentParser("ssh public key scanner")
parser.add_argument("-f", help="SSH PublicKey file")
parser.add_argument("-F", help="SSH fingerprint")
parser.add_argument("-i", help="Target IP/Host")
parser.add_argument("-l", help="Target IP/Host list (one per line, in host:port format or just host format)")
parser.add_argument("-p", help="Target Port (default is 22)", default=22)
parser.add_argument("-t", action="store_true", help="Use Tor for the SSH key grab (for hidden services, etc!)")
args = parser.parse_args()
if args.f:
local_query(keyfile=args.f)
elif args.F:
fingerprint=args.F
msg_info("SSH Fingerprint: %s" %(fingerprint))
do_shodan(fingerprint)
elif args.i:
if args.t:
remote_query(host=args.i, port=args.p, tor=True)
else:
remote_query(host=args.i, port=args.p)
elif args.l:
if args.t:
list_query(hosts=args.l, tor=True)
else:
list_query(hosts=args.l)
elif not args.f or args.i or args.l:
parser.error("give me some arguments or get the fuck out")
if __name__ == "__main__":
main()