Security

如何創建一個難以殺死的程序

  • December 14, 2013

我想創建一個一旦啟動(使用 root 權限)就很難停止的程序(即使對於管理員來說也是如此)。一旦啟動,該過程應在啟動時繼續自行啟動,直到被要求停止。停止過程應該需要一些時間(即應該很昂貴)。

我知道這聽起來像是一個惡意軟體,但我想要它是出於真正的原因。我想在我的筆記型電腦(我是管理員)上執行站點攔截器。我想讓自己很難阻止他們。

我想到的解決方案如下——

  1. 該程序每次執行時都應該以不同的名稱執行,這樣我就無法預測程序名稱並殺死它。
  2. 該程序將在關機時將自身保存在 /etc/rc5.d 中
  3. 該程序將在某個已知位置使用密碼對其名稱進行加密。停止過程將不得不使用蠻力來恢復程序名稱並將其殺死。

我想為這項任務找到一個好的解決方案。

一種方法是使用 PID 命名空間:

init=/some/cmd使用as 核心參數引導您的系統,其中在新命名空間 ( )中/some/cmd派生一個程序並在其中執行(它將在該新命名空間中具有 PID 1,在根命名空間中具有 pid 2),然後在父級中執行您的“程序”。CLONE_NEWPID``/sbin/init

您可能需要一種以某種方式控製程序的方法(例如 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.

然後將您的虛擬機引導為:

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

引用自:https://unix.stackexchange.com/questions/104866