I want to create a program that will be difficult to stop (even for the administrator) once it is started (with root privileges). Once started the process should continue to start itself at startup until asked to stop. The stopping process should take some time (I.e. should be expensive).

I know this may sound like a malicious software, but I want it for a genuine reason. I want to run site blockers on my Laptop (on which I am the admin). And I want to make it difficult for myself to stop them.

The solution that I thought of is the following-

  1. The process should run with a different name each time it is run, so that I cannot predict the process name and kill it.

  2. The process will save itself in /etc/rc5.d at shutdown

  3. The process will encrypt its name using a cypher in some known location. The stopping process will have to use bruteforce to recover the program name and kill it.

I would like to find a good solution for this task.

  • 3
    you're actually right, it does sound like a very mean program
    – Kiwy
    Dec 12 '13 at 13:54
  • cultural web sites... yes I do understand. I think compiling the DNS with a list of incorrect dns could help you
    – Kiwy
    Dec 12 '13 at 14:14
  • @Kiwy Yes that is an option, but then I can just reinstall DNS right?
    – Miheer
    Dec 12 '13 at 14:42
  • You can always have a way for every thing. Maybe ask a friend to keep the root password of you're computer is a nice way to comply with what you're asking for :D because you will end up using a bootable usb key, if you like cultural content that much.
    – Kiwy
    Dec 12 '13 at 14:44
  • Yes but it should not be a simple 2 minute job.
    – Miheer
    Dec 12 '13 at 14:46

One approach could be to use PID namespaces:

Boot your system with a init=/some/cmd as kernel parameter, where /some/cmd forks a process in a new namespace (CLONE_NEWPID) and runs /sbin/init in it (it will have PID 1 in that new namespace and pid 2 in the root namespace), then in the parent, execute your "program".

You'll probably want a way to control your program in one way or another (TCP or ABSTRACT Unix socket for instance).

You'll probably want to mlock your program in memory and close most references to the filesystem so that it doesn't rely on anything.

That process won't be seen from the rest of the system. The rest of the system will in effect run like in a container.

If that process dies, the kernel will panic which gives you an extra guarantee.

An inconvenient side-effect though is that we won't see the kernel threads in the output of ps.

As a proof of concept (using this trick to boot a copy of your system in a qemu virtual machine):

Create a /tmp/init like:

#! /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"

(you need unshare from a recent version of util-linux (2.14)). Above we're using socat as the "program" which just answers on TCP connections on port 1234 with the output of ps -efH.

Then boot your VM as:

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'

Then, we see:

Begin: Running /scripts/init-bottom ... done.
root@(none):/# ps -efH
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...
Connected to localhost.
Escape character is '^]'.
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
  • But then can't I can just change the bootfile to not start /some/cmd?
    – Miheer
    Dec 12 '13 at 14:51
  • 1
    @Miheer, and you could boot from a USB key, or install a different operating system... To avoid that, you'd need to physically lock down the machine and BIOS and boot loader and kernel and initrd (and have the program started from that initrd) on some read-only device. Otherwise, whatever you do, you'll always be able to take the hard drive off and remove the thing that starts your process. Dec 12 '13 at 14:57

Not sure if it is the final solution or if it is the best way to do it. My opinions:

  • Modify init since it is the first process if it dies all others die too. So your machine will only be usable with it.

  • Create a kernel module and load critical modules depending on it (if it gets killed it will cause a chain reaction like the init example).

  • Modify the kernel to ignore kill requests for a certain process.

Keep in mind that the last two will run in kernel mode (which is very limited in terms of libs and so one). Modifying init will run in userspace allowing you to use many features of it.

  • 1
    Not sure if it is really safe. Dec 12 '13 at 13:55
  • And how to stop the process?
    – Miheer
    Dec 12 '13 at 14:03
  • This would need to be done in the software itself. You would have to create a way to request the software to stop. Lets suppose that it has a thread that checks a file like: /var/lib/stop.request. If this file contains a password X the software stops the WORK that it is doing and enter in a kind of sleep mode. The you could re-enable it by creating another file /var/lib/start.request. Dec 12 '13 at 14:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.