Linux 系统日志小结,内附清理工具 LLC
上周近距离观赏了一次 APT 组织的攻击,感受最深的是他们非常有组织,搞办公网和搞生产网的人属于不同的组;有纪律,与攻击目标无关的机器能不动就不动,用到的技术其实大家都会,能不能管好自己的手不乱动是比较难的。不过让我比较惊讶的是,所有被入侵的机器的日志都被清除了(好在这些机器都在云上,厂商有对在云服务器上执行的命令做日志),只有一台机器(恰好还是本地机房)的 lastlog 没有清除,这让我十分不解。如果没有这台机器的 lastlog,那么在梳理攻击的链条时就会在中间断掉,无法准确还原入侵的路线,所以学会给自己擦屁股还是很重要的。
我本来以为自己对 Linux 的系统日志这个知识点十拿九稳,在翘着二郎腿欣赏的过程中突然发现自己不能准确回答 lastlog 的用途,只有一个模糊的印象(虽然猜对了),之前似乎确实没有完整地过一遍,有点不爽,故有此文。
介绍
说到 Linux 的日志,就不得不提到 syslogd。它是大部分 Linux 发行版默认的日志守护进程,是一个记录日志的服务,子配置文件位于 /etc/syslog 或 /etc/syslogd,默认配置文件为 /etc/syslog.conf。从架构来看,这个服务下面有一系列的子服务,例如 mail、cron 等等,这些子服务对外提供日志记录的功能,当其它的程序或服务需要记录日志的时候,就可以直接调用这些子服务将日志记录到指定的地方。
我们编写的代码可以通过 syslog 的接口进行 log,syslog 会通过 socket 将 log 发送给 syslogd,syslogd 在获取到 log 后,会对 log 进行处理,然后根据用户配置,将 log 保存到本地或者发送到其他服务器上去。
最简单的,用 logger -t '[test]' "I'm Tr0y" 就可以直接日志记录到 message 里:
1 | |
再举个 python 使用 syslog 的例子吧:
1 | |
然后就可以在 /var/log/messages 里面看到它了:
1 | |
配置文件详解
作为 syslogd 的配置文件,syslog.conf 指定了:
格式如下:
1 | |
具体来说:
*:代表任意服务.:即 >=,大于等于该等级的日志都要记录下来.=:即 ==,等于该等级的日志都要记录下来.!:即 !=,除了该等级的日志都要记录下来*:任意优先级最后还有 2 点需要注意:
; 来合并:1 | |
, 来合并:1 | |
目前不少的 Linux 发行版已经用 rsyslogd 代替了 syslogd。rsyslogd 是 syslogd 的升级版,子配置文件位于 /etc/rsyslog.d,默认配置文件为 /etc/rsyslog.conf,由于其配置语法与 syslogd 的配置文件一致,这里就不重复说了。
那么在说各个具体的系统日志之前,我们先来看看 rsyslogd 的配置。因为有些系统日志是通过 rsyslogd 记录的,那么正如前面说的,rsyslog.conf 就决定了这些系统日志存放的位置。
如果你在网上搜索 “linux ssh 日志位置”,很大概率会告诉你是 /var/log/secure。但是这个其实是默认位置,是有可能被改掉的(不同发行版或者是恶意修改)。所以不管是应急也好,做威胁检测也好,最好要通过 rsyslog.conf 来确定特定系统日志真正的位置。
比如这是我虚拟机的配置:
1 | |
这下我们才可以确定,messages 存放了除了 mail、authpriv、cron 之外所有的 info 等级的日志(所以这个日志文件通常是比较大的);authpriv 存在 secure 里;cron 存在 cron 里。
最后有两个小经验:
/proc/pid/fd/n(pid 和 n 取决于实际情况)恢复日志。步骤非常简单,先用 sudo lsof +L1 看一下有没有被删除的 log 文件,有的话记下 pid,然后 ls -l /proc/pid/fd 找一下日志文件是对应的哪个 fd,直接 cp 即可/proc/pid/fd/n 下面的表现就是后面多了一个 (deleted)(这里面的机制有些复杂,不仅仅是 inode 那么简单的,有机会的话详细介绍)。如果要恢复中断的记录,那么就需要从 /proc/pid/fd/n 下面 cp 出来,然后重启 rsyslogd;如果不想找回中断的记录,那么直接重启就行。默认路径:/var/log/messages
它是默认的日志文件,记录 Linux 内核消息及各种应用程序的日志信息,包括:启动、IO 错误、网络错误、程序自定义日志等等。
虽然信息种类会多一些,但是这个一般用得少,就不多说了。
默认路径:/var/log/secure
只要牵涉到需要输入帐号密码的程序,包括 login、有图形界面的 Linux 登录的时候、su、sudo、ssh、telnet、groupadd、useradd、passwd 等等,那么当登录时(不管成功或者失败)都会被记录在此。
secure 是应急响应中最常查看的文件,例如疑似存在 ssh 爆破的时候,我们就可以查看这个文件,这类应急基本上是在考验我们使用 grep、awk、sed 的熟练度。
默认路径:/var/log/cron
该日志文件记录了 cron 运行的日志。包含:
cron 的作用比较专一,它一般有两种用途:
先来看一下整体的流程。
在 Linux 中,每当有一个用户登录时,如果有分配 tty,login 命令要负责:
接下来详细看一下每个日志的用途,这些日志都是二进制格式的日志,用 cat、less 是看不了的。btmp、utmp 和 wtmp,它们的数据结构是一样的,而 lastlog 文件有自己的数据结构,关于它们的具体的数据结构可以使用 man 命令查询,例如 man utmp。
默认路径:/var/log/lastlog
该日志文件记录了每个用户最近一次成功的登录事件和最后一次不成功的登录事件,每次用户登录的时候都会查一下这个日志的记录。
一般用 lastlog 命令查看,会根据 UID 排序来显示用户名、tty、IP 和最后登录时间,如果某用户从来没有登录过,就显示为 **Never logged in**:

