From 29facd6ffeace97278beaf23f0048dac2cfe9651 Mon Sep 17 00:00:00 2001 From: Olivier Bilodeau Date: Mon, 1 Feb 2016 12:00:33 -0500 Subject: [PATCH] Protocol changes to prevent Telnet data to appear before password prompt Not perfect because there is no ECHO when entering Username... A proper fix will need more testing but I need to gather data now. --- cowrie/telnet/transport.py | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/cowrie/telnet/transport.py b/cowrie/telnet/transport.py index 4e6db5b..03e834b 100644 --- a/cowrie/telnet/transport.py +++ b/cowrie/telnet/transport.py @@ -117,8 +117,18 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol, TimeoutMixin): self.transport.write(self.factory.banner) self.transport.write("User Access Verification\n\nUsername: ") + # Enable some Telnet options for proper output and echo + # This supports both smart Telnet clients and raw bytes sending + # malware + # XXX this works with dumb but not smart + # check how I should negotiate + #self.transport.do(ECHO) + #self.transport.will(SGA) + self.transport.will(ECHO) + self.setTimeout(120) + # FIXME TelnetTransport is throwing an exception when client disconnects # Not sure if this is true anymore def connectionLost(self, reason): @@ -133,20 +143,32 @@ class HoneyPotTelnetAuthProtocol(AuthenticatingTelnetProtocol, TimeoutMixin): AuthenticatingTelnetProtocol.connectionLost(self, reason) + def telnet_User(self, line): + """ + Overriden to kill Will ECHO which confuses badly coded malware not + expecting Telnet commands. + """ + self.username = line + #self.transport.will(ECHO) + self.transport.write("Password: ") + return 'Password' + + def telnet_Password(self, line): username, password = self.username, line del self.username - def login(ignored): - self.src_ip = self.transport.getPeer().host - creds = UsernamePasswordIP(username, password, self.src_ip) - d = self.portal.login(creds, self.src_ip, ITelnetProtocol) - d.addCallback(self._cbLogin) - d.addErrback(self._ebLogin) + self.src_ip = self.transport.getPeer().host + creds = UsernamePasswordIP(username, password, self.src_ip) + d = self.portal.login(creds, self.src_ip, ITelnetProtocol) + d.addCallback(self._cbLogin) + d.addErrback(self._ebLogin) + + # XXX disabled since it seems to confuse dumb clients # even if ECHO negotiation fails we still want to attempt a login # this allows us to support dumb clients which is common in malware # thus the addBoth: on success and on exception (AlreadyNegotiating) - self.transport.wont(ECHO).addBoth(login) + #self.transport.wont(ECHO).addBoth(login) return 'Discard'