【问题标题】:Telenet server in Twisted gets "Unhandled error in Deferred" errorsTwisted 中的 Telenet 服务器出现“延迟中的未处理错误”错误
【发布时间】:2018-02-12 13:54:07
【问题描述】:

我正在尝试制作一个简单的 Telnet 服务器,用于记录那些试图暴力破解弱 Telnet 凭据(Mirai、Gafgyt 等)的机器人使用的用户名/密码对。我正在尝试为此目的使用 Twisted,因为它似乎是用于此类目的的最先进技术。

这是我到目前为止所做的:

#!/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 错误,这让我完全困惑。我没有使用任何延迟,至少不是故意的。是什么导致了错误以及如何解决问题?

有趣的是,如果我手动远程登录到服务器并尝试自己输入用户名/密码,则不会出现错误;它们仅在机器人尝试登录时出现。我猜机器人正在尝试做一些我的服务器没有考虑到的事情,但我不知道我应该做什么。


编辑:

我已将上述脚本更改为使用 Twisted 记录器而不是 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'

有什么解决办法吗?

【问题讨论】:

  • 请将完整、准确的错误添加到您的问题中(复制/粘贴)。
  • 嗯,但我做到了。确切的错误消息是“Deferred 中的未处理错误:”,打印在控制台上。显然不是严重错误,因为脚本没有中断并且没有回溯,但它是某种类型的错误或警告,因为显示它的不是我的脚本。
  • 如果这就是全部,那么我认为您使用的 Twisted 版本存在此日志记录错误:twistedmatrix.com/trac/ticket/7927>。如果是这种情况,则有关故障的有用详细信息将被静默删除。能够看到它们会有所帮助 - 可能通过更改日志记录配置来避免问题,降级到足够旧的 Twisted 版本,或者修复错误然后升级。
  • 对不起,我不明白你的参考。我根本没有使用 Twisted 记录器(它将我不想要的东西放在日志中);我正在使用 Python 记录器。我的 Twisted 版本是 17.5.0 - 最新版本可通过 pip 获得。我可以做些什么来帮助您定位问题吗?修改脚本等?
  • 您无法完全避免使用 Twisted 记录器。 Twisted 不使用标准库 Python 日志系统。不过,它可能桥接到那个系统。我不完全确定该桥是否受到我链接到的错误的影响。值得一看。不过,您似乎做了一些更改,并获得了更多信息。

标签: python twisted telnet


【解决方案1】:

这是你对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))

另外请注意,您的应用程序中实际上没有任何回声逻辑,因此如果您要提供回声,您可能需要添加它。您可能希望围绕Password 提示而不是Username 提示进行意志/不会 ECHO 协商。 will/wont ECHO 协商的目的通常是抑制密码的回显。

【讨论】:

  • 好的,我已经按照您的建议进行了修改,但我仍然收到此错误。日志现在包含Failure: twisted.internet.error.ConnectionLost: Connection to the otherside was lost in a non-clean fashion: Connection lost.Failure: twisted.conch.telnet.AlreadyDisabled: twisted.conch.telnet.AlreadyDisabled:'\x01'。如何捕获多个错误?以逗号分隔的列表或其他方式列出它们?
  • 谢谢。不得不在列表中添加更多(AlreadyNegotiatingConnectionDone),但最终设法抑制了错误消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多