357 lines
7.0 KiB
C
357 lines
7.0 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <utmp.h>
|
|
|
|
#define HOSTNAME "lalis"
|
|
|
|
//test if pid is in lsit of known sshd processus
|
|
int isinarray( int pid, int array[], int n )
|
|
{
|
|
//if (n == 0) return 0;
|
|
int x;
|
|
for(x=1;x<=n;x++)
|
|
{
|
|
if( pid == array[x])
|
|
{
|
|
return x;
|
|
}
|
|
} return 0;
|
|
}
|
|
|
|
//get utmp datas
|
|
void getutmp( int pid, char user[], char host_ip[], char host_ipv6[], time_t * time )
|
|
{
|
|
struct utmp * utmp;
|
|
int ipv6;
|
|
int ipv4;
|
|
int x;
|
|
char str[6];
|
|
|
|
setutent();
|
|
while ( (utmp = getutent()) != NULL )
|
|
{
|
|
if ( utmp->ut_pid == pid )
|
|
{
|
|
sprintf(user, "%s", utmp->ut_user); //got user login
|
|
sprintf(host_ip, "%s", utmp->ut_host); //got ip of origin
|
|
if((utmp->ut_addr_v6[1] && utmp->ut_addr_v6[2] && utmp->ut_addr_v6[3]) == 0)
|
|
{
|
|
ipv4 = utmp->ut_addr_v6[0] & 0x00000000000000ff;
|
|
sprintf( str, "%x.", ipv4);
|
|
strcat(host_ip, str);
|
|
ipv4 = (utmp->ut_addr_v6[0] & 0x000000000000ff00) >> 8;
|
|
sprintf( str, "%x.", ipv4);
|
|
strcat(host_ip, str);
|
|
ipv4 = (utmp->ut_addr_v6[0] & 0x0000000000ff0000) >> 16;
|
|
sprintf( str, "%x.", ipv4);
|
|
strcat(host_ip, str);
|
|
ipv4 = (utmp->ut_addr_v6[0] & 0x00000000ff000000) >> 24;
|
|
sprintf( str, "%x", ipv4);
|
|
strcat(host_ip, str);
|
|
|
|
}else
|
|
{
|
|
for (x=0;x<4;x++)
|
|
{
|
|
ipv6 = utmp->ut_addr_v6[x] & 0x000000000000ffff;
|
|
sprintf( str, "%x:", ipv6);
|
|
strcat(host_ipv6, str);
|
|
ipv6 = (utmp->ut_addr_v6[x] & 0x00000000ffff0000) >> 16;
|
|
sprintf( str, "%x:", ipv6);
|
|
strcat(host_ipv6, str);
|
|
ipv6 = (utmp->ut_addr_v6[x] & 0x0000ffff00000000) >> 32;
|
|
sprintf( str, "%x:", ipv6);
|
|
strcat(host_ipv6, str);
|
|
ipv6 = (utmp->ut_addr_v6[x] & 0xffff000000000000) >> 48;
|
|
sprintf( str, "%x:", ipv6);
|
|
strcat(host_ipv6, str);
|
|
}
|
|
host_ipv6[strlen(host_ipv6)-1] = '\0';
|
|
}
|
|
*time = (time_t) utmp->ut_tv.tv_sec; //got connexion time
|
|
break;
|
|
}
|
|
}
|
|
endutent();
|
|
}
|
|
|
|
//replace null characters by space
|
|
int null2space( char str[] )
|
|
{
|
|
int flag =0;
|
|
int x = 0;
|
|
|
|
while ( flag == 0 )
|
|
{
|
|
if ( (int) str[x] == 0 )
|
|
{
|
|
if ( (int) str[x+1] != 0 )
|
|
{
|
|
str[x] = ' ';
|
|
}else
|
|
{
|
|
flag = 1;
|
|
}
|
|
}
|
|
x++;
|
|
}
|
|
return x-1 ;
|
|
}
|
|
|
|
// get the childs pids
|
|
int getpids(int pid, int exploded[])
|
|
{
|
|
FILE *fh;
|
|
char * pch;
|
|
char path[1024];
|
|
char str[4096];
|
|
char separator[] = " ";
|
|
int x = 0;
|
|
|
|
sprintf( path, "/proc/%d/task/%d/children", pid,pid);
|
|
//printf(" %s", proc_path);
|
|
if ((fh = fopen( path, "r")) == NULL)
|
|
{
|
|
perror(path);
|
|
return -1;
|
|
}
|
|
if ( fgets( str, 40, fh ) != NULL )
|
|
{
|
|
pch = strtok( str, separator );
|
|
while( pch != NULL )
|
|
{
|
|
exploded[x++] = atoi( pch );
|
|
pch = strtok( NULL , separator );
|
|
}
|
|
fclose(fh);
|
|
return x;
|
|
}else
|
|
{
|
|
fclose(fh);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int getprocinfo( int ppid, char cmdline[], char cmd[], char user[], char host_ip[], char host_ipv6[], char date[] )
|
|
{
|
|
FILE *fh1;
|
|
char child_path[128];
|
|
char str[1024];
|
|
int child_pid[10];
|
|
int flag = 0;
|
|
int r;
|
|
int pid = ppid;
|
|
int level = 0;
|
|
int retval = 0;
|
|
time_t timet=0;
|
|
|
|
//get connexion time
|
|
getutmp( pid, user, host_ip, host_ipv6, &timet );
|
|
if ( timet == 0)
|
|
{
|
|
time( &timet );
|
|
}
|
|
sprintf( date, "%s", ctime(&timet) );
|
|
date[strlen(date)-1] = 0;
|
|
|
|
//get the pid of the last processus
|
|
while ( flag == 0)
|
|
{
|
|
r = getpids( pid, child_pid );
|
|
if( level == 0 && r == 2 )
|
|
{
|
|
flag = 1;
|
|
retval = -1;
|
|
}else if ( r != -1 )
|
|
{
|
|
level++;
|
|
pid = child_pid[0];
|
|
}else
|
|
{
|
|
flag = 1;
|
|
}
|
|
}
|
|
|
|
// get the command parameters
|
|
sprintf( child_path, "/proc/%d/cmdline", pid );
|
|
if ( (fh1= fopen( child_path, "r" )) == NULL)
|
|
{
|
|
perror(child_path);
|
|
return 2;
|
|
}
|
|
fgets( str, 1024, fh1);
|
|
flag = 0;
|
|
null2space( str );
|
|
sprintf(cmdline, "%s", str);
|
|
fclose(fh1);
|
|
// get the command name
|
|
sprintf( child_path, "/proc/%d/comm", pid );
|
|
if ( (fh1= fopen(child_path, "r" )) == NULL)
|
|
{
|
|
perror(child_path);
|
|
return 3;
|
|
}
|
|
fscanf( fh1, "%s", cmd );
|
|
fclose(fh1);
|
|
return retval;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
FILE *fh;
|
|
FILE *fh1;
|
|
int n_ssh=10;
|
|
int id;
|
|
int pid;
|
|
int x=0;
|
|
int y=0;
|
|
int r;
|
|
int i;
|
|
int j;
|
|
int n;
|
|
int start=1;
|
|
int childrens[n_ssh];
|
|
int pids[n_ssh];
|
|
int flag[n_ssh];
|
|
int rinfo;
|
|
int status;
|
|
// char path[1024];
|
|
char commande[] = "/usr/local/bin/send_sms";
|
|
char logfile[] = "/var/log/sshdetect.log";
|
|
char cmd[24];
|
|
char cmdline[1000];
|
|
char user[24]="";
|
|
char host_ip[42];
|
|
char host_ipv6[42];
|
|
char str[1024];
|
|
char date[60];
|
|
time_t now ;
|
|
time( &now );
|
|
sprintf( date, "%s", ctime(&now));
|
|
date[strlen(date)-1] = 0;
|
|
if ( (fh = fopen(logfile, "a")) == NULL)
|
|
{
|
|
perror(logfile);
|
|
return 1;
|
|
}
|
|
fprintf(fh, "%s: Démarrage de sshdetect\n", date);
|
|
fclose(fh);
|
|
sprintf( str, "%s \"%s - %s: Démarrage de sshdetect\"", commande, HOSTNAME, date );
|
|
id=fork();
|
|
if(id == 0)
|
|
{
|
|
r = system( str );
|
|
exit(r);
|
|
}else if( id<0 )
|
|
{
|
|
printf("erreur de création du fork: %s", str);
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
// get the sshd process ID (PID)
|
|
if ( (fh = fopen("/run/sshd.pid", "r" )) == NULL)
|
|
{
|
|
perror("/run/sshd.pid");
|
|
return 1;
|
|
}
|
|
if ( fscanf(fh, "%i", &pid) == 0)
|
|
{
|
|
printf("erreur fscanf: /run/sshd.pid" );
|
|
return 10;
|
|
}
|
|
fclose(fh);
|
|
//printf("%i", pid);
|
|
|
|
//get the list of children
|
|
if ( (n=getpids( pid, pids )) != -1)
|
|
{
|
|
for ( y=0; y<n; y++)
|
|
{
|
|
pid = pids[y];
|
|
r = isinarray(pid, childrens, x);
|
|
if( r == 0 )
|
|
{
|
|
user[0]='\0';
|
|
rinfo = getprocinfo( pid, cmdline, cmd, user, host_ip, host_ipv6, date );
|
|
if( rinfo == 0 )
|
|
{
|
|
x++;
|
|
childrens[x] = pid;
|
|
flag[x] = 1;
|
|
// date of connexion
|
|
|
|
if (user[0] == '\0')
|
|
{
|
|
sprintf( str, "%s \"%s: tunnel ouvert le %s depuis %s avec la commande: %s %s\"", commande, HOSTNAME, date, host_ip, cmd, cmdline );
|
|
}else
|
|
{
|
|
sprintf( str, "%s \"%s: %s s'est connecté le %s depuis %s avec la commande: %s %s\"", commande, HOSTNAME, user, date, host_ip, cmd, cmdline );
|
|
}
|
|
if ( start != 1 )
|
|
{
|
|
id=fork();
|
|
if(id>0)
|
|
{
|
|
if ( (fh1 = fopen(logfile, "a")) == NULL)
|
|
{
|
|
perror(logfile);
|
|
return 7;
|
|
}
|
|
fprintf(fh1, "%s: Connexion de %s depuis %s commande: %s %s", date, user, host_ip, cmd, cmdline);
|
|
fclose(fh1);
|
|
}else if (id<0)
|
|
{
|
|
printf("erreur de création du fork: %s", str);
|
|
}else
|
|
{
|
|
printf("%s\n", str);
|
|
r = system( str );
|
|
exit (r);
|
|
}
|
|
}else
|
|
{
|
|
if ( (fh1 = fopen(logfile, "a")) == NULL)
|
|
{
|
|
perror(logfile);
|
|
return 7;
|
|
}
|
|
fprintf(fh1, "%s: %s Connecté depuis %s - %s %s\n", date, user, host_ip, cmd, cmdline);
|
|
fclose(fh1);
|
|
}
|
|
}
|
|
}else
|
|
{
|
|
flag[r] = 1;
|
|
}
|
|
}
|
|
for(i=1;i<=x;i++)
|
|
{
|
|
if (flag[i] == 0 )
|
|
{
|
|
printf("Session %d terminée\n", childrens[i]);
|
|
for( j=i; j<x; j++ )
|
|
{
|
|
childrens[j] = childrens[j+1];
|
|
flag[j] = flag[j+1];
|
|
}
|
|
i--;
|
|
x--;
|
|
}else
|
|
{
|
|
flag[i] = 0;
|
|
}
|
|
}
|
|
sleep(2);
|
|
waitpid(-1, &status ,WNOHANG);
|
|
}
|
|
start = 0;
|
|
}
|
|
return 0;
|
|
}
|