Posso impedire la creazione di una cartella con un determinato nome?


16

Sto lavorando su un'app Web LAMP e c'è un processo pianificato da qualche parte che continua a creare una cartella chiamata shopnella radice del sito. Ogni volta che questo appare provoca conflitti con le regole di riscrittura nell'app, non va bene.

Fino a quando non trovo lo script offensivo, c'è un modo per impedire che qualsiasi cartella chiamata shopvenga creata nella radice? So che posso modificare le autorizzazioni su una cartella per impedire che il contenuto venga modificato, ma non ho trovato un modo per impedire la creazione di una cartella con un determinato nome.


4
Per scoprire cosa sta facendo la creazione, è possibile abilitare il controllo .
Andrew Henle,

Risposte:


30

Non è possibile, dato che l'utente che crea la directory dispone dell'autorizzazione sufficiente per scrivere nella directory principale.

Puoi invece sfruttare la inotifyfamiglia di chiamate di sistema fornite dal kernel Linux, per cercare la creazione (e facoltativamente mv-ing) della directory shopnella directory data, se creata (o facoltativamente mv-ed), rmla directory.

Il programma userspace di cui hai bisogno in questo caso è inotifywait(viene fornito inotify-tools, installalo prima se necessario).


Supponendo che la directory shoprisieda nella /foo/bardirectory, impostiamo un monitoraggio per la /foo/bar/shopcreazione e rmistantaneamente se creato:

inotifywait -qme create /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'
  • inotifywait -qme create /foo/barcontrolla la /foo/bardirectory per qualsiasi file / directory che potrebbe essere creata, ad esempio guarda per qualsiasi createevento

  • Se creato, awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'controlla se il file è una directory e il nome è shop( /,ISDIR shop$/), in tal caso rmla directory ( system("rm -r -- /foo/bar/shop"))

È necessario eseguire il comando come utente con autorizzazione di scrittura sulla directory /foo/barper la rimozione shopdalla directory.


Se vuoi monitorare mvanche le operazioni -ing, aggiungi anche watch for moved_toevent:

inotifywait -qme create,moved_to /foo/bar | \
             awk '/,ISDIR shop$/ { system("rm -r -- /foo/bar/shop") }'

Solo per notare, se stai cercando un file, non una directory, chiamato shop:

inotifywait -qme create /foo/bar | \
                 awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'

inotifywait -qme create,moved_to /foo/bar | \
                 awk '$NF == "shop" { system("rm -- /foo/bar/shop") }'

2
Inoltre, se stai usando inotifywaitper fare questo, è anche possibile che il trigger possa anche essere in grado di catturare il processo conps -ef
roaima,

30

Rispondere letteralmente in base alla domanda di impedire la creazione di una cartella con un determinato nome.

touch shop

Non è possibile creare una directory se esiste un file con un nome identico

mkdir: cannot create directory ‘shop’: File exists


6
Questo * potrebbe non * essere sufficiente. mkdir potrebbe non farlo, ma può essere fatto. È un buon primo tentativo però.
coteyr,

9
Sui sistemi Linux, utilizzare chattr +i shopper renderlo immutabile. Fino a quando il flag immutabile non viene rimosso, non può nemmeno essere rinominato / eliminato.
R .. GitHub FERMA AIUTANDO ICE

1
Questo è un piccolo trucco intelligente, non del tutto adatto alla mia situazione, ma un'idea intelligente per determinate circostanze 👍
Andrew

1
@R .. interessante. Mi aspettavo rename(2)di funzionare ancora, dato che il nome non fa parte dell'inode, ma non lo fa. La ricerca rapida su Internet non rivela il perché. Qualche suggerimento?
domen,

@domen: Perché fa parte dello scopo dell'attributo "immutabile". Ho il sospetto che ci vuole un lavoro extra non banale a livello di implementazione per impedire il renamefunzionamento.
R .. GitHub FERMA AIUTANDO ICE

4

Che dire del dirottamento mkdir Syscall con LD_PRELOAD...?

$ ls
test.c
$ cat test.c 
#define _GNU_SOURCE

#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>

typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);

