Banda Ancha EU

Comunidad de usuarios
de fibra, móvil y ADSL

Fibra

Auditoria para router HGU MitraStar de Movistar

BocaDePez
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 impli­citas 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 impli­citas 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 ;
}
👁 1K4