在WEB程序中隐藏后门

作者: 空虚浪子心

  在很多商业程序中,程序员也许会出于某种目的,在程序中留下后门。我们不讨论这样做的目的是什么,只谈谈如何在程序中隐藏一个“终极后门”。

  首先给大家看一个例子,去年我写了一篇文章《对校园网的第二次安全检测,文中提到一个类似的后门:“…隐藏账户做后门!…如果不是我先拿到数据库,分析了一段时间以后才拿到程序,相信我也不会注意这个问题。某账户,在后台查询管理员账户的时候,他不出现,在管理员查询登陆和工作日志的时候,他自动消失…”。当时对JSP不了解,通过TOMCAT配置不正确漏洞下载了数据库,然后登陆后台,立刻就发现不对,知道有个后门,却不知道是什么原理,这次我们来把程序仔细“解剖”下。

  一般情况下,在页面上显示用户列表,是由页面去查询数据库的数据,然后返回给浏览器。查询出来的数据是一堆“结果集”,页面显示的时候会把它们一条一条遍历出来。打开存在漏洞的页面,manager.jsp文件代码找到显示用户列表的代码(我加上了注释):

  发现有个重要的数组变量manager,看看它是怎么来的,往上找:

  可以看到代码中manager的值是通过调用managermgt的search方法返回的数组。JSP程序在服务器下运行,除了JSP文件本身,在WEB-INF目录下的classes目录里,有一些“.class文件”,他们是已经写好的JAVA类,可以用来实例化对象。Managermgt对象是MgrMgt这个类实例化出来的,在manager.jsp里,一开始就导入了“speedcharge.controller.*”下的全部包。

  <%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*,speedcharge.entity.*,speedcharge.controller.*" errorPage="" %>

  “.class”文件存储的是java字节码,是由.JAVA文件编译而来的,并不是源代码。所以我们要反编译回去。使用“jad.exe”反编译,然后找到MgrMgt 类的search方法:

  ……Manager amanager[] = null;……//调用searchManager方法
  amanager = Manager.searchManager(s);……

  继续往下找,Manager 类的searchManager方法。

  看到了吧!这个程序从这条SQL语句上做了手脚,让客户在后台查询所有管理员时看不到’ilovethisgame’这个用户,记录日志的时候,也同样使用了类似的方法,导致系统日志忽略了该用户。而程序的其他地方,比如修改管理员、登陆,等地方不受影响。

  这个例子,总体上来说思想很有创意,但是手法上并不成熟,只要看到了代码,或者看到了数据库的数据,就会被我一层一层抓出来,甚至在我以前不懂JSP的情况下还把后门揪了出来。而且数据库里的管理员表里的数据也很明显,一旦客户使用mysqladmin一类的工具浏览数据库,不就曝光了?后门的“覆盖面”有点大,容易被客户的数据库管理员发现。

  MYSQL 5.0版本已经支持了存储过程,针对这个例子,应该把后门放到数据库的存储过程中,这样程序里就不会出现这么明显的痕迹。当客户查看代码时,只能看到一个返回结果集的存储过程,把这句"SELECT * FROM csmmanager WHERE managerid <> ‘ilovethisgame’"封装到存储过程里。在登陆的时候也调用一个返回值是布尔的存储过程,判断如果用户是ilovethisgame时,直接通过。效果是一样的,却很隐蔽,代码简单,我就不写了,只提供个思路。

  总的来说,我们应该尽量减少代码里的后门痕迹,把侧重点扔到数据库上。有这么几大好处。

  1, 避免了后门覆盖面太大,降低被发现的风险。

  2, 代码开发管理员不必都知道有这么一个后门,等程序开发完成,就由某个特定的人把数据库的存储过程一改。

  3, 存储过程可以加密,又降低了风险。

  4, 即使暴露,可以解释为测试程序时遗留的小问题。利于推卸责任。

  5, 有一天需要清除后门,只需给数据库加个SQL文件补丁就可以了。

  可以想象,如果我给你个试用版,而你一直不买正版,我对你不满,随时可以在任何地方登陆你的后台,做出一些合法(程序上允许)而不合法(你不希望出现)的操作,系统上没有日志,然后告诉你这个“现象”属于试用版BUG…(黑…真黑…)

发表评论?

2 条评论。

  1. 顶一下

    从语句上看 从

    “SELECT * FROM csmmanager WHERE managerid”

    改成
    “SELECT * FROM csmmanager WHERE managerid <> ‘ilovethisgame'”

    确实不够隐蔽
    而且程序员似乎特别喜欢做这样的事
    要不然也不会以 ilovethisgame 作为用户名了
    呵呵

  2. 本人很希望结识高手噢!
    我的QQ284610811

发表评论