Logrotate 下的持续化后门

TL;DR

logrotate 在日志轮询中,支持简单的生命周期事件 prerotate / postrotate 等,当日志轮询之前/之后,会尝试调用 sh 执行定义的语句块。

0x0 概述

日志对于应用调试、故障排查、攻击溯源等都有非常重要的作用。而随着时间的累加,日志的大小也随之增长,对单个庞大的日志文件进行分析,会消耗较多的时间和资源。

而 logrotate 可以很好的解决这些问题,logrotate 可以根据定义的规则,定期对日志进行归档重建、压缩等。

0x1 配置

logrotate 的主配置文件位于 /etc/logrotate.conf 下:

weekly      # logrotate 工作的间隔
rotate 4    # 预保留的日志数量
create      # 在 rotate 之后,被归档的日志使用新的名称(如 secure.1),此命令将新建日志,并使用最原始的日志名
dateext     # 对于默认是用 1、2、3、4 作为日志轮询的后缀,修改为日志被归档的日期
compress    # 使用 gzip 对日志进行压缩

主配置文件作为默认的配置信息,可以被单独的配置文件继承和覆盖,对于自定义的日志轮询配置,一般存放于 /etc/logrotate.d 下 :

/var/log/secure {
	daily           # 覆盖默认的每周 rotate
	missingok       # 如果日志不存在,忽略错误
	notifempty      # 如果日志为空,则不归档
}

0x2 How it works

由于日志轮询需要定期进行,所以在 /etc/cron.daily 下,可以发现 logrotate 的任务脚本:

user@server:/etc/cron.daily$ cat logrotate 
#!/bin/sh

test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf

logrotate 通过 crond 服务定期运行,并检测对应的配置文件,根据规则定期对日志进行归档处理。

0x3 持续化后门

对于 Linux 下持续化后门的方式非常之多:

  • /etc/rc.local,/etc/rc.x
  • /etc/init.d
  • /etc/cron.x

当然不限于上述的方式,但对于日常的取证活动,这些地方基本都会被光顾。而在这些边边角角之中,logrotate 也可以作为一个持续化后门的安置区。

0x4 事件支持

logrotate 在日志轮询中,支持简单的生命周期事件,可以通过此事件来执行 shell 命令。

/var/log/secure {
    firstaction
        echo "logrotate start" > /tmp/logrotate
    endscript

    # 在日志轮询之前
    prerotate
        echo "logrotate prepare" >> /tmp/logrotate
        /usr/bin/chattr -a /var/log/secure
    endscript
    
    # 日志轮询之后
    postrotate
        echo "logrotate done" >> /tmp/logrotate
        /usr/bin/chattr +a /var/log/secure
    endscript
    
    lastaction
        echo "logrotate end" >> /tmp/logrotate
    endscript
}

其事件生命周期为:

firstacition -> prerotate -> postrotate -> lastaction

事件只支持定义在日志文件块中(即不能作为全局配置),当日志轮询之前/之后,会尝试调用 sh 执行定义的语句块:

enter image description here

0x5 最后

  • 对于较新的 Linux 发行版,都会预装 logrotate 包
  • 指定的目录下必须存在对应的日志文件,事件才会触发

EOF