一、漏洞描述
在upload-labs第十六关,服务器exit_imagetype()函数检测上传图片类型是否为白名单图片格式来验证上传文件合法性。可以通过制作图片马绕过,再配合文件包含漏洞解析文件来获取服务器配置信息。
二、漏洞发现
先在本地写php脚本若上传成功,且知道上传后文件在网站保存的路径,可通过网页访问获得服务器配置信息,命名为z.php。但是在这里不能用php文件直接上传,需要制作图片马来绕过服务器检测文件二进制头信息。
有两种方法,但都是一个意思,将写入图片里面
方法一:准备z.php和一个真jpg图片用cmd命令行输入:copy 1.jpg/b+z.php/a 2.jpg
参数/b指定以二进制格式复制合并文件
参数/a指定以ascll格式复制合并文件
方法二:直接用010edior打开1.jpg,在末尾加上执行语句。个人建议第一个方便。
直接看源码,
$_FILES['myFile']['name']文件上传时候本身的名字,用户定义的名字
$_FILES['myFile']['tmp_name'] 文件被上传后在服务端储存的临时文件名,一般是系统默认
将文件临时名字传入自定义函数isImage()中。返回结果作判断,如果返回false则上传失败。否则定义img_path变量为上传到的文件路径+随机数文件名。然后将零时文件上传到指定路径。
文件名传入isImage函数,使用exif_imagetype函数检测文件类型,将返回的文件类型用swith语句进行比对。若复合gif,jpg,png格式则返回对应类型,否则返回false。
exif_imagetype()函数:读取一个图像的第一个字节并检查其签名,如果发现恰当的签名返回一个对应的常量,否则返回false。返回值和getimagesize()返回值的数组中的索引2的值是一样的,但本函数快的多。
常见值和常量:
1=>imagetype_gif,2=>imagetype_jpeg,3=>imagetype_png,4=>image_swf等等,其他感兴趣可以自查
当然只上传图片访问后是不能当作php执行的,这里要配合文件包含漏洞利用。靶场也很贴心的直接给了一个包含漏洞页面。用get方式接受file变量,include直接包含运行文件,所以1.jpg也能当php执行。
文件包含漏洞的环境要求:
allow_url_fopen=On(默认为On)规定是否允许从远程服务器或者网站检索数据
allow_url_include=On(php5.2之后默认为off)规定是否允许include/require远程文件
三、漏洞利用
上传成功,因为上传的图片返回给了用户,所以直接获得文件路径
打开后,虽然里面写了脚本但是无法直接执行。利用包含漏洞页面,直接执行获取服务器配置信息,也可上传一句话木马,通过蚁剑,菜刀等后门工具链接获取webshell。