日志文件是服务器提供的非常有价值的信息。几乎所有服务器、服务和应用程序都提供某种日志记录。日志文件记录在服务或应用程序运行期间发生的事件和操作。
日志文件为我们提供了服务器行为的精确视图以及关键信息,例如何时、如何以及由谁访问服务器。此类信息可以帮助我们监控性能、排除故障和调试应用程序,并帮助取证调查人员展开可能导致恶意活动的事件链。
让我们以后端 Web 服务器为例。通常,Apache HTTP 服务器提供两个主要的日志文件—— access.log和error.log。access.log记录所有对文件的请求。如果访问者请求www.example.com/main.php,则会将以下条目添加到日志文件中:
88.54.124.17 - - [16/Apr/2016:07:44:08 +0100] "GET /main.php HTTP/1.1" 200 203 "-" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
以上日志显示,IP地址为88.54.124.178的访问者在2016年4月16日07:44请求了main.php文件,请求成功。
此信息可能不太有趣,但如果日志文件显示 IP为88.54.124.178的访问者在 2016 年4 月 16 日 07:44请求了dump_database.php文件并且请求成功了怎么办?在没有该日志文件的情况下,您可能永远不知道有人发现并运行了您网站上的秘密或受限脚本并转储数据库。
确定日志文件是一项重要资产后,让我们看一个日常示例,说明日志文件如何帮助识别网站何时、如何以及由谁被黑客入侵。
假设我们管理的一个网站被破坏了。我们还假设该站点是一个简单且最新的 WordPress 网站,运行在一个完全打补丁的 Ubuntu 服务器上。
在寻求帮助后,取证小组将服务器下线,以便能够继续调查。
服务器被隔离以保留系统的当前状态及其日志,阻止对攻击者的远程访问(如果安装了后门),以及阻止与网络上的任何其他机器交互。
要识别 Web 服务器上的恶意活动,您通常会创建服务器的合法副本,然后继续进行调查。但是,由于没有计划对攻击者采取法律行动,在这种情况下,取证团队可以处理原始数据。
为了开始调查,调查人员需要确定要寻找的证据。通常,攻击的证据包括对隐藏或异常文件的直接访问、在有或没有身份验证的情况下访问管理区域、远程代码执行、SQL 注入、文件包含、跨站点脚本 (XSS)以及其他可能表明的异常行为漏洞扫描或侦察。
让我们假设在我们的示例中,Web 服务器access.log可用。
root@secureserver:/var/log/apache2# less access.log
access.log往往是一个相当大的文件,通常包含数千个记录的请求。
84.55.41.57 - - [16/Apr/2016:20:21:56 +0100] "GET /john/index.php HTTP/1.1" 200 3804 "-" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
84.55.41.57 - - [16/Apr/2016:20:21:56 +0100] "GET /john/assets/js/skel.min.js HTTP/1.1" 200 3532 "http://www.example.com/john/index.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
84.55.41.57 - - [16/Apr/2016:20:21:56 +0100] "GET /john/images/pic01.jpg HTTP/1.1" 200 9501 "http://www.example.com/john/index.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
84.55.41.57 - - [16/Apr/2016:20:21:56 +0100] "GET /john/images/pic03.jpg HTTP/1.1" 200 5593 "http://www.example.com/john/index.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
检查每一行是不切实际的,所以我们需要过滤掉很可能不感兴趣的数据。这通常包括图像和 CSS 样式表等资源。一些调查人员也更喜欢去除 JavaScript 文件。
然而,在这种情况下,由于网站正在运行 WordPress Web 应用程序,我们将使用稍微不同的方法。我们不会排除某些数据,而是过滤access.log以获取 WordPress 特定的特征。
root@secureserver:~#cat /var/log/apache2/access.log | grep -E "wp-admin|wp-login|POST /"
上面的命令过滤access.log并只显示字符串包含wp-admin的记录,这是 WordPress 的默认管理文件夹wp-login是 WordPress 登录文件 ( wp-login.php ) 的一部分,最后是, POST
, 它将显示使用 POST 方法发送到服务器的 HTTP 请求,这些请求很可能是登录表单提交。
输出返回许多结果。在筛选它们之后,我们将专注于以下单个记录:
84.55.41.57 - - [17/Apr/2016:06:52:07 +0100] "GET /wordpress/wp-admin/ HTTP/1.1" 200 12349 "http://www.example.com/wordpress/wp-login.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
我们看到 IP 84.55.41.57成功访问了 WordPress 管理界面。让我们看看拥有这个 IP 地址的用户还做了什么。我们将grep
再次使用该 IP过滤access.log 。
root@secureserver:~#cat /var/log/apache2/access.log | grep 84.55.41.57
这导致了以下有趣的记录。
84.55.41.57 - - [17/Apr/2016:06:57:24 +0100] "GET /wordpress/wp-login.php HTTP/1.1" 200 1568 "-"
84.55.41.57 - - [17/Apr/2016:06:57:31 +0100] "POST /wordpress/wp-login.php HTTP/1.1" 302 1150 "http://www.example.com/wordpress/wp-login.php"
84.55.41.57 - - [17/Apr/2016:06:57:31 +0100] "GET /wordpress/wp-admin/ HTTP/1.1" 200 12905 "http://www.example.com/wordpress/wp-login.php"
84.55.41.57 - - [17/Apr/2016:07:00:32 +0100] "POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1" 200 454 "http://www.example.com/wordpress/wp-admin/"
84.55.41.57 - - [17/Apr/2016:07:00:58 +0100] "GET /wordpress/wp-admin/theme-editor.php HTTP/1.1" 200 20795 "http://www.example.com/wordpress/wp-admin/"
84.55.41.57 - - [17/Apr/2016:07:03:17 +0100] "GET /wordpress/wp-admin/theme-editor.php?file=404.php&theme=twentysixteen HTTP/1.1" 200 8092 "http://www.example.com/wordpress/wp-admin/theme-editor.php"
84.55.41.57 - - [17/Apr/2016:07:11:48 +0100] "GET /wordpress/wp-admin/plugin-install.php HTTP/1.1" 200 12459 "http://www.example.com/wordpress/wp-admin/plugin-install.php?tab=upload"
84.55.41.57 - - [17/Apr/2016:07:16:06 +0100] "GET /wordpress/wp-admin/update.php?action=install-plugin&plugin=file-manager&_wpnonce=3c6c8a7fca HTTP/1.1" 200 5698 "http://www.example.com/wordpress/wp-admin/plugin-install.php?tab=search&s=file+permission"
84.55.41.57 - - [17/Apr/2016:07:18:19 +0100] "GET /wordpress/wp-admin/plugins.php?action=activate&plugin=file-manager%2Ffile-manager.php&_wpnonce=bf932ee530 HTTP/1.1" 302 451 "http://www.example.com/wordpress/wp-admin/update.php?action=install-plugin&plugin=file-manager&_wpnonce=3c6c8a7fca"
84.55.41.57 - - [17/Apr/2016:07:21:46 +0100] "GET /wordpress/wp-admin/admin-ajax.php?action=connector&cmd=upload&target=l1_d3AtY29udGVudA&name%5B%5D=r57.php&FILES=&_=1460873968131 HTTP/1.1" 200 731 "http://www.example.com/wordpress/wp-admin/admin.php?page=file-manager_settings"
84.55.41.57 - - [17/Apr/2016:07:22:53 +0100] "GET /wordpress/wp-content/r57.php HTTP/1.1" 200 9036 "-"
84.55.41.57 - - [17/Apr/2016:07:32:24 +0100] "POST /wordpress/wp-content/r57.php?14 HTTP/1.1" 200 8030 "http://www.example.com/wordpress/wp-content/r57.php?14"
84.55.41.57 - - [17/Apr/2016:07:29:21 +0100] "GET /wordpress/wp-content/r57.php?29 HTTP/1.1" 200 8391 "http://www.example.com/wordpress/wp-content/r57.php?28"
84.55.41.57 - - [17/Apr/2016:07:57:31 +0100] "POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1" 200 949 "http://www.myw ebsite.com/wordpre ss/wp-admin/admin.php?page=file-manager_settings"
让我们进一步分析这些记录。攻击者访问了登录页面。
84.55.41.57 - GET /wordpress/wp-login.php 200
攻击者提交了登录表单(使用 POST 方法的 HTTP 请求)并被重定向(302 HTTP 状态码)。
84.55.41.57 - POST /wordpress/wp-login.php 302
攻击者被重定向到wp-admin(WordPress 仪表板),这意味着身份验证成功。
84.55.41.57 - GET /wordpress/wp-admin/ 200
攻击者导航到主题编辑器。
84.55.41.57 - GET /wordpress/wp-admin/theme-editor.php 200
攻击者试图编辑文件 4 04.php,这是一种非常常见的用于将恶意代码注入文件的策略。由于缺乏写权限,攻击者很可能未能这样做。
84.55.41.57 - GET /wordpress/wp-admin/theme-editor.php?file=404.php&theme= twentysixteen 200
攻击者访问了插件安装程序。
84.55.41.57 - GET /wordpress/wp-admin/plugin-install.php 200
攻击者安装并激活了文件管理器插件。
84.55.41.57 - GET /wordpress/wp-admin/update.php?action=install-plugin&plugin= file-manager &_wpnonce=3c6c8a7fca 200
84.55.41.57 - GET /wordpress/wp-admin/plugins.php?action=activate&plugin=file-manager%2Ffile-manager.php&_wpnonce=bf932ee530 200
攻击者使用文件管理器插件上传r57.php,这是一个 PHP web shell脚本。
84.55.41.57 - GET /wordpress/wp-admin/admin-ajax.php?action=connector& cmd= upload&target=l1_d3AtY29udGVudA&name%5B%5D=r57.php&FILES=&_=1460873968131 200
日志表明攻击者运行了r57 shell 脚本。查询字符串?1
(攻击者运行phpinfo();)和?28
(攻击者获得了服务列表)指示通过 shell 脚本的不同部分的导航。他们似乎没有发现任何有趣的东西。
84.55.41.57 - GET /wordpress/wp-content/r57.php 200
84.55.41.57 - POST /wordpress/wp-content/r57.php?1 200
84.55.41.57 - GET /wordpress/wp-content/r57.php?28 200
攻击者的最后一个动作是通过文件管理器插件编辑主题的索引文件,并将其内容替换为HACKED!
84.55.41.57 - POST /wordpress/wp-admin/admin-ajax.php 200 - http://www.
example.com/wordpress/wp-admin/admin.php?page=file-manager_settings
基于上述信息,我们现在有了攻击者导致网站被破坏的行为的时间表。然而,难题中缺少一块。攻击者最初是如何获得登录凭据的,或者他们是否绕过了身份验证?
假设我们确定管理员密码没有泄露或暴力破解,让我们回去看看是否能找到有关此事的任何信息。
当前的access.log没有包含任何可能发生的事情的线索。但是,我们可以调查的不仅仅是一个access.log文件。Apache HTTP Server 日志轮换算法归档旧的日志文件。列出/var/log/apache2/目录会显示四个额外的日志文件。
首先,我们需要过滤日志以查看 IP 84.55.41.57是否采取了任何操作。其中一个日志被包含大量 SQL 命令的记录轰炸,这些命令清楚地表明对似乎是与 SQL 服务器一起使用的自定义插件的SQL 注入攻击。
84.55.41.57- - [14/Apr/2016:08:22:13 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=1 AND (SELECT 6810 FROM(SELECT COUNT(*),CONCAT(0x7171787671,(SELECT (ELT(6810=6810,1))),0x71707a7871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) HTTP/1.1" 200 166 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
84.55.41.57- - [14/Apr/2016:08:22:13 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=(SELECT 7505 FROM(SELECT COUNT(*),CONCAT(0x7171787671,(SELECT (ELT(7505=7505,1))),0x71707a7871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) HTTP/1.1" 200 166 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
84.55.41.57- - [14/Apr/2016:08:22:13 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=(SELECT CONCAT(0x7171787671,(SELECT (ELT(1399=1399,1))),0x71707a7871)) HTTP/1.1" 200 166 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
84.55.41.57- - [14/Apr/2016:08:22:27 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=1 UNION ALL SELECT CONCAT(0x7171787671,0x537653544175467a724f,0x71707a7871),NULL,NULL-- HTTP/1.1" 200 182 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
假设这个插件是通过复制粘贴系统管理员在网上找到的一些代码创建的。该脚本旨在根据给定的 ID 检查用户的有效性。该插件在主网页上公开了一个表单,该表单正在向/wordpress/wp-content/plugins/custom_plugin/check_user.php发送 AJAX GET 请求。
当我们分析check_user.php时,很明显该脚本编写得很糟糕并且容易受到 SQL 注入攻击。
//Include the WordPress header
include('/wordpress/wp-header.php');
global $wpdb;
// Use the GET parameter ‘userid’ as user input
$id=$_GET['userid'];
// Make a query to the database with the value the user supplied in the SQL statement
$users = $wpdb->get_results( "SELECT * FROM users WHERE user_id=$id");
?>
access.log中的记录数量和模式表明攻击者使用 SQL 注入利用工具来利用 SQL 注入漏洞。攻击日志可能看起来像胡言乱语,但它们是 SQL 查询,通常旨在通过 SQL 注入漏洞提取数据。作为枚举过程的一部分,该利用工具尝试各种 SQL 注入技术来查找数据库名称、表名称和列。
我们不会深入研究 SQL 注入攻击,或者如何修复 SQL 注入漏洞(例如,使用准备好的语句),因为这超出了本文的范围。但是,日志中的记录将类似于以下内容:
/wordpress/wp-content/plugins/my_custom_plugin/check_user.php?userid=-6859 UNION ALL SELECT (SELECT CONCAT(0x7171787671,IFNULL(CAST(ID AS CHAR),0x20),0x616474686c76,IFNULL(CAST(display_name AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_activation_key AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_email AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_login AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_nicename AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_pass AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_registered AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_status AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_url AS CHAR),0x20),0x71707a7871) FROM wp.wp_users LIMIT 0,1),NULL,NULL--
上面的 SQL 代码非常强烈地表明 WordPress 数据库已被入侵,并且该 SQL 数据库中的所有敏感信息都可能被盗。
通过这次调查,我们现在可以创建导致这次攻击的事件链。
一些问题仍然存在,例如谁是袭击的幕后黑手。此时,只能知道攻击者的IP地址。除非攻击者留下与真人身份相关的具体证据,否则尝试将大多数攻击归因于非常困难并且可能不可行。请记住,攻击者经常利用代理和匿名网络(例如 Tor)来进行大多数攻击,以掩盖他们的真实位置。
最重要的是,导致 SQL 注入攻击的不安全代码存在于自定义 WordPress 插件中。如果该站点在部署到生产环境之前已经过安全漏洞测试,那么攻击者就不可能利用导致污损的安全漏洞。
上述虚构示例中的攻击者非常马虎,留下了大量的证据和痕迹,这使得调查非常容易。但是请记住,情况并非总是如此,尤其是在处理更复杂的攻击时。
您需要哪些日志文件来调查 Web 应用程序攻击?
您如何开始对 Web 应用程序攻击进行调查?
您可以使用哪些工具来调查 Web 应用程序攻击?
如何保护自己免受 Web 应用程序攻击?