使用IIS url重写来防止SQL注入

时间:2015-06-12 12:18:55

标签: iis url-rewriting rewrite sql-injection requestfiltering

我们在服务器上使用各种CMS(Wordpress,Joomla),因此很多代码都是第三方,因此我们无法控制质量。虽然我们总是把所有东西都保持最新,但我们最近有一个被黑客入侵的网站。

为了防止将来发生这种情况,我已将URL重写规则添加到web.config文件中。但我有几个问题:

  1. 我应该使用RequestFiltering而不是Query_String来检测注入吗?或者没有区别?

  2. IIS是否缓存了web.config,还是像Apache .htaccess一样,并在每个请求中查询?如果是这样,这会导致性能下降吗?

  3. 我是否错过了任何可能的攻击?

  4. ... CODE

    <rule name="Injection Blocking">
         <match url="^(.*)$" ignoreCase="false" />
         <conditions logicalGrouping="MatchAny">
           <add input="{HTTP_USER_AGENT}" pattern="(havij|libwww-perl|wget|python|nikto|curl|scan|java|winhttp|clshttp|loader)" />
           <add input="{HTTP_USER_AGENT}" pattern="(%0A|%0D|%27|%3C|%3E|%00)" />
           <add input="{HTTP_USER_AGENT}" pattern="(;|&lt;|>|'|&quot;|\)|\(|%0A|%0D|%22|%27|%28|%3C|%3E|%00).*(libwww-perl|wget|python|nikto|curl|scan|java|winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner)" />
           <add input="{THE_REQUEST}" pattern="(\?|\*|%2a)+(%20+|\\s+|%20+\\s+|\\s+%20+|\\s+%20+\\s+)HTTP(:/|/)" />
           <add input="{THE_REQUEST}" pattern="etc/passwd" />
           <add input="{THE_REQUEST}" pattern="cgi-bin" />
           <add input="{THE_REQUEST}" pattern="(%0A|%0D|\\r|\\n)" />
           <add input="{URL}" pattern="owssvr\.dll" />
           <add input="{HTTP_REFERER}" pattern="(%0A|%0D|%27|%3C|%3E|%00)" />
           <add input="{HTTP_REFERER}" pattern="\.opendirviewer\." />
           <add input="{HTTP_REFERER}" pattern="users\.skynet\.be.*" />
           <add input="{QUERY_STRING}" pattern="[a-zA-Z0-9_]=http://" />
           <add input="{QUERY_STRING}" pattern="[a-zA-Z0-9_]=(\.\.//?)+" />
           <add input="{QUERY_STRING}" pattern="[a-zA-Z0-9_]=/([a-z0-9_.]//?)+" />
           <add input="{QUERY_STRING}" pattern="\=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" />
           <add input="{QUERY_STRING}" pattern="(\.\./|%2e%2e%2f|%2e%2e/|\.\.%2f|%2e\.%2f|%2e\./|\.%2e%2f|\.%2e/)" />
           <add input="{QUERY_STRING}" pattern="ftp\:" />
           <add input="{QUERY_STRING}" pattern="http\:" />
           <add input="{QUERY_STRING}" pattern="https\:" />
           <add input="{QUERY_STRING}" pattern="\=\|w\|" />
           <add input="{QUERY_STRING}" pattern="^(.*)/self/(.*)$" />
           <add input="{QUERY_STRING}" pattern="^(.*)cPath=http://(.*)$" />
           <add input="{QUERY_STRING}" pattern="(\&lt;|%3C).*script.*(\>|%3E)" />
           <add input="{QUERY_STRING}" pattern="(&lt;|%3C)([^s]*s)+cript.*(>|%3E)" />
           <add input="{QUERY_STRING}" pattern="(\&lt;|%3C).*embed.*(\>|%3E)" />
           <add input="{QUERY_STRING}" pattern="(&lt;|%3C)([^e]*e)+mbed.*(>|%3E)" />
           <add input="{QUERY_STRING}" pattern="(\&lt;|%3C).*object.*(\>|%3E)" />
           <add input="{QUERY_STRING}" pattern="(&lt;|%3C)([^o]*o)+bject.*(>|%3E)" />
           <add input="{QUERY_STRING}" pattern="(\&lt;|%3C).*iframe.*(\>|%3E)" />
           <add input="{QUERY_STRING}" pattern="(&lt;|%3C)([^i]*i)+frame.*(>|%3E)" />
           <add input="{QUERY_STRING}" pattern="base64_encode.*\(.*\)" />
           <add input="{QUERY_STRING}" pattern="base64_(en|de)code[^(]*\([^)]*\)" />
           <add input="{QUERY_STRING}" pattern="GLOBALS(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />
           <add input="{QUERY_STRING}" pattern="_REQUEST(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" />
           <add input="{QUERY_STRING}" pattern="^.*(\(|\)|&lt;|>|%3c|%3e).*" />
           <add input="{QUERY_STRING}" pattern="^.*(\x00|\x04|\x08|\x0d|\x1b|\x20|\x3c|\x3e|\x7f).*" />
           <add input="{QUERY_STRING}" pattern="(NULL|OUTFILE|LOAD_FILE)" ignoreCase="false" />
           <add input="{QUERY_STRING}" pattern="(\.{1,}/)+(motd|etc|bin)" />
           <add input="{QUERY_STRING}" pattern="(localhost|loopback|127\.0\.0\.1)" />
           <add input="{QUERY_STRING}" pattern="(&lt;|>|'|%0A|%0D|%27|%3C|%3E|%00)" />
           <add input="{QUERY_STRING}" pattern="concat[^\(]*\(" />
           <add input="{QUERY_STRING}" pattern="union([^s]*s)+elect" />
           <add input="{QUERY_STRING}" pattern="union([^a]*a)+ll([^s]*s)+elect" />
           <add input="{QUERY_STRING}" pattern="\-[sdcr].*(allow_url_include|allow_url_fopen|safe_mode|disable_functions|auto_prepend_file)" />
           <add input="{QUERY_STRING}" pattern="(;|&lt;|>|'|&quot;|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|order|script|set|md5|benchmark|encode)" />
           <add input="{QUERY_STRING}" pattern="(sp_executesql)" />
        </conditions>
       <action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
    </rule>
    

1 个答案:

答案 0 :(得分:1)

基本上,您正在尝试编写自己的基于黑名单的原始迷你WAF(Web应用程序防火墙)。 根据我的经验,尝试仅根据黑名单原始签名来猜测所有可能的攻击是毫无意义的,这是一场你无法获胜的游戏。 例如,您通过阻止脚本和Iframe标记来阻止XSS的尝试可以通过很多方式轻松绕过,其中一些就像<img src='a' onerror=alert('xss')/>一样简单,我甚至都没有提到小写字母-case regex evasion可以绕过几乎所有的反SQL注入尝试。

Web应用程序防火墙是价值数百万美元的产品,它们保留了一大批试图更新其签名的调查员,并且在行为分析和基于白名单的学习模式方面付出了巨大努力,这大大提高了安全级别,你不能真正比较你对他们的产品的好尝试。 你可能会停止停止脚本小子,让专业黑客出汗多一点,但你不会基于这种防御阻止攻击者。

我的建议,而不是尝试自己动手,购买一个主要的WAF(F5,Imperva),或者如果你买不起,只需为你搜索合适的free IIS based WAF并安装它。它可能会比你做得更好 - 没有冒犯。说到免费的WAF,我熟悉那些显然也有IIS版本的好ModSecurity

祝你好运!