我如何创建一个难以终止的过程


10

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

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

我想到的解决方案如下:

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

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

  3. 该过程将在某个已知位置使用密码来加密其名称。停止过程将必须使用bruteforce来恢复程序名称并杀死它。

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


2
您实际上是对的,听起来确实很卑鄙
Kiwy 2013年

文化网站...是的,我确实了解。我认为用错误的dns列表编译DNS可以为您提供帮助
Kiwy 2013年

@Kiwy是的,这是一个选择,但随后我可以重新安装DNS了吗?
Miheer 2013年

您总能为每件事做好准备。也许请朋友保留您计算机的root密码是符合要求的好方法:D,因为如果您非常喜欢文化内容,最终将使用可启动的USB密钥。
Kiwy 2013年

是的,但这绝非一项2分钟的简单工作。
Miheer 2013年

Answers:


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"

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

然后以以下方式启动您的VM:

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'

然后,我们看到:

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

但是,我不能仅将启动文件更改为不启动/ some / cmd吗?
Miheer 2013年

1
@Miheer,您可以从USB钥匙启动,或安装其他操作系统...为避免这种情况,您需要物理锁定计算机和BIOS以及启动加载程序以及内核和initrd(并启动程序)在某些只读设备上)。否则,无论您做什么,您都将始终能够卸下硬盘驱动器并卸下启动过程的操作。
斯特凡Chazelas

1

不知道这是最终的解决方案还是最佳的解决方案。我的意见:

  • 修改,init因为如果它死了,这是第一个过程,其他所有人也都死了。因此,您的机器将只能与它一起使用。

  • 创建一个内核模块并依赖于它加载关键模块(如果它被杀死,将像init示例一样引起连锁反应)。

  • 修改内核以忽略某些进程的终止请求。

请记住,最后两个将在内核模式下运行(就libs而言非常有限,因此一个)。修改init将在用户空间中运行,使您可以使用它的许多功能。


1
不知道它是否真的安全。
Tinti 2013年

以及如何停止该过程?
Miheer 2013年

这需要在软件本身中完成。您将必须创建一种方法来请求软件停止。假设它有一个检查文件的线程,例如:/var/lib/stop.request。如果此文件包含密码X,则软件将停止正在执行的工作,并进入一种睡眠模式。您可以通过创建另一个文件/var/lib/start.request来重新启用它。
Tinti 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.