第七章 不安全的文件下载和上传
1.不安全的文件下载原理及演示
场景演示
可以通过点击名字来进行下载,在新建标签页打开
我们来看一下下载过程中的url
把ai.png这个filename传到了后台,后台去找这个文件,把这个文件读取后,又响应输出到前端,浏览器可以把它下载下来。
文件下载漏洞,可以用目录遍历的方式去做测试。在filename这里输入足够多的../../../../可以直接跳到根目录下。再以根目录为起始点做相关的读取。
可以直接下载这个文件
查看一下后台的代码
当点击图片时,实际上是传了一个a标签,通过a标签(get请求)传一个参数,然后传给exedownload.php。
先获取到文件名,然后直接拼接到download目录下,图片都是存在download下的,没有进行任何处理。
做完拼接后,去fopen,对它进行读取,同时算出它的长度,然后放到header里响应到前端。
后面对文件进行循环的读取,把里面的字节流全部读取出来,echo到前端。
最主要的问题就是没有对前端传过来的文件进行判断,不会判断文件是不是它目录里存在的,就直接进行了读取。应该在传进来时进行一个校验,还需要对范围进行限定。
2.不安全的文件上传原理及客户端绕过
场景演示
尝试上传一个php文件,不可以
这个是直接通过前端弹出一个框
我们来看一下限制是不是由前端做的
当input标签去onchange(发生改变)的时候,就会去调用checkFileExt()
查看一下页面源代码
这个函数是通过JavaScript去判断上传的内容。这个判断操作完全是在前端进行完成的。这里是很容易被绕过的。就跟之前的xss一样,把长度改掉。
把onchange的参数去掉,再来上传一次试试
成功
这里我们必须要知道我们上传文件上传到什么路径
我们复制路径来访问一下
通过x参数来传一个命令
在这里我们是直接绕过客户端的限制上传了一个非预期文件,system,php文件里写的是一句话木马,我们上传了一个一句话木马文件,通过一句话木马的访问控制后台服务器。
3.上传漏洞之MIME type验证原理和绕过(服务端)
当浏览器对文件进行识别的时候,它会给这个文件定义一个类型,同时会把这个类型放到HTTP头里。
可以获取文件相关信息。
场景演示
图片上传成功
查看一下源代码
先获取前端提交的请求。
关键点在于,通过这个函数获取文件的类型,将其和定义好的类型进行比较。
问题在于,这个函数是从浏览器的HTTP头里来获取到content type,content type是前端的用户可以控制的。这个信息的获取是不靠谱的。
我们抓包来抓一下上传图片时的和上传一句话木马文件的
图片的:
上传成功
木马文件的
将这个数据包发送到repeater里
我们把content-type修改成image/png看看怎么样
成功,通过HTTP头的修改,绕过MIME type的限制。这个一句话木马文件上传成功,我们就可以通过传参进行控制
4.文件上传之getimagesize()类型绕过案例及防范措施
这个函数的功能是php提供的用来判断目标文件是不是图片。
对目标文件的十六进制进行读取,然后去读取十六进制内容里的头几个字符串,看它符不符合图片的要求。一般来说图片的十六进制的头部是一样的,比如.png类型的图片十六进制的头部都是一样的。
xxd使用来读取目标文件的十六进制,我们可以看到这两个.png文件的前几位是相同的。
这个函数实际上判断文件是不是图片,就是根据这个来判断的。
那就是我们可以伪造一个图片,保证前面这几个字符串和一个图片是一样的,但是在图片里面,这些十六机制内容的后面我们可以插入一些恶意的代码,然后再把图片传上去。
场景演示
这个时候我们可以制作一个包含恶意代码的图片,看看能不能绕过
方法二是在Windows环境下搞得
制作一下
最后接入了phpinfo.php文件
前面还是一样的,但实际上它是包含有恶意代码的。
成功上传
意味着在这个点实际上是存在文件上传漏洞的,只不过不太好利用,因为只是上传了含有恶意代码的图片,但是实际上访问这个图片是不会执行这段代码的。
并没有执行
我们可以利用之前所学的本地文件包含漏洞,把这个文件的路径传给本地包含文件漏洞的参数里。让这个本地文件包含漏洞的include()对这个图片进行包含,虽然前面不是php代码是十六进制,但是include会继续执行,直到最后发现后面有一段php代码,就会把这段执行。
这个路径非常重要,要能在传进去的时候让其正确读取。
因为在这个上传点上,所以要用这个路径
替换掉
在文件包含里面,它是以当前的代码点为对应的根节点去读取。
再加上../../去进行尝试
出来了,phpinfo()被执行。
文件包含漏洞和文件上传漏洞相结合的演示。