Security
如何創建一個難以殺死的程序
我想創建一個一旦啟動(使用 root 權限)就很難停止的程序(即使對於管理員來說也是如此)。一旦啟動,該過程應在啟動時繼續自行啟動,直到被要求停止。停止過程應該需要一些時間(即應該很昂貴)。
我知道這聽起來像是一個惡意軟體,但我想要它是出於真正的原因。我想在我的筆記型電腦(我是管理員)上執行站點攔截器。我想讓自己很難阻止他們。
我想到的解決方案如下——
- 該程序每次執行時都應該以不同的名稱執行,這樣我就無法預測程序名稱並殺死它。
- 該程序將在關機時將自身保存在 /etc/rc5.d 中
- 該程序將在某個已知位置使用密碼對其名稱進行加密。停止過程將不得不使用蠻力來恢復程序名稱並將其殺死。
我想為這項任務找到一個好的解決方案。
一種方法是使用 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