Verificar se os logs foram corrompidos
Este artigo, incluindo o programa, deve ser uma das ferramentas que um cuidadoso administrador de sistema, deve ter sempre a' mao!
O que me levou a fazer este programa, foi, o facto de ser extremamente dificil arranjar um, que me fizesse especificamente o que desejava, pois o que
mais parecido encontrei foram os conhecidos utmp editors, mas porem esses apenas nos oferecem um interface visual para o conteudo do utmp,
ficando o trabalho da deteccao de irregularidades ao cuidado do utilizador, depois ate' porque nenhum deles testava a integridade de um outro ficheiro, o
wtmp, e o mais importante neste aspecto, o lastlog!!
Se nao sabem o que sao estas palavroes, que nao se conseguem pronunciar, pois tem mais consoantes, do que vogais,...podem passar a frente, pois
nao vamos aqui explicar isso!! So' um esclarecimento muito breve, o utmp e' um ficheiro onde se encontra informacao acerca de quem se encontra a
utilizar o sistema currentemente, o wtmp da-nos informacao acerca do logins e logouts do sistema, e o lastlog, conforme o nome indica esta
relacionado com o ultimo logged on de cada user. Para mais informacao consultem por exemplo, as paginas do manual de Linux.
Pois bem, o programa que exponho aqui (link para logs.c) e' nada mais nada menos do que uma ferramenta que testa e procura irregularidades nos
ficheiros de logs (nao soa bem mas,...), como o utmp e o wtmp, inci- dindo mais sobre o utmp e o lastlog, pois sao os ficheiros que nos podem dar
mais informacao acerca dos infractores do sistema!:))))
Para quem ja "teve em sua poder" uma maquina que nao lhe pertencia, (porreiro eufemismo para hackada!:)))), sabe que uma das preocupacoes, se
nao a principal, e estar constantemente a limpar os logs!!!
Para isso que existem pequenos (mas inteligentes) programas cuja funcao e alterar o conteudo dos ficheiros de log do sistema. Talvez o mais
conhecido seja o famoso Zap! Vamos entao estudar um pouco como e' que estes programas funcionam (vamos usar como exemplo o Zap!, pois muito
provavelmente e' o responsavel pela corrupcao da maioria dos ficheiros de logs dos servers hackados pelo mundo fora!!):
#zap elektro (elektro e' por exemplo um user que queremos "apagar", da vida da maquina)
ao fazermos um #w ou #lastlog podemos ver que tudo que se relacionava com o user elektro desapareceu!
Nada como dar uma olhadelha ao codigo do programa para perceber:
a struct definida em C, que guarda a informacao dos utilizadores e' a seguinte:
O que o Zap! se limita a fazer e' apenas ir "buscando" uma destas structs ao ficheiro (por enquanto referimo-nos ao utmp), e verifica se no campo
ut_user (ou ut_name), se encontra a string correspondente ao user a eliminar (neste caso a busca e' por user, mas pode ter ou- tros criteios, desde o
host, remote IP, device ("tty") etc...), E AGORA VEM O MAIS IMPORTANTE, quando encontra uma struct em cujo num dos campos (no caso do Zap! o
username), o apontador para o ficheiro e' recuado n=sizeof(struct utmp) bytes, e esse espaco e' preenchido (os n bytes), com zeros!! E' usada a
funcao bzero definida em
Agora que ja' sabemos como e' que funcionam os programas como o Zap! podemos entao pensar numa maneira, de o melhor que conseguirmos,
desco- brirmos se a nossa maquina, foi alvo de algum ataque, ou se anda algum utilizador a brincar aos roots, POIS E PRECISO SER ROOT para ter
permis- soes de escrita nos ficheiros de log!
E' precisamente, que o programa a que eu elegantemente :))) chamo Utmp & Wtmp & Lastlog Verificador, faz! Ele procura, se assim de pode chamar,
por porcoes do ficheiro que apresentem estas lacunas, na sua constituicao!
O que ele faz e' comparar todas as entradas do ficheiro com uma porcao de memoria, do mesmo tamanho das struct utmp, que se encontra com as
caracteristicas de uma porcao de ficheiro manipulado por programas como o Zap!, ou seja "cheia" de zeros! (a linguagem usada para explicar nao esta
a ser a mais feliz, mas penso que assim toda a gente entendera' e isso e' que importa!).
Devido a' propria maneira do Linux manter os logs, sabiam que se por exemplo usarmos o Zap! para apagar os nossos logs, e depois sairmos do
sistema, as lacunas do utmp, sao repostas,...o que permite que se ao corrermos o programa detectarmos intrusoes, faz-se um ps -aux, comparam-se
os processos correntes com os users "legais", e o(s) logins, que aparecam a mais no 'ps', correspondem (muito provavlemente) a users ilegais!!!!!! E
assim podemos apanha-los em flagrante.
O programa pode ser chamado da linha de comandos da seguinte maneira:
#a.out [-opcoes]
em que as opcoes sao:
Porem o recomendado e' utilizar o crontab para fazer verificacoes regulares, principalmente se for uma maquina constantemente ligada a' Net ou com
muitos utilizadores, e redireccionar o output do programa para um ficheiro para mais tarde analisar os resultados. Uma excelente ideia, ja' que a
imagem do administrador de sistemas moderno nao passa sem o telemo- vel e todos os operadores movel, ou quase todos, ja fornecem servicos de
sms, porque nao criar uma rotina que redireccione os resultados para o telemovel!!!
Agora a nivel de programacao o que o programa faz, e' ir guardando em memoria as entradas do utmp, usando listas ligadas (um pequeno melhora-
mento:))), e testando se existem entradas que tenham a "marca zap", se tal acontecer, imprime no ecra os utilizadores "legais", colocando '?', quando a
"marca zap" aparece.
A nivel do ficheiro wtmp a este nao e' dada particular atencao pois nao e' grande fornecedora de informacao relativa a quem esta' a abusar do sistema,
mas o programa indica quantas lacunas existem neste ficheiro e para mais ajuda indica a hora e se possivel o login da entrada anterior, para o root
poder minorar a hora do "trabalhinho"!
Agora, o que ainda nos pode trazer muita informacao, quando nao se apa- nha o peixe na rede, e' o ficheiro lastlog! Vamos ver como a informacao de
cada user e disposta neste ficheiro:
Ora, com isto o programa pode obter muita informacao, pois ao contrario do wtmp e do utmp a informacao nao e' disposta ao acaso! Logo
conseguimos descobrir que users tem a sua entrada apagada! Depois o que o programa faz e' verificar se um user que possui a sua entrada apagada,
possui entradas no ficheiro wtmp. Se tiver, e' obvio que andou obra do Zap!, se nao procura se existe o ficheiro .bash_history, na sua directoria, pois
assim, consegue distinguir +/- um user que apagou os seus logs, de um user que pura e sim- plesmente nunca fez log on!
E' obvio verificar, que este nao e' um programa milagroso, que caiu do ceu para resolver os problemas dos administradores de sistemas, pois ele ape-
nas automatiza funcoes muito dificeis e morosas para uma cabeca humana! Por- tanto continua a ser sempre necessario um bom olho observador e
um bom conhe- cimento dos seus users, para poder interpretar o resultado deste programa!
Eis o codigo do programa logs.c
-----------------------------------------------------
by Elektro
....
while(read (f, &utmp_ent, sizeof (utmp_ent))> 0 )
if (!strncmp(utmp_ent.ut_name,who,strlen(who))) {
bzero((char *)&utmp_ent,sizeof( utmp_ent ));
lseek (f, -(sizeof (utmp_ent)), SEEK_CUR);
write (f, &utmp_ent, sizeof (utmp_ent));
....
Vemos aqui como o programa apaga a informacao relativa ao user 'who' do ficheiro utmp.
struct utmp
{
short ut_type; /* type of login */
pid_t ut_pid; /* pid of login-process */
char ut_line[UT_LINESIZE];
char ut_id[4]; /* inittab id */
time_t ut_time; /* login time */
char ut_user[UT_NAMESIZE];/* username */
char ut_host[UT_HOSTSIZE];/* host */
long ut_addr; /* IP addr of remote host */
};
para mais informacoes relativas a' maneira como o Linux mantem a informacao dos users, faca "man utmp".
...
if ((f=open(LASTLOG_NAME, O_RDWR)) >= 0) {
lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0);
bzero((char *)&newll,sizeof( newll ));
write(f, (char *)&newll, sizeof( newll ));
close(f);
...
Ao contrario dos outros ficheiros de log como o utmp e o wtmp, em que a informacao, ou melhor as entradas, se dispunham sequencialmente, neste
ficheiro as coisas sao um pouco diferentes! Existe uma struct lastlog que e'
struct lastlog{
long ll_time;
char ll_line[XX];
char ll_host[XX];
}
Ora o primeiro byte desta struct de informacao, encontra-se no (uid * sizeof(struct lastlog)) byte do ficheiro, sendo uid, o user id de cada user! Por
exemplo, se quisermos aceder a' struct do user X, cujo uid e' 1000, basta posicionar o apontador para o ficheiro em 1000 * sizeof(struct lastlog), e basta
fazer um read, com os argumentos adequados, para acedermos a esta in- formacao!