BocaDePez ✎
1
⋮
Con la intención de aportar una utilidad para el foro, publico un fuente en C que permite arrancar un tcpdump
en el router de referencia y recoger los paquetes seleccionados en un fichero en local.
El fuente es para compilar y ejecutar bajo GNU/Linux. Necesita como requisitos los paquetes ssh-cliente
y sshpass
.
El programa (no trata de ser un exploit) se aprovecha de la vulnerabilidad CVE-2017-16523 de este router que no está fijada completamente para el último firmware "ES_s00.00_g001_100VNJ0b38_2" de Movistar. La contestación de Telefónica al que notificó el problema está en este enlace.
/***---------------------------------------------------------------***/
/* Software: HGUAudit.c */
/* Estado: Version 0 Release 0 Modif. 1 */
/* Copyright (C) 2018 bandaancha.eu */
/* */
/* Funcion: Auditoria de Accesos (TCPDUMP) del Router HGU */
/* Modificado: 15 Agosto 2016 - v001 Inicio */
/* */
/* Utilizacion: HGUAudit <Password del Router> [<parametros TCPDUMP<]*/
/* */
/* Descripcion: Llama al comando TCPDUMP del router HGU */
/* */
/* Observaciones */
/* This program is free software:you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License as */
/* published by the Free Software Foundation,either version 2 of the */
/* License,or any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program.If not, see <http://www.gnu.org/licenses/>*/
/* */
/* Este programa es Software Libre; Usted puede redistribuirlo y/o */
/* modificarlo bajo los terminos de la GNU Licencia Publica General */
/* (GPL) tal y como ha sido publicada por la Free Software Foundation*/
/* o bien la version 2 de la Licencia, o cualquier version posterior.*/
/* */
/* Este programa se distribuye con la esperanza de que sea util, */
/* pero SIN NINGUNA GARANTIA; tampoco las implicitas garantias de */
/* MERCANTILIDAD o ADECUACION A UN PROPOSITO PARTICULAR. */
/* Consulte la GNU General Public License (GPL) para mas detalles. */
/* Usted debe recibir una copia de la GNU General Public License(GPL)*/
/* junto con este programa; si no,lea <http://www.gnu.org/licenses/> */
/* */
/* Compilacion: */
/* Linux x86_64 gcc -m64 HGUAudit.c -o HGUAudit -lrt */
/* */
/***---------------------------------------------------------------***/
/***---------------------------------------------------------------***/
/*Includes */
/***---------------------------------------------------------------***/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <sys/fcntl.h>
#include <sys/un.h>
#include <syslog.h>
#include <dirent.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <mqueue.h>
/***---------------------------------------------------------------***/
/*Defines*/
/***---------------------------------------------------------------***/
#define version "v001"
#define PGMID "HGUAudit"
#define MAXDATASIZE 131072
#define MSGQOBJIN_NAME "/HGUAuditIN"
#define MSGQOBJOU_NAME "/HGUAuditOU"
#define Q_MAX_MSG_LEN 8192
/***---------------------------------------------------------------***/
/*Funciones*/
/***---------------------------------------------------------------***/
int CreateQ(void);
void DeleteQ(void);
void ReceiveQ(void);
void SendQ(char *);
void TerminarJOB(void);
void TerminarPID(void);
void EscribeSYSOUT(void);
void GrabaHora(void);
/***---------------------------------------------------------------***/
/***Variables Globales---------------------------------------------***/
/***---------------------------------------------------------------***/
FILE *fplynx=0;
FILE *fpsale=0;
FILE *fpsalt=0;
char FPLYNX[255]="\x0";
char FPSALE[255]="\x0";
char FPSALT[255]="\x0";
int i=0,j=0,k=0,z=0;
char pagina[MAXDATASIZE]="\x0";
char str[MAXDATASIZE]="\x0";
char LynxCMD[MAXDATASIZE]="\x0";
int num=0;
int RCI=0;
int trace=0;
char CMD[255]="";
int index1=0;
char *string1 = (char *)": ";
char *arpini=0;
char SYSOUT[Q_MAX_MSG_LEN]="\x0";
pid_t process_id;
char *HomePath=0;
char DBPath[255]="\x0";
DIR *dir=0;
int ContaPac=0;
int ContaW=0;
/*Estructuras de tiempo*/
time_t lt,tini,tfin; /*Sin uso*/
struct tms bt1,bt2,bt3,bt4,bt5,bt6; /*Otras*/
clock_t t1,t2,t3,t4,t5,t6; /*Otras*/
int TPS=0; /*Ciclos de cpu*/
struct timeval tvt;
struct tm *tmt;
/*MessagesQ*/
mqd_t IPCQueueIN;
mqd_t IPCQueueOU;
/***---------------------------------------------------------------***/
/***Main-----------------------------------------------------------***/
/***---------------------------------------------------------------***/
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("Uso:%s <Password del Router> [<opciones TCPDUMP>]\n",
argv[0]);
return(0);
}
sprintf(LynxCMD,"sshpass -p %s ssh 1234@192.168.1.1 tcpdump ",
argv[1]);
for (i=2;i<argc;i++)
{
strncat(LynxCMD,argv[i],(int)strlen(argv[i]));
strcat(LynxCMD," ");
}
process_id = getpid();
TPS = sysconf(_SC_CLK_TCK); /*obtengo los ciclos de cpu*/
t1 = times(&bt1); /*Tomar tiempos de inicio de ejec*/
/***---------------------------------------------------------------***/
/*Verifico PATH escritura fichero de salida o lo creo en el home */
/***---------------------------------------------------------------***/
HomePath = getenv("HOME");
sprintf(DBPath,"%s/.%s",HomePath,PGMID);
dir = opendir((char *)DBPath);
if ( dir == NULL)
{
RCI =mkdir(DBPath, 0750);
if (RCI != 0)
{
sprintf(SYSOUT,"Generar directorio %.255s Error %i %s",
DBPath,errno,strerror(errno));
EscribeSYSOUT();
TerminarJOB();
return 16;
}
}
else
{
closedir(dir);
}
/***---------------------------------------------------------------***/
/***Creo las COLAS IPC para enviar comandos al PGM */
/***---------------------------------------------------------------***/
RCI=CreateQ();
if (RCI != 0) {return RCI;}
/***---------------------------------------------------------------***/
/***Genero Fichero de Salida con los datos interceptados */
/***---------------------------------------------------------------***/
char Fichero[255]="\x0";
sprintf(Fichero,"%s/audit.txt",DBPath);
if ((fpsale=fopen(Fichero, "a+")) == NULL)
{
sprintf(SYSOUT,"No he podido Abrir %s Error:%i %s",
Fichero,errno,strerror(errno));
EscribeSYSOUT();
TerminarJOB();
return 12;
}
else
{
if ((fplynx = popen(LynxCMD,"r")) == NULL)
{
sprintf(SYSOUT,"No he podido Conectar Error:%i %s",
errno,strerror(errno));
EscribeSYSOUT();
TerminarJOB();
return 12;
}
else
{
/***---------------------------------------------------------------***/
/***Obtener el PID del POPEN para matarlo previo al cierre de PGM */
/***---------------------------------------------------------------***/
char scmd[255]="\x0";
sprintf(scmd,"ps -o pid,ppid,command -ax | grep sshpass | grep %i",
process_id);
if ((fpsalt = popen(scmd,"r")) == NULL)
{
sprintf(SYSOUT,"Sin determinar Pid Error:%i %s",
errno,strerror(errno));
EscribeSYSOUT();
TerminarJOB();
return 12;
}
else
{
RCI=1;
while (fgets(pagina, sizeof(pagina), fpsalt) != NULL )
{
if (strstr(pagina,"tcpdump") != NULL)
{
char id[6]="\x0";
memcpy(id,pagina,5);
process_id = (int)atoi(id);
sprintf(SYSOUT,"Proceso %i CMD=%s",
process_id,LynxCMD);
EscribeSYSOUT();
RCI=0;
break;
}
}
pclose(fpsalt);
}
if (RCI != 0)
{
sprintf(SYSOUT,"Sin determinar Pid Error:%i %s",
errno,strerror(errno));
EscribeSYSOUT();
TerminarJOB();
return 8;
}
/***---------------------------------------------------------------***/
/***Bucle de Lectura/Escritura de paquetes interceptados */
/***---------------------------------------------------------------***/
while (fgets(pagina, sizeof(pagina), fplynx) != NULL )
{
ContaPac++;
if (ContaPac > 999999)
{
GrabaHora();
ContaPac=0;ContaW=0;
}
if (strstr(pagina," IP ") != NULL)
{
index1=0; memset(str,'\x0',(int)sizeof(str));
arpini = strstr(pagina,string1);
index1 = pagina - arpini;
if (index1 < 0) {index1 = -index1;}
memcpy(str,pagina, index1);
gettimeofday(&tvt, NULL);
tmt = localtime(&tvt.tv_sec);
fprintf(fpsale, "%04d-%02d-%02d %s\n",
tmt->tm_year+1900,
tmt->tm_mon+1,
tmt->tm_mday,
str);
ContaW++;
}
memset(pagina,'\x0',(int)sizeof(pagina));
ReceiveQ();
if (RCI != 0) {TerminarPID();}
}
}
}
TerminarJOB();
return 0;
}
/***-----------------------------------------------------------------*/
/***---------------------------------------------------------------***/
/***Terminar JOB ***/
/***---------------------------------------------------------------***/
void TerminarJOB(void)
{
DeleteQ();
if (fpsale != 0) {fclose(fpsale);}
GrabaHora();
return;
}
/***---------------------------------------------------------------***/
/***Terminar PID ***/
/***---------------------------------------------------------------***/
void TerminarPID(void)
{
char cmd[15]="\x0";
sprintf(cmd,"kill -9 %i",process_id);
system(cmd);
if (fplynx != 0) {pclose(fplynx);}
return;
}
/***---------------------------------------------------------------***/
/***Envio de Mensajes IPC OU ***/
/***---------------------------------------------------------------***/
void SendQ( char * MsjOU)
{
char msgcontent[Q_MAX_MSG_LEN]="\x0";
int msgsz=0;
unsigned int msgprio = 0;
memcpy(msgcontent,(char *)MsjOU,(int)strlen(MsjOU));
msgsz = mq_send(IPCQueueOU, msgcontent, strlen(msgcontent)+1,msgprio);
if (msgsz != 0)
{
sprintf(SYSOUT,"SendQ_mq_sendOU Error %s %i %s",
MSGQOBJOU_NAME,errno,strerror(errno));
EscribeSYSOUT();
}
return;
}
/***---------------------------------------------------------------***/
/***Recepcion de Mensajes IPC IN ***/
/***---------------------------------------------------------------***/
void ReceiveQ(void)
{
char msgcontent[Q_MAX_MSG_LEN]="\x0";
int msgsz=0;
unsigned int sender;
struct timespec tmWait;
int Conta=0;
int Conta2=0;
char id2[32]="\x0";
int RCsql=0;
int rcc=0;
tmWait.tv_sec = 0;
msgsz=mq_timedreceive(IPCQueueIN,msgcontent,Q_MAX_MSG_LEN,&sender,
&tmWait);
if (msgsz > 0)
{
sprintf(SYSOUT,"En progreso %s...",msgcontent);
SendQ((char *)SYSOUT);
memset(SYSOUT,'\x0',(int)sizeof(SYSOUT));
/*Terminar*/
if (memcmp(msgcontent,"Terminar",8) == 0)
{
sprintf(SYSOUT,"Solicitado Terminar");
EscribeSYSOUT();
RCI=1;
}
/*Estado*/
else if (memcmp(msgcontent,"Estado",6) == 0)
{
GrabaHora();
}
/*No Reconocido Presenta la Ayuda*/
else
{
sprintf(SYSOUT,"Comando no reconocido (Terminar,Estado)");
SendQ((char *)SYSOUT);
memset(SYSOUT,'\x0',(int)sizeof(SYSOUT));
}
sprintf(SYSOUT,"Ejecutado %s",msgcontent);
SendQ((char *)SYSOUT);
memset(SYSOUT,'\x0',(int)sizeof(SYSOUT));
}
return;
}
/***---------------------------------------------------------------***/
/***Eliminar Cola de Mensajes IPC ***/
/***---------------------------------------------------------------***/
void DeleteQ(void)
{
mq_unlink(MSGQOBJIN_NAME);
mq_unlink(MSGQOBJOU_NAME);
return;
}
/***---------------------------------------------------------------***/
/***Generar Cola de Mensajes IPC ***/
/***---------------------------------------------------------------***/
int CreateQ(void)
{
struct mq_attr q_attrs;
DeleteQ();
q_attrs.mq_maxmsg = 10;
q_attrs.mq_msgsize = Q_MAX_MSG_LEN;
IPCQueueIN=mq_open(MSGQOBJIN_NAME,
O_RDONLY | O_CREAT | O_EXCL, // | O_NONBLOCK,
S_IRWXU | S_IRWXG,
&q_attrs);
if (IPCQueueIN == (mqd_t)-1)
{
sprintf(SYSOUT,"CreateQ_mq_openIN Error %s %i %s",
MSGQOBJIN_NAME,errno,strerror(errno));
EscribeSYSOUT();
return 1;
}
IPCQueueOU=mq_open(MSGQOBJOU_NAME,
O_WRONLY | O_CREAT | O_EXCL, // | O_NONBLOCK,
S_IRWXU | S_IRWXG,
&q_attrs);
if (IPCQueueOU == (mqd_t)-1)
{
sprintf(SYSOUT,"CreateQ_mq_openOU Error %s %i %s",
MSGQOBJOU_NAME,errno,strerror(errno));
EscribeSYSOUT();
return 2;
}
return 0;
}
/***--------------------------------------------------------------***/
/***Funcion GrabaHora Estadisticas de T.CPU T.Elapsed ***/
/***--------------------------------------------------------------***/
void GrabaHora()
{
t2 = times(&bt2);
sprintf(SYSOUT,
"Version %s Paquetes Leidos/Escritos %06i %06i \
T.CPU:%.2f Seg \
T.Ejec.:%.2f horas",\
version,ContaPac,ContaW,
(float)(bt2.tms_utime - bt1.tms_utime)/(float)TPS,\
((float)(t2 - t1)/(float)TPS)/3600);
EscribeSYSOUT();
return;
}
/***--------------------------------------------------------------***/
/***EscribeSYSOUT ***/
/***--------------------------------------------------------------***/
void EscribeSYSOUT()
{
struct timeval tvx;
struct tm *tmx;
gettimeofday(&tvx, NULL);
tmx = localtime(&tvx.tv_sec);
printf("%04d-%02d-%02d %02d:%02d:%02d.%06ld %s\n",
tmx->tm_year+1900,
tmx->tm_mon+1,
tmx->tm_mday,
tmx->tm_hour,
tmx->tm_min,
tmx->tm_sec,
tvx.tv_usec,
SYSOUT);
memset(SYSOUT,'\x0',(int)sizeof(SYSOUT));
return;
}
/***---------------------------------------------------------------***/
Dejo también un segundo fuente que permite terminar de forma ordenada e ir sacando estadísticas del programa de auditoría.
/*********************************************************************/
/* Software: HGUcmd.c */
/* Estado: Version 0 Release 0 Modif. 1 */
/* Copyright (C) 2018 bandaancha.eu */
/* */
/* Funcion: Envio de Comandos al pgm HGUAudit */
/* Utilizacion: HGUcmd <Comando> */
/* Modificado: 15 Agosto 2018 - v0001 Inicio */
/* */
/* Observaciones */
/* This program is free software:you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License as */
/* published by the Free Software Foundation,either version 2 of the */
/* License,or any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* You should have received a copy of the GNU General Public License */
/* along with this program.If not, see <http://www.gnu.org/licenses/>*/
/* */
/* Este programa es Software Libre; Usted puede redistribuirlo y/o */
/* modificarlo bajo los terminos de la GNU Licencia Publica General */
/* (GPL) tal y como ha sido publicada por la Free Software Foundation*/
/* o bien la version 2 de la Licencia, o cualquier version posterior.*/
/* */
/* Este programa se distribuye con la esperanza de que sea util, */
/* pero SIN NINGUNA GARANTIA; tampoco las implicitas garantias de */
/* MERCANTILIDAD o ADECUACION A UN PROPOSITO PARTICULAR. */
/* Consulte la GNU General Public License (GPL) para mas detalles. */
/* Usted debe recibir una copia de la GNU General Public License(GPL)*/
/* junto con este programa; si no,lea <http://www.gnu.org/licenses/> */
/* */
/* Compilacion: */
/* Linux x64 */
/* gcc -m64 HGUcmd.c -o HGUcmd -lrt */
/* */
/*********************************************************************/
#include <stdio.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
#include <string.h>
#include <errno.h>
#define MSGQOBJ_NAMEIN "/HGUAuditIN"
#define MSGQOBJ_NAMEOU "/HGUAuditOU"
#define MAX_MSG_LEN 8192
/**/
void EnviaQ(char *);
/**/
mqd_t msgq_id;
unsigned int msgprio = 0;
char msgcontent[MAX_MSG_LEN];
int msgsz=0;
int i=0; int j=0;
unsigned int sender;
struct timespec tmWait;
struct timeval tvt;
struct tm *tmt;
char cmd[80]="\x0";
/***---------------------------------------------------------------***/
/***Funcion Main */
/***---------------------------------------------------------------***/
int main(int argc, char **argv)
{
for (i=1;i<argc;i++)
{
j=j+(int)strlen(argv[i])+1;
if (j< (int)sizeof(cmd))
{
strncat(cmd,argv[i],(int)strlen(argv[i]));
strcat(cmd," ");
}
}
EnviaQ((char *)cmd);
return 0;
}
/***---------------------------------------------------------------***/
/***Envia el comando tomado de la parm */
/***---------------------------------------------------------------***/
void EnviaQ(char *Comando)
{
if (Comando == NULL)
{
printf("Comando:");
scanf("%78s",msgcontent);
}
else
{
memcpy(msgcontent,Comando,(int)strlen(Comando));
}
msgq_id = mq_open(MSGQOBJ_NAMEIN, O_RDWR);
if (msgq_id == (mqd_t)-1)
{
perror("In mq_openIN()");
exit(1);
}
mq_send(msgq_id, msgcontent, strlen(msgcontent)+1, msgprio);
mq_close(msgq_id);
msgq_id = mq_open(MSGQOBJ_NAMEOU, O_RDWR);
if (msgq_id == (mqd_t)-1)
{
perror("In mq_openOU()");
exit(1);
}
memset(msgcontent,'\x0',(int)sizeof(msgcontent));
clock_gettime(CLOCK_REALTIME, &tmWait);
tmWait.tv_sec += 30;
msgsz=mq_timedreceive(msgq_id,msgcontent,MAX_MSG_LEN,&sender,
&tmWait);
if (msgsz > 0)
{
while (msgsz > 0)
{
gettimeofday(&tvt, NULL);
tmt = localtime(&tvt.tv_sec);
printf("%04d-%02d-%02d %02d:%02d:%02d.%06ld %s \n",
tmt->tm_year+1900,
tmt->tm_mon+1,
tmt->tm_mday,
tmt->tm_hour,
tmt->tm_min,
tmt->tm_sec,
tvt.tv_usec,
//msgsz,Len:%i
msgcontent
);
if (strstr(msgcontent,"Ejecutado") != NULL) {break;}
msgsz=0;
msgsz=mq_timedreceive(msgq_id,msgcontent,MAX_MSG_LEN,&sender,
&tmWait);
}
}
else
{
printf("msg:%d:%i %s\n",msgsz,errno, strerror(errno));
}
mq_close(msgq_id);
return ;
}