DEV Community

Higor Diego
Higor Diego

Posted on

Explorando redes com ESP32 WIFI.

ESP32 Wifi

Recentemente, vivenciei uma situação peculiar em um banco durante uma revista em minha bolsa. Foi constatado que a entrada de notebooks não era permitida na área específica, levando o guarda encarregado da revista a retirar meu notebook, em conformidade com as normas estabelecidas.

No entanto, o que despertou minha curiosidade foi o fato de que outros dispositivos periféricos, como bateria, cabos e um ESP32, permaneceram na bolsa, possibilitando minha entrada na área restrita. Após adentrar o recinto, fui conduzido a uma sala para aguardar o gerente. Durante esse período, aproveitei para realizar uma análise do ambiente e, para minha surpresa, deparei-me com um papel sobre a mesa contendo as informações de login e senha da rede Wi-Fi interna.

Essa situação suscitou uma reflexão: se a restrição de entrada com notebooks visa à segurança, será que o ESP32 não poderia ser utilizado para efetuar ataques à rede? Com base nessa ponderação, optei por redigir este artigo com o intuito de explorar um estudo sobre redes, buscando compreendê-las sem a utilização de notebooks ou ferramentas avançadas como o nmap (por exemplo), concentrando-se apenas no ESP32.

É fundamental salientar que o propósito deste artigo é proporcionar informações relevantes sobre segurança, sendo estritamente um estudo teórico.

O que e arduino ?

Arduino é uma plataforma de prototipagem de código aberto que consiste em hardware e software projetados para facilitar o desenvolvimento de projetos eletrônicos. O hardware Arduino é baseado em placas de circuito integradas com microcontroladores e uma interface de programação. Já o software consiste em uma IDE (Ambiente de Desenvolvimento Integrado) que permite a programação dessas placas.

Principais características do Arduino:

  • Microcontrolador: As placas Arduino são equipadas com microcontroladores que executam programas escritos em uma linguagem de programação derivada do C/C++.
  • IDE Arduino: A IDE Arduino fornece um ambiente de programação simples e intuitivo, facilitando o desenvolvimento de código para controle de dispositivos e interação com sensores.
  • Placas Variadas: Existem várias placas Arduino com diferentes especificações e tamanhos, desde placas básicas para projetos simples até modelos mais avançados com maior poder de processamento e recursos adicionais.
  • Entradas e Saídas (I/O): As placas Arduino têm pinos de entrada/saída (I/O) que permitem a conexão a diferentes componentes eletrônicos, como sensores, LEDs, motores, entre outros.
  • Comunicação: As placas Arduino suportam diferentes métodos de comunicação, como USB, UART, I2C e SPI, permitindo a interação com outros dispositivos e módulos.
  • Comunidade Ativa: Arduino possui uma comunidade global ativa que compartilha projetos, códigos e oferece suporte, facilitando o aprendizado e a resolução de problemas.

O que é ESP32?

O ESP32 é um microcontrolador de baixo custo, baixa potência e altamente integrado, pertencente à família ESP8266. Desenvolvido pela Espressif Systems, uma empresa chinesa, este microcontrolador é amplamente utilizado em projetos de Internet das Coisas (IoT) devido às suas capacidades de conectividade Wi-Fi e Bluetooth.

Reconhecido por sua versatilidade e desempenho, o ESP32 oferece uma ampla gama de recursos, incluindo processador dual-core, conectividade sem fio, GPIOs (General Purpose Input/Output), capacidade de interface com sensores e periféricos, além de suporte a diversos protocolos de comunicação. Tais características fazem dele uma escolha popular para aplicações em IoT, automação residencial, projetos de eletrônica e desenvolvimento de protótipos.

Configuração Necessária

A seguir, listamos alguns itens essenciais para a realização do estudo de caso.

Conexao de rede.

No esp32 podemos se conectar na wifi e com isso iremos analisar o codigo simples que nos possibilita a conexao.

