Pikachu:Unsafe Fileupload(不安全的文件上传)

概述:

因为业务功能需要,很多 Web 站点都有文件上传的接口,比如:

  • 注册时上传头像图片(比如jpg,png,gif等)
  • 上传文件附件(doc,xls等)

  文件上传功能在web应用系统很常见,比如很多网站注册的时候需要上传头像、上传附件等等。当用户点击上传按钮后,后台会对上传的文件进行判断 比如是否是指定的类型、后缀名、大小等等,然后将其按照设计的格式进行重命名后存储在指定的目录。而在后台开发时,并没有对上传的文件进行安全考虑,或者采用了有缺陷的措施,导致攻击者可以通过一些手段绕过安全措施从而上传一些恶意文件(如:一句话木马),从而通过对该恶意文件的访问来控制整个 Web 后台。

  所以,在设计文件上传功能时,一定要对传进来的文件进行严格的安全考虑。比如:
    --验证文件类型、后缀名、大小;
    --验证文件的上传方式;
    --对文件进行一定复杂的重命名;
    --不要暴露文件上传后的路径;
    --等等...

client check(客户端)

  我们来创建一个一句话木马的文件,然后上传,我这里创建lh.php,里面写入一句话木马,上传结果发现报错,提醒只能上传图片:

   我们查看页面源码,发现它只在前端进行了防御,调用下图所写的这个方法来阻止其他格式的文件上传,那我们找到它调用的地方,删除调用不就可以了吗:

   打开Web控制台,我们找到相对应部分的源代码,可以看到,当 input 标签的状态发生改变时,就会调用 checkFileExt(),下面是这个函数的源码把图中选中的部分删除,即:把onchange="checkFileExt(this.value)"改为onchange=“”"

   然后再次上传,发现上传成功:

   接下来用URL也可以,用菜刀访问也可以,都可以达到目的了,这里以URL为例访问网卡信息:

http://192.168.11.1/pikachu-master/vul/unsafeupload/uploads/lh.php?liuhui=ipconfig

MIME type (服务端)

  在开始试验之前,我们需要先明确一下MIME是什么,以及$_FILES()函数。

MIME

  MIME(全程Multipurpose Internet Mail Extensions),多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问时,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

  每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。常见的 MIME 类型,比如:

  • 超文本标记语言:.html,.html text.html
  • 普通文件:.txt text/plain
  • RTF文件:.rtf application/rtf
  • GIF图形:.gif image/gif
  • JPEG图形:.jpeg,.jpg image/jpeg

$_FILES()函数

  它从浏览器的HTTP头里获取 Content-Type ,这个 Content-Type 前端用户是可以控制的,通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。

  第一个参数是表单的 input name,第二个下标可以是 “name”,“type”,“size”,“tmp_name” 或 “error”,就像这样:

  • $_FILES['file']['name']:被上传文件的名称
  • $_FILES['file']['type']:被上传文件的类型
  • $_FILES['file']['size']:被上传文件的大小
  • $_FILES['file']['tmp_name']:存储在服务器的文件的临时副本的名称
  • $_FILES['file']['error']:由文件上传导致的错误代码

实验:

  我们进入页面, 还是一样只允许上传图片,上传php文件还是会报错提醒:

 

  我们上传图片格式,发现成功:

  我们来看看源码(路径如下图所示):

  在后端进行了文件类型的比对,我们可以在后台抓包之后再改包,也就是说,在它比对之后再把数据包换了,那我们做个代理,用Burp Suite抓包,上传一句话木马的文件,发现抓包成功,然后发送到Repeater改包:

   我们把图中的选中位置的Content-Type,即内容类型里的参数,改为image/png(只要图片格式就可以,jpg,jpeg都行):

   当然接下来点击Go了,我们在右边的Reader部分,看到有很多乱码,但是还是能判断上传成功的字样,因为上传失败会提示上川岛正确格式,而不是文件路径:

   用URL方式访问这个路径,输入网卡访问的命令,看看能不能跳出想要的结果(当然要先解除代理):

  http://192.168.11.1/pikachu-master/vul/unsafeupload/uploads/lh.php/?liuhui=ipconfig

   发现结果输出成功。

 getimagesize()函数验证

  在开始试验之前,我们来熟悉一下getimagesize()函数。getimagesize() 函数是一个PHP的函数,用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。getimagesize() 函数将测定任何 GIF,JPG,PNG,SWF,SWC,PSD,TIFF,BMP,IFF,JP2,JPX,JB2,JPC,XBM 或 WBMP 图像文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度。

  这个函数的返回结果中有文件大小和文件类型,如果用这个函数来获取类型,从而判断是否是图片的话,会存在问题。后台会根据上传的图片的16进制格式的前几位进行对比 符合才是真的图片,前几位是固定的,符合才是真的图片,例如:

  png:8950 4e47

  我们可以利用它的特性来构造图片16进制的前面几位,其他可以随意放恶意的代码。

  还是进入页面,与上面没什么区别,告诉我们上传图片格式:

   为了方便,我们直接在桌面创建两个文件,一个普通的png格式的图片文件,一个含有恶意代码的php文件,php文件中的内容,我们这里放一个phpinfo()函数,输出php全部的参数,关于这个函数的含义在上一节文件下载中可以找到:

  图片木马的制作方法有三种:

    法一:直接伪造头部GIF89A

       法二:CMD:copy  /b  正常图片.png  +  恶意代码.php  合成新的图片.png

    法三:使用GIMP(开源的图片修改软件),通过增加备注,写入执行命令

  我们这里使用法二,更加方便,打开命令提示符,进入桌面(如果你创建的路径不是桌面,那就自行调整进入相应的文件目录即可),输入下面的命令来创建图片木马:

  copy /b 1.png+1.php Eyi.png

  最后面的png格式的文件是最后生成的恶意文件,名字可以自己起。

   然后我们发现桌面上已经有了一个名为Eyi的png格式文件

   然后回到Pikachu页面来上传这个文件,发现上传成功:

   当然不会直接执行代码,那么我们需要通过URL结合本地文件包含漏洞进一步利用,这里注意要使用上图中提示的文件保存的路径,即为下图的红色部分,运行成功后,前面有很多的乱码,这些都是图片转化为文本的字符,直接拉到最下方即可看到代码已经成功执行后出现的php页面所有内容:

  http://192.168.11.1/pikachu-master/vul/fileinclude/fi_local.php?filename=../../unsafeupload/uploads/2020/04/01/5378955e8473f39896e235759675.png&submit=%E6%8F%90%E4%BA%A4%E6%9F%A5%E8%AF%A2

文件上传漏洞防范措施:

1.不要在前端使用js实施上传限制策略

2.通过服务端对上传文件进行限制

   1>进行多条件组合检查:比如文件的大小,路径,扩展名,文件类型,文件完整性

   2>对上传的文件在服务器上存储时进行重命名(制定合理的命名规则)

   3>对服务器端上传文件的目录进行权限控制(比如:只读),限制执行权限带来的危害

猜你喜欢

转载自www.cnblogs.com/FHBBS/p/12611555.html
今日推荐