文件上传是Web系统中常见的功能,也是获取服务器权限的常见入口,通常情况下处理文件上传漏洞的办法是这么来搞:
- 文件类型识别(包括后缀、文件头);
- 文件类型白名单;
- 文件大小限制;
- 上传目录可执行权限限制;
- 上传文件重命名;
..............
但在可以上传zip文件同时后台自动解压的情况下,就可能出现这种新的情况。
网站后台会通过解压用户上传的zip文件,从而实现任意文件读取。
Linux下的软链接和硬链接
链接---------是一种在共享文件和访问它的用户的若干目录项之间建立联系的一种方法。
Linux中包括两种链接:硬链接(Hard Link)和软链接(Soft Link),软链接又称为符号链接(Symbolic link)。
首先了解一下这几个概念。
索引节点(inode)
要了解链接,我们首先得了解一个概念,叫索引节点(inode)。在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号,我们可以将inode简单理解成一个指针,它永远指向本文件的具体存储位置。文件属性保存在索引结点里,在访问文件时,索引结点被复制到内存在,从而实现文件的快速访问。系统是通过索引节点(而不是文件名)来定位每一个文件。
硬链接(Hard Link)
硬链接说白了是一个指针,指向文件索引节点,系统并不为它重新分配inode。
可以用:ln命令来建立硬链接。
命令:ln [options] existingfile newfile //为“existingfile”创建硬链接,文件名为"newfile" 命令:ln [options] existingfile-list directory //在"directory"目录中,为"existingfile-list"中包含的所有文件创建一个同名的硬链接
//常用可选[options]:-f无论"newfile"存在与否,都创建链接。-n 如果"newfile"已存在,就不创建链接
假设现在目录下有两个文件,blue和green。

这里我们注意在创建硬链接前,blue显示的链接数目为1,创建链接后
- blue和bluehard的链接数目都变为2。
- blue和bluehard的inode号是一样的,都是524662。
- blue和bluehard显示的文件大小也是一样,都是11。
可见:blue和bluehard是同一个文件的两个名字,它们具有同样的索引节点号和文件属性,建立文件blue的硬链接,就是为blue的文件索引节点在当前目录上建立一个新指针。你可以删除其中任何一个,如rm blue,每次只会删除一个指针,链接数同时减一,只有将所有指向文件内容的指针,也即链接数减为0时,内核才会把文件内容从磁盘上删除。
但硬链接也有不足之处:
- 不允许给目录创建硬链接。
- 不可以在不同文件系统的文件间建立链接。
而软链接就克服了硬链接的不足。
软链接(Soft Link)
软链接又叫符号链接,这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。和win下的快捷方式差不多。
可以用:ln -s 命令来建立软链接。
命令:
ln -s existingfile newfile
ln -s existingfile-list directory
下面再举个栗子:

从上面的结果来看,软链接与硬链接的区别:
- 硬链接原文件/链接文件公用一个inode号,说明他们是同一个文件,而软链接原文件/链接文件拥有不同的inode号,表明他们是两个不同的文件;
- 在文件属性上软链接明确写出了是链接文件,而硬链接没有写出来,因为在本质上硬链接文件和原文件是完全平等关系;
- 链接数目是不一样的,软链接的链接数目不会增加;
- 文件大小是不一样的,硬链接文件显示的大小是跟原文件是一样的。而这里软链接显示的大小与原文件就不同了,BBB大小是95B,而BBBsoft是3B。
总而言之,可以把软链接当作win下的快捷方式来看。
软链接导致任意文件读取
搞懂了这个概念。那上面的漏洞就很简单了。
我们可以压缩一个软链接,类似于windows下的快捷方式,然后网站后台会解压读取该软链接指向的服务器上的文件,就能达到读取任意文件的效果。
举例:
我们使用
ln -s /etc/passwd passwd
生成一个指向/etc/passwd文件的软链接,然后用
zip -y passwd.zip passwd
将软链接压缩,然后上传至服务器,就能够成功读取服务器上的/etc/passwd文件内容。结果如下:
