文件上传漏洞是Web安全中一种常见的漏洞在渗透测试中经常使用到,能够直接快速地获得服务器的权限,如果说一个没有文件上传防护规则的网站,只要传一个一句话木马就可以轻松拿到目标了。上传文件上传漏洞是指用户上传了如木马、病毒、webshell等可执行文件到服务器,通过此文件使服务器执行命令从而控制网站。
0x01文件上传检验
- 黑名单检测
- 白名单检测
- 文件头检测
- 正则检测
- WAF检测
- 前端JavaScript检测
在客户端进行检测的时候一般是通过JavaScript的脚本对上床的文件名后缀进行检测。有白名单也有黑名单,比如只允许上传.jpg .png .gif .jpeg等后缀文件名。但前端检测可以通过对代码进行·修改轻松绕过。前端的代码在浏览器执行,可以通过bp拦截进行修改。
文件上传一般会进行检测然后上传到缓存文件(tmp)再通过后端代码的移动移动到指定目录重命名。
0x02文件上传
2.1前端检验
通过抓取返回包并修改白名单规则加上.php或者直接删去所有校验代码
上传成功查看图片路径
蚁剑连接
2.2content-type
在服务端的检测比如通过文件头content-type进行检测。
PHP校验代码,可以看到只允许上传jpeg png 和gif的后缀文件
1 $is_upload = false; 2 $msg = null; 3 if (isset($_POST['submit'])) { 4 if (file_exists($UPLOAD_ADDR)) { 5 if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) { 6 if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR . '/' . $_FILES['upload_file']['name'])) { 7 $img_path = $UPLOAD_ADDR . $_FILES['upload_file']['name']; 8 $is_upload = true; 9 10 } 11 } else { 12 $msg = '文件类型不正确,请重新上传!'; 13 } 14 } else { 15 $msg = $UPLOAD_ADDR.'文件夹不存在,请手工创建!'; 16 } 17 }
补充一下content-type的知识:
HTTP协议(RFC2616)采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请求的方法、URI、协议版本、以及包含请求修饰符、客户 信息和内容的类似于MIME的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以 及可能的实体内容。
通常HTTP消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域 值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。
请求消息和响应消息都可以包含实体信息,实体信息一般由实体头域和实体组成。实体头域包含关于实体的原信息,实体头包括Allow、Content- Base、Content-Encoding、Content-Language、 Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type、 Etag、Expires、Last-Modified、extension-header。
Content-Type是返回消息中非常重要的内容,表示后面的文档属于什么MIME类型。Content-Type: [type]/[subtype]; parameter。例如最常见的就是text/html,它的意思是说返回的内容是文本类型,这个文本又是HTML格式的。原则上浏览器会根据Content-Type来决定如何显示返回的消息体内容。
type有下面的形式
Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据;
Application:用于传输应用程序数据或者二进制数据;
Message:用于包装一个E-mail消息;
Image:用于传输静态图片数据;
Audio:用于传输音频或者音声数据;
Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。
修改content-type为 image/jpeg
上传成功
2.3文件后缀
可以看到第5行定义了后缀为 asp aspx php jsp的文件不能上传,黑名单对特定的后缀文件其效果,可以通过上传xxx.a等不可能后缀的文件判断是否为黑名单检测。
1 $is_upload = false; 2 $msg = null; 3 if (isset($_POST['submit'])) { 4 if (file_exists($UPLOAD_ADDR)) { 5 $deny_ext = array('.asp','.aspx','.php','.jsp'); 6 $file_name = trim($_FILES['upload_file']['name']); 7 $file_name = deldot($file_name);//删除文件名末尾的点 8 $file_ext = strrchr($file_name, '.'); 9 $file_ext = strtolower($file_ext); //转换为小写 10 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA 11 $file_ext = trim($file_ext); //收尾去空 12 13 if(!in_array($file_ext, $deny_ext)) { 14 if (move_uploaded_file($_FILES['upload_file']['tmp_name'], $UPLOAD_ADDR. '/' . $_FILES['upload_file']['name'])) { 15 $img_path = $UPLOAD_ADDR .'/'. $_FILES['upload_file']['name']; 16 $is_upload = true; 17 } 18 } else { 19 $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!'; 20 } 21 } else { 22 $msg = $UPLOAD_ADDR . '文件夹不存在,请手工创建!'; 23 } 24 }
那么 asp aspx php jsp的文件不能上传还有没有其它的后缀能被当成脚本进行解析呢。在默认状态下一些后缀名也是能被解析的
jsp | jspx | jspf | |
asp | asa | cer | aspx |
php | phtml | php4 | php5 |
exe | exee |
文件后缀大小写:也可以利用后缀大小写进行尝试绕过 PhP PHp等 但有些防护机制会将文件名同义转换为小写
$file_ext = strtolower($file_ext); //转换为小写
文件后缀为空:windows上在保存文件名的时候如果有空格 比如php空格和php是相同的,但是对于检测来说php和php空格是不同的,那么他可能只会拦截php而不会拦截php空格的后缀文件。
加点进行绕过 php.空格.
双写 pphphp
2.4 .htaccess文件绕过
1 AddType application/x-httpd-php .php 2 AddType application/x-httpd-php .html 3 可以加入更多可以执行php的文件类型, 4 AddType application/x-httpd-php .htm 5 .htm文件也可以执行php程序, 6 AddType application/x-httpd-php .txt 普通的文本文件格式也能运行php程序。
创建htaccess写入命令,在某些win10和win7上不能创建文件名为空的htaccess文件可以使用命令转换
2.5 文件偷绕过
在一句话的基础上添加文件头,例如2.6 windows数据流绕过 :: $DATA
通俗点说就是其他文件可以寄宿在某个文件上,而在资源管理器中只能看到宿主文件找不到激素文件。
在cmd可以通过命令写入
echo 9999>>a.txt:b.txt 数据写入b.txt生成了一个a.txt
echo 9999>>c.php::$DATA 利用windows文件的特性Linux不行
2.7 %00和00截断
在文件上传的的时候如果白名单只允许上窜jpg等后缀的文件,在没有解析漏洞的情况下jpg格式不会被解析,那么需要绕过上传过滤。0x00实际上是一个十六进制的表示方式,表示acsii码值为0,有些函数在处理的时候会把它当作结束符,读取到这里的时候就结束了,%00是经过url编码的。
php<5.3的一个漏洞
可以看到这里的移动路径
那么进行修改
修改成功
将文件名为you.phpa的文件上传抓包
在十六进制找到文件名这行,因为a的acsii为61 那么在这里修改为00
可以看到文件后缀名已经改变
有些会对文件后缀和内容进行检测,那么可以上传图片马,如果对图片末尾进行检测那么可以用图片+木马+图片绕过。如果对于图片进行了二次渲染进行绕过,那么可以用动态图gif尝试,通常在第四行胡总和第三行开始写会比较好。
文件上传的绕过方法有很多种,通过不断测试选择方法。