任意文件读取和上传
任意文件读取
任意文件读取,也可以称为任意文件下载或文件包含(File Inclusion),指的是代码中没有对参数进行严格限制,导致攻击者可以通过目录穿越或修改读取的文件名从而达到读取任意文件的目的
危害
- 配置文件泄露:攻击者通过任意文件读取漏洞查看配置文件,从而获取数据库连接等相关的敏感信息;也可以读取业务代码,造成源码泄露
- 执行shell命令:攻击者首先可以通过任意文件上传的漏洞,将包含恶意代码的文件上传到服务器的某处,然后通过任意文件读取的漏洞来执行该文件
存在位置
- 通常具有附件、文档或图片等资源,涉及到文件读取或下载的地方可能会存在这个漏洞
在Java中,存在任意文件读取漏洞的代码大概如下:
String fileName = request.getParameter("fileName"); String path = "/tmp/"; File file = new File(path + fileName);
在这串代码中,由于没有校验从请求中获取的参数fileName,如果fileName的值是
../../../../etc/passwd
,在new File(path + fileName)
时会对参数路径计算,就会导致多个../
穿越到了根目录下,然后便会读取到/etc/passwd
的值
防御手段
- 在使用前端传递过来的参数前,首先对参数进行校验,去掉参数值中包含的
../
,从而防止目录穿越 - 上传的文件名以随机数的形式存放在文件夹内,实际的文件名则存放于数据库中。这样攻击者无法得知具体的文件名是什么,从而无法读取文件
例1
-
此处以靶场pikachu为例
-
该处存在文件读取的漏洞,在选择某项后点击submit query按钮,并使用burp抓包
-
修改filename的值为另一个文件名
file2.php
,然后发包,可以看到显示的内容变成了新文件的内容(原本是科比)
造成这个漏洞的原因是文件在存储时没有使用随机数命名文件,因此攻击者可以轻易的猜出文件名并读取它
例2
-
此处以靶场DVWA为例,级别为low
-
点击file1.php,并抓包
-
将page参数修改为payload:
../../../../../../../../../../../../../etc/passwd
后发包(注意../
一定要足够多,否则穿越不到根目录,从而导致文件读取失败) -
在页面中可以看到
passwd
的内容造成该漏洞是因为代码中没有过滤掉
../
导致可以路径穿越,从而读取了任意路径下的文件
任意文件上传
任意文件上传(File upload),指绕过代码中对上传文件的检查,从而达到上传任意类型文件,甚至上传到任意的位置。它配合任意文件读取漏洞可以实现远程命令执行,甚至getshell
危害
- GetShell
- 上传木马文件,导致服务瘫痪
防御手段
- 根据绕过的方式来指定白名单,校验上传文件的类型
- 过滤
../
,防止目录穿越 - 对上传文件的内容进行校验
绕过姿势
前端JS校验
- 绕过JS校验可以先将文件后缀名修改为符合格式的文件后缀,然后上传后抓包再修改回来,从而绕过
代码校验
-
截断绕过。通过
%00, 0x00, \x00
等截断绕过,比如test,php%00.jpg
-
双后缀名绕过。比如
test.php.jpg
-
切换大小写绕过。比如
test.PHp
-
.htaccess绕过。PHP环境可以通过上传
.htaccess
绕过-
.htaccess
文件时Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过.htaccess
文件,可以帮我们实现自定义文件解析方式(改变扩展名),比如<FileMatch "dd"> SetHandler application/x-httpd-php </FileMatch>
当遇到文件名中有dd的文件时,便会以php的形式来进行解析该文件(无论后缀名是什么)。如果不加
<FileMatch>
则表示所有文件都按照php形式来解析。上传成功后,本地新建一个text.php,里边写入php的payload,然后将后缀名改为符合格式的后缀并上传,最后便可上传成功 -
使用该方式绕过需要满足以下两个条件:
- mod_rewrite模块开启
- AllowOverrideAll
-
-
上传特殊但可被解析的后缀绕过
- PHP:
.php, .php2, .php3, .php4, .php5, .php6, .php7, .phps, .phps, .pht, .phtm, .phtml, .pgif, .shtml, .htaccess, .phar, .inc
- ASP:
.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml
- Jsp:
.jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action
- Coldfusion:
.cfm, .cfml, .cfc, .dbm
- **Flash: **
.swf
- Perl:
.pl, .cgi
- Erlang Yaws Web Server:
.yaws
- PHP:
-
特殊字符绕过。在文件名最后增加特殊的字符,比如:
%20, %0a, %00, %0d%0a, /, .\, .
-
::$DATA绕过。在windows环境下,可以使用NTFS文件系统的特性来实现绕过。NTFS文件系统中支持备用数据流,它允许文件中包含多个数据流,而每个文件都至少包含一个数据流。如果在文件名后添加
::$data
,则:
号及之后的内容会被windows作为数据流而不是文件名,从而实现绕过文件名的校验 -
MIME绕过。有的代码会在客户端校验
content-type
来实现上传文件类型的检查,因此在上传文件时便可将content-type
修改,从而绕过检查 -
使用图片木马。图片木马是指在一张图片后增加一串payload,比如增加了php的payload,上传成功后便可通过php环境解析该文件,从而执行payload。图片木马制作方式如下:
-
windows环境。
-
准备一张图片(1.jpg)和一个包含payload的php文件(a.php)
-
然后在该文件夹中打开cmd,执行代码:
copy 1.jpg/b+a.php/a 2.jpg
。(jpg后边的b表示二进制文件,php后边的a表示ASCII码文件) -
使用文本打开生成的2.jpg,在最后即可看到payload
-
-
linux环境。
-
同样的准备,执行命令:
cat 1.png a.php > 2.jpg
-
打开文件即可在末尾看到
-
-
-
有的地方上传了压缩包,上传后会将压缩包内的文件放在目录里。此时便可将含有payload的文件放在压缩包里上传到服务器
例子
(随便举个)
-
使用pikachu靶场,准备一个php文件(a.php),包含代码
<?php phpinfo() ?>
,并将后缀名改为.jpg
-
上传a.jpg,并抓包
-
将filename修改为绕过的名字后上传
-
根据地址即可访问到