Password sbagliata? Sudo ti insulta
In questo tutorial mostrerò come attivare una funzionalità molto interessante e vitale di sudo
(Super User DO), far si che offenda senza ritegno l'utente quando questo sbaglia la password di accesso.
Lo so è una funzionalità importante e non potevate vivere senza, ecco un esempio che farà ricredere ogni scettico di questo mondo:
fabrizio@raspberrypi:~ $ sudo ls
[sudo] password di fabrizio:
Tanto morirete tutti!
Attiviamo l'easter egg
Attivare la funzionalità è semplice, lanciamo con gioia il comando:
sudo visudo
e aggiungiamo dopo i commenti (#) l'istruzione (attenzione trattasi di un file delicato non toccate altro):
Defaults insults
Da questo momento in poi verremo insultati ad ogni errore nell'inserimento della password.
In inglese?
Lo so per un utente italiano la cosa non è molto divertente, soprattutto perché trattasi principalmente di citazioni e/o giochi di parole spesso intraducibili, come possiamo ovviare? Al terzo Have you considered trying to match wits with a rutabaga? mi sono chiesto, quale rutabaga di file devo modificare per tradurre le frasi e/o aggiungerne di nuove?. Controllando in rete ho scoperto che stranamente farlo è molto difficile (e anche piuttosto rischioso). Praticamente le frasi sono inserite direttamente in un file .h dei sorgenti di sudo il che ci porta o a dover modificare il file e ricompilare tutto o (come faremo noi grazie ad uno script che ho trovato e leggermente modificato) ad andare a sostituire le frasi direttamente nel file .so di sudo (un .so è un .h compilato). Qualcuno potrebbe dire che non ne vale la pena ma siamo nerd quindi sì.
Avvertenza importantissima: tutto quello che è riportato da qui in poi può compromettre il corretto funzionamento del sistema. Non ci assumiamo nessuna responsabilità relativa ad eventuali danni
1) Backup del file originale
Dobbiamo modificare (in termine tecnico si dice smailare) il file /usr/bin/sudo/sudoers.so
quindi è cosa buona e giusta prima copiarlo sulla nostra cartella home, nel mio caso:
sudo cp /usr/bin/sudo/sudoers.so /home/fabrizio
Stranamente l'operazione ha cambiato il proprietario del mio file di backup (mandando tutto a ... quando ho provato a ripristinare) quindi riportiamolo all'originale:
sudo chown root:root /home/fabrizio/sudoers.so
Ok abbiamo un backup, possiamo passare al punto 2.
2) Riattiviamo l'utente root
Ci sono ottime probabilità che in caso di problemi sudo smetta di funzionare e quindi, visto che in molte distribuzioni l'utente root è disabilitato (senza password), rischiamo di non poter rimettere le cose a posto. Per ovviare possiamo riattivare l'utente root assegnandoli una password:
sudo passwd root
Adesso possiamo accedere da un terminale con l'utente root e la nuova password o possiamo usare il semplice comando su
. Se tutto va per il verso giusto non dovremmo averne bisogno.
3) Recuperiamo le stringhe dal file .so
Un file .so è la controparte Unix di quello che Windows chiama dll. Per rendere il nostro tutorial utile a qualcosa faremo la conoscienza del comando strings che, come ci informa lui stesso aggiungendo il solito argomento --help, è in grado di estrapolare stringhe da file prettamente binari. Essendo la libreria un file binario usando cat nomefile
riceviamo quello che in gergo informatico è definibile con bestemmine (caratteri quasi satanici e un output praticamente illeggible). Per recuperare le stringhe che ci servono ci basta invece il comando:
strings /usr/lib/sudo/sudoers.so
Adesso abbiamo un output leggibile (senza bestemmine) ma troppo lungo, usiamo quindi:
strings /usr/lib/sudo/sudoers.so | less
Less ci permette di scorrere (tasto invio) un output lungo (si esce con q). Scorrendo vediamo cose serie ma arrivando ad un certo punto spunta: Just what do you think you're doing Dave?(citazione da 2001 odissea nello spazio), ci siamo da li in poi abbiamo tutte le frasi di insulto di sudo, ce ne sono veramente tante. Creiamo un file di testo dove copiamo una ad una le frasi, dopo ogni frase andiamo a capo e lasciamo una riga vuota per la frase che dovrà sostituirla. Ecco un piccolo estratto del mio esempio:
You can't come in. Our tiger has got flu
E che cavolo stii piu' attento fantocci.
Speak English you fool --- there are no subtitles in this scene.
Piano, piano, che poi sudi, ti raffreddi, ti ammali e poi MUORI!
And you call yourself a Rocket Scientist!
Quindi tu saresti un bravo informatico?
Take a stress pill and think things over.
Ricordati che il viagra non ti fa bene.
Your mother was a hamster and your father smelt of elderberries!
Ho appuntamento con tua madre per una notte di sesso selvaggio.
Importante: Dovendo andare a sporcare un file serio ogni frase non può essere più lunga della precedente. Non crea problemi al funzionamento di sudo ma sconsiglio l'uso di caratteri accentati.
Salviamo il file come sudoinsult.txt
E ora facciamo scoppiare tutto
Siamo pronti abbiamo il file di sostituzione (per 5 frasi) ecco quindi lo script leggermente rimaneggiato (principalmente tradotto) reperito in rete:
#!/bin/bash
# NOTE: Sostituisce gli insulti di default di SUDO con dei personalizzati
# Nel file sudoinsult.txt dobbiamo riportare a coppia originale/sostituto
# Metto in un array il contenuto del file
IFS=$'\n' Arr=( $(cat sudoinsult.txt) )
# Inizializzo le variabili
File="/usr/lib/sudo/sudoers.so"
upper=0
Spaces=" "
Spaces="$Spaces"" "
[[ ${#Arr[@]} -gt 0 ]] && upper=$(( ${#Arr[@]} - 1 ))
[[ $upper -gt 0 ]] && for (( i=0; i<upper; i=i+2 )) ; do
Search="${Arr[i]}" # Muovo la riga del file in una variabile
Replace="${Arr[i+1]}" # e quella successiva
printf "Sostituisco: '%s'\n con: '%s'\n" "$Search" "$Replace"
if [[ "${#Search}" -lt "${#Replace}" ]] ; then
echo "Il sostituto non può essere più lungo dell'originale"
continue
elif [[ "${#Search}" -lt 8 ]] ; then
echo "L'originale non può avere meno di 8 caratteri"
continue
elif [[ "${#Search}" -gt "${#Spaces}" ]] ; then
echo "L'originale non può avere più di ${#Spaces} caratteri"
continue
elif [[ "${#Replace}" -lt 1 ]] ; then
echo "Il sostituto non può avere meno di un carattere"
continue
elif ! grep "$Search" "$File" >/dev/null ; then
echo "Originale non trovato $File"
continue
fi
#Aggiungo al sostituto gli spazi necessario
ReplaceS="$Replace${Spaces:0:$((${#Search} - ${#Replace}))}"
[[ "${#ReplaceS}" -ne "${#Search}" ]] && \
{ echo Internal error ReplaceS different length than Search; exit; }
# Looks wrong: https://unix.stackexchange.com/a/354493/200094
#y="${y:0:40}${forty:0:$((40 - ${#y}))}"
#echo "'${y}'"
sed -i "s/$Search/$ReplaceS/" "$File"
(( InsultCount++ ))
done
if [[ $upper -gt 0 ]] ; then
echo "$InsultCount insulti sostituiti."
else
echo "Il file (sudoinsult.txt) non esiste o è vuoto." >2
fi
Il nostro script scorre il file, accoppia due a due le frasi e se idonee le sostituisce aggiungendo gli spazi necessari. La procedura è abbastanza controllata e non gestisce la stringa in questi casi:
- frase originale non trovata: probabilmente non avete copiato tutto (ce ne sono un paio su due righe quello non sono riuscito a gestirle)
- frase sostitutiva più lunga dell'originale (se lo facesse porterebbe all'esplosione totale)
- frase sostitutiva mancante
- frase di originale troppo lunga
Salviamo lo script nella stessa cartella che contiene il file .txt (io ho usato il nome sudoinsults.sh) e diamo i permessi di esecuzione.
Adesso possiamo lanciarlo con permessi di root (modifichiamo sudo usando sudo bello):
sudo ./sudoinsults.sh
Se non ci sono errori il nostro script ha modificato le frasi all'interno della libreria senza toccare altro.
Facciamo una prova:
sudo ls
Se non escono errori tutto è andato per il verso giusto, sbagliamo appositamente la password e riceveremo:
fabrizio@raspberrypi:~ $ sudo ls
[sudo] password di fabrizio:
Quindi tu saresti un bravo informatico?
Ovviamente le frasi sono random quindi per ricevere una delle nostre potrebbe volerci un po'.
Se qualcosa esplode?
In questo caso sudo non sarà in grado di funzionare e quindi dovremmo loggarci usando su (e la password che abbiamo impostato) e rimettere a posto il nostro file di backup:
su
cp /home/fabrizio/sudoers.so /usr/lib/sudo
Nota: anche se volessimo riportare il file originale senza errori dovremmo seguire questa procedura, in quanto il nostro amico sudo dovendo scrivere su un file che deve leggere restituirebbe un segmentation fault al comando
sudo cp /home/fabrizio/sudoers.so /usr/lib/sudo
Adesso tutto è tornato a posto, il nostro sudo funziona di nuovo.
Metodo alternativo
Se usiamo una distribuzione Debian o derivata (Ubuntu, LinuxMint, Raspberry Pi OS, ecc.) possiamo semplicemente reinstallare il pacchetto sudo:
su
apt reinstall sudo
Disabilitare di nuovo l'utente root
Quando ci sentiamo sicuri possiamo riportare l'utente root nel suo limbo di pace e tranquillità utilizzando il comando:
sudo passwd -l root