gpt4 book ai didi

python - 使用 twisted.conch 作为客户端使用 ssh 接收扩展数据

转载 作者:行者123 更新时间:2023-11-28 19:27:05 24 4
gpt4 key购买 nike

我目前正在通过蛮力学习 ssh/继续破解直到我理解它的方法。经过一些试验和错误后,我已经能够成功发送一个“pty-req”,然后是一个“shell”请求,我可以获得登录序言,发送命令并接收标准输出,但我不确定如何告诉SSH 服务 我想接收 stderr 和状态消息。目前,通读其他 SSH 实现(paramiko、Net::SSH)并不是什么好指南。

就是说,查看 SSH 的 RFC 之一,我相信也许列出的请求之一可能是我正在寻找的:https://www.rfc-editor.org/rfc/rfc4250#section-4.9.3

#!/usr/bin/env python


from twisted.conch.ssh import transport
from twisted.conch.ssh import userauth
from twisted.conch.ssh import connection
from twisted.conch.ssh import common
from twisted.conch.ssh.common import NS
from twisted.conch.ssh import keys
from twisted.conch.ssh import channel
from twisted.conch.ssh import session
from twisted.internet import defer

from twisted.internet import defer, protocol, reactor
from twisted.python import log
import struct, sys, getpass, os
log.startLogging(sys.stdout)


USER = 'dward'
HOST = '192.168.0.19' # pristine.local
PASSWD = "password"
PRIVATE_KEY = "~/id_rsa"

class SimpleTransport(transport.SSHClientTransport):
def verifyHostKey(self, hostKey, fingerprint):
print 'host key fingerprint: %s' % fingerprint
return defer.succeed(1)

def connectionSecure(self):
self.requestService(
SimpleUserAuth(USER,
SimpleConnection()))

class SimpleUserAuth(userauth.SSHUserAuthClient):
def getPassword(self):
return defer.succeed(PASSWD)

def getGenericAnswers(self, name, instruction, questions):
print name
print instruction
answers = []
for prompt, echo in questions:
if echo:
answer = raw_input(prompt)
else:
answer = getpass.getpass(prompt)
answers.append(answer)
return defer.succeed(answers)

def getPublicKey(self):
path = os.path.expanduser(PRIVATE_KEY)
# this works with rsa too
# just change the name here and in getPrivateKey
if not os.path.exists(path) or self.lastPublicKey:
# the file doesn't exist, or we've tried a public key
return
return keys.Key.fromFile(filename=path+'.pub').blob()

def getPrivateKey(self):
path = os.path.expanduser(PRIVATE_KEY)
return defer.succeed(keys.Key.fromFile(path).keyObject)



class SimpleConnection(connection.SSHConnection):
def serviceStarted(self):
self.openChannel(SmartChannel(2**16, 2**15, self))




class SmartChannel(channel.SSHChannel):
name = "session"


def getResponse(self, timeout = 10):
self.onData = defer.Deferred()
self.timeout = reactor.callLater( timeout, self.onData.errback, Exception("Timeout") )
return self.onData

def openFailed(self, reason):
print "Failed", reason

@defer.inlineCallbacks
def channelOpen(self, ignoredData):
self.data = ''
self.oldData = ''
self.onData = None
self.timeout = None
term = os.environ.get('TERM', 'xterm')
#winsz = fcntl.ioctl(fd, tty.TIOCGWINSZ, '12345678')
winSize = (25,80,0,0) #struct.unpack('4H', winsz)
ptyReqData = session.packRequest_pty_req(term, winSize, '')

try:
result = yield self.conn.sendRequest(self, 'pty-req', ptyReqData, wantReply = 1 )
except Exception as e:
print "Failed with ", e

try:
result = yield self.conn.sendRequest(self, "shell", '', wantReply = 1)
except Exception as e:
print "Failed shell with ", e


#fetch preample
data = yield self.getResponse()
"""
Welcome to Ubuntu 11.04 (GNU/Linux 2.6.38-8-server x86_64)

* Documentation: http://www.ubuntu.com/server/doc

System information as of Sat Oct 29 13:09:50 MDT 2011

System load: 0.0 Processes: 111
Usage of /: 48.0% of 6.62GB Users logged in: 1
Memory usage: 39% IP address for eth1: 192.168.0.19
Swap usage: 3%

Graph this data and manage this system at https://landscape.canonical.com/
New release 'oneiric' available.
Run 'do-release-upgrade' to upgrade to it.

Last login: Sat Oct 29 01:23:16 2011 from 192.168.0.17
"""
print data
while data != "" and data.strip().endswith("~$") == False:
try:
data = yield self.getResponse()
print repr(data)
"""
\x1B]0;dward@pristine: ~\x07dward@pristine:~$
"""
except Exception as e:
print e
break

self.write("false\n")
#fetch response
try:
data = yield self.getResponse()
except Exception as e:
print "Failed to catch response?", e
else:
print data
"""
false
\x1B]0;dward@pristine: ~\x07dward@pristine:~$
"""

self.write("true\n")
#fetch response
try:
data = yield self.getResponse()
except Exception as e:
print "Failed to catch response?", e
else:
print data
"""
true
\x1B]0;dward@pristine: ~\x07dward@pristine:~$
"""

self.write("echo Hello World\n\x00")
try:
data = yield self.getResponse()
except Exception as e:
print "Failed to catch response?", e
else:
print data
"""
echo Hello World
Hello World
\x1B]0;dward@pristine: ~\x07dward@pristine:~$
"""

#Close up shop
self.loseConnection()
dbgp = 1


def request_exit_status(self, data):
status = struct.unpack('>L', data)[0]
print 'status was: %s' % status

def dataReceived(self, data):
self.data += data
if self.onData is not None:
if self.timeout and self.timeout.active():
self.timeout.cancel()
if self.onData.called == False:
self.onData.callback(data)

def extReceived(self, dataType, data):
dbgp = 1
print "Extended Data recieved! dataType = %s , data = %s " % ( dataType, data, )
self.extendData = data

def closed(self):
print 'got data : %s' % self.data.replace("\\r\\n","\r\n")
self.loseConnection()
reactor.stop()



protocol.ClientCreator(reactor, SimpleTransport).connectTCP(HOST, 22)
reactor.run()

此外,我尝试向远程 shell 添加一个明确的错误命令:

    self.write("ls -alF badPathHere\n\x00")
try:
data = yield self.getResponse()
except Exception as e:
print "Failed to catch response?", e
else:
print data
"""
ls -alF badPathHere
ls: cannot access badPathHere: No such file or directory
\x1B]0;dward@pristine: ~\x07dward@pristine:~$
"""

看起来 stderr 被混入了 stderr

最佳答案

深入了解 OpenSSH 的源代码, channel session 逻辑在 session.c 中处理。在线2227 函数 -> session_input_channel_req,如果给定 pty-req,则“shell”请求导致 do_exec_pty,最终导致调用 session_set_fds(s, ptyfd, fdout, -1, 1, 1)。第四个参数通常是负责处理 stderr 的文件描述符,但由于未提供任何参数,因此不会有任何用于 stderr 的扩展数据。

最终,即使我修改了 openssh 以提供 stderr FD,问题仍然出在 shell 上。在这一点上完成猜测工作,但我相信类似于通过 xterm 或 putty 之类的终端登录 ssh 服务,stderr 和 stdout 被一起发送,除非通过诸如“2> someFile”之类的东西明确重定向,这超出了 a 的范围SSH 服务提供商。

关于python - 使用 twisted.conch 作为客户端使用 ssh 接收扩展数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7937651/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com