什么是上传漏洞?
我的理解是由于程序员未对上传的文件作过滤或者过滤机制不严格,导致恶意用户可以上传动态脚本页面,从而通过上传的这张脚本页面达到控制网站权限的目的。
我们简单来说下什么叫做过滤机制不严格:
比如一个网站只支持ASP脚本,在上传功能中程序员对此的过滤策略是“取得客户端文件名中最后一位小数点后的后缀内容,如果碰到后缀为html、shtml、asp格式,程序则不允许上传,否则,上传成功” 。假设程序员知道本网站只支持解析ASP,不支持解析php或者aspx,也就是说其他脚本即使被上传成功,也执行不了。看来这个情况下我们确实只需要限制掉asp就可以了。如果你的想法也是这样,那真的错了,默认情况下asa、cer后缀均调用的是asp的解析dll,那么,你觉得这样的程序还安全吗?很多程序员未必会了解这一点。再反问,以这种验证方式为前提,如果我把所有能当做asp去执行的后缀都限制上传了,你觉得安全吗?后面我会告诉你的。
这里我先来简单归纳一下上传漏洞的总类(个人能力有限应该还有遗留的):
一、未做任何限制
二、客户端JS验证绕过(本地javascript扩展名检测)
三、http包头检测绕过(content-type检测)
四、文件名可定义上传漏洞(自定义文件名,可使用0×00截断写入,参看dvbbs6.0上传漏洞同理)
五、文件夹可定义上传漏洞(自定义文件夹名,可使用0×00截断写入,参看dvbbs6.0上传漏洞)
六、文件头检测绕过(gif89a等文件头部检测)
七、第三方解析漏洞(IIS、apache、nginx的解析问题)
八、等等
相信以上这些大家多多少少都碰到过,并且也都知道原理,这里不再重复复述,不懂的可以问我或者找我们共同的老师搜索引擎问一下。
进入正题,我们先来看一段代码
很明显上述功能首先获得用户文件名中最后一个小数点后面的内容-即后缀,如果后缀为第三行定义中数组中的词语,则不允许上传,甚至我们还限制了shtml、html,想的比较周到。
现在来看看我们如何来突破他吧。仔细分析一下,程序取得文件名最后一个小数点的值,以此来判断文件是否允许被上传。如果上传成功,则以date()一个数值加上文件名来进行最终命名,然后将此临时文件移动到我们要保存的目录。
我们先来补充点小知识,对于windows来说,会默认“吃掉”文件名最后的小数点,可以尝试一下,在文件名最后输入一个小数点保存,小数点是不会出现的,被吃掉了。Linux则会继续将小数点写进去。
有了这个概念,我们来针对这个上传程序进行测试,首先上传一个木马页面test.php,很显然上传失败,然后我们对上传的这个地址加以改进,写成如下样式(同样是刚才那张木马页面,我们仅仅是在这个input中手工多加了个小数点哦)
接收进去的文件名“test.php.”被程序认为是可被允许的,因为最后一个小数点后面的值不在黑名单范围,下一步程序就进行写入,date()给予一个当前时间数“120421003323”加上“_”再加上文件名“test.php.” ,即变成“120331142923_test.php.” ,相信大家先前的那个小知识的内容都试过了,程序在windows中写入文件名的时候,如果最后一位是英文的小数点,默认就吃掉了,最终变为“120331142923_test.php” ,木马上传成功。
虽然在linux中仍然是“120331142923_test.php.”格式写入,但是还是由于apache和nginx的解析特性,大部分此类情况还是继续会被当做php去执行,具体版本情况大家可以自行测试。
总结
防御:一些单纯的本地检测、包头检测、图片头检测、图片体检测getimagesize()、黑白名单检测,只要稍微不小心,就有可能会被突破,所以,我们如果要使用这些方法的话,请先严格理解这些可能造成的漏洞隐患,然后再对相关的问题点进行针对性的修补。
最后还是表达我感悟的一句话:入侵技术点或许大家都会,但是这远远不够,实际渗透中由于环境问题有各种变化,能否举一反三、细心、坚持才是渗透最重要的。
转载自:http://www.2cto.com/Article/201205/129862.html