1. 前言
提到黑客攻击,必然会想起某政府部门的网站首页被篡改、或者某名人隐私被窃取等等情景。黑客攻
击,听起来像是离我们很遥远的事情,但前阵子确实发生在我们身上。公司自开发、自用的一个老信息系
统(J2EE)被黑客攻击——首页被篡改。我们技术人员在排查时发现被上传了很多 WebShell(可以远程操
作服务器上文件的 JSP),技术人员经过几天修改,最终将系统漏洞堵上了。此事件虽没给我们造成损失,
但是给我们的系统安全敲响了警钟。
被攻击的系统是基于 JSP+Servlet 技术,多年前由一些刚学习 J2EE 的新手开发,里面存在很多的攻击
漏洞。时至今日,我们现在的系统是否还存在一些这样的漏洞呢?要想了解系统中会存在哪些漏洞,首先
有必要了解黑客是怎样利用漏洞攻击网站的,开发时才知道如何规避漏洞。本文先介绍黑客攻击常见的三
种方式和原理,然后提出对应规避漏洞的办法。
本文假定服务器是Windows操作系统、SQL Server数据库、J2EE应用。
示例代码中的红色字体表示是用户输入提交的内容。
2. 黑客攻击方式
2.1 SQL注入
SQL注入主要是因为程序没有检查用户输入内容,直接将输入内容拼接成SQL 进行执行。我们通过例
子来进行说明。
假设系统通过输入用户名、密码进行登录验证的代码是这样子的:
String sql = "select * from tablename where account='" + account + "' and password='" +
password + "'";
这样的 sql 语句就存在 SQL 注入漏洞。在正常输入的情况下,比如输入 admin 和 123456,那么最终
执行的 sql是这样子的(红色表示是输入的内容):
select * from tablename where account=’admin’ and password=’123456’
这不会有任何问题,但是黑客可不会这样规矩,他会输入特殊的内容,执行的 sql会是这样:
select * from tablename where account=’a’ and password=’1’ or ‘1’=’1’
这样的 sql 执行结果是返回整个表的记录,那么就会以结果集的第一行记录用户登录了系统。除此以
外,黑客还可以输入分号(;)和注释符(--)来做更多的事情,比如查询 sysobjects 表,执行存储过程等
等:
select * from tablename where account=’a’; sql语句或存储过程 --’ and password=’’
上面的sql先执行分号前的条件查询,再执行分号后黑客输入的 sql语句或存储过程,--符号后面的内
容被注释掉了。
通过SQL注入,黑客可以猜解出数据库表结构以及表数据,当然黑客最终感兴趣的还是获得拥有最高
权限的 admin 账号和密码,用 admin 登录系统,然后继续黑客行为(可以利用上传漏洞上传 WebShell 从
而控制这台机器的,后面还会讲上传漏洞) 。
黑客还可执行SQLServer 提供的一些特殊存储过程,执行操作系统cmd命令,增加操作系统用户并给
予最高权限,开通端口和远程桌面功能,那么就可以直接远程桌面连接并控制机器(假设没有防火墙或在
防火墙外)。
2.2 跨站攻击
跨站攻击(Xss)主要是程序没有检查用户输入,可以提交 HTML代码或脚本。黑客利用这种漏洞,输
入恶意的脚本代码,当恶意的代码被执行后就形成了跨站攻击,可以隐蔽运行网页木马,甚至格式化浏览
者的硬盘,只要脚本代码能够实现的功能,跨站攻击都能够达到。跨站攻击主要是攻击浏览含有恶意代码
网页的人。跨站漏洞最容易发生在留言板、论坛、评论、短消息等可以输入富文本的地方。
跨站漏洞我想是多数开发人员很容易理解而且知道的,所以程序中有的地方会将用户输入的<和>转换
成<和>,防止用户提交 HTML代码或脚本。但仅这样做还不够,跨站攻击还可以利用已存在的HTML
标签。我们来看个例子。
<img src=”用户提交的内容”></img>
<a href=”用户提交的内容”>用户提交内容2</a>
上面的代码片断演示用户提交的内容最终会被放到HTML标签内,这里就存在跨站漏洞,我们来看看
黑客会怎么构造脚本代码。
<a href=”javascript:恶意脚本代码”> //有关键字 javascript。
<a href=”javascript:恶意脚本代码”>
//同上一行,只是将关键字 javascript进行了转换。
<a href=”#” οnmοuseοver=”恶意脚本代码”> // 无明显关键字,空格和引号可以勉强算是。
如果程序在网页显示时没有在用户提交内容前后加引号,
<a href=用户提交的内容>用户提交内容2</a>
那么黑客构造的脚本中也就没有引号了,
<a href=# οnmοuseοver=恶意脚本代码> // 输入的内容中,引号也不用了;
注:在 HTML标签内,&#符号开头后面加字符的ASCII,会被浏览器自动转换成字符。
2.3 附件上传
利用系统对附件上传控制不严,直接上传一个WebShell,从而控制了服务器。 比如黑客利用上传功能,
上传一个 jsp,然后黑客就可以直接访问这个上传的jsp 了,http://ip:port/ctxPath/uploadFiles/xxx.jsp。
有的系统限制了普通用户上传的附件类型,但对系统管理员、或者后台管理控制功能中没有做附件类
型的限制,黑客可以先利用 SQL注入,拿到最高权限的账号登录,然而再上传jsp 附件。
2.4 旁注攻击
假设A、B两个系统部署在同一台机器,黑客要入侵的 A系统很安全,无法入侵,但B 系统存在安全
漏洞,黑客先攻破B 系统,从而攻破 A系统。
我们的系统有集成 eWebEditor 组件。eWebEditor 有后面登录管理界面,如果我们在集成时没有修改
eWebEditor 默认的管理员密码(在 config.jsp中定义),通过 eWebEditor,黑客很轻松地就攻破我们的系统。
3. 防黑措施
了解了黑客的入侵手段,接下来我们就可以有针对性的防止漏洞的产生。
3.1 防 SQL注入
1、 尽量不进行SQL拼接,利用 PreparedStatement.setXXX 设置参数的形式来处理;
2、 必须拼接SQL时,要检查用户输入,不能有单引号、and、or、select等等关键字;
3、 将连接数据库的账号权限设置为最小,不能查询系统表(如 sysobjects);
4、 应用系统admin、sa 等账号密码要尽量复杂;
3.2 防跨站
1、 将HTML标记<和>进行转义;
2、 要在HTML 标签内显示的内容,要过滤 javascript,vbscript,jscript等关键字,将单双引号转义,将&
符号转义;
3、 在输入框和数据库字段,限制字符长度;
3.3 附件上传
1、 规定只允许上传哪些类型的附件(一般有图片、Office 文档、压缩文件、pdf、txt);不要规定不
允许哪些文件上传,这样有可能会被黑客绕过(比如在文件后缀后面加空格或小数点,后缀后面
这些都会被Windows系统忽略),防不胜防;
2、 文件类型检查不仅在客户端做,后台也要进行检查,防止绕过前端检查;
3、 上传目录不要放在WebRoot目录下,这样即使黑客上传了,也无法通过HTTP访问。