一般是在网页上写一段Js脚本,用Js去检测,校验上传文件的后缀名,有白名单也有黑名单。
判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包,所以可以通过抓包来 判断,如果弹出不准上传,但是没有抓到数据包,那么就是前端验证
前端验证非常不可靠,传正常文件改数据包就可以绕过,甚至关闭JS都可以尝试绕过
服务端检测几个常见的手段:
检查Content-Type (内容类型)
检查后缀 (检查后缀是主流)
检查文件头
黑白名单机制:
黑名单:不允许上传什么
白名单:只允许上传什么
白名单比黑名单跟安全
绕过靶场演示——使用upload-labs靶场
1.客户端绕过
上传tt.php提示不允许上传.php的文件:
1.1绕过:浏览器删除事件
右键查看页面元素,定位表单,发现事件
右键删除事件
成功上传
1.2绕过:伪造上传表单
上面的删除事件是直接删除JS的检测,比较残暴,可以使用伪造上传表单,通过伪造一个没有做任何限制的表单,数据依然提交到目标地址,绕过原来的JS代码的限制。BURP抓包修改绕过,修改格式,将PHP文件的后缀.php改为.jpg等支持上传的文件格式,然后上传修改后的文件:
上传phpinfo.jpg使用BURP抓包,将jpg文件重新修改为php格式:
上传成功
2 服务器绕过
2.1 Content-Type方式绕过
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。常见的MIME类型如下:
文件扩展名 |
Mime-Type |
.js |
application/x-javascript |
.html |
text/html |
.jpg |
image/jpeg |
.png |
image/png |
|
application/pdf |
在HTTP协议中,使用Content-Type字段表示文件的MIME类型。
这种服务器检测和前端检测没什么太大区别,只是检查一下文件的上传格式,虽然无法通过删除浏览器事件来绕过,但是依旧可以使用BURP抓包,修改绕过。
直接上传phpinfo.php文件,显示的Content-Type为application/octet-stream,而服务器上会检测此字段是否为jpeg等符合标准的文件类型,所以我们可以直接修改Content-Type字段的值为image/jpeg:
上传成功
2.2 黑名单绕过
查看一下源码,发现过滤的内容是以'.asp','.aspx','.php','.jsp'为后缀的文件类型,很明显这个过滤不严谨,php中,如果默认状下.php3,.php4,.php5,.phtml 都是会被解析为php的,直接上传:
查看源码
修改后缀为.php3
上传成功
但是发现无法访问
因为phpstudy的http配置文件中没有允许.php3格式,可以手动添加上:
2.3 .htaccess文件绕过
什么是.htaccess?它全称是Hypertext Access(超文本入口) .htaccess文件也被成为分布式配置文件,提供了针对目录改变配置的方法,在一个特定的文档目录中放置一个包含一个或多个指令的文件, 以作用于此目录及其所有子目录。.htaccess功能:文件夹密码保护、用户自定义重定向、自定义404页面、扩展名伪静态化、禁止特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表很可惜,这么一个强大的功能默认是不开启的 Apache (有伪静态的都可以试试)
例如:AddType application/x-httpd-php .jpg 这个指令代表着.jpg文件会当做php来解析。
查看源码发现黑名单很全面,无法上传php文件
上传一张带有php代码的jpg格式图片
查看图片,并没有执行php代码
制作.htaccess文件,先写一个txt文件:
然后将文件名更改为.htaccess将其上传
再次查看phpinfo.jpg
成功当做php代码解析。
2.4 大小写绕过
直接上传php文件,发现有黑名单无法上传,但是黑名单不全面。没有进行大小写转换直接上传.Php
上传成功,但是发现无法访问
将文件名修改为上传的文件名即可成功执行
2.5 文件后缀(空)绕过
在文件名后面留一个空格,然后上传上去后空格会被自动的省略,对于过滤规则来说有没有空格是不一样的,但是对于操作系统来说,文件名的最后一个是空格会直接将其删除。直接上传php文件使用Burp抓包:
上传成功
查看图片,成功执行
2.6 文件后缀(点)绕过
上传php文件使用Burp抓包
上传成功
查看图片,成功执行
2.7 ::$DATA(Windows文件流绕过)
这里利用到了NTFS交换数据流(ADS),ADS是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流。通俗的理解,就是其它文件可以“寄宿”在某个文件身上,而在资源管理器中却只能看到宿主文件,找不到寄宿文件。
::$DATA就是默认不修改文件流的情况,可以利用windows特性,可在后缀名中加” ::$DATA“,绕过检测
上传php文件使用Burp抓包
上传成功
打开图片,执行失败
将url后面的::$DATA删除再次访问即可
2.8 构造文件后缀绕过
查看源码:
发现有”删除文件名末尾的点“和”首尾去空“。但是并没有循环执行,说明只执行一次。所以我们可以自己构造文件名后缀来绕过,构造”. .“来绕过,过滤了一个”.“和一个” “,还剩下一个”.“。这样就又变成了上面讲到的” 文件后缀(点)绕过“。
上传php文件使用Burp抓包
上传成功
查看图片,成功执行
2.9 双写绕过
查看源码:
源码的意思大概就是:只要后缀出现黑名单内容就直接为空。这样就没办法使用什么点绕过空格绕过了。但是依然没有循环执行过滤代码,我们将后缀规则为pphphp,过滤了一个php之后还剩下一个php,就可以成功上传
上传php文件使用Burp抓包
上传成功
查看图片,成功执行
2.10 基于GET的00截断
了解%00实际上我们要先了解0x00,0x00实际上是一个十六进制表示方式,实际上就是表示ascii码值为0,有些函数在处理这个字符的时候会把这个字符当做结束符,他们就读取到这里认为这一段结束了
在文件上传时,如果遇到了白名单机制只允许上传jpg后缀的,在没有解析漏洞的情况下我们该怎么办?
JPG格式并不会被解析,那么我们需要绕过上传过滤。
假如我写了1.php%00.jpg 传参之后,有些过滤都是直接匹配字符串,他强行匹配到了结尾是.jpg,然后允许上传,但是php的函数去执行的时候他读取到0x00认为结束了,那么这个文件就变成了1.php
%00实际上和00截断是一模一样的原理,只不过%00是经过URL编码的,%00解码后就是0x00截断的那个字符
%00只能用于php版本低于5.3的
上传jpg使用Burp抓包
上传成功
查看文件,注意直接查看后缀是不对的,需要将php后面的%00还有一串数字这些删掉:
2.11 基于POST的00截断
与GET唯一不同的地方在于获取文件路径的方式不同,这里是通过POST方式获取,上传jpg图片使用Burp抓包:
发现上传失败
懵逼了不,%00是0x00的URL编码,URL 编码 => %xxxx,GET可以接受URL编码因为可以自行解码,但是POST不能,所以我们需要直接修改其16进制值为00,再次上传jpg图片抓包:
上传成功
删除
成功执行
2.12 图片马绕过
二次渲染
在我们上传文件后,网站会对图片进行二次处理(格式、尺寸要求等),服务器会把里面的内容进行替换更新,处理完成后,根据我们原有的图片生成一个新的图片并放到网站对应的标签进行显示。
制作图片马
真图片马:
C:\Users\31105\Desktop>copy 1.png /b + 123.php xiaoheizi.png
1.png
123.php
已复制 1 个文件。
1.png是正常的图片
123.php是一句话木马文件
xiaoheizi.png看起来是一张正常的图片,可以打开,但是通过16进制查看可以看到照片的最后有一句话木马
- 参数/b指定以二进制格式复制、合并文件,用于图像类/声音类文件
- 参数/a指定以ASCII格式复制、合并文件,用于txt等文档类文件
假图片马,直接将php文件重命名为图片格式,在php文件的头部加上图片头部信息:
#常见的图片文件头
JPG:FF D8 FF E0 00 10 4A 46 49 46
GIF:47 49 46 38 39 61(GIF89a)
PNG:89 50 4E 47
可以cmd命令行制作图片马,也可以使用图片编辑器进入16进制模式直接插入一句话木马,也可以上传图片时使用Burp抓包插入一句话木马
上传图片马:编辑器制作
二次渲染不会去渲染前面的几行代码,推荐从3-4行开始写,使用编辑器打开图片使用16进制模式进行编辑,插入一句话木马
上传
下载图片,查看一句话木马是否存在:
一句话木马还存在,绕过成功
2.13 条件竞争
开发者在进行代码开发时常常倾向于认为代码会以线性的方式执行,而且他们忽视了并行服务器会并发执行多个线程,这就会导致意想不到的结果。
线程同步机制确保两个及以上的并发进程或线程不同时执行某些特定的程序段,也被称之为临界区(critical section),如果没有应用好同步技术则会发生“竞争条件”问题。
在我理解就是两只哈士奇(线程)同时去抢一个丢出去的飞盘(资源),不知道到底哪只能抢到,此处便形成了竞争。
竞争对象
一般而言我们是上传了文件,上传了但是最后却因为过滤或者因为其他原因被删除了,那么我们可以使用条件竞争,我们实际上是和unlink,是和删除文件的函数进行竞争。
假如我不断的上传发包,然后我同时也不断的访问那个我们上传上去的文件的地址,我们就开始和服务器的函数比手速了,函数执行都是要时间的,如果我这边上传上去,且没有删除,那个时间可能很短,然后被我访问到了,岂不是就可以执行PHP了
如果是先上传——被保存——被检测——被删除,我们就可以在被删除之前访问到我们上传的文件。
是不是就有机会干点什么?
比如:让功能强大的PHP 来写一句话木马。先上传1.php,它的目的是让服务器上的php来创建一个2.php,我们在1.php被删除之前访问到他,就可以在服务器中创建2.php,2.php是一个木马文件,但是这个是系统自身创建的,所以不会被删除。
上传php文件使用burp抓包:
php文件内容:');?>
意思是:访问到这个文件时在当前目录创建一个内容为,名字为xiaoheizi.php的文件
我们可以使用burpsuit抓包软件中的Intruder模块,创建两个自动攻击方案,第一个自动攻击方案是一直持续的将文件上传到服务器中;第二个自动攻击方案是一直持续的访问我们上传的文件(我们可以写一个php代码,当我们访问执行该php代码时,会自动在该文件所在目录下创建一个一句话木马,这样就达到了我们将一句话木马上传到服务器的目的了)
用burpsuit拦截test.php文件的上传请求,将拦截到的报文发送到intrude中
然后设置攻击方案:
用burpsuit拦截访问test.php文件请求,将拦截到的报文发送到intrude中
设置攻击方案:
我们可以看到,在upload目录中是没有任何文件的
点击3自动攻击方案,点击start attack;点击4自动攻击方案,点击start attack;
开始攻击之后我们可以看到第一个攻击方案的攻击结果
第二个攻击方案的攻击结果
当第二个攻击方案返回的状态码为200时,就可以查看到upload目录上已经被写入了一个xiaoheizi.php文件,这时我们要上传一句话木马的目的就达到了
使用蚁剑成功连接