写在前面
我写本文的目的,是和各位分享一下内容篡改式攻击的判断方法、SQL注入攻击的防范、以及被攻击后的补救(数据恢复)相关知识,如有谬误,期待您的指正。
前言
2009年9月5日中午1点,历史会记住这个时刻,我们网站被“成功”攻击了,网站一些页面被插入了下载病毒的代码,经查:
- 生产服务器的代码没有任何被改动过的迹象,排除服务器被入侵,代码被篡改的可能;
- 有病毒下载代码的部分,在数据库里真实看到了篡改迹象,可以排除ARP欺骗的可能;
- 同上,能确定网站被SQL注入攻击了,因为数据库被篡改了。
- 马上找到含有SQL注入漏洞的程序,修复之;
- 马上增加一个应用程序防火墙(Application Firewall),从HTTP请求时就阻断攻击。
如何在IIS6中安装WebKnight?
我们的 WebServer 是 IIS6,所以这里只介绍IIS6的安装,我见有些帖子介绍WebKnight的安装时,说只有把IIS调整成IIS5.0隔离模式(IIS5.0 isolation mode)才可以,但实际上WebKnight的官方网站有介绍不需要此操作即可安装的办法,但这需要放弃WebKnight的全局配置特性,相比放弃IIS6.0,我更愿意放弃WebKnight的这个特性:
- 首先下载一份WebKnight,下载地址:http://aqtronix.com/?PageID=99#Download(注,这不是直接下载地址,点开后需要再点击WebKnight 2.2 (Release date: 2008.09.02),以防更新后各位朋友还下载旧的版本)
- 解压后有2个目录Setup、Source,其中Source是源码,我们这里只需要安装,进入Setup
- 进入Setup后还有2个目录:w32代表32位;x64代表64位;按照您服务器的操作系统来选择即可,我这里选x64(由于WebKnight的32位、64位文件结构完全相同,所以下面的内容完全适用与32位操作系统)
- 确保自己的每一个网站都运行在独立的应用程序池中;
- 在WebKnight的配置程序中
- 取消选择“Global Filter Capabilities”下的“Is Installed As Global Filter”
- 选择“Logging”下的“Per Process Logging”,这样每一个应用程序池的实例都会加载一个单独的WebKnight实例
- 确保Windows用户NETWORK SERVICE(或您设定的应用程序池的其他用户)有WebKnight文件夹的修改权限
- 拷贝第3步中x64文件夹中的所有文件到服务器上(如:F:\WebKnight\WebSite1\),注意:每一个网站均需要一个独立完整的WebKnight,不可共用
- 打开IIS Manager
- 在需要安装WebKnight的网站上点击右键 > 属性 > ISAPI filters
- 点击添加 > Filter Name随意,如(WebKnight),Excutable选择WebKnight目录下的WebKnight.dll(注意:要选网站所属的WebKnight目录,不要选错)
- 点击确定,完成安装
- 点击WebKnight目录中的Config.exe,具体配置方法见下一节,配置完成后再进行下一步,切记
- 在以上操作后,重新启动IIS(重启IIS其实可以避免,只需将配置WebKnight的网站的应用程序池停止再启动即可)
如何配置WebKnight
声明:由于WebKnight的配置很多,这里我只写一下推荐配置,个人观点,仅供参考,如果更好的建议,期待您的分享
- Scanning Engine 扫描引擎
- 无需更改默认配置
- Incident Response Handling 已发生攻击的处理
- 如果您希望有人攻击时看到的页面是WebKnight目录中的denied.htm,选择Response Directly即可;
- 如果您希望有人攻击时看到的页面是您网站下的某个文件(如:http://www.xxx.com/Error/Denied.htm),选择Response Redirect,并在下面的Response Redirect URL中填写您网站下文件的路径(如:/Error/Denied.htm)
- 如果您只希望记录攻击,但不希望中断用户的访问,您可以选择Response Log Only
- Logging 日志
- 如果日志量特别大,请取消选择Enabled,否则很有可能磁盘可用空间不知不觉就没有了,还有可能有比较严重的磁盘I/O性能问题
- 日志默认是存储在WebKnight目录下的LogFiles文件夹中,如果您想改变该路径,可以修改Log Directory的值
- WebKnight每天的日志是由不同文件存储的,默认保存28天的数据,您可以在Log Retention中修改该值
- Connection 连接
- 无需更改默认配置
- Authentication 安全认证
- 无需更改默认配置
- Request Limits 请求限制
- 取消选择Limit Content Length(Content-Length是header中的一个值,代表所请求元素的尺寸),我个人觉得这项没有必要选择,因为元素尺寸有可能很大
- 取消选择Limit URL(即限制URL的长度),原因同上,URL也可能很长
- 取消选择Limit Query String(即查询字符串的长度),原因同上,查询字符串也可能很长
- 取消选择Limit HTTP Version(即HTTP版本),我感觉没有必要限制HTTP版本,有可能会造成使用过旧版本浏览器的用户无法访问自己的网站
- 取消选择Use Max Headers(即限制Headers中各项的最大长度)。我一开始是选择了该项的,但在我的实践中,由于我们用了网站流量统计、广告合作代码等,导致Headers中的一些项超长,阻止了相当多的正常请求,所以我想干脆一劳永逸,取消选择了该项
- URL Scanning 网址扫描
- 取消选择RFC Compliant URL、RFC Compliant HTTP Url、Deny Url HighBitShellCode,勾选了这三项,很多不太标准的URL格式就会无法访问,比如包含中文的URL
- 取消选择Deny URL Backslash,因为我们网站中,“\”在URL里面也会用到
- 在URL Denied Sequences中,描述了拒绝请求的一些URL字符串,如果其中有您网站中正在使用的,可以删除,方法是选中要删除的项目,右键,点击Remove Selected
- Mapped Path 映射目录
- Use Allowed Paths,这项保持勾选,因为这项可以限制Web程序可以访问的服务器上的物理路径,我们需要做的只是在下面的Allowed Paths中添加上我们自己的网站物理路径,比如F:\WebSite1,添加方法是在任意项上点击右键 > Insert Item > 输入物理路径后,回车即可
- Requested File 被请求的文件
- 在Denied Files(拒绝请求的文件)中,去掉网站允许请求的文件,如:log.htm、logfiles
- 在Denied Extensions(拒绝请求的后缀名)中,去掉网站循序请求的后缀名,如:shtm
- Robots 蜘蛛程序
- 无需更改默认配置
- Headers 头信息
- Server Header中,可以修改Header中的Server字段的值,我觉得这个也可以改改,挺好玩的
- 为了防止组织合法的请求,取消勾选RFC Compliant Host Header、Use Denied Headers
- ContentType 内容类型
- 取消选择Use Allowed Content Types,若选中,则无法上传文件
- Cookie 这个就不需要翻译成中文了吧:)
- 无需更改默认配置
- User Agent 用户代理/客户端
- 取消勾选Deny User Agent Empty、Deny User Agent Non RFC,否则有部分合法访问会被拒绝
- Referrer 访问来路
- 取消选择Use Referrer Scanning,因为我觉得一个访问的来路可能不会有太严重的安全问题,还是为了尽量让合法的请求通过,我选择取消勾选该项
- Methods HTTP请求方法
- 无需更改默认配置
- Querystring 查询字符串
- 无需更改默认配置
- Global Filter Capabilities 全局过滤功能
- 取消勾选Is Installed As Global Filter,切记,该项一定要取消选择,否则WebKnight不能正产工作
- SQL Injection SQL 注入
- 无需更改默认配置
- Web Applications Web应用程序
- 勾选Allow File Uploads,否则上传文件的功能会失效
- 勾选Allow Unicode
- 勾选Allow ASP NET
- 如果您的网站需要支持ASP,勾选Allow ASP
- 同理,您的网站需要支持什么,请您自己选择需要勾选的项
提示:您可以通过查看WebKnight的日志,来查看哪些合法请求被阻止了,然后修改相应的配置
如何恢复被篡改的数据
通过安装这个Application Firewall,攻击是被阻止了,但数据库里被篡改的数据,还需要恢复,这里其实包含了2个问题:
1、如何找到被篡改的数据
3、当还原成功后,执行下面的语句对数据进行恢复:
以彼之道还施彼身。我找到了实施SQL注入的一篇帖子,里面讲到,是“通过游标遍历数据库中的所有表和列并在列中插入代码”,同理,我们也可以写一个程序,遍历数据库中所有表和列,并判断是否存在特征字符串,这个特征字符串即被插入的恶意代码特征。由于此种攻击是将数据库所有行数据修改,所以每个表我们只看一行数据就可以,也不会耗时太久。
2、如何恢复被篡改的数据
我找到了被篡改的表后,其中一些字段是存储的冗余数据,可以通过SQL语句从数据源读取然后更新即可,如:
1 UPDATE TableA SET ColumnA = (SELECT TableB.ColumnA FROM TableB WHERE TableB.BID = TableA.BID)
还有比较费劲的就是源数据被改,要修复这样的数据,就必须得有备份了,我们先将备份的数据库还原成一个用户恢复的数据库:
1、执行
1 restore filelistonly FROM disk='X:\BackupName.BAK'
获得当前备份文件的逻辑名
2、使用windows账户或者sa登陆执行以下SQL语句:
1 restore DATABASE [还原目的数据库]
2 FROM disk='X:\BackupName.BAK' --备份文件的路径
3 WITH
4 file=1, --文件的编号
5 move '备份数据文件的逻辑名' TO 'X:\MSSQL\Data\物理文件名_Data.MDF', --数据库逻辑名 to 还原到的物理文件名
6 move '备份日志文件的逻辑名_Log' TO 'X:\MSSQL\Data\物理文件名_Log.LDF' --日志逻辑名 to 还原到的物理文件名
2 FROM disk='X:\BackupName.BAK' --备份文件的路径
3 WITH
4 file=1, --文件的编号
5 move '备份数据文件的逻辑名' TO 'X:\MSSQL\Data\物理文件名_Data.MDF', --数据库逻辑名 to 还原到的物理文件名
6 move '备份日志文件的逻辑名_Log' TO 'X:\MSSQL\Data\物理文件名_Log.LDF' --日志逻辑名 to 还原到的物理文件名
1 UPDATE [被篡改数据库].[dbo].[表] SET [待恢复字段] = (SELECT 还原的数据库.dbo.表.[待恢复字段] FROM 还原的数据库.dbo.表 WHERE 还原的数据库.dbo.表.主键 = [被篡改数据库].[dbo].[表].主键) WHERE 主键 IN (SELECT 还原的数据库.dbo.表.主键 FROM 还原的数据库.dbo.表)
如何找到有漏洞的程序
应用程序防火墙安装完毕、数据恢复了,接下来我们要找到有SQL注入漏洞的页面,常规的检测方法不再赘述,这里着重说一下如何找到本次攻击被利用的那个漏洞。方法其实很简单,因为被攻击的时间段是已知的,我们只需要把当天的IIS日志中相同时段的内容分析一下,很容易能得出结果,然后修复之。
至此,本次内容篡改式攻击的攻击方法判断,判断出SQL注入攻击后的防范措施,修复数据、修复漏洞的补救措施就全部描述完毕,因为是针对我们网站的例子讲的,普适性可能不够,仅供参考,如有谬误,期待您的指正。