绕过白名单检查实现文件上传
文件上传指将客户端数据以文件形式封装,通过网络协议发送到服务器端。在服务器端解析数据,最终在服务端硬盘上作为真实的文件保存。了解文件上传漏洞产生的原因,掌握漏洞的利用方法。
1. 文件上传漏洞简介
通常web站点会有用户注册功能,而当用户登录之后大多数情况下会存在类似头像上传、附件上传之类的功能,这些功能点往往存在上传验证方式不严格的安全缺陷,导致攻击者通过各种手段绕过验证,上传非法文件,这是在web渗透中非常关键的突破口。
2. 文件上传漏洞危害
攻击者绕过上传验证机制上传恶意文件,通过上传的web后门获得整个web业务的控制权,复杂一点的情况是结合web服务器的解析漏洞来获取权限。
3. 文件上传检测流程
通常一个文件以HTTP协议进行上传时,将以POST请求发送至web服务器,web服务器收到请求并同意后,用户与web服务器将建立连接,并传输数据。
4. 常见的MIME类型
1)超文本标记语言.html文件的MIME类型为:text/html
2)普通文本.txt文件的MIME类型为:text/plain
3)PDF文档.pdf的MIME类型为:application/pdf
4)MicrosoftWord文件.word的MIME类型为:application/msword
5)PNG图像.png的MIME类型为:image/png
6)GIF图像.gif的MIME类型为:image/gif
7)MPEG文件.mpg、.mpeg的MIME类型为:video/mpeg
8)AVI文件.avi的MIME类型为:video/x-msvideo
5. 00截断
1) 0x00截断
0x00是十六进制表示方法,表示ASCII码为0的字符,在一些函数处理时,会把这个字符当作结束符。
0x00可以用在对文件名的绕过上,具体原理:系统在对文件名进行读取时,如果遇到0x00,就会认为读取已经结束。但要注意是文件的十六进制内容里的00,而不是文件名中的00。也就是说系统是按二进制或十六进制读取文件,遇到ASCII码为0的位置就停止,而这个ASCII码为0的位置在十六进制中是00。
总之就是利用ASCII码为0这个特殊字符,让系统认为字符串已经结束。
2) %00截断
url发送到服务器后被服务器解码,这时还没有传到验证函数,也就是说验证函数里接收到的不是%00字符,而是%00解码后的内容,即解码成了0x00。总之就是%00被服务器解码为0x00发挥了截断作用。
3) 0x0a
0x0a是十六进制表示方法,表示ASCII码为/n的换行字符,具体为换行至下一行行首起始位置。
通过该实验了解文件上传漏洞的基础知识及如何绕过白名单检测上传恶意文件。
操作系统:
Windows10:部署文件上传漏洞环境及漏洞利用;ip:10.1.1.100
辅助工具:phpStudy、Mozilla Firefox、burpsuite、菜刀
源码与工具请在实验机内下载使用:http://tools.hetianlab.com/tools/T044.zip(包里有菜刀,为避免误杀下载之前先关闭defender)
关闭defender步骤:在桌面搜索栏搜关键字 defender-> 设置-> 实时保护(关闭)即可
本次实验采用github开源项目upload-labs靶场,项目地址:https://github.com/c0ny1/upload-labs
任务描述:通过修改MIME类型,使其符合$_FILES['upload_file']['type']的白名单,达到上传恶意文件的目的。
1. Windows机器上下载的源码文件放到phpStudy的WWW目录下,在源码文件里创建一个名为upload的文件夹:
PHP版本切换至5.2.17,开启phpStudy;
2. 在桌面写一个简单的一句话木马eval.php:
3. 浏览器访问http://10.1.1.100/upload-labs/index.php,选择Pass-02,查看源码可以发现是白名单判断,只允许上传$_FILES['upload_file']['type']为'image/jpeg'、'image/png'及'image/gif'的文件。
4. 上传eval.php并用burpsuite抓包:
此时的MIME类型为application/octet-stream
5. 修改Content-Type为image/gif,点击‘go’之后在Response处查看响应内容:
成功上传木马文件到upload文件夹。
任务描述:$img_path直接拼接,利用%00截断进行绕过,上传恶意文件并通过浏览器连接webshell。
1. 选择Pass-11,点击右上方‘显示源码’,根据源码提示进行文件上传:
可以看到是白名单判断,但是$img_path直接对上传的文件名拼接,使用$_GET传参,我们可以利用%00截断进行绕过。
注:%00截断的条件:
1)PHP版本小于5.3.4;
2)打开PHP的配置文件php-ini,将magic_quotes_gpc设置为Off。
2. 桌面写一个test.jpg文件:
3. Windows中修改PHP配置文件php.ini:
保存后重启phpStudy。
4. 上传test.jpg并使用burpsuite抓包,save_path改为../upload/test.php%00:
5. 点击‘go’之后查看响应内容,最后保存下来的文件会是test.php:
6. Firefox浏览器连接webshell:
连接成功。
任务描述:0x00截断绕过,利用burpsuite的hex功能将save_path改成../upload/test.php[二进制00]形式,上传恶意文件并通过菜刀浏览器连接webshell。
1. 选择Pass-12,通过源码提示进行文件上传:
和Pass-11不同的是,'save_path'是通过post传进来的,需要在二进制文件中进行修改,因为post不会像get那样对%00进行自动解码。
2. 上传test.jpg并使用burpsuite抓包,利用burpsuite的hex功能将save_path改成../upload/test.php[二进制00]形式:
在../upload/后添加test.php (.php后面加空格),filename不用修改,然后点击‘Hex’:
预备知识里说到了0x0a是十六进制表示方法,表示ASCII码为/n的换行字符,具体为换行至下一行行首起始位置;而0x0d表示ASCII码为/r的回车字符,回车的作用只是移动光标至该行的起始位置。
3. 将0d前面的20改为00,然后点击‘go’查看响应内容:
最终上传的是test.php文件。
4. 使用菜刀连接webshell:
点这个‘+’号;
输入webshell地址http://10.1.1.100/upload-labs/upload/test.php:
在后面的post数据输入框里输入:test=phpinfo();
点击post数据输入框后面的提交键,即可连接webshell:
任务描述:本关考察CVE-2015-2348,move_uploaded_file() 00截断,上传webshell同时自定义保存名称,上传成功后用菜刀连接。
1. 选择Pass-19,点击右上方‘显示源码’,根据源码提示进行文件上传:
发现move_uploaded_file()函数中的$img_path是由post参数save_name控制的,可以在save_name中利用00截断进行绕过。
2. 上传test.jpg并使用burpsuite抓包:
保存名称修改为‘test.php+空格.1.jpg’,点击‘上传’;
3. 在‘Hex’中将20(表示php后的那个空格)改为00,然后点击‘go’查看响应内容:
最终上传的是test.php文件。
4. 通过菜刀连接webshell:
此处的‘test’即为@eval($_POST['test']);中的‘test’,脚本类型选择‘PHP’,点击‘添加’:
菜刀连接webshell成功。
1. 将上传的目录设置为不可执行;
2. 判断文件类型:结合MIME Type、后缀检查等方式,推荐文件类型检查使用白名单的方式;
3. 使用随机数改写文件名和文件路径。
相关文章
- 1条评论
- 南殷柔侣2022-05-28 17:14:05
- 文件名拼接,使用$_GET传参,我们可以利用%00截断进行绕过。 注:%00截断的条件: 1)PHP版本小于5.3.4; 2)打开PHP的配置文件php-ini,将magic_quotes_gpc设置为Of