int mkdir(const char *path, mode_t mode) {
    if(!strcmp(path, "shop")) return 1;

    orig_mkdir_func_type orig_func;
    orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
    return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir test
$ LD_PRELOAD='./test.so' mkdir shop
mkdir: cannot create directory ‘shop’: No such file or directory
$ ls
test  test.c  test.so

Si noti che all'interno di questo gestore è possibile registrare il PID del processo che desidera invece creare questa directory:

$ cat test.c 
#define _GNU_SOURCE

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>

typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);

int mkdir(const char *path, mode_t mode) {
    if(!strcmp(path, "shop")) {
        FILE* fp = fopen("/tmp/log.txt", "w");
        fprintf(fp, "PID of evil script: %d\n", (int)getpid());
        fclose(fp);
    }

    orig_mkdir_func_type orig_func;
    orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
    return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir shop
$ cat /tmp/log.txt 
PID of evil script: 8706

Devi metterlo in ~/.bashrcroot (o chiunque stia eseguendo la tua app) per assicurarti che verrà usato:

export LD_PRELOAD=/path/to/test.so

2
questo non dovrebbe avere un downvote, è una soluzione e buona
cat

4
Sta usando una bomboletta di valigia per aprire una scatola di fagioli. Ma ehi almeno saranno cotti ...
Lightness Races con Monica il

2
@cat: non sono d'accordo. LD_PRELOADgli hack come questo sono fondamentalmente sempre sbagliati e, a meno che tu non sappia cosa stai facendo, possono danneggiare gravemente il programma in cui li carichi rompendo proprietà come la sicurezza del segnale asincrono della funzione che stai sostituendo.
R .. GitHub FERMA AIUTANDO ICE

1
Inoltre, penso che fopendovrebbe avere "a"invece di "w", in modo che possa conservare i registri precedenti
cat

2
Anche questo non funzionerà se un codice errato chiama direttamente la syscall, non tramite libc. O se il codice errato è staticamente collegato.
domen,

3

(Avrebbe commentato la risposta di Miati ma non ricordo il mio vecchio account e non ho abbastanza reputazione su questo nuovo ...)

È possibile bloccare la creazione creando un file e quindi modificando gli attributi del file.

$ sudo touch shop
$ sudo chattr +i shop

Quindi qualsiasi tentativo di fare qualcosa con quel file verrà bloccato, anche se l'utente diventa root.

$ rm shop
rm: remove write-protected regular empty file ‘shop’? y
rm: cannot remove ‘shop’: Operation not permitted
$ sudo rm shop
rm: cannot remove ‘shop’: Operation not permitted

2
Se conosci il nome / indirizzo e-mail del tuo vecchio account, puoi richiedere la fusione di un account dal modulo di contatto collegato in fondo a ogni pagina .
wizzwizz4,

Inoltre, perché non dirci come questo è correlato all'altra risposta, piuttosto che al motivo per cui hai deciso di pubblicare?
jpaugh

2

Creare un collegamento simbolico che punta a una posizione inesistente all'interno di una directory inesistente. Ciò ha alcune implicazioni divertenti:

$ ln -s non-existent/foobar foo
$ ls -ln
total 0
lrwxrwxrwx 1 1000 1000 19 Okt  4 17:17 foo -> non-existent/foobar
$ mkdir foo
mkdir: cannot create directory ‘foo’: File exists
$ cat foo
cat: foo: No such file or directory
$ echo foo > foo
zsh: no such file or directory: foo
  1. mkdir, link e altri falliranno EEXIST (Il file esiste).
  2. Il tentativo di aprire il percorso di lettura, scrittura o aggiunta non andrà a buon fine ENOENT (Nessun file o directory del genere)
  3. Anche l'uso di stat (2) (non lstat (2) o stat (1)) sulla posizione fallisce ENOENT. Ovviamente lstat restituirà le informazioni sul collegamento simbolico.

Ciò ha due vantaggi rispetto ad alcune delle altre soluzioni proposte qui: (a) non è necessario un servizio in esecuzione che tiene traccia della creazione della directory e (b) il nome sembra inesistente alla maggior parte dei comandi.

Dovrai provarci, ma sospetto che, qualunque siano le regole di riscrittura che hai, non usano lstat o altri comandi di non dereferenziamento, facendoli fallire.

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.