Add re-entrant banner retrieval method.

This commit is contained in:
Andris Raugulis 2016-04-01 18:19:18 +03:00
parent 06992d7da6
commit b8201f2550

View File

@ -124,7 +124,11 @@ class SSH(object):
MSG_KEXDH_REPLY = 32 MSG_KEXDH_REPLY = 32
class Socket(ReadBuf): class Socket(ReadBuf):
SM_BANNER_SENT = 1
def __init__(self, host, port, cto = 3.0, rto = 5.0): def __init__(self, host, port, cto = 3.0, rto = 5.0):
self.__state = 0
self.__banner = None
super(SSH.Socket, self).__init__() super(SSH.Socket, self).__init__()
try: try:
self.__sock = socket.create_connection((host, port), cto) self.__sock = socket.create_connection((host, port), cto)
@ -136,6 +140,14 @@ class SSH(object):
def __enter__(self): def __enter__(self):
return self return self
def get_banner(self):
if self.__state < self.SM_BANNER_SENT:
self.send_banner()
if self.__banner is None:
self.recv()
self.__banner = self.read_line()
return self.__banner
def recv(self, size = 2048): def recv(self, size = 2048):
data = self.__sock.recv(size) data = self.__sock.recv(size)
pos = self._buf.tell() pos = self._buf.tell()
@ -147,6 +159,11 @@ class SSH(object):
def send(self, data): def send(self, data):
self.__sock.send(data) self.__sock.send(data)
def send_banner(self, banner = SSH_BANNER):
self.send(banner.encode() + b'\r\n')
if self.__state < self.SM_BANNER_SENT:
self.__state = self.SM_BANNER_SENT
def read_packet(self): def read_packet(self):
block_size = 8 block_size = 8
if self.unread_len < block_size: if self.unread_len < block_size:
@ -385,9 +402,7 @@ def parse_args():
def main(): def main():
host, port = parse_args() host, port = parse_args()
s = SSH.Socket(host, port) s = SSH.Socket(host, port)
s.send(SSH_BANNER.encode() + b'\r\n') banner = s.get_banner()
s.recv()
banner = s.read_line()
out.head('# general') out.head('# general')
out.good('[info] banner: ' + banner) out.good('[info] banner: ' + banner)
if banner.startswith('SSH-1.99-'): if banner.startswith('SSH-1.99-'):