Password sbagliata? Sudo ti insulta

sudo_0

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

Fonte e script