
Criptografia E2E para sessões tty multi-hop ou portshells + encaminhamento de portas TCP/UDP
Este projeto – assim como seu projeto irmão crash – pertence ao meu conjunto de ferramentas anti-censura que permite configurar shells criptografadas totalmente funcionais e encaminhamento TCP/UDP em ambientes censores hostis. Também é útil para perícia forense para despejar dados de dispositivos via UART ou adb quando nenhum outro meio estiver disponível.
Consulta DNS e sessão SSH encaminhadas por uma conexão UART para um Pi
PSC permite criptografar de ponta a ponta sessões de shell, com um ou múltiplos saltos, sendo
agnóstico em relação ao transporte subjacente, desde que seja confiável e possa enviar/receber
dados codificados em Base64 sem modificar/filtrar. Junto com o pty de ponta a ponta que
você recebe (por exemplo, dentro de um port-shell), você pode encaminhar conexões TCP e UDP,
semelhante ao parâmetro -L do OpenSSH. Isso funciona de forma transparente
e sem a necessidade de um endereço IP atribuído localmente no ponto de partida.
Isso permite que peritos forenses e testadores de penetração criem conexões de rede,
por exemplo, via:
adb shell, se o adbd OEM não suportar encaminhamento TCPImagine que você teria uma sessão ppp invisível dentro da sua sessão de shell, sem que o peer remoto realmente suporte ppp.
Funciona em Linux, Android, OSX, Windows, FreeBSD, NetBSD e (possivelmente) OpenBSD.
PSC também inclui suporte a proxy SOCKS4 e SOCKS5 para ter sessões reais de navegação web via port-shells ou conexões discadas remotamente.
Edite o Makefile para refletir suas chaves pré-compartilhadas, conforme definido no topo do Makefile.
Depois basta digitar make no Linux e OSX.
No BSD você precisa instalar o GNU make e invocar gmake em seu lugar.
No Windows você precisa instalar cygwin e selecionar
os pacotes apropriados gcc, gcc-g++, make e git.
No Linux, o PSC usará terminais pseudo Unix98, em outros sistemas usará POSIX pty, mas isso deve ser transparente para você. Uma vez adicionei suporte a pty 4.4BSD e SunOS na idade da pedra por uma razão específica, então pode ou não compilar até com Solaris.
orgulhosamente patrocinado por:
Simples e direto. Na sua máquina local, execute pscl, e passe quaisquer
portas TCP ou UDP que você deseja encaminhar do site remoto para um endereço
específico. Por exemplo:
linux:~ > ./pscl -T 1234:[192.168.0.254]:22 -U 1234:[8.8.8.8]:53
PortShellCrypter [pscl] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: set up local TCP port 1234 to proxy to 192.168.0.254:22 @ remote.
pscl: set up local UDP port 1234 to proxy to 8.8.8.8:53 @ remote.
pscl: Waiting for [pscr] session to appear ...
linux:~ >
[ UART / SSH / ... login to remote side ... ]
No site remoto (o último salto) com a sessão de shell, não importa se está em
um port-shell, SSH, login de console etc, você executa pscr:
linux:~ > ./pscr
PortShellCrypter [pscr] v0.60 (C) 2006-2020 stealth -- github.com/stealth/psc
pscl: Seen STARTTLS sequence, enabling crypto.
linux:~ >
Assim que você executa pscr, ambas as extremidades estabelecem um handshake criptográfico e sobrepõem um protocolo
adicional sobre sua sessão existente, que é transparente para você. Você pode então
conectar-se a 127.0.0.1:1234 na sua máquina local para alcançar 192.168.0.254:22 via
TCP ou o resolvedor 8.8.8.8 via UDP. Isso também funciona com endereços [IPv6],
se o site remoto tiver conectividade IPv6. Na verdade, você pode até usá-lo para traduzir
software IPv4 para IPv6, já que você sempre se conecta a 127.0.0.1 no lado local.
Você pode passar múltiplos parâmetros -T e -U. Se você perder o controle se sua sessão
já está criptografada de ponta a ponta, pode enviar um SIGUSR1 para o processo local pscl, e ele
informará.
PSC também é útil se você quiser usar tor a partir de um shell SSH remoto, onde você
pode encaminhar a porta socks5 e a porta DNS para o endereço 127.0.0.1 do host remoto.
Como o SSH não encaminha pacotes UDP, você normalmente usaria dois conectores socat
ou similar para resolver via nó tor. PSC tem a vantagem de manter os limites dos datagramas UDP,
enquanto socat sobre SSH -L pode quebrar os limites dos datagramas e criar requisições DNS malformadas.
A sessão será criptografada com aes_256_ctr de uma PSK que você escolhe no
Makefile. Esse esquema criptográfico é maleável, mas adicionar dados AAD ou OAD aumenta o
tamanho do pacote, onde cada byte conta, pois em sessões interativas e devido à codificação
Base64, cada caractere digitado já causa muito mais dados a serem enviados.
Sessões UART podem ser usadas via screen, mas por exemplo não via minicom, pois
minicom cria janelas invisíveis com linhas de status e age como um filtro
que destrói o protocolo do PSC. PSC tenta detectar filtragem e pode conviver com
certa quantidade de adulteração de dados, mas em algumas situações não é possível recuperar.
Algo semelhante com tmux. Você deve evitar empilhar manipuladores pty com PSC que
adulteram/processam demais os dados de entrada.
A variável de ambiente SHELL precisa estar definida tanto para pscl quanto para pscr para que
o PSC saiba qual shell executar no pty. SHELL está definida na maioria dos ambientes
por padrão, mas caso não esteja, o PSC precisa ser executado como SHELL=/bin/bash pscl
etc.
pscl também suporta encaminhamento de conexões TCP via SOCKS4 (-4 porta) e SOCKS5
(-5 porta). Isso configura porta como porta SOCKS para conexões TCP, então por exemplo você
pode navegar em redes remotas a partir de uma sessão port-shell sem a necessidade de abrir qualquer outra
conexão durante um teste de penetração. Se você passar -N para pscl, ele ativa a resolução de nomes DNS
no lado remoto, então você também pode usar chrome com ele. Mas esteja avisado: Há um problema de
privacidade com navegadores que tentam resolver uma sequência de nomes DNS na inicialização que
não está sob seu controle. Além disso, se o seu lado remoto tiver uma configuração DNS quebrada, seu shell
de digitação pode travar por vários segundos se pacotes de resposta DNS estiverem faltando. Não existem
boas funções de resolvedor assíncronas que sejam incorporáveis e portáveis, então tive que usar
getaddrinfo() em uma única thread ao preço de possíveis bloqueios por vários segundos
se existirem problemas de DNS. É por isso que a resolução de nomes deve ser ativada explicitamente. pscr
tenta minimizar esse problema potencial com caches de consulta DNS, então na maioria das
situações deve funcionar sem dor.
Se você passar -X endereço-IP (deve ser o primeiro argumento), você pode vincular seu proxy local
a um endereço diferente de 127.0.0.1, assim você pode compartilhar o proxy na sua rede local.
psc oferece recursos que permitem encaminhar conexões TCP ou blobs de dados binários de/para dispositivos
remotos através de múltiplos saltos, mesmo que não seja possível instalar o binário pscr no
site remoto. Isso é muito útil para fins forenses se você não tiver meios
de baixar artefatos do dispositivo (que pode ser um telefone conectado por UART, por exemplo)
ou precisar encaminhar conexões sem tocar no sistema de arquivos para não destruir evidências no sistema
ou quando o sistema de arquivos raiz está montado como somente leitura e você não pode fazer upload do seu conjunto de ferramentas.
Este é um recurso realmente interessante, pois você pode ver sua conexão TCP saltar através do seu tty local para uma máquina remota sem a necessidade de instalar nada remotamente.
Isso funciona apenas com punkrock pty local e passando um comando de bounce para pscl que ele irá
injetar no shell remoto (sem pscr em execução) e alguma mágica de máquina de estado que filtra
e manipula os dados no lado local. Normalmente isso requer configurar o pty remoto para modo raw
primeiro antes de emitir o comando real e alguns outros detalhes que são passados para -B. O
argumento é dividido nas seguintes partes:
:, por exemplo, 1234:.stty -echo raw ou
python -c "import tty;tty.setraw(0)" (cuidado com as aspas, pois -B também precisa
ser citado) ou algo similar.pscl para começar a enviar dados para evitar uma condição de corrida entre
stty realmente ocorrer e o início do comando, por exemplo, um echo GO é perfeito.nc 127.0.0.1 22 para saltar a porta local 1234 para o servidor SSH remoto.pscl redefina seu estado tty.
echo FIN fará isso. Recomendado, caso contrário, você pode ter problemas para reconhecer o final do
seu comando.Exemplos:
Se você deseja encaminhar uma conexão TCP, este exemplo requer stty e nc instalados no
dispositivo, mas teoricamente poderia ser qualquer outra coisa que faça o equivalente.
Inicie uma sessão local:
./pscl -B '1234:[stty -echo raw;echo GO;nc example.com 22;echo FIN]'
Isso emitirá o comando stty -echo raw;echo GO;nc example.com 22;echo FIN para o dispositivo
remoto se você conectar localmente à porta 1234 e então apenas encaminha quaisquer dados que vê de um lado para o outro,
limitando a taxa de tráfego para que não exceda a velocidade tty do dispositivo (115200 é o padrão).
Quando a sessão pscl for iniciada, conecte-se ao dispositivo remoto por UART, ssh -e none ... ou
qualquer que seja e, assim que tiver o shell remoto, também digite localmente:
ssh [email protected] -p 1234 para saltar a conexão SSH da sua máquina local através do dispositivo
remoto para o destino example.com. Claro, a variante pscr é preferida, pois -B pode apenas
saltar uma única conexão por vez (embora você possa passar múltiplos comandos -B para vários
encaminhamentos) e há a chance de travar o shell após a sessão TCP, já que o pty está em modo raw -echo
e dependendo se o peer remoto final também fecha a conexão, pode ser
que o shell simplesmente trave depois disso. Se você receber uma notificação do pscl de que a conexão
foi concluída e vir um prompt, você deve fazer reset, para que uma nova conexão possa ser iniciada.
Enquanto os dados estão sendo encaminhados, você verá notificações ASCII de 7 bits < e > no pscl, que
são apenas locais para facilitar a depuração e detecção de progresso.
Observe que a conexão com o site remoto precisa ser limpa em 8 bits, ou seja, o ssh, telnet, UART ou
qualquer canal não deve processar sequências de escape (diferente de quando se usa pscr). Para conexões ssh,
isso significa que você deve usar ssh -e none na sessão pscl.
Em seguida, seguem alguns exemplos para lidar com transferência de arquivos binários, onde rfile denota o arquivo remoto e lfile o arquivo local.
Para iniciar uma sessão para despejar arquivos remotos, localmente:
./pscl -B '1234:[stty -echo raw;echo GO;dd of=rfile.bin bs=1 count=7350;echo FIN]'
Onde você precisa especificar a quantidade de dados que o lado remoto está esperando. Também funcionaria
sem (por exemplo, cat>...), mas então a sessão travará após a transmissão terminar, pois
cat está esperando entrada indefinidamente. Usando dd count=..., você terá uma saída limpa e será notificado
sobre isso pelo marcador FIN.
Em seguida, ssh ou o que for necessário para obter um shell no dispositivo remoto a partir da sessão
pscl que acabou de ser iniciada. Em um segundo terminal local:
dd if=lfile.bin|nc 127.0.0.1 1234
que se conectará à porta local 1234 do pscl e disparará o comando de despejo no lado remoto,
encaminhando os dados binários do lfile.bin local para rfile.bin remoto. Devido à limitação de taxa,
isso pode levar um tempo e você apenas confie na tela de progresso do psc para saber se a transferência foi concluída.
O comando local dd ...|nc ... mostrará apenas o status local, que pode consumir arquivos inteiros
em milissegundos devido aos buffers TCP locais enquanto o arquivo ainda está sendo transferido pelo pty.
Portanto, certifique-se de pressionar Ctrl-C apenas quando a tela do pscl indicar que terminou ou você vir
o marcador final FIN sendo ecoado de volta para você na sessão dd ...|nc ....
Da mesma forma, comandos similares poderiam ser usados para transferir dados binários de um dispositivo remoto para a máquina local para fins forenses. Novamente, início da sessão localmente:
./pscl -B '1234:[stty -echo raw;echo GO;dd if=rfile.bin]' ou
./pscl -B '1234:[stty -echo raw;echo GO;cat rfile.bin]'
Em seguida, ssh para o dispositivo remoto para obter o shell, então novamente localmente:
nc 127.0.0.1 1234|dd of=lfile.bin bs=1 count=7350
Para obter rfile.bin de tamanho 7350 copiado para o arquivo local lfile.bin
Se stty -echo raw não estiver disponível no dispositivo, algo como
python -c "import tty;tty.setraw(0)" também funciona. Observe que no dispositivo remoto você precisa ter
um tty (não apenas um port-shell) ao usar comandos de bounce, pois o comando stty para configurar o modo raw
requer um tty real.
Se o psc for executado por uma conexão serial, bits perdidos podem acabar com toda a diversão. Se você executar
sem HW FC, eventualmente experimentará perda de bits e conexões travadas, em particular
como não há limitação quando o dispositivo está enviando dados em sua direção ao usar
comandos de bounce. Despejar dados para o dispositivo funciona melhor, pois esses dados passam
pelos limites de taxa do pscl.
No entanto, aqui estão algumas dicas que funcionaram para mim em circunstâncias em que não é
possível usar pscr no dispositivo e HW FC. Isso se aplica apenas ao usar UARTs, pois este
é um canal de transporte potencialmente não confiável.
pscr no dispositivo para que você possa definir a limitação de taxa para dados sendo enviados em sua direção.
Como a direção em direção ao dispositivo é sempre limitada em taxa, você pode usar comandos de bounce para
despejar um binário pscr cross-compilado no dispositivo e iniciar uma sessão limitada bidirecional com ele.tio -o 1 ou -o 2 para adicionar atrasos entre os bytes de saída enviados38400 embora a linha serial esteja configurada para 115200)psc com -DRESPECT_UART_BUFSIZE=4096, no entanto isso tornará a sessão muito lentaDentro da pasta contrib você também encontrará um patch tio-noprefix para desabilitar o processamento de caracteres de escape,
mas este patch é necessário apenas para versões mais antigas, pois o upstream já aceitou e
integrou este patch. Eu realmente recomendo usar tio ao usar UARTs.
Ao usar comandos de bounce através do tio, você deve adicionar ao seu arquivo ~/.tioconfig:
[default]
prefix-ctrl-key = none
o que desabilita o tratamento de ESC e fornece um canal limpo de 8 bits.
Você pode enviar SIGUSR1 para pscl para que ele informe se a sessão está criptografada. Se o remoto
pscr morrer ou sair sem possibilidade de sinalizar isso para a parte local, pscl permanecerá
no modo de criptografia e, portanto, travará. Nesse caso, você pode forçar uma redefinição para o modo de texto simples
enviando SIGUSR2, para que uma nova sessão possa ser iniciada.
A partir da versão 0.64, o psc suporta sockets de script, para que você não precise mais de screen para
obter/colocar arquivos ou despejar buffers de colagem no console remoto. Em vez disso, você inicia sua sessão
local assim:
~ > ./pscl -S ~/psc.script_sock
Você pode então usá-lo como antes. Se precisar 'colar' algo, faça assim:
~ > ./pscsh -S ~/psc.script_sock -f script_/helloworld
Isso 'digitará' o conteúdo de script_/helloworld no console. Durante o script,
o stdin do pscl é bloqueado para que a entrada injetada não se misture com qualquer
digitação. Se -S for omitido no pscsh, ~/psc.script_sock é usado automaticamente.
Por razões de segurança, os scripts devem começar com o prefixo script_.
Como bônus, pscr agora contém a capacidade de codificar/decodificar arquivos em base64, mesmo com caracteres
CR incorporados para conveniência. É compatível com uuencode -m.
; e colocados entre colchetes.