默认路径:/var/log/wtmp
该日志文件记录了每个用户登录、注销及系统的重启等事件,主要用于查看用户的登录记录。
一般用 last 命令查看,会以反序从后向前显示用户的登录记录,也能根据用户名、tty 或时间显示相应的记录:

默认路径:/var/run/utmp
该日志文件记录了当前登录的每个用户的信息。因此这个文件会随着用户登录、注销而不断变化,因为它只保留了当前已登录的用户记录,不会为用户保留永久的记录。
系统中需要查询当前用户状态的程序,如 who、w、users、finger 等其实就是从这个文件获取的信息:

默认路径:/var/log/btmp
该日志文件记录了失败的登录尝试。默认没有初始化,不会记录,可以执行一次 lastb 开始记录。
一般用 lastb 命令查看:

清空日志
简单粗暴,但是很容易被发现,除非已经到了收割成果的阶段,被不被发现都无所谓了,那么可以这么做。需要注意的是,清空有两种做法,一种是用空字符串覆盖原文件,这种没什么问题;另一种是直接将文件删除,对于用 rsyslogd 记录的日志来说,如果没有停过 rsyslogd 那么是可以被恢复到,这一点上面也提到过了。
修改日志
对于用 rsyslogd 记录的日志来说,可读性很好,直接修改即可。
比如篡改自己使用的 ip:sed -i 's/192.168.166.85/192.168.1.1/g' secure;或者直接删掉有 ip 信息的行 sed -i '/192.168.166.85/d' test。
稍微有些费劲是那些二进制格式的日志。对于登录相关日志来说,由于手动修改比较麻烦,所以我写了一个日志清理的工具:
https://github.com/Macr0phag3/LLC

以 utmp 为例:
用 w 我们可以看到 macr0phag3 在线:

清除:

再用 w 看看:

macr0phag3 就没有显示在线了。
如果觉得这样麻烦,其实也有办法避免记录登录日志。登录后,在分配伪 tty(建议看下资料 1)的时候才会出现这些登录日志(btmp 除外),那如果没有分配的话,就不会做记录,这也是这个命令的原理:
-T 代表不要分配 tty,-i 代表要一个交互型的 bash,去掉其实也能用,甚至整个 /bin/bash -i 都可以去掉,就是不太美观,用起来不爽。
比如我们可以创建一个新的用户来试试,用上述方式登录:

可以看到除了爆破失败的记录之外,其他登录日志均无记录。
当然了,隐藏/清理痕迹的手法有很多,有各种姿势,像这种 ssh 的算烂大街了。等有时间我专门写一篇文章来总结这些知识。
日志在应急中是非常重要的。现在很多运维在突发事故上吃了亏,都会对日志做备份,甚至有专门的日志备份服务器,但是基本上是出于运维角度的考虑。其实安全事件也算突发事故,如果意识到了日志对于应急响应的作用,应该会有更多人做备份吧。当然如果有实时备份的话,攻击者直接清理日志就没啥用了,但是可以想办法让日志停止记录。
攻与防,始终是相互促进的嘛
如果橘友们是这个 APT 组织的成员
会记得清理日志吗?
会漏掉那个关键的 lastlog 吗?