2017-09-04 46 views
0

我正在试图制作一个简单的Telnet服务器,用于记录那些试图暴力破解弱Telnet证书的机器人使用的用户名/密码对(Mirai,Gafgyt等)。我试图用Twisted来达到这个目的,因为它似乎是用于此目的的最新技术。Twisted中的Telenet服务器获取“未处理的延迟错误”错误

这是我到目前为止做出:

#!/usr/bin/env python 

from twisted.conch.telnet import TelnetTransport, TelnetProtocol, ECHO 
from twisted.internet.protocol import ServerFactory 
from twisted.application.internet import TCPServer 
from twisted.application.service import Application 
from twisted.internet import reactor 

import logging 

class TelnetEcho(TelnetProtocol): 

    ip = '' 
    user = '' 
    state = '' 
    line = '' 

    def connectionMade(self): 
     self.ip = self.transport.getPeer().host 
     self.transport.write('Username: ') 
     self.transport.will(ECHO) 
     self.state = 'User' 

    def dataReceived(self, data): 
     if self.state != 'Password': 
      self.transport.write(data) 
     self.line += data 
     if data == '\n': 
      self.processLine() 
      self.line = '' 
     return 

    def processLine(self): 
     if self.state == 'User': 
      self.user = self.line.strip() 
      self.transport.write('Password: ') 
      self.state = 'Password' 
     elif self.state == 'Password': 
      print 'IP: ' + self.ip + ', user:' + self.user + ', pass:' + self.line.strip() 
      logging.info(self.ip + ',' + self.user + ',' + self.line.strip()) 
      self.transport.write('\r\nIncorrect password or username.\r\n') 
      self.transport.write('Username: ') 
      self.state = 'User' 

def CreateMyFactory(): 
    factory = ServerFactory() 
    factory.protocol = lambda: TelnetTransport(TelnetEcho) 
    return factory 

if __name__ == "__main__": 
    logging.basicConfig(filename='telnet.log', format='%(message)s', level=logging.DEBUG) 
    logging.info('Tmestamp,IP,Username,Password') 
    for handler in logging.root.handlers[:]: 
     logging.root.removeHandler(handler) 
    logging.basicConfig(filename='telnet.log', format='%(asctime)s,%(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.DEBUG) 
    MyFactory = CreateMyFactory() 
    reactor.listenTCP(23, MyFactory) 
    reactor.run() 

和它的作品大多是罚款 - 我的意思是,机器人尝试登录,并记录他们所使用的凭据 - 但我不断收到Unhandled error in Deferred错误,这些错误离开我完全迷惑。我没有使用任何延期,至少不是故意的。什么是造成错误和如何解决问题?

有趣的是,如果我手动telnet到服务器并尝试自己输入用户名/密码,则不会出现错误;它们只在僵尸程序试图登录时出现。我猜僵尸正试图做一些我的服务器没有考虑到的事情,但我无法弄清楚我应该做什么。


编辑:

我已经改变了上面的脚本使用双绞线代替记录了Python记录器。现在我在日志中获得一些附加信息。首先,我得到以下警告:

2017-09-06 16:17:01+0300 [-] Warning: primary log target selected twice at <c:\python\lib\site-packages\twisted\application\app.py:212> - previously selected at <c:\python\lib\site-packages\twisted\python\log.py:214>. Remove one of the calls to beginLoggingTo. 

我想这是Twisted中的一些错误。

接下来,当错误“递延未处理的错误”的发生,我得到这个我的日志:

2017-09-06 16:33:33+0300 [-] Unhandled error in Deferred: 
2017-09-06 16:33:33+0300 [-] Unhandled Error 
    Traceback (most recent call last): 
    Failure: twisted.conch.telnet.OptionRefused: twisted.conch.telnet.OptionRefused:'\x01' 

任何想法如何解决呢?

+0

请将完整的确切错误添加到您的问题(复制/粘贴)。 –

+0

嗯,但我做到了。确切的错误信息是在控制台上打印的“Deferred:Unhandled error in Deferred:”。显然不是一个严重的错误,因为脚本没有中断,也没有回溯,但它有一些错误或警告,因为它不是我的脚本显示它。 – bontchev

+0

如果这些都出现了,那么我认为你正在使用一个Twisted版本,它有这个日志记录错误:。如果是这样,那么有关正在悄悄丢弃的故障的有用细节。这将有助于能够看到它们 - 也许可以通过更改日志记录配置以避免该问题,降级到足够旧的Twisted版本,或修复错误并进行升级。 –

回答

0

这是你的Deferred使用:

self.transport.will(ECHO) 

这里是will API文档:

def will(option): 
    """ 
    Indicate our willingness to begin performing this option locally. 

    Returns a Deferred that fires with True when the peer agrees to allow us 
    to begin performing this option, or fails with L{OptionRefused} if the 
    peer refuses to allow us to begin performing it. If the option is 
    already enabled locally, the Deferred will fail with L{AlreadyEnabled}. 
    If negotiation regarding this option is already in progress, the 
    Deferred will fail with L{AlreadyNegotiating}. 

    Note: It is currently possible that this Deferred will never fire, 
    if the peer never responds, or if the peer believes the option to 
    already be enabled. 
    """ 

在你的情况下,对拒绝你的报价来执行ECHO功能。如果要抑制这种拒绝的报告,增加一个errback可吞下异常类型:

d = self.transport.will(ECHO) 
    d.addErrback(lambda reason: reason.trap(OptionRefused)) 

还要注意的是,你实际上并没有在应用程序中的任何回音逻辑,所以你可能想补充一点,如果你会提供做echo'ing。您可能想要在Password提示符附近执行ECHO协商,而不是提示Username。 ECHO协商的意愿通常是抑制密码的回声。

+0

好的,我已经完成了你所建议的修改,但是我正在解决这个错误。该日志现在包含'Failure:twisted.internet.error.ConnectionLost:与其他人的连接以非干净的方式丢失:连接丢失.'和'Failure:twisted.conch.telnet.AlreadyDisabled:twisted.conch.telnet。 AlreadyDisabled:'\ x01''。我如何捕获多个错误?列出他们在一个逗号分隔的列表或东西? – bontchev

+0

https://twistedmatrix.com/documents/17.5.0/api/twisted.python.failure.Failure.html#trap –

+0

谢谢。不得不添加更多的列表('AlreadyNegotiating'和'ConnectionDone'),但最终设法抑制错误消息。 – bontchev