cgi在现在的互联网应用越来越广泛,cgi编程的安全问题也得到越来越多的重视。perl作为cgi编程的主要语言之一,其安全性也受到很大的关注。在 w3c组织的 "www security faq" 之 "cgi scripts"一章中,perl安全编程就整整占了一节。由此可见 perl cgi 安全编程的重要性。
这里我不会重复 "www security faq" 的内容,而是根据一直以来对 perl免费/商业程序包的源代码的研究,得出一些较易被忽略的编程漏洞,在此将几个最常见的(主要是变量字符过滤方面)写出来,供广大程序员作为参考。
如果你对本文的内容有不同意见或任何建议,请告诉我。如果你发现了其它perl cgi 编程漏洞,也请告诉我。如果你也发表了关于这方面的文章,当然也请告诉我。:-)
---------------------
1、“有毒”的null字符
---------------------
如果我说:"root"=="root",相信没有什么人反对。但同时我也这样说:"root"!="root"!还有多少人会认为我是个“正常人”?:)
但在各种不同的编程语言中,确实存在着这种情况。
对于每一个希望发现cgi漏洞的安全专家或黑客来说,最常用的方法之一是通过传递特殊字符(串),绕过cgi限制以执行系统级调用或程序。如果你仔细留意的话,或许也会发现null字符确实有它的“妙用”。:)
阅读以下例子:
# parse $user_input
$database="$user_input.db";
open(file "<$database");
这个例子用于打开客户端指定的数据库文件。例如客户端输入"backend",则系统将打开"backend.db"文件考只读方式)。(注:在这里我们暂且不讨论"../" 的安全问题。)这种处理方式在互联网中是很常见的。
现在,让我们在客户端输入"backend%00",在该perl程序中$database="backend.db",然后调用open函数打开该文件。但结果是什么呢?系统会打开"backend"文件(,如果该文件存在)!
出现这种情况的原因是由于perl允许在字符串变量中使用null空字符,而在c语言中字符串则不允许包含空字符。因此,也就有了"root"!="root"(在perl中)和"root"="root"(在c语言中)。由于系统内核/调用等都是使用c语言编写,因此当perl将"backend.db"字符串传递到(c语言的)链接库/程序时,空字符以后的字符将被忽略?(或许还有利用价值?我还没发现。:))
这种编程缺陷的影响可大可小。试想一下,如果利用以上编程原理编写一个给系统其他管理员修改除了root外的其他用户口令的perl程序:
$user=$argv[1] # user the jr admin wants to change
if ($user ne "root"){
# do whatever needs to be done for this user }
那么,聪明的你应该知道如何绕过这个限制修改root用户口令了吧?对了,只要使 $user="root",则perl会执行上面程序中花括号内的语句。除非所有处理过程均使用perl,否则一旦该变量传递给系统,则会造成安全问题。如修改root用户口令等。
也许你认为很难遇到这种会造成严重安全问题的情况,那么我们能否将它作为一种寻找网站源程序漏洞的间接手段呢?;-)
不知你有没有经常遇到这种类型的cgi程序,该程序用于打开客户端(提交的表单中)要求的页面?如:
page.cgi?page=1
然后网站是否返回页面"1.html"呢?;-) 好,现在将其改为:
page.cgi?page=page.cgi%00
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器