一、前言

做题的时候有见到过这个名词,一直都挺好奇的,这次就打算深入了解一下其原理

我也是通过这篇文章学习一下,并写下一点自己的体会

https://xz.aliyun.com/t/2548

二、文件描述符和重定向

文件所有输入输出都是由该进程所有打开的文件描述符控制的。(Linux一切皆文件,就连键盘显示器设备都是文件,因此他们的输入输出也是由文件描述符控制)

1、三种文件描述符(0、1、2)

  • 标准输入standard input 0 (默认设备键盘)
  • 标准输出 standard output 1 (默认设备显示器)
  • 错误输出 error output 2 (默认设备显示器)

image-20220125153728862

这个图片应该表示的就是文件描述符默认绑定的文件

在下面理解了重定向之后,我觉得才能更好的理解这张图的含义

2、重定向

主要分为两种:

  • < 输入重定向
  • > 输出重定向

该文章也指出了注意点:

  1. bash在执行命令的时候,首先检查有没有重定向符号,若有则先将文件描述符重定向
  2. bash执行命令的顺序是从左到右的,若是存在多个重定向符号,顺序就显得很重要

(1)输入重定向

这里我一开始对输入和输出重定向也不是特别理解,就自己测试了一番

文章中展示了一种输入重定向:cat < file 等价于 cat 0< file

显示器上输出了file文件的内容,这里的0(输入)是默认的

到这我就有一个疑问:cat命令不是输出吗?为什么是输入重定向?

经过测试,写一下我的理解:

cat命令存在三个文件描述符,默认输入就是键盘输入,默认输出就是显示器输出

而我们重定向的就是这个输入,cat < file相当于输入就是这个file文件,而输出还是显示器

那么,到这,cat file 这个命令看上去就是重定向了输入

想到这,假如我是使用单纯的cat命令,不指定输入,会怎样?(默认输入是键盘的话。。)

image-20220125155950340

一开始并没有反应,当我从键盘输入了一个a,它也输出了一个a

image-20220125160040772

所以,没有指定输入的话,默认的输入就是键盘输入

(2)输出重定向

经过了上面对cat命令的测试,也就能更好的理解这个输出重定向了。

文章中使用了这个例子:echo hello > ctf 等价于 > ctf echo hello

image-20220125161134751

接下来还是使用cat命令来演示,将输入输出都修改一下试试:

我在桌面创建了两个文件:

  • ctf :内容为 in
  • 123 :内容为 out

我们使用cat命令,将ctf的内容写到123中去:< ctf > 123 cat

然后再读取123的内容:

image-20220125161553829

这里再来理解第一张图片的含义:(到这我就觉得这个三个文件描述符更像是C语言中的指针)

2

(3)标准输出和标准错误输出重定向

标准输出和错误输出是不一样的(因为输出报错的是另外一个文件)

标准错误输出格式(以mkdir为例):mkdir >& file 等价于 mkdir &> file

文章中又提到:mkdir > file 2>&1 与上面是等价的

&符号是为了区分文件名和文件描述符的

然后我们先从字面上去理解一下:

  • 首先遇到第一个> (输出重定向) ,将1重定向为file
  • 然后遇到 2>&1,将2 (错误输出) 重定向到1(标准输出)
  • 而1已经重定向到了file,所以2也重定向到了file

(感觉更像C语言的指针了。。。)

通过文章给的图片也就能更好理解了

image-20220125164253218

(4)文件描述符的复制

以上面2>&1为例吧

2>&1 等价于 2<&1 ,所以上面这两种格式都是可以的

因为&符号是为了区分文件名和文件描述符,所以不能变

<>和前面的输入重定向和输出重定向不一样,这里表示的是只读<和只写>

但是这两种对文件描述符的重定向没有任何影响

3、文件描述符的顺序

文章中特地拿出来单独讲,我也拿文章中的例子分析一下:

  1. mkdir > file 2>&1
  2. mkdir 2>&1 >file

第一个上面解释过了,直接看第二个

  • 首先遇到2>&1,将2重定向到1,而1这个时候还是默认的(默认为显示器)
  • 然后遇到了>(输出重定向),将1重定向到了file
  • 所以,先拿出结论:错误输出还是在显示器,而由于mkdir只有错误输出,标准输出为空,所以file为空

测试:将file中随意写入点东西(如:123)

image-20220125170219579

所以,文件描述符的顺序是很重要的

4、exec绑定重定向

由于上面的输入和输出重定向都是一次性的(也就是只对当前命令生效)

而为了满足需求,可以使用exec永久绑定一个文件或设备

格式:[n]<>file

以读写的方式打开file,如果n不指定,默认为标准输入0

文章中的例子为:

  • exec 3<>file
  • ls >&3
  • cat file

理解一下:

  • 首先执行第一个exec命令,将3和file绑定了
  • 然后执行ls命令,将输出重定向到了文件描述符3(其实就是file)
  • 所以,cat file 其实就是获得了ls的输出

三、总结

这篇文章是反弹shell的前置知识,只有更好的理解了文件描述符和重定向,才能更好的理解反弹shell