(RESOLVIDO) Iniciando o Ettercap está me dando um erro

3

Eu estive preso encontrando este problema on-line nos últimos 5 dias, e não consegui encontrar uma resposta, toda vez que eu inicio o ettercap e escolho minha interface como wlan0, isso me causa um erro, como este

ERROR: 9, Bad file descriptor
[/build/ettercap-jPFHOw/ettercap-08.2/src/ec_network.c:source_init:245]
libnet_init: unknown physical layer type 0x323

Eu nem tenho o arquivo ec_network.c, ou o arquivo libnet (se isso é relevante para este problema) se eu precisar baixá-lo, de onde posso baixá-lo?

Obrigado

    
por KoyaCho 23.07.2016 / 16:57

1 resposta

1

Você provavelmente encontrou um bug do kernel. Talvez eu não devesse ir tão longe como um bug, já que pode ser que o suporte para o identificador específico da placa nunca tenha sido adicionado ao código do kernel.

O código ettercap que lida com a camada física é o seguinte:

 switch (ifr.ifr_hwaddr.sa_family)
 {
     case ARPHRD_ETHER:
     case ARPHRD_METRICOM:
#ifdef ARPHRD_LOOPBACK
     case ARPHRD_LOOPBACK:   
#endif
         l->link_type = DLT_EN10MB;
         l->link_offset = 0xe;
         break;
     case ARPHRD_SLIP:
     case ARPHRD_CSLIP:
     case ARPHRD_SLIP6:
     case ARPHRD_CSLIP6:
     case ARPHRD_PPP:
         l->link_type = DLT_RAW;
         break;
     case ARPHRD_FDDI:
         l->link_type   = DLT_FDDI;
         l->link_offset = 0x15;
         break;
     /* Token Ring */
     case ARPHRD_IEEE802:
     case ARPHRD_IEEE802_TR:
     case ARPHRD_PRONET:
         l->link_type   = DLT_PRONET;
         l->link_offset = 0x16;
         break;

     default:
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
             "unknown physical layer type 0x%x",
             ifr.ifr_hwaddr.sa_family);
     goto bad;
 }

E você pode verificar os valores de todos aqueles definidos dentro de /usr/include/net/if_arp.h . E sim, 0x323 acaba por não ser nenhum deles. Além disso 0x323 não é nenhum dispositivo conhecido para net/if_arp.h

Aqui está um programa de teste para preencher ifr.ifr_hwaddr.sa_family e imprimi-lo:

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stropts.h>

#include <net/if.h>
#include <netinet/if_ether.h>
#include <net/if_arp.h>

int
main(int argc, char** argv)
{
    struct ifreq ifr;
    int fd = -1;
    char *iface = argv[1];

    fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
    if (fd == -1)
    {
        if (errno == EPERM) {
            printf("UID/EUID 0 or capability CAP_NET_RAW required\n");

        } else {
            printf("socket: %s\n", strerror(errno));
        }
        return 1;
    }

    memset(&ifr, 0, sizeof (ifr));
    strncpy(ifr.ifr_name, iface, sizeof (ifr.ifr_name) -1);
    ifr.ifr_name[strlen(iface)] = '
[root@haps ~]# /home/grochmal/tmp/libnet/test enp3s0
IFR: [24240001] sa_family [00]
[root@haps ~]# /home/grochmal/tmp/libnet/test wlp2s0
IFR: [22000001] sa_family [00]
'; if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0 ) { printf("SIOCGIFHWADDR: %s\n", strerror(errno)); return 1; } printf( "IFR: [%08x] sa_family [%02x]\n" , ifr.ifr_hwaddr, ifr.ifr_hwaddr.sa_family); return 0; }

Metade é simplesmente copiada do código do ettercap. De qualquer forma, a compilação deve ser trivial gcc -o prog prog.c (dado que a fonte é nomeada prog.c ) e você deve executá-la com o nome da interface como seu primeiro argumento. por exemplo,

ioctl(fd, SIOCGIFHWADDR, &ifr)

(na minha máquina)

Podemos ver que sa_family é preenchido por:

  struct net_device *dev = dev_get_by_name_rcu(net, ifr->ifr_name);

  ...

  case SIOCGIFHWADDR:
          if (!dev->addr_len)
                  memset(ifr->ifr_hwaddr.sa_data, 0,
                         sizeof(ifr->ifr_hwaddr.sa_data));
          else
                  memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
                         min(sizeof(ifr->ifr_hwaddr.sa_data),
                             (size_t)dev->addr_len));
          ifr->ifr_hwaddr.sa_family = dev->type;
          return 0;

Que executa isso:

IFR: [********] sa_family [323]

Em que dev_get_by_name_rcu é uma macro do kernel que preenche o struct net_device . E como temos ifr->ifr_hwaddr.sa_family = dev->type; também preenche sa_family .

Encontrei um relatório de erros na página do Kali Linux sobre esse sa_family , mas o kali não não use o kernel mais recente.

Portanto, eu executaria o programa de teste acima para garantir que ele seja impresso:

 switch (ifr.ifr_hwaddr.sa_family)
 {
     case ARPHRD_ETHER:
     case ARPHRD_METRICOM:
#ifdef ARPHRD_LOOPBACK
     case ARPHRD_LOOPBACK:   
#endif
         l->link_type = DLT_EN10MB;
         l->link_offset = 0xe;
         break;
     case ARPHRD_SLIP:
     case ARPHRD_CSLIP:
     case ARPHRD_SLIP6:
     case ARPHRD_CSLIP6:
     case ARPHRD_PPP:
         l->link_type = DLT_RAW;
         break;
     case ARPHRD_FDDI:
         l->link_type   = DLT_FDDI;
         l->link_offset = 0x15;
         break;
     /* Token Ring */
     case ARPHRD_IEEE802:
     case ARPHRD_IEEE802_TR:
     case ARPHRD_PRONET:
         l->link_type   = DLT_PRONET;
         l->link_offset = 0x16;
         break;

     default:
         snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
             "unknown physical layer type 0x%x",
             ifr.ifr_hwaddr.sa_family);
     goto bad;
 }

O programa de teste precisa ser executado como root, já que ele usa um soquete bruto.

E então eu tentaria uma nova versão do kernel para verificar se o bug foi corrigido na ramificação do kernel 4.x (por exemplo, gentoo ou arch). Por exemplo, executando um live CD com gcc . O programa de teste não possui nenhum requerimento de biblioteca, portanto ele pode ser facilmente compilado em um live CD.

Isso é tão profundo quanto eu posso entrar no código do kernel. Como exatamente o sa_family é determinado pelo hash do dispositivo , está além de mim.

    
por 23.07.2016 / 20:12

Tags