Segue abaixo o codigo:



#include <WiFi.h>

const char *ssid = "SEU_SSID";
const char *password = "SUA_SENHA";

void setup() {
  Serial.begin(115200);
  delay(10);

  // Conectar-se à rede WiFi
  Serial.println();
  Serial.print("Conectando a ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Conectado ao WiFi");
  Serial.print("Endereço IP: ");
  Serial.println(WiFi.localIP());
}

void loop() {

}



Enter fullscreen mode Exit fullscreen mode

Com referência ao exemplo anterior, procedemos com a explicação detalhada, partindo do código apresentado.

  • Inclusão da Biblioteca WiFi:



#include <WiFi.h>


Enter fullscreen mode Exit fullscreen mode

Isso inclui a biblioteca WiFi, necessária para lidar com as funcionalidades de conexão WiFi do ESP32.

  • Definição das Credenciais da Rede WiFi:



const char *ssid = "SEU_SSID";
const char *password = "SUA_SENHA";


Enter fullscreen mode Exit fullscreen mode

Substitua "SEU_SSID" e "SUA_SENHA" pelos respectivos SSID e senha da sua rede WiFi.

  • Configuração do Ambiente no Método setup():



void setup() {
  Serial.begin(115200);
  delay(10);


Enter fullscreen mode Exit fullscreen mode

Inicia a comunicação serial com uma taxa de 115200 bps e espera por 10 milissegundos.

  • Conexão à Rede WiFi no Método setup():



Serial.println();
Serial.print("Conectando a ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}


Enter fullscreen mode Exit fullscreen mode

O programa imprime no console serial que está tentando se conectar à rede especificada.

WiFi.begin(ssid, password) inicia a conexão à rede WiFi usando as credenciais fornecidas.

O loop while espera até que a conexão seja estabelecida (WL_CONNECTED).

  • Exibição de Informações Após a Conexão Bem-sucedida no Método setup():



Serial.println("");
Serial.println("Conectado ao WiFi");
Serial.print("Endereço IP: ");
Serial.println(WiFi.localIP());


Enter fullscreen mode Exit fullscreen mode

Uma vez conectado, o programa imprime que foi conectado com sucesso e exibe o endereço IP atribuído ao ESP32.

  • Método loop():


    void loop() {

    }


Enter fullscreen mode Exit fullscreen mode

O método loop() está vazio neste exemplo. Este é o local onde você colocaria o código que deve ser executado continuamente após a inicialização.

O que faremos ?

Agora que adquirimos conhecimento sobre como realizar a conexão com o dispositivo, podemos ponderar sobre os seguintes aspectos:

  1. Possuo um periférico capaz de se integrar à rede.
  2. Esse periférico dispõe de capacidade de processamento.
  3. Ele opera utilizando uma linguagem de programação.

Diante dessas considerações, surge a pergunta: por que não desenvolver algo para explorar a rede?

A partir dessa premissa, exploraremos os endereços IP da rede para identificar portas abertas.

Atualmente, já possuímos:

  1. Conexão estabelecida com a rede WiFi.
  2. Atribuição dinâmica de endereço IP por meio do DHCP da rede.

Com base nessas informações, iniciaremos uma busca por portas abertas em possíveis computadores ou servidores.

A seguir, apresento o código correspondente:




#include <WiFi.h>

const char *ssid = "SEU_SSID";
const char *password = "SUA_SENHA";

// Lista de IPs a serem testados
IPAddress ips[255];
int currentIpIndex = 0;

// Lista de portas a serem testadas
int portas[] = {80, 443, 22};

void setup() {
  Serial.begin(19200);
  delay(10);

  Serial.println("Conectando ao WiFi...");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi conectado");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  scanner();

  // Aguardar antes de repetir o teste
  delay(5000);
}

void scanner() {
  if (currentIpIndex >= 255) {
    // Resetar o índice para começar de novo
    currentIpIndex = 0;
  }

  // Extrair os três primeiros octetos do endereço IP
  byte firstThreeOctets[3];
  IPAddress localIP = WiFi.localIP();
  for (int i = 0; i < 3; i++) {
    firstThreeOctets[i] = localIP[i];
  }

  // Criar o IPAddress com base nos três primeiros octetos e no último octeto variável
  IPAddress ipToTest(firstThreeOctets[0], firstThreeOctets[1], firstThreeOctets[2], currentIpIndex);

  for (int j = 0; j < sizeof(portas) / sizeof(portas[0]); j++) {
    WiFiClient client;
    if (client.connect(ipToTest, portas[j])) {
      Serial.printf("Conectado a %s na porta %d\n", ipToTest.toString().c_str(), portas[j]);
      client.stop();
    } else {
      Serial.printf("Falha na conexão a %s na porta %d\n", ipToTest.toString().c_str(), portas[j]);
    }
  }

  // Incrementar o índice para o próximo IP na próxima chamada
  currentIpIndex++;
}



Enter fullscreen mode Exit fullscreen mode

Inclusão de Bibliotecas:




#include <WiFi.h>


Enter fullscreen mode Exit fullscreen mode

Essa parte do código inclui as bibliotecas necessárias para a comunicação com a rede WiFI.




const char *ssid = "SEU_SSID";
const char *password = "SUA_SENHA";


Enter fullscreen mode Exit fullscreen mode

Substitua "SEU_SSID" e "SUA_SENHA" pelo nome e senha da sua rede WiFi.
Listas de IPs e Portas:




IPAddress ips[255];
int currentIpIndex = 0;
int portas[] = {80, 443, 22};


Enter fullscreen mode Exit fullscreen mode
  • ips: Uma lista de endereços IP a serem testados.
  • currentIpIndex: Índice atual na lista de IPs.
  • portas: Uma lista de portas a serem testadas.

Configuração no Método setup():




void setup() {
  Serial.begin(19200);
  delay(10);

  Serial.println("Conectando ao WiFi...");
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi conectado");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


Enter fullscreen mode Exit fullscreen mode
  • Serial.begin(19200): Inicia a comunicação serial com uma taxa de 19200 bps.
  • WiFi.begin(ssid, password): Inicia a conexão WiFi usando as credenciais fornecidas.
  • while (WiFi.status() != WL_CONNECTED): Aguarda até que a conexão seja estabelecida.

Após a conexão bem-sucedida, o código imprime mensagens indicando que o WiFi foi conectado e exibe o endereço IP atribuído ao dispositivo.

Método loop():




void loop() {
  scanner();

  // Aguardar antes de repetir o teste
  delay(5000);
}


Enter fullscreen mode Exit fullscreen mode

O método loop() chama a função scanner() (que ainda não está definida neste código) para realizar o teste de porta e aguarda 5 segundos antes de repetir.

Método scanner():




void scanner() {
  if (currentIpIndex >= 255) {
    // Resetar o índice para começar de novo
    currentIpIndex = 0;
  }


Enter fullscreen mode Exit fullscreen mode
  • scanner(): Uma função que realiza a verificação de portas em diferentes IPs.
  • if (currentIpIndex >= 255): Quando todos os IPs foram testados, o índice é resetado para reiniciar o processo.

Continuação do Método scanner():




  // Extrair os três primeiros octetos do endereço IP
  byte firstThreeOctets[3];
  IPAddress localIP = WiFi.localIP();
  for (int i = 0; i < 3; i++) {
    firstThreeOctets[i] = localIP[i];
  }

  // Criar o IPAddress com base nos três primeiros octetos e no último octeto variável
  IPAddress ipToTest(firstThreeOctets[0], firstThreeOctets[1], firstThreeOctets[2], currentIpIndex);



Enter fullscreen mode Exit fullscreen mode
  • firstThreeOctets: Extrai os três primeiros octetos do endereço IP local do dispositivo.
  • IPAddress ipToTest: Cria um novo endereço IP usando os três primeiros octetos e o índice variável para o último octeto.

Continuação e Finalização do Método scanner():




  for (int j = 0; j < sizeof(portas) / sizeof(portas[0]); j++) {
    WiFiClient client;
    if (client.connect(ipToTest, portas[j])) {
      Serial.printf("Conectado a %s na porta %d\n", ipToTest.toString().c_str(), portas[j]);
      client.stop();
    } else {
      Serial.printf("Falha na conexão a %s na porta %d\n", ipToTest.toString().c_str(), portas[j]);
    }
  }

  // Incrementar o índice para o próximo IP na próxima chamada
  currentIpIndex++;
}


Enter fullscreen mode Exit fullscreen mode

Um loop que percorre a lista de portas e tenta conectar-se a cada combinação de IP e porta. Se a conexão for bem-sucedida, imprime a mensagem "Conectado". Caso contrário, imprime "Falha na conexão".

Exploração

Após a compilação e o upload no ESP32, o resultado na porta serial é apresentado da seguinte forma:

Scanner Port

Com base nesse resultado, identificamos um IP (192.168.0.1) com a porta 80 aberta, possibilitando a enumeração de servidores e portas abertas no ambiente ao qual estamos conectados.

Vetores de Ataque

Considerando o ESP32, é possível realizar diversos tipos de ataques, tais como:

  • Sniffer: Interceptação de dados em uma rede para análise.
  • Scan de Portas: Identificação de portas abertas em um sistema.
  • Scan de WiFi: Exploração de redes sem fio disponíveis.
  • Ataque de Força Bruta: Tentativa de descobrir senhas por meio de repetidas combinações.

Com a proliferação de dispositivos portáteis no mundo da IoT, embora esses dispositivos ofereçam inovações significativas, também abrem oportunidades para ataques mais sofisticados, muitas vezes realizados com custos inferiores a 5 dólares.

Como se Proteger?

Para proteger-se contra esses vetores de ataques, é fundamental adotar práticas de segurança robustas, incluindo:

  • Monitoramento Constante: Monitorar regularmente o tráfego e as atividades suspeitas na rede.
  • Firewalls: Configurar firewalls para restringir o tráfego indesejado.
  • Desabilitar Serviços Não Necessários: Desativar serviços que não são essenciais para reduzir a superfície de ataque.
  • Filtro de Endereço MAC: Habilite o filtro de endereço MAC no roteador para permitir apenas dispositivos autorizados.Mantenha uma lista branca de endereços MAC permitidos.
  • Desative o SSID Broadcasting: Desative a transmissão do nome da sua rede (SSID broadcast).Isso torna sua rede menos visível para scanners, mas não fornece segurança total.

Compartilhe seu carinho:

Estou verdadeiramente empenhado em criar conteúdo constante, explorando compras de equipamentos e ferramentas para trazer temas relevantes. Se você gostou deste artigo, ou de outros que compartilhei, e deseja oferecer seu apoio para me ajudar a continuar nessa jornada, ficaria imensamente grato. Cada contribuição é um passo significativo para manter viva essa paixão que compartilhamos. 

Aqui está o link para apoiar: Buy Me a Coffee.

Obrigado pelo seu carinho e por fazer parte desta jornada! 🌟

Conclusão

Em conclusão, exploramos a conexão WiFi com o ESP32, aprendemos sobre a identificação de portas abertas na rede e discutimos medidas de segurança contra acessos não autorizados. O código apresentado mostrou como realizar um scanner de portas simples, ressaltando a importância de práticas seguras, atualizações regulares e consciência sobre potenciais vetores de ataques. Proteger sua rede WiFi é vital para garantir a segurança dos dispositivos conectados, e a implementação de medidas preventivas é fundamental para mitigar riscos e manter a integridade do ambiente digital.

Referências

https://www.espressif.com/en/products/socs/esp32
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html

Top comments (0)