这次我要给大家讲解地是上传漏洞,但这个上传漏洞和ASP的不同,因为它是在PHP中的上传漏洞。比较经典,在很多场合都能用得上,希望对大家的学习之路能有所帮助。
开始之前我先罗嗦一下ASP的上传原理,就以动网曾经存在的上传漏洞为例吧。对于特殊字符chr(0),学过C的人都知道,它其实就是“/0”,也就是结束了。当我们上传一个
“aaa.asp.jpg”(中间的空格表示chr(0))文件时,用right(file,4)看的时候,确实显示的是.jpg,
但当实际读取filename="aaa.asp .jpg"并生成文件的时候,系统读到chr(0)就以为结束了,所以后面的.jpg就被截断了,这样就可以执行我们的aaa.asp文件了。但是对于PHP来说,上传漏洞的种类就非常多了,利用也很广泛。也许是我对ASP的研究不够深才这么说的,希望大家看完这篇文章以后,能帮我到我不足的地方。
基础知识
首先我们要了解的是HTTP协议,要是详细讲解的话够写一本书了,这里就概要的讲解一些我们用得着的东西。
HTTP是超文本传输协议的缩写,用于传送WWW方式的数据。它采用了请求/响应模型,客户端向服务器发送一个请求,请求头包含请求的方法、URI、协议版本,以及包含请求修饰符、客户信息和内容的类似
于MIME的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。
我们先来看一个详细的上传JPG的正规模式的数据包,然后我再给大家讲解一下。
POST /upload/upload.php HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer:127.0.0.1/upload/upload.html
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=---------------------------7d718341001a2
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727)
Host: 127.0.0.1
Content-Length: 337365
Connection: Keep-Alive
Cache-Control: no-cache
Cookie:
phpbb2mysql_data=a%3A2%3A%7Bs%3A11%3A%22autologinid%22%3Bs%3A0%3A%22%2
2%3Bs%3A6%3A%22userid%22%3Bi%3A-1%3B%7D;
这个数据包的第一行“POST /upload/upload.php HTTP/1.1”是利用HTTP的Post方法向“/upload/upload.php”文件打包传递数据。Accept是定义客户端可以处理的媒体类型,按优先级排序;在一个以逗号为分隔的列表中,可以定义多种类型和使用通配符。Referer头域允许客户端指定请求URL的源资源地址,可以允许服务器生成回退链表,可用来登录、优化
Cache等,也允许废除的或错误的连接由于维护的目的而被追踪。如果请求的URL没有自己的URL地址,Referer不能被发送。如果指定的是部分URL地址,则此地址应该是一个相对地址。
对于HTTP协议,我们了解这些就足够了,更详细的内容大家可以查阅相关资料。下面我们就正式进入PHP上传漏洞的详细讲解部分。
php是文件什么
最基础的上传漏洞
最基础的上传漏洞一般很少出现,能写出存在这样漏洞的程序的人大多是初学PHP语言,对PHP安全根本就不了解。
下面我们就来详细地讲解一下这种最简单的PHP上传漏洞。首先我们需要两个源程序,第一个是upload.html,用于提交文件,第二个是upload.php文件,用于接收文件并且对它进行相应的处理。
upload.html的源代码如下:
<form action=”upload.php” method=”POST” ENCTYPE=”multipart/form-data”>
点这里上传文件:<input type=”file” name=”userfile”>
<input type=”submit” value=”提交” name=”upload”>
</form>
upload.php源代码如下:
<?php
$uploaddir = PreviousFile/;
$PreviousFile = $uploaddir . basename($_FILES[userfile][name]);
if(move_uploaded_file($_FILES[userfile][tmp_name], $PreviousFile))
{
echo "<pre>";
print_r($_FILES);
echo "</pre>";
}
?>
小提示:move_uploaded_file()函数的原型是“bool move_uploaded_file ( string filename, string destination)”,用于检查并确保由filename指定的文件是合法的上传文件(即通过PHP 的HTTP Post上传机制所上传的)。如果文件合法,则将其转为由destination指定的文件。
我们直接在upload.html中上传PHP后门c99shell.php,如图1和2所示,成功地执行了我们的脚本了。不过相信现在最的程序员也不会这样办了。呵呵,好了,我们深入一些吧。
图1
图2
文件上传类型漏洞之一
可以让用户上传任意的文件和查看任意的文件通常不是一个好的程序员的做法,因此大多数的程序都有防范它的功能。
为了演示这个漏洞,我们还是需要两个文件,PreviousFile.html和PreviousFile.php。我们还是先看一下源代码,然后一句一句地分析。
PreviousFile.html的源代码如下:
<form action="PreviousFile.php" method="POST" enctype="multipart/form-data">
点这里上传文件:<input type="file" name="userfile">
<input type="submit" value="提交" name="upload">
</form>
PreviousFile.php的源代码如下:
<?php
if($_FILES[userfile][type] != "image/gif")
{
echo "对不起,我们只允许上传GIF格式的图片!!";
exit;
}
$uploadfir = PreviousFile/;
$PreviousFile = $uploaddir . basename($_FILES[userfile][name]);
if(move_uploaded_file($_FILES[userfile][tmp_name], $PreviousFile))
{
echo "文件是有效的,成功上传!!!";
} else {
echo "文件上传错误!!!请重新上传!!!!";
}
?>
其中“if($_FILES[userfile][type] != "image/gif")”这句代码的意思是检测文件的MIME类型,需要浏览器提供该信息的支持。本例中使用的是“image/gif”,其他的代码和第一个例子差不多,我就不详细讲解了。
我们还是看实际操作。如图3所示,我们直接上传PHP是不能成功的。下面我们来看看如何绕过它来继续上传要执行的PHP文件。
图3
在这之前,我们要用到一个Perl写的小程序来实现上传,非常的简单,我就不详细讲解了,不然十页也写不完了,大家只要知道怎么用就可以了。其源代码如图4所示,只要将图中画线的地方改为我们的实际地址与文件名就可以了。
图4
把我们要上传的shell.php保存在当前目录下,然后执行一下Perl程序,如图5所示,提示成功上传了!再确认一下我们的文件到底有没有上传上去,如图6所示,上传的文件安静地躺在我们程序的目录中了。
图5
图6
图7是我们执行后的效果,传说中的上传经典漏洞产生了,这里就是利用了PHP自身的$_FILES[]漏洞来绕过HTTP协议上传的。Upload.pl这个程序用于把Content-type的类型修改为image/gif。
图7
我们继续往下看,一步一步的把这个程序完美化,看是否还存在漏洞。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。