如何创建一个难以杀死的进程

Mih*_*eer 10 security process kill

我想创建一个一旦启动(具有 root 权限)就很难停止(即使对于管理员)的程序。一旦启动,该进程应继续在启动时自行启动,直到被要求停止。停止过程应该需要一些时间(即应该是昂贵的)。

我知道这听起来像是一个恶意软件,但我出于真正的原因想要它。我想在我的笔记本电脑(我是管理员)上运行站点拦截器。我想让自己很难阻止他们。

我想到的解决方案如下-

  1. 进程每次运行时都应该以不同的名称运行,这样我就无法预测进程名称并杀死它。

  2. 该进程将在关机时将自身保存在 /etc/rc5.d 中

  3. 该进程将在某个已知位置使用密码对其名称进行加密。停止过程将不得不使用蛮力来恢复程序名称并杀死它。

我想为这项任务找到一个好的解决方案。

Sté*_*las 8

一种方法是使用 PID 命名空间:

使用init=/some/cmdas 内核参数启动系统,其中/some/cmd在新命名空间 ( CLONE_NEWPID)中派生进程并/sbin/init在其中运行(它将在新命名空间中具有 PID 1,在根命名空间中具有 pid 2),然后在父命名空间中执行您的“程序”。

您可能想要一种以一种或另一种方式控制程序的方法(例如 TCP 或 ABSTRACT Unix 套接字)。

您可能希望将程序锁定在内存中并关闭对文件系统的大多数引用,以便它不依赖任何东西。

从系统的其余部分看不到该过程。系统的其余部分实际上将像在容器中一样运行。

如果该进程死亡,内核将恐慌,这为您提供了额外的保证。

但是,一个不方便的副作用是我们不会在ps.

作为概念证明(使用此技巧在 qemu 虚拟机中启动系统副本):

创建一个/tmp/init喜欢:

#! /bin/sh -
echo Starting
/usr/local/bin/unshare -fmp -- sh -c '
  umount /proc
  mount -nt proc p /proc
  exec bash <&2' &
ifconfig lo 127.1/8
exec socat tcp-listen:1234,fork,reuseaddr system:"ps -efH; echo still running"
Run Code Online (Sandbox Code Playgroud)

(您需要unshare最新版本的 util-linux (2.14))。上面我们socat用作“程序”,它只回答端口 1234 上的 TCP 连接,输出ps -efH.

然后启动你的虚拟机:

kvm -kernel /boot/vmlinuz-$(uname -r) -initrd /boot/initrd.img-$(uname -r) \
    -m 1024 -fsdev local,id=r,path=/,security_model=none \
    -device virtio-9p-pci,fsdev=r,mount_tag=r -nographic -append \
    'root=r rootfstype=9p rootflags=trans=virtio console=ttyS0 init=/tmp/init rw'
Run Code Online (Sandbox Code Playgroud)

然后,我们看到:

Begin: Running /scripts/init-bottom ... done.
Starting
[...]
root@(none):/# ps -efH
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 14:24 ?        00:00:00 bash
root         4     1  0 14:24 ?        00:00:00   ps -efH
root@(none):/# telnet localhost 1234
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
UID        PID  PPID  C STIME TTY          TIME CMD
root         2     0  0 14:24 ?        00:00:00 [kthreadd]
root         3     2  0 14:24 ?        00:00:00   [ksoftirqd/0]
[...]
root         1     0  2 14:24 ?        00:00:00 socat tcp-listen:1234,fork,reuseaddr system:ps -efH; echo still running
root       204     1  0 14:24 ?        00:00:00   /usr/local/bin/unshare -fmp -- sh -c    umount /proc   mount -nt proc p /proc   exec bash <&2
root       206   204  0 14:24 ?        00:00:00     bash
root       212   206  0 14:25 ?        00:00:00       telnet localhost 1234
root       213     1  0 14:25 ?        00:00:00   socat tcp-listen:1234,fork,reuseaddr system:ps -efH; echo still running
root       214   213  0 14:25 ?        00:00:00     socat tcp-listen:1234,fork,reuseaddr system:ps -efH; echo still running
root       215   214  0 14:25 ?        00:00:00       sh -c ps -efH; echo still running
root       216   215  0 14:25 ?        00:00:00         ps -efH
still running
Connection closed by foreign host.
root@(none):/# QEMU: Terminated
Run Code Online (Sandbox Code Playgroud)