一、简介
SQL 注入是黑客常用攻击手段,会对组织机构声誉、经济等造成严重损害。许多机构存在 SQL 注入漏洞,可能是新应用忽视安全测试或开发生命周期缺乏安全整合所致。当黑客发现并利用漏洞时,需计算机取证专家调查、检验并响应,以遏制攻击或恢复,降低商业影响。
二、调查可疑的 SQL 注入攻击
(一)取证的合理实践
过去十余年,虽安全意识和计算机取证经验有进步,但仍有调查及证据无法被法律程序采用。若要在法庭用证据,收集和管理须有严格规则与指导原则:
- 由接受过计算机取证培训且获机构授权的人处理调查。
- 调查期间收集的所有文件都应镜像,创建副本用于分析,确保需要时原始镜像可用。
- 对新建的每份文件镜像生成哈希,源文件及日志服务器日志文件也需如此。为刚创建的镜像文件(副本)也创建哈希,用如
dcfldd
的专业工具创建镜像,它能验证文件未受污染,还能为原始文件和新建镜像文件分别生成哈希并验证匹配。 - 调查期间,用文档记录所有操作,包括连接数据库服务器完成的操作:保留连接时间和所用数据库语境记录;保留所有 RDBMS 执行命令记录;将标准输出(
stdout
)从数据库客户端控制台重定向到文本文件(主流 RDBMS 客户端重定向命令见表 10 - 1)。 - 确保所有证据写入无毒存储介质,并存放在安全地方(如储物柜或保险箱)。
- 维护监管链(Chain of Custody)文档,跟踪收集的所有证据,从被防护时间到在执行案某个调查期间的移动、存放位置和所有者。
(二)分析数字化证据
数字化证据(digital artifact)范围很广,包括操作系统中 Web 服务器的日志文件、内存中的信息及 RDBMS 内核中的信息等。调查 SQL 注入攻击时,Web 服务器日志、数据库执行计划、事务日志(transaction log)和数据库对象的时间戳(timestamp)是最有效的证据。
1. Web 服务器日志文件
Web 服务器作为交互层,接收用户输入并传递给后台应用程序,通常维护持久日志文件,记录页面请求历史和请求处理后的输出状态。系统管理员可定制日志记录信息,主流 Web 服务器产品默认启用基本信息日志记录。表 10 - 2 列出了对调查 SQL 注入攻击最有用的 Web 服务器日志属性,这些信息对分析日志文件中的数据至关重要。默认情况下,Web 服务器以文本文件方式存储日志数据,因大 Web 服务器日志文件(含大量兆字节数据),用日志分析工具(如 Microsoft 开发的 Log Parser,支持 IIS 和 Apache 日志文件格式)分析更高效,能快速精确用 SQL 分析庞大日志文件。可通过分析 Web 服务器日志,查找 Web 请求带宽利用率异常偏高的日志文件,还可分析页面每天命中次数、某天某个 IP 命中次数等,识别可疑访问(如含恶意 SQL 注入语法的查询参数)。
2. 数据库执行计划
数据库执行计划是 RDBMS 生成的执行步骤列表,说明 RDBMS 访问或修改信息时效率最高的方式。查询第一次到数据库服务器时,服务器会解析、分析查询,确定需访问的表、使用的索引(若存在)及连接(join)或合并(merge)结果集等,分析结果存在存储结构中即执行计划。执行期间,数据库内部组件可共享这些计划,相同计划可存储在内存区域(执行计划缓存),接收类似查询时,可用缓存的执行计划。数据库执行计划能提供接收到的实际查询语句(包括攻击中攻击者终止的代码),而 Web 服务器和防火墙日志可能忽略这些数据。不同 RDBMS 对执行计划的缓存机制不同,较高版本的 Microsoft SQL Server 和 Oracle RDBMS 用这种机制,MySQL 和 PostgreSQL 没有保护敏感信息缓存的机制,会将敏感信息记录在普通日志文件和二进制日志文件中,调查期间收集的所有信息都必须加密处理。可通过执行计划查询的副本分析,识别应用程序中被攻击的 Web 页面和可执行文件、攻击的时间和源 IP 地址等,确认攻击企图是否成功。
3. 事务日志
事务日志(transaction log)由子元素组成,包括子句、查询和语句,语句包含一个或多个数据库操作,分数据操作语言(DML,作用于表内数据)和数据定义语言(DDL,作用于数据库结构)。事务日志用于记录事务开始及恢复所需信息,若数据库将信息写入硬盘失败,可利用恢复信息将数据回到一致状态。事务日志中的信息会用于实际数据页写入磁盘,虽写入非实时,但速度快。几乎所有操作(无论归类为 DML 还是 DDL)都可归结为 INSERT
、UPDATE
和 DELETE
操作,需要写入、更新或删除磁盘上的信息时,用这 3 种操作实现。攻击者执行修改表数据的 SQL 语句时,相应事务会在事务日志中留下痕迹,即使攻击者执行 SELECT
语句,若 RDBMS 在返回结果前对中间结果排序,也会在事务日志中创建与临时表创建和加载相关的条目。事务日志分析是深入且内容广泛的主题,重点介绍支持调查取证的关键事务:
- 可疑攻击时间段内执行的
INSERT
、UPDATE
和DELETE
语句,该信息可用于标识调查时间段内执行的活动及相关事件的其他痕迹。 - 数据库用户执行的非标准数据库操作(如普通从数据库读取信息的应用程序用户账号突然执行
INSERT
、UPDATE
和DELETE
语句)。
三、不同数据库的恢复与调查要点
(一)Microsoft SQL Server
默认情况下,事务日志功能启用且无法禁用,可使用原生的 fn_dblog
函数访问事务日志。可通过查询事务日志,获取如 Spid
(分配给执行事务日志记录连接的唯一标识符)、Transaction ID
(用于分组相关事务的唯一标识)、Login_or_User
(执行事务的数据库服务器登录账号或数据库用户账号)、Transaction Type
(执行事务的类型描述)、Begin Time
(执行事务的时间)等信息,识别可疑操作(如用 EXEC
命令将数据 INSERT
到表中)。
(二)Oracle
事务(归档)日志默认启用,测试系统也无法禁用。可通过查询返回已执行的 INSERT
、UPDATE
和 DELETE
操作列表,例如:
SELECT OPERATION, SQL_REDO, SQL_UNDO FROM V$LOGMNR_CONTENTS WHERE SEG_OWNER = 'WEBRPT' AND SEG_NAME = 'SYNGRSS' AND (timestamp > sysdate - 1) AND (timestamp < sysdate) AND OPERATION IN ('DELETE', 'INSERT', 'UPDATE') AND USERNAME = 'KEVIN';
(三)MySQL
默认情况下不启用事务日志,需用命令启用。可使用 SHOW BINARY LOGS
语句查看是否激活事务日志功能,若启用,会返回所有事务日志名称列表。在非 Windows 服务器上可使用原生的 mysqlbinlog
工具,在 Windows 系统中可使用 MySQL 命令行客户端,从事务日志中转储事务列表,查看执行的语句。
(四)PostgreSQL
PostgreSQL 可通过 SQL 命令行客户端返回事务日志信息,事务日志默认未启用,启用后也可禁用。较新版本中,UNLOGGED
表的 INSERT
、UPDATE
和 DELETE
操作不会写入事务日志。调查取证时,可利用 statement log
标记关注的事务(包括来自 UNLOGGED
表的事务)。事务日志配置决定了其重要性、可用性及信息留存时间,不同 RDBMS 在事务日志保留和记录信息方面有差异,需参考数据库厂商说明文档。
四、数据库对象的时间戳
多数 RDBMS 产品会为系统结构内创建和修改的对象及文件维护时间戳信息。在调查取证期间,生成关键对象和对应时间戳的列表,有助于在可疑攻击时间段内标识对象的创建和修改活动。与攻击有关的活动包括:创建用户账号(用于创建访问后门)、为已有账号增加权限(权限提升操作的一部分)、创建新表(用于存储中间结果,将信息返回给攻击者前暂存)。
不同数据库查询对象时间戳的方式:
- SQL Server:可查询返回当前数据库中视图、过程、函数、表和扩展过程的列表,按修改日期和创建日期降序排序,示例查询:
(select sob.name as 'object', sch.name as 'schema', type_desc, create_date, modify_date from sys.all_objects sob, sys.schemas sch where sob.schema_id = sch.schema_id and sob.type in ('V','P','FN','IF','TF','X'))
UNION
(select name, '', 'Xbl User', createdate, updatedate from sys.sysusers)
UNION
(select name, '', 'Login', createdate, updatedate from sys.syslogins)
若查询结果中存在异常表名(如 invIsble
)且在攻击时间段内创建或修改,需重点调查。
- Oracle:可查询返回当前数据库中表、视图和过程的列表,按修改日期和创建日期降序排序,示例查询:
Select object_name, object_id, object_type, created, last_ddl_time from dba_objects ORDER BY last_ddl_time DESC, created DESC
- MySQL:部分对象(如触发器和视图)不存储时间戳,查询时无时间戳的对象会返回
NULL
,示例查询:
select * from
(
(SELECT TABLE_NAME AS "OBJECT", TABLE_SCHEMA AS "OBJECT_SCHEMA", TABLE_TYPE AS "OBJECT_TYPE", CREATE_TIME, UPDATE_TIME from information_schema.tables)
UNION
(SELECT SPECIFIC_NAME, ROUTINE_SCHEMA, ROUTINE_TYPE, CREATED, LAST_ALTERED FROM information_schema.routines WHERE ROUTINE_TYPE = 'PROCEDURE')
UNION
(SELECT User, '', 'DB_USER', '' from mysql.user)
)
需注意不符合服务器命名规范的条目。
- PostgreSQL:不记录对象、表和用户的时间戳信息,可查询返回当前数据库中关键对象的名称、模式和类型,检查不符合规范的对象名称,示例查询:
select proname as "OBJECT_NAME", '' as "OBJECT_SCHEMA", 'PROCEDURE' as "OBJECT_TYPE" from pg_proc UNION ALL select tgname, '', 'TRIGGER' from pg_trigger UNION ALL select tablename, schemaname, 'TABLE' from pg_tables UNION ALL select usename, '', 'USER' from pg_user
五、如果你是受害者,该怎么办?
(一)遏制安全事件
管理 SQL 注入攻击事件时,高效有用的遏制很有必要。SQL 注入漏洞暴露时间越长,额外记录受损坏的可能性越大,或攻击者在数据库环境中涉足程度越深。遏制方法可简单拔掉受损害服务器的网线,但需考虑直接目标是数据库服务器,根据攻击者行为和基于网络的控制(如防火墙对数据流量施加的规则),攻击者可能已将数据库中的数据导出到另外一台连接到网络的服务器,此时仅拔除受损害服务器网线,攻击者仍可从外部传输数据。在这种情况下,若仅拔除数据库服务器网线,Web 服务器仍可能使数据从网络上移除,必须格外小心,既不能拔除系统的电源线,也不能停止和重启 Web 服务器或数据库服务器进程,因为这将删除易失(volatile)的数据,而这些数据对于全面的证据调查至关重要。另外,还应确保记录以下信息:在什么时间将哪一根网线从哪一个系统上拔除。在对安全事件进行遏制之后,可进入到管理安全事件的下一步骤,确定安全事件涉及哪些数据。
(二)评估涉及的数据
数据库可能存储各种信息,部分是公开信息,部分则可能包含可用于社会工程攻击的个人信息、可用于欺诈的金融和健康信息等,若这些信息被泄露,可能带来严重风险(如公民身份和住址信息泄露会威胁人身安全)。安全事件中确定涉及数据的类型,可让你所在的机构决定管理安全事件要采取的步骤,这些步骤可能包括召开监管和法律方面的会议,以讨论将如何管理该安全事件以及安全事件应该通报给谁。需考虑的数据特性包括:涉及信息的类型、涉及的信息是可辨识为个人信息还是组织机构的信息、影响到哪些国家、州或有的人、对数据执行了什么操作(更新、删除、修改或泄漏)、重用未授权数据的影响、任何缓解措施(比如数据加密,可降低未经授权重用这些信息的可能性)。这些要点有助于确定信息的危险程度,进而确定要求采取的行动,包括需要将安全事件通报给谁。
(三)通知相应人员
世界上很多州和省都制定了规则,要求受委托管理个人信息的组织机构在数据安全遭受破坏时通知受影响的人员。州与州之间、省与省之间,具体要求各有差异,具体要求取决于受影响的人员所在的地区。另外,与客户的契约和诸如 PCI、DDS 等规程的要求,可授权公开损坏所影响到的信用卡信息,倘若信息遭到破坏,还可以进一步强制公布所需的通告。从前面的分析可以看到,搞清楚应该通知谁是一项困难的任务,可能包括具有法律约束的契约、法规和规章,这一任务最好由受害组织机构的高级管理人员和法律顾问来完成,他们可以做出业务决策,确定需要提出哪些申请,需要发送的通知、消息和最适合处理这件事情。这种方式还可以免除对事件处理者和取证专家的干扰,使他们可以专注于安全事件的技术层面,比如确定攻击者在系统上执行了哪些操作。
(四)确定攻击者在安全事件期间执行了哪些操作
之前介绍的关键痕迹可用于标识数据库服务器已经成功执行的恶意语句,但仅靠这些还不够,还可以得出结论:是否存在一次成功的 SQL 注入攻击只是开始,搞清楚数据被谁或修改的具体记录才可以缩小安全事件的涉及范围。在考虑上面降低恢复的通知要求时,如果可以减少信用卡详细信息或个人隐私信息泄露的范围,就可以降低组织的总成本,也可以降低被攻击组织机构所受的影响。这最好由执行了安全事件取证的数据库取证人员来执行。数据库取证人员直接致力于证据的鉴别、保存和分析,这些证据可以证明发生了安全事件,另外还可以通过攻击者查看端到端地界定受影响的范围,包括:识别出攻击者执行的 DML 和 DDL 操作,以及受影响的特定记录;恢复事务之前和事务之后受影响的数据状态,以支持恢复数据库;标识出已经被删除的数据。数据库取证专家受过非常专业的训练,包括诸如分析用于存储数据库表数据的特定数据页(data page),从日志文件中获取逆向工程信息。但这超出了本书的内容,表 10 - 5 列出了一些参考资源,其中包含了一些与数据库取证有关的图书信息和工具。
(五)从 SQL 注入攻击中高效地恢复
从 SQL 注入攻击中恢复的第一步,是确定成功的 SQL 注入攻击投送了什么类型的有效载荷。有效载荷分为静态有效载荷和动态有效载荷:
- 静态有效载荷:从一个受损害系统到另外一个受损害系统,在后继(post - compromise)系统上执行的活动是一致的,当识别出漏洞与 SQL 注入漏洞和脚本有关时,实际上这些脚本并没有太多的形态,每次它们有效载荷通常与一个注入点,它们将重复相同的操作。
- 动态有效载荷:从一个受损害系统到另外一个受损害系统,在后继(post - compromise)系统上执行的活动是不一致的,攻击者使用某种漏洞利用工具执行了 SQL 注入后,一旦攻击者获得了访问权,就将枚举数据库并根据数据库服务器的版本、启用的特性和当前具有的权限,在 RDBMS 中执行许多操作,即使攻击者使用相同的工具攻击了多个服务器,但在不同的受损害系统之间,执行的操作也几乎是完全不同的,这取决于攻击者的权限、数据库服务器的配置和想要获取的信息。
这两种类型的有效载荷可以勾勒出攻击者的轮廓,确定攻击所携带的有效载荷后,可进行相应的恢复操作:
1. 从携带静态有效载荷的攻击中恢复
恢复处理过程相对简单,因为蠕虫或其他威胁执行的恶意操作是已知的。恢复的核心问题,是将数据库回滚到受攻击影响之前的状态,或者识别并取消(undo)那些恶意查询和语句所执行的具体操作。恢复步骤如下:
- 恢复数据库状态:使用下面方法之一,将受攻击的数据库恢复到某个已知的良好状态,即从备份中恢复(使用磁盘分区刚刚创建的快照时间戳,可以将受攻击影响的数据库立即恢复到受影响之前的某个已知状态,这可能会丢失从已知良好状态到遏制安全事件这段时间之内的事务);
- 标识要回滚的事务:无论是手工分析还是使用日志分析器(比如 Oracle 的 Logminer),只有识别出与攻击有效的载荷关联的事务,才可以执行回滚。以 Lulzophilippop 蠕虫为例,它搜索 Microsoft SQL Server 事务日志,寻找与有效载荷有关的事务,找到后写入到 Lulzophilippop 蠕虫所运载载荷的事务,示例查询:
select proname as "OBJECT_NAME", '' as "OBJECT_SCHEMA", 'PROCEDURE' as "OBJECT_TYPE" from pg_proc UNION ALL select tgname, '', 'TRIGGER' from pg_trigger UNION ALL select tablename, schemaname, 'TABLE' from pg_tables UNION ALL select usename, '', 'USER' from pg_user
可使用前面的信息来标识需要恢复的事务,既可以手工创建 undo
事务的脚本,也可以使用日志读取工具创建 undo
事务的脚本(比如用于 Microsoft SQL Server 和其他数据库产品的 ApexSQL,以及 Oracle 发布的用于回滚 Oracle 事务的免费工具 Logminer);
- 检验数据库服务器配置:如果静态有效载荷带有频繁针对 RDBMS 特性的攻击,或者解除服务器的安全配置以实现进一步的攻击,那么应该将数据库服务器的配置恢复到已知的良好状态,无论是从备份中恢复损害的数据,还是手工回滚事务,在攻击期间对服务器范围内任何配置设置的改变都将保留下来,直到明确地识别配置的改变并恢复设置,应该对服务器配置的设置进行审计,确保它们与预期的配置保持一致;
- 识别并修复 SQL 注入漏洞:确保对整个代码库进行一次应用程序安全评估,以识别可被利用的漏洞和其他可能存在的情况;
- 在线恢复系统并恢复 Web 服务。
2. 从携带动态有效载荷的攻击中恢复
携带动态有效载荷的攻击恢复起来非常困难,因为攻击者的行为会随着每一种损害而发生较大的变化。如果 SQL 注入攻击是通过 HTTP POST 请求发起的,那么绝大多数 Web 服务器都没有配置为可以在日志中记录这种活动。如果在受到攻击损害与调查取证之间,间隔了较长的时间,那么执行计划和其他证据可能已经被覆写(overwritten)。还存在其他方面的复杂性,比如攻击者可能脱离了数据库的上下文进入操作系统,建立到受攻击服务器的带外连接,并旁路(bypass)数据库以继续利用漏洞进行攻击。对于携带动态有效载荷的成功攻击,强烈建议聘请数据库取证专家进行调查取证。安全专家可以很快缩小审查的范围并从安全事件中恢复,步骤如下:
- 恢复数据库状态:对于动态有效载荷的 SQL 注入攻击,建议将 RDBMS 和操作系统都恢复到受损害之前的状态,这可能会丢失从已知良好状态到遏制安全事件这段时间内的事务,也可以选择不按照推荐的方法恢复数据库和操作系统,在这种情况下,可遵循静态有效载荷攻击的恢复步骤来恢复数据库,但必须事先提出警告,攻击与调查取证之间存在一定的时间间隔,攻击的痕迹可能已经被部分覆盖,很可能无法准确地捕获攻击者在系统上执行过的所有操作,在恢复之后攻击者可能依然维护服务器或网络设备的控制,对于这样的风险必须格外小心;
- 识别脱离数据库进入底层操作系统的攻击:在之前收集好的恶意查询清单中,标识出那些允许攻击者脱离数据库服务器的活动,若发现针对操作系统的活动,应执行下列操作:查找创建了带外通信的任何方法(比如创建操作系统用户账号的方法,攻击者可以使用创建的账号进一步攻击数据库的外部);查找对操作系统文件的引用,或者攻击者读取、创建或加载到数据库中的注册表键值(key),确保从法律分析角度保护文件或注册表键值,然后查阅脚本,搞清楚攻击者执行了哪些操作,这种正途还可能识别出他带外连接的方法(比如通过 SQL 注入漏洞将恶意文件上传到某个表中,然后输出恶意文件并在受害系统上重新构建);查看网络日志,标识从数据库服务器到其他联网机器的通信,如发现可疑的活动,应该调查有关的主机是否有受攻击;
- 检验数据库服务器的配置:一旦攻击者获得对数据库服务器的访问之后,就会解除存在的安全设置,以便进一步在服务器上实施攻击,将受损害的数据库恢复到已知的良好状态,并不能消除攻击者可能已经创建的后门,比如攻击者创建的 RDBMS 登录账号,应该对服务器执行一次审计,以确保现在的服务器设置依然保持在正常状态;
- 识别并修复 SQL 注入漏洞:确保对整个代码库进行一次应用程序安全评估,以识别可被利用的漏洞和其他可能存在的情况;
- 在线恢复系统并恢复 Web 服务。
六、防御价值与实践要点
(一)防御价值
通过调查可疑 SQL 注入攻击,利用取证合理实践、分析数字化证据(Web 服务器日志、数据库执行计划、事务日志),能精准识别攻击行为、攻击源及影响范围,为后续恢复、追责及加固系统提供关键依据,有效降低 SQL 注入攻击带来的持续损害。
(二)实践要点
- 严格遵循取证合理实践,确保证据的合法性、完整性和可追溯性,为可能的法律程序提供有效支持。
- 熟练运用各类日志分析工具(如 Log Parser)和数据库自身的查询工具,高效从 Web 服务器日志、数据库执行计划、事务日志中提取可疑信息。
- 针对不同数据库(Microsoft SQL Server、Oracle、MySQL、PostgreSQL 等),熟悉其事务日志的访问方式和特点,以及对象时间戳的查询方式,以便在调查时快速获取关键信息。
- 定期演练 SQL 注入攻击的调查与恢复流程,提升应对实际攻击时的效率和准确性。