Files
2026-07-28 03:21:34 +08:00

99 lines
3.3 KiB
Python

import paramiko
from paramiko import ServerInterface
from paramiko.common import AUTH_SUCCESSFUL, AUTH_FAILED, OPEN_SUCCEEDED, OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
import threading
from utils import *
from shell import HoneypotShell
class FakeSSHServer(ServerInterface):
def __init__(self, config, client_ip):
self.username = None
self.password = None
self.command = None
self.config = config
self.channel_ready = threading.Event()
self.client_ip = client_ip
def check_auth_password(self, username, password):
self.username = username
self.password = password
for user in self.config['users']:
if (username == user['username'] and
password == user['password']):
print("login success", self.client_ip, username, password)
return AUTH_SUCCESSFUL
print("login failed", self.client_ip, username, password)
return AUTH_FAILED
def check_channel_request(self, kind, chanid):
if kind == "session":
return OPEN_SUCCEEDED
return OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
def check_channel_shell_request(self, channel):
self.channel_ready.set()
return True
def check_channel_pty_request(self, channel, term, width, height, pixel_width, pixel_height, modes):
return True
def check_channel_exec_request(self, channel, command):
self.channel_ready.set()
self.command = command.decode('utf-8')
print("RUNCOMMAND: ", self.client_ip, self.command)
return True
def get_allowed_auths(self, username):
return "password"
def handle_connection(client_sock, client_addr, config, shell_config, rsa_key):
client_ip = client_addr[0]
print("CON:", client_ip)
transport = None
channel = None
try:
transport = paramiko.Transport(client_sock)
transport.local_version = config['settings']['banner']
transport.add_server_key(rsa_key)
server = FakeSSHServer(config, client_ip)
try:
transport.start_server(server=server)
channel = transport.accept(60)
transport.banner_timeout = 60
transport.handshake_timeout = 30
except paramiko.SSHException as e:
print(client_ip, "Invalid SSH banner (possible telnet/HTTP/scan tool)", "-")
except (ConnectionResetError, ConnectionError):
print(client_ip, "Connection reset by peer", "-")
except EOFError:
print(client_ip, "Connection closed by client (possible telnet/HTTP/scan tool)", "-")
except Exception as e:
print("x", traceback_info())
return
if channel is None:
print(client_ip)
print(client_ip, "Timeout or Connection closed by client")
return
shell = HoneypotShell(channel, client_ip, config, shell_config, server)
server.channel_ready.wait()
if server.command is None:
shell.run()
else:
shell.exec_command(server.command)
except Exception as e:
print("x", traceback_info())
else:
print(client_ip, "Client disconnected", "!")
finally:
if transport:
transport.close()