30 de julho de 2021

Do bit Ao Byte

Embarcados, Linux e programação

Porta serial pela rede (Raspberry e x86)

porta serial pela rede

Esse tipo de artigo não é exatamente sobre o que gosto de escrever, principalmente por fragilizar segurança de redes e sistemas. O conhecimento relacionado pode servir para instrução de segurança, mas também acaba sendo uma porta para pessoas com más intenções. Não seja essa última. E o que uma mera porta serial pela rede tem a ver com segurança? Vamos lá.

O que é o socat?

Para entender o poder da ferramenta, alguns conceitos precisam ser citados. Em Linux (que herda características do UNIX) dispositivos de sistema são arquivos descritores. Dispositivos de massa (HD, SSD, pendrive), dispositivos de caractere (teclado, mouse etc), portas seriais, named pipes (FIFOs) e tudo o mais. Já escrevi um artigo demonstrando como fazer algumas comunicações de rede usando shell script, sem nenhum programa. O socat é uma ferramenta que faz uso extensivo dos recursos do sistema, entre eles:

  • socksifier.
  • Ataque fraco a firewalls (usado em pentest).
  • Interfaces sockets, inclusive para socket UNIX (usado para IPC).
  • Port forwarder TCP.
  • Relay IPv6.
  • Redirecionamento de TCP para linha serial.

Esse último exemplo é o que utilizaremos nesse momento para acessar a porta serial pela rede, e talvez eu faça outros artigos exemplificando a utilização dessa ferramenta, mas para não deixar ninguém com vontade, vamos fazer alguns testes básicos – lembrando que você precisa ter um Linux, seja desktop, seja Raspberry.

porta serial pela rede

Nessa imagem tem dois terminais. O de baixo é meu notebook e o de cima é uma conexão SSH ao Raspberry. No Raspberry instalei o navegador de linha de comando, chamado Links.

Em meu notebook digitei a linha:

sudo socat TCP4-LISTEN:100,fork TCP:www.dobitaobyte.com.br:80

Essa linha redireciona conexões feitas ao meu laptop na porta 100 para o blog, na porta 80, que por sua vez redireciona para HTTPS (443). Reparem que o blog abriu no navegador links no Raspberry.

No Raspberry simplesmente fiz uma conexão ao meu laptop, usando seu IP como URL:

links 192.168.1.200:80

Isso foi o suficiente para o Raspberry acessar o blog. Supondo então que um determinado computador da rede tenha acesso à Internet e por norma da empresa outros computadores não o tenham, basta fazer um redirecionamento como esse a partir do computador que tem acesso para que as demais máquinas também acessem a Internet. Esse é um ponto de segurança a considerar, principalmente quando se está implementando um projeto com Raspberry, e o Raspberry tem acesso à Internet. Ele poderá ser usado como meio para saída e ataques. Ou pior: se houver conexão entrante para o Raspberry, ele poderá ser usado para acessar outras máquinas da rede interna que porventura façam interface com ele.

Outra possibilidade é a interceptação de dados entrantes como, por exemplo, na comunicação MQTT. Basta trocar a porta no serviço, usar a porta padrão para receber os dados, repassar para a nova porta como se nada tivesse acontecido, e ao mesmo tempo coletar esses dados para qualquer fim.

No primeiro momento pode parecer insignificante, mas imagine esse Raspberry coletando dados de fazendas, onde essas informações podem representar dinheiro, muito dinheiro. Exemplos não faltam, mas não vamos nos estender.

Esse redirecionamento específico também pode ser feito por firewall, como já devo ter mostrado em algum artigo sobre iptables.

O que é o ser2net?

O programa ser2net converte uma conexão serial para rede. A diferença para o socat é que o ser2net é instalado como serviço de sistema, cujo arquivo de configuração se encontra em /etc/ser2net.conf.

Dentro do arquivo de configuração tem toda a explicação necessária para criar uma linha de comunicação com a serial, mas para exemplificar, adicionei:

1234:telnet:0:/dev/ttyUSB0:115200 8DATABITS NONE 1STOPBIT remctl

Sendo a porta de origem, o serviço, o timeout, a porta serial e seus parâmetros.

Feita essa configuração, é necessário reiniciar o serviço para que os parâmetros recém adicionados sejam assumidos.

sudo service ser2net restart

Dá pra rodar em modo debug também – que pode ser o modo padrão, bastando para isso desabilitar o serviço. Daí quando precisar executar, pode chamar uma linha de comando assim:

ser2net -d -C "1234:raw:0:/dev/ttyACM0:9600 8DATABITS NONE 1STOPBIT remctl"

O que tem a ver socat com ser2net?

Agora é hora de fazê-los trabalhar em conjunto. Definimos a porta 1234 para a comunicação serial com o ser2net, agora usamos o socat para disponibilizar essa porta na rede através de um dispositivo remoto:

mkdir -p $HOME/dev
socat pty,link=$HOME/dev/ttyNET0,waitslave tcp:192.168.1.200:1234

E será necessário dar as permissões de leitura e escrita no dispositivo fake criado:

sudo chmod 666 /dev/ttyNET0 #ou $HOME/dev/ttyNET0

Como estou fazendo a conexão de exemplo em um Raspberry sem a parte gráfica, instalei nele o GTKTerm pelo ssh, então fiz uma nova conexão por ssh que me permite abrir programas gráficos do Raspberry remotamente.

sudo apt-get update
sudo apt-get install gtkterm
exit
ssh pi@192.168.1.2 -X
gtkterm

Feito isso, o programa se abrirá nativamente como se local fosse. No Windows dá pra fazer esse tipo de conexão usando o MobaXterm.

Configura-se então a porta:

porta serial pela rede - gtkterm - porta

Mas já não é necessário utilizar o socat remotamente, se for acessar por telnet, por exemplo.

Na imagem abaixo, temos a linha de comando no host dobitaobyte (meu laptop) e acima está a janela da conexão por ssh ao Raspberry (ns1). Repare que fiz a conexão pela rede a partir do Raspberry usando o programa telnet, que me deu acesso à serial em que o Arduino está conectado no laptop. A saída que está sendo exibida na tela é a leitura de debug da maquineta do Banco Imobiliário, cadastrando 2 tags RFID e 2 iButtons.

maquineta do banco imobiliário

Mas se tiver um programa que se conecta pela serial e “somente” pela serial, usando o socat como descrito lhe permitirá acessar o dispositivo remoto como se fosse local:

porta serial pela rede - imagem do vídeo

Na janela mais abaixo estou rodando o ser2net para disponibilizar a porta /dev/ttyACM0 no modo raw. Na janela um pouco mais acima estou conectado ao Raspberry, usando socat para criar a porta serial fake ttyNET0. A janela quadrada é o programa GTKTerm instalado no Raspberry, que abri remotamente pela conexão ssh, usando a flag -X para exportar o serviço gráfico pelo túnel.

Não vou exemplificar porque esse blog não é uma central de treinamento hacker, mas pense no conjunto, desde o redirecionamento de porta, ao acesso direto à serial de um dispositivo da rede IoT. Esse é um dos pontos que me referi ao risco do IoT à segurança nacional. É bem interessante, sugiro a leitura.

Se gosta de coisas bem diferentes do padrão, vou sugerir mais uma leitura: USB gadget, para criar uma conexão ethernet usando a USB (não é um dungle USB-ethernet).

Vídeo: porta serial pela rede

Talvez tenha ficado um pouco abstrato para quem não é do mundo Linux, por isso sugiro também que assista ao vídeo “Conexão serial pela rede“, no canal DobitaobyteBrasil no Youtube. Se não é inscrito ainda, inscreva-se, clique no sininho para receber notificações e proporcione um pouco mais de felicidade a esse ser serviente que vos escreve.

Revisão: Ricardo Amaral de Andrade