首页 | 麦客学吧 | 视频教程 | FLASH小游戏 | 素材下载 | 常用工具
您当前的位置:首页 > 程序开发 > CGI > 正文

Perl CGI编程安全点滴

出处:麦客学吧 [2006-4-15 12:17:00] 来源:未知 点击数:1131

讨论交流:http://x8.maicoo.com/team/574.html

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 (%00 == '' escaped)  

这样,我们就可以得到我们感兴趣的文件内容了!这种方法连PERL的"-e"参数也可绕过:  

$file="/etc/passwd.txt.whatever.we.want";  
die("hahaha! Caught you!) if($file eq "/etc/passwd");  
if (-e $file){  
open (FILE, ">$file");}  

绕过这段程序的后果你应该想像得到吧?:)  
  解决方法?最简单地,过滤NULL空字符。在PERL程序中,  

$insecure_data=~s///g;  

------------------------  
2、漏网之鱼--反斜杠()  
------------------------  

  对于每一个关心CGI安全的人,也许都看过 W3C 的 www.Security FAQ 中关于CGI安全编程一节。其中列出了建议过滤的字符:  

&;`'"|*?~<>^()[]{}$nr  

但我在很多时候发现反斜杠()往往被遗忘了。以下是正确的过滤表达式:  

s/([&;`'\|"*?~<>^()[]{}$nr])/\$1/g;  

但在很多商业的CGI程序中反斜杠却没有被包含进去,这可能是程序员们写程序时被这些过滤用的匹配表达式搞迷糊了?  
  那么,没有过滤反斜杠会造成安全问题吗?试想一下,如果向你的程序中发送如下一行内容:  

user data `rm -rf /`  

大多数情况下,程序员编写的程序会将以上内容过滤为:  

user data `rm -rf /`  

从而保护了系统。但如果PERL程序中忘记过滤了反斜杠,当客户端向该程序提交如下内容时:  

user data `rm -rf / `  

经过匹配表达式后为:  

user data \`rm -rf / \`  

怎么样,看出危险了吗?由于两个反斜杠经系统解释后为一个字符"",但`字符却因此没有被过滤掉,`rm -r

【责任编辑: lanier

关于 Perl CGI编程安全点滴 的相关文章
素材中心
麦客酷站赏析频道

精彩图文推荐

关于本站 - 联系站长 - 广告服务 - 合作伙伴 - 网站地图 - 版权声明 - 报告错误 - 收藏本站 | Http://www.MaiCoo.com

Copyright © 2005 - 2008 MaiCoo.com All Rights Reserved

违法和不良信息举报中心 本站服务器空间和带宽由雷克斯网络提供赞助
浙ICP备06017818号