Explorando redes com ESP32 WIFI.
Tags: iot, osint, scanner, hacking
Published: 2023-11-26 14:35:09




![ESP32 Wifi](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vskm5c1giiu11b6cgb90.png)





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.

- [IDE Arduino](https://docs.arduino.cc/software/ide-v2)
- [ESP32 Wifi](https://www.robocore.net/wifi/esp32-wifi-bluetooth?gad_source=1)

## 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:

```cpp
#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() {
  
}

``` 

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

- Inclusão da Biblioteca WiFi:

```cpp

#include <WiFi.h>
```

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:

```cpp

const char *ssid = "SEU_SSID";
const char *password = "SUA_SENHA";
```
Substitua "SEU_SSID" e "SUA_SENHA" pelos respectivos SSID e senha da sua rede WiFi.

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

```cpp

void setup() {
  Serial.begin(115200);
  delay(10);
```
Inicia a comunicação serial com uma taxa de 115200 bps e espera por 10 milissegundos.

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

```cpp

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

WiFi.begin(ssid, password);

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

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():

```cpp

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

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

- Método loop():

```cpp
    void loop() {
    
    }
```

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:

```cpp

#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++;
}

``` 

Inclusão de Bibliotecas:

```cpp

#include <WiFi.h>
```

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

```cpp

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

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

```cpp

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

- 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():

```cpp

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());
}
```

- 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():

```cpp

void loop() {
  scanner();

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

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():

```cpp

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

- 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():

```cpp

  // 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);
  
```


- 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():

```cpp

  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++;
}
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hhep1uqcgx16r5pz9bhk.png)


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](https://www.buymeacoffee.com/higordiego).

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