Domanda

Qualcuno può indicare un codice che si occupa della sicurezza dell'accesso ai file tramite un percorso specificato (in parte) da una variabile di ambiente, in particolare per Unix e le sue varianti, ma anche le soluzioni Windows sono interessanti?

Questa è una grande domanda lunga: non sono sicuro di come si adatti al paradigma SO.

Considera questo scenario:

Sfondo:

  • Il pacchetto software PQR può essere installato in una posizione scelta dagli utenti.
  • La variabile di ambiente $ PQRHOME viene utilizzata per identificare la directory di installazione.
  • Per impostazione predefinita, tutti i programmi e file in $ PQRHOME appartengono a un gruppo speciale, pqrgrp.
  • Allo stesso modo, tutti i programmi e i file sotto $ PQRHOME appartengono a un utente speciale, pqrusr o all'utente root (e questi sono programmi root SUID).
  • Alcuni programmi sono SUID pqrusr; alcuni altri programmi sono SGID pqrgrp.
  • La maggior parte delle directory sono di proprietà di pqrusr e appartengono a pqrgrp; alcuni possono appartenere ad altri gruppi e i membri di tali gruppi acquisiscono ulteriori privilegi con il software.
  • Molti degli eseguibili privilegiati devono essere gestiti da persone che non sono membri di pqrgrp; i programmi devono confermare che l'utente è autorizzato a eseguirlo secondo regole arcane che non riguardano direttamente questa domanda.
  • Dopo l'avvio, alcuni dei programmi privilegiati devono conservare i loro privilegi elevati perché sono demoni di lunga durata che possono agire per conto di molti utenti nel corso della loro vita.
  • I programmi non sono autorizzati a cambiare directory in $ PQRHOME per una serie di ragioni arcane.

Controllo corrente:

  • I programmi attualmente controllano che $ PQRHOME e le directory chiave in esso contenute siano "sicuri" (di proprietà di pqrusr, appartengono a pqrgrp, non hanno accesso pubblico alla scrittura).
  • Successivamente, i programmi accedono ai file in $ PQRHOME tramite il valore completo della variabile di ambiente.
  • In particolare, G11N e L10N si ottengono accedendo ai file in directory "sicure" e leggendo stringhe di formato per printf () ecc. dai file in tali directory, utilizzando il percorso completo derivato da $ PQRHOME più un sottotitolo noto -struttura (ad esempio $ PQRHOME / g11n / en_us / messages.l10n).

Supponi che il valore "come installato" di $ PQRHOME sia / opt / pqr.

Attacco noto:

  • L'attaccante imposta PQRHOME = / home / attacker / pqr.
  • Questo è in realtà un link simbolico a / opt / pqr, quindi quando uno dei programmi PQR, chiamato pqr-victim, controlla la directory, ha i permessi corretti.
  • Immediatamente dopo aver completato con successo il controllo di sicurezza, l'attaccante cambia il collegamento simbolico in modo che punti a / home / attacker / bogus-pqr, che è chiaramente sotto il controllo dell'attaccante.
  • Le cose spiacevoli accadono quando la vittima di pqr ora accede a un file nella directory presumibilmente sicura.

Dato che PQR attualmente si comporta come descritto, ed è un pacchetto di grandi dimensioni (più milioni di righe di codice, sviluppato in più di un decennio a una varietà di standard di codifica, che sono stati spesso ignorati, comunque), quali tecniche useresti per risolvere il problema?

Le opzioni conosciute includono:

  1. Modifica tutte le chiamate di formattazione per utilizzare la funzione che controlla gli argomenti effettivi rispetto alle stringhe di formato, con un argomento aggiuntivo che indica i tipi effettivi passati alla funzione. (Questo è difficile e potenzialmente soggetto a errori a causa del numero assoluto di operazioni di formattazione da modificare - ma se la funzione di controllo è di per sé valida, funziona bene.)
  2. Stabilisci il percorso diretto a PQRHOME e convalidalo per motivi di sicurezza (dettagli sotto), rifiutando di avviarlo se non è sicuro, e successivamente usando il percorso diretto e non il valore di $ PQRHOME (quando differiscono). (Ciò richiede tutte le operazioni sui file che utilizzano $ PQRHOME per utilizzare non il valore di getenv () ma il percorso mappato. Ad esempio, ciò richiederebbe il
È stato utile?

Soluzione

L'opzione 2 funziona se si scrive un nuovo valore per $ PQRHOME dopo aver risolto il suo percorso reale e averne verificato la sicurezza. In questo modo molto poco del codice deve essere modificato in seguito.

Per quanto riguarda il mantenimento dei privilegi setuid, sarebbe utile se si potesse fare una sorta di separazione dei privilegi, in modo che tutte le operazioni che comportano l'input dell'utente reale vengano eseguite con il vero uid. Il processo privilegiato e il processo real-uid quindi parlano usando un socketpair o qualcosa del genere.

Altri suggerimenti

Beh, sembra paranoico, ma se dipende o meno da quale sistema / i è in esecuzione l'applicazione e da quali danni può subire un attaccante.

Quindi, se la tua base di utenti è probabilmente ostile e se il danno è forse molto elevato, sceglierei l'opzione 4, ma modificata come segue per rimuovere i suoi svantaggi.

Vorrei citare due cose rilevanti:

1)

  

I programmi attualmente controllano che $ PQRHOME e le directory chiave   sotto di esso sono "sicuri" (di proprietà di pqrusr,   appartiene a pqrgrp, non ha pubblico   accesso in scrittura).

2)

  

Successivamente, i programmi accedono ai file in $ PQRHOME per intero   valore della variabile d'ambiente.

Non è necessario codificare effettivamente l'intero percorso, è possibile codificare solo il percorso relativo dal "programma" hai citato in 1) il percorso menzionato in 2) dove si trovano i file.

Problema da controllare:

a) devi essere sicuro che non ci sia nulla " accessibile agli aggressori " (ad es. in termini di collegamenti simbolici) tra il percorso dell'eseguibile e il percorso dei file

b) devi essere sicuro che l'eseguibile controlla il proprio percorso in modo affidabile, ma questo non dovrebbe essere un problema in tutti gli Unix che conosco (ma non li conosco tutti e non li faccio) non conosco affatto le finestre).


MODIFICATO dopo il 3 ° commento:

Se il tuo sistema operativo supporta / proc, syslink / proc / $ {pid} / exe è il modo migliore per risolvere b)


EDITED dopo aver dormito su di esso:

L'installazione è un "sicuro"? processi? In tal caso, è possibile creare (al momento dell'installazione) uno script wrapper. Questo script dovrebbe essere eseguibile ma non scrivibile (e forse neppure leggibile). Impostare $ PQRHOME env var su "sicuro" valore e quindi chiama il tuo programma reale (potrebbe eventualmente fare anche altre cose utili). Poiché in UNIX le variabili di ambiente di un processo in esecuzione non possono essere modificate da nient'altro che il processo di esecuzione, si è sicuri (ovviamente le variabili di ambiente possono essere modificate dal genitore prima il processo ha inizio). Non so se questo approccio funzioni in Windows, tuttavia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top