Come posso creare un processo difficile da uccidere


10

Voglio creare un programma che sarà difficile da arrestare (anche per l'amministratore) una volta avviato (con i privilegi di root). Una volta avviato, il processo dovrebbe continuare ad avviarsi all'avvio fino a quando non viene chiesto di interrompere. Il processo di arresto dovrebbe richiedere del tempo (vale a dire che dovrebbe essere costoso).

So che potrebbe sembrare un software dannoso, ma lo voglio per una vera ragione. Voglio eseguire i blocchi dei siti sul mio laptop (di cui sono l'amministratore). E voglio rendere difficile per me stesso fermarli.

La soluzione a cui ho pensato è la seguente-

  1. Il processo dovrebbe essere eseguito con un nome diverso ogni volta che viene eseguito, quindi non posso prevedere il nome del processo e ucciderlo.

  2. Il processo si salverà da solo in /etc/rc5.d allo spegnimento

  3. Il processo crittograferà il suo nome usando un cifratore in una posizione nota. Il processo di arresto dovrà utilizzare bruteforce per recuperare il nome del programma e ucciderlo.

Vorrei trovare una buona soluzione per questo compito.


2
in realtà hai ragione, sembra un programma molto cattivo
Kiwy

siti web culturali ... sì, ho capito. Penso che compilare il DNS con un elenco di DNS non corretti possa aiutarti
Kiwy

@Kiwy Sì, questa è un'opzione, ma poi posso reinstallare il DNS giusto?
Miheer,

Puoi sempre avere un modo per ogni cosa. Magari chiedi a un amico di conservare la password di root del tuo computer è un bel modo di soddisfare ciò che stai chiedendo: D perché finirai per usare una chiave USB avviabile, se ti piacciono così tanto i contenuti culturali.
Kiwy,

Sì, ma non dovrebbe essere un semplice lavoro di 2 minuti.
Miheer,

Risposte:


8

Un approccio potrebbe essere quello di utilizzare gli spazi dei nomi PID:

Avvia il tuo sistema con un init=/some/cmdparametro come kernel, in cui esegue il /some/cmdfork di un processo in un nuovo spazio dei nomi ( CLONE_NEWPID) e lo esegue /sbin/init(avrà PID 1 in quel nuovo spazio dei nomi e pid 2 nello spazio dei nomi radice), quindi nel genitore, esegui il tuo " programma".

Probabilmente vorrai un modo per controllare il tuo programma in un modo o nell'altro (ad esempio socket TCP o ABSTRACT Unix).

Probabilmente vorrai bloccare il tuo programma in memoria e chiudere la maggior parte dei riferimenti al filesystem in modo che non faccia affidamento su nulla.

Questo processo non sarà visibile dal resto del sistema. Il resto del sistema funzionerà in effetti come in un contenitore.

Se quel processo si interrompe, il kernel sarà preso dal panico e ciò ti darà una garanzia in più.

Un effetto collaterale scomodo è che non vedremo i thread del kernel nell'output di ps.

Come prova del concetto (usando questo trucco per avviare una copia del tuo sistema in una macchina virtuale qemu):

Crea un /tmp/initlike:

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

(è necessario unshareda una versione recente di util-linux (2.14)). Sopra stiamo usando socatcome "programma" che risponde alle connessioni TCP sulla porta 1234 con l'output di ps -efH.

Quindi avviare la macchina virtuale come:

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'

Quindi vediamo:

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

Ma allora non posso semplicemente cambiare il file di boot per non avviare / some / cmd?
Miheer,

1
@Miheer, e potresti avviarlo da una chiave USB o installare un sistema operativo diverso ... Per evitarlo, dovresti bloccare fisicamente la macchina, il BIOS, il caricatore di avvio, il kernel e initrd (e avviare il programma da quel initrd) su qualche dispositivo di sola lettura. Altrimenti, qualunque cosa tu faccia, sarai sempre in grado di togliere il disco rigido e rimuovere ciò che avvia il processo.
Stéphane Chazelas,

1

Non sono sicuro se è la soluzione finale o se è il modo migliore per farlo. Le mie opinioni:

  • Modifica initpoiché è il primo processo se muore muoiono anche tutti gli altri. Quindi la tua macchina sarà utilizzabile solo con essa.

  • Crea un modulo del kernel e carica i moduli critici a seconda di esso (se viene ucciso causerà una reazione a catena come initnell'esempio).

  • Modifica il kernel per ignorare le richieste di kill per un certo processo.

Tieni presente che gli ultimi due verranno eseguiti in modalità kernel (che è molto limitata in termini di librerie e così via). La modifica initverrà eseguita nello spazio utente che consente di utilizzare molte funzionalità di esso.


1
Non sono sicuro che sia davvero sicuro.
Tinti,

E come fermare il processo?
Miheer,

Questo dovrebbe essere fatto nel software stesso. Dovresti creare un modo per richiedere l'arresto del software. Supponiamo che abbia un thread che controlla un file come: /var/lib/stop.request. Se questo file contiene una password X, il software interrompe il LAVORO in corso e entra in una sorta di modalità di sospensione. È possibile riattivarlo creando un altro file /var/lib/start.request.
Tinti,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.