> For the complete documentation index, see [llms.txt](https://stacked-rwx.gitbook.io/public/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stacked-rwx.gitbook.io/public/lateral-movement/shadowmove-movimentacao-lateral-furtiva.md).

# ShadowMove - Movimentação Lateral Furtiva

Movimentação Lateral é uma técnica usada por atacantes após comprometer um ponto inicial de uma rede. O objetivo do atacante é mover-se **lateralmente** através da rede e obter credenciais ou explorar outros serviços/máquinas com o propósito de aumentar o acesso e alcançar ativos mais valiosos — como servidores, banco de dados e DC’s (domains controllers).

*Não vou me aprofundar muito sobre o que seria a técnica de movimentação lateral, apenas expliquei de uma forma resumida para que, durante a leitura deste artigo, você não se perca e fique confuso sobre o que está acontecendo.*

## ShadowMove — O que é? <a href="#id-318c" id="id-318c"></a>

ShadowMove é uma técnica de movimentação lateral descoberta e apresentada na USENIX pelos pesquisadores **Amirreza Niakanlahiji, Jinpeng Wei, Md Rabbi Alam, Qingyang Wang e Bei-Tseng Chu.**

Essa técnica de movimentação lateral funciona reutilizando (duplicando) conexões estabelecidas e legítimas para se movimentar lateralmente dentro de uma rede comprometida por um atacante.

De acordo com a pesquisa apresentada, o ShadowMove funciona em três etapas.

<figure><img src="/files/sD4yZmbuIZdI7Bwqri6s" alt=""><figcaption></figcaption></figure>

1. Primeiro, ele duplica SILENCIOSAMENTE um socket usado por um aplicativo CLIENTE legítimo para se comunicar com um aplicativo SERVIDOR.
2. Logo em seguida, ele vai usar o socket duplicado para injetar pacotes na sessão TCP já existente entre o cliente e o servidor.
3. Por fim, o servidor processa os pacotes que foram injetados pelo ShadowMove, sem intenção, salva e/ou executa uma nova instância do ShadowMove.

Como resultado dessas três etapas, o atacante move-se de forma furtiva da máquina CLIENTE para o SERVIDOR.

## Fraquezas básicas exploradas pelo ShadowMove <a href="#a1b5" id="a1b5"></a>

O ShadowMove ataca duas fraquezas que são fundamentais nos ambientes de computadores. A primeira vulnerabilidade se chama “isolamento de processos e compartilhamento de recursos”. A segunda fraqueza é que muitos protocolos de rede existentes não possuem mecanismos adequados de verificação da integridade da origem da mensagem, o que torna vulneráveis a ataques de “Message injection”.

* **O que é isolamento de processos e o compartilhamento de recursos?**\
  *Isolamento de processos é a ideia de que cada processo no sistema deve rodar de forma independente, sem acessar diretamente a memória ou os dados de outros processos. Ao mesmo tempo, os sistemas operacionais permitem que processos compartilhem certos recursos, como: **arquivos, memória mapeada (shared memory), sockets, dispositivos, etc.** Chamamos isto de compartilhamento de recursos!*

O problema disso tudo é que essa necessidade de compartilhamento de recursos abre brechas. Mesmo com o isolamento de processos, os pontos de compartilhamento criam canais por onde os processos maliciosos podem interagir indiretamente com outros processos.

É como se o sistema dissesse:

“**Você está isolado… exceto por essas portas que eu deixei abertas porque você precisa delas.**” *E aí um atacante:* “**Hmm… talvez eu consiga explorar essas portas.**”

E para entender isso melhor, vou usar um trecho do paper.

> Por outro lado, os sistemas operacionais modernos oferecem suporte ao compartilhamento entre processos, já que compartilhar dados/recursos pode ser útil. Tomando o compartilhamento de soquetes como exemplo, um processo primeiro cria soquetes e estabelece conexões e, então, os entrega a outros processos, que serão responsáveis ​​por trocar informações por meio desses soquetes. No entanto, o compartilhamento entre processos tem riscos e, por isso, deve ser cuidadosamente controlado. Os sistemas operacionais modernos pressupõem que os processos que compartilham recursos confiam uns nos outros, definindo políticas de segurança apropriadas para controlar o acesso a objetos compartilhados e, assim, garantir a segurança desse compartilhamento.

“*Por outro lado, os sistemas operacionais modernos oferecem suporte ao compartilhamento entre processos, já que compartilhar dados/recursos pode ser útil.*”

➡️ Os sistemas operacionais atuais, permitem que os processos compartilhem recursos como memória, arquivos, sockets de rede, porque isso pode ser necessário em vários cenários. Por exemplo, em servidores multi-processos, clusters de processos, etc.

“*Tomando o compartilhamento de soquetes como exemplo, um processo primeiro cria soquetes e estabelece conexões e, então, os entrega a outros processos, que serão responsáveis ​​por trocar informações por meio desses soquetes.*”

➡️ Um processo (por exemplo, um servidor principal) pode criar um socket, fazer a conexão com outro computador, e depois passar esse socket para outro processo (por exemplo, um worker) que vai continuar fazendo a comunicação por aquele canal já estabelecido. Isso acontece, por exemplo, em servidores com Nginx ou Apache com múltiplos workers.

“*No entanto, o compartilhamento entre processos tem riscos e, por isso, deve ser cuidadosamente controlado.*”

➡️ Apesar de útil, permitir que processos compartilhem recursos é perigoso se isso não for bem controlado. Um processo malicioso pode abusar disso para interceptar dados, manipular comunicações, ou explorar vulnerabilidades.

“*Os sistemas operacionais modernos pressupõem que os processos que compartilham recursos confiam uns nos outros…*”

➡️ Em geral, o sistema operacional, PRESSUPÕE que o processo que compartilha um recurso e o processo que o recebe pertencem ao mesmo dono (grupo, usuário, etc) e confiam entre si.

“*…definindo políticas de segurança apropriadas para controlar o acesso a objetos compartilhados e, assim, garantir a segurança desse compartilhamento.*”

➡️ Para evitar abusos, o sistema operacional impõe regras de segurança (como permissões de acesso, ACLs, sandboxing, etc.) para garantir que somente processos autorizados consigam acessar ou usar recursos compartilhados.

## Então… <a href="#id-9ae1" id="id-9ae1"></a>

O que basicamente a PoC do ShadowMove faz é explorar justamente esse modelo de confiança: você se infiltra em um processo legítimo (como o ftp.exe) e pega o socket já existente.

As políticas de controle de acesso padrão dos sistemas operacionais comerciais sofrem com suposições incorretas sobre esse relacionamento de confiança de processos. Um exemplo, que pode ser útil para melhor esclarecimento. A política de segurança do Windows permite que processos do mesmo usuário compartilhem seus identificadores para recursos, enquanto no Linux, o processo pai acessa a memória de um processo filho via ptrace.

Como resultado, essa política de padrão pode ser abusada por atacantes.

Outro problema que o ShadowMove vai lidar, é com a falta de verificação da integridade da origem das mensagens em muitos protocolos, por exemplo o FTP. Por consequências, os endpoints não podem verificar a origem das mensagens para evitar que atacantes não intercalem mensagens.

Ou seja, muitos protocolos **não verificam se quem está enviando a mensagem é realmente quem diz ser**.

Em relação a integridade de origem da mensagem, os protocolos podem ser divididos em três categorias:

* **Sem verificação de integridade de origem:**\
  *Um protocolo de exemplo, é o FTP. O servidor não tenta verificar quem enviou a mensagem, então qualquer mensagem é aceita, mesmo que seja de um atacante.*
* **Verificação fraca (o servidor gera números aleatórios):**\
  *Um protocolo de exemplo, é o WinRM. O servidor tenta validar o usando um número aleatório, mas esse número gerado pode ser observado pelo atacante. O invasor pega esse número e o reutiliza na mensagem falsa.*
* **Verificação forte (cliente gera parte das informações para verificação de integridade):**\
  Um protocolo de exemplo, é o SSL. O cliente ele gera uma parte da secret de verificação. O atacante **não consegue saber essa secret** apenas observando a resposta do servidor. Então, o ShadowMove não consegue ser efetivo aqui.

## **Threat Modeling (Modelo de Ameaça)** <a href="#e8ff" id="e8ff"></a>

Supondo que um atacante invade um computador de um funcionário de TI através de uma técnica de spear phishing e obtem acesso a máquina inicial. Dentro desse acesso inicial (me refiro ao computador do funcionário de TI), o atacante identifica uma conexão legítima entre o computador do funcionário de TI (cliente) e um servidor de aplicativos FTP. O computador do funcionário possui um cliente FTP instalado que está se comunicando com o servidor final.

<figure><img src="/files/HePbem1k8xEDmYBVFPTw" alt=""><figcaption><p><strong>Computador do funcionário</strong> se comunicando com o servidor FTP.</p></figcaption></figure>

Dentro do servidor FTP, existe um arquivo que é executado periodicamente para fazer alguma determinada função.

<figure><img src="/files/JuSK1qE6kzLX8qY6I2yR" alt=""><figcaption><p>Programa configurado no crontab que é executado periodicamente para realizar alguma função.</p></figcaption></figure>

O atacante encontra a conexão que está sendo feita entre o computador do funcionário com o servidor FTP.

<figure><img src="/files/LAZR62CqvtupVLZcuXAd" alt=""><figcaption></figcaption></figure>

Sabendo disso, o atacante prepara a PoC do ShadowMove para duplicar o socket de conexão legítimo entre o CLIENTE e o SERVIDOR FINAL.

<figure><img src="/files/z19ykSt0uC6kMZybyGlf" alt=""><figcaption><p>PoC modificada por mim para fazer um envio de um arquivo programa.sh contendo uma mensagem.</p></figcaption></figure>

Esse arquivo poderia ser um malware, preparado para ser executado automaticamente sempre que o `crontab` acionasse o programa configurado para rodar periodicamente.

E olhando o servidor ftp…

<figure><img src="/files/QxfwEBXTqHeWMj4B9e7C" alt=""><figcaption></figcaption></figure>

O programa.sh foi recebido com sucesso pelo servidor FTP. E o mais interessante disso tudo é o fato dele não ter feito nenhuma conexão durante todo esse tempo!

<figure><img src="/files/81duQJl1jHQQwsFYauHA" alt=""><figcaption></figcaption></figure>

O mais legal de tudo isso é que esse processo pode ser repetido em protocolos diferentes como o WinRM e Microsoft SQL.

## Explicação da alteração do código <a href="#b064" id="b064"></a>

A alteração que foi feita, foi com o objetivo de capturar a segunda conexão de dados corretamente e enviar o conteúdo, sem que ele se perca no caminho e chegue apenas com 0 bytes.

Para entender melhor, farei uma explicação técnica que se encontra no paper sobre o ShadowMove.

Um cliente FTP pode solicitar a criação de um novo canal de dados de duas maneiras: FTP ativo e FTP passivo. No FTP ativo, o cliente envia um comando ao servidor para especificar em qual porta o servidor precisa reestabelecer a conexão. No FTP passivo, o cliente envia o comando PASV ao servidor, solicitando ao servidor que o servidor escute em uma porta que o cliente possa se conectar para criar um novo canal de dados.

O cliente envia o comando PASV ao servidor e é respondido pelo servidor com informações sobre alguns pontos de conexão ao qual o cliente deve se conectar para criar um novo canal de dados.

<figure><img src="/files/07DIAhhspSUkJ3zL3CsW" alt=""><figcaption><p>Imagem tirada do paper.</p></figcaption></figure>

Podemos observar que o servidor ele responde com algumas informações do endereço de IP e a porta de conexão.

<figure><img src="/files/JpybPJonOv3ljJrE2q4F" alt=""><figcaption></figcaption></figure>

Para descobrir a porta, é necessário calcular 179\*256 + 181 (46005). Então o ShadowMove carrega o nosso arquivo pro servidor (programa.sh e na ilustração é PoC2.txt). Após receber um código de resposta 150 do servidor, o ShadowMove abre uma conexão com o ponto de acesso especificado e envia o conteúdo do arquivo para a conexão aberta.

```cpp
// Meus reajustes daqui em diante...
targetSocket = findTargetSocket(dwProcessId, dstIP);

char pasv[] = "PASV\r\n";
send(targetSocket, pasv, strlen(pasv), 0);
recv(targetSocket, buff, sizeof(buff), 0);
printf("[*] Resposta do PASV: %s\n", buff);

int h1, h2, h3, h4, p1, p2;
sscanf(buff, "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)", &h1, &h2, &h3, &h4, &p1, &p2);
char dataIP[32];
sprintf(dataIP, "%d.%d.%d.%d", h1, h2, h3, h4);
int dataPort = (p1 << 8) + p2;

SOCKET dataSock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in dataAddr;
dataAddr.sin_family = AF_INET;
dataAddr.sin_port = htons(dataPort);
dataAddr.sin_addr.s_addr = inet_addr(dataIP);

printf("[*] Conectando à porta de dados %s:%d\n", dataIP, dataPort);
connect(dataSock, (struct sockaddr*)&dataAddr, sizeof(dataAddr));


char stor[] = "STOR programa.sh\r\n";
send(targetSocket, stor, strlen(stor), 0);
recv(targetSocket, buff, sizeof(buff), 0);
printf("[*] Resposta do STOR: %s\n", buff);

// Aqui ele está enviando o conteúdo pro servidor.
char conteudo[] = "#!/bin/bash\necho Pwned!\n";
send(dataSock, conteudo, strlen(conteudo), 0);
closesocket(dataSock);

recv(targetSocket, buff, sizeof(buff), 0);
printf("[*] Resposta final do servidor: %s\n", buff);
```

## Como funciona a replicação de sockets no Windows? <a href="#df07" id="df07"></a>

De acordo com o paper, no Windows você pode chamar a API DuplicanteHandle para duplicar Identificadores de diferentes tipos de um processo remoto. Todavia, como afirma a documentação do DuplicanteHandle, essa função não pode ser usada para duplicar sockets.

A API chamada WSADuplicateSocket é fornecida pelo Windows para fazer duplicações de soquetes, mas essa função não pode ser usada diretamente porque requerer cooperação entre processos.

Existe um cenário onde isso pode ser usado:

“Um cenário típico para usar esse recurso é o seguinte: um processo de origem cria um soquete e deseja compartilhá-lo com um processo de destino. Primeiro, o processo de origem chama WSADuplicateSocket para obter uma estrutura especial WSAPROTOCOL\_INFO. Essa estrutura de informação é fornecida ao processo de destino por meio do mecanismo de comunicação entre processos (IPC). O processo de destino passa a estrutura de informações para o WSASocket para reconstruir o soquete em seu lado.”

Mas o principal “desafio” dessa abordagem é que ambos os processos devem cooperar entre si, o que não é o caso em nosso cenário, onde o invasor deseja copiar o soquete de um processo vítima desavisado. Uma maneira de contornar esse problema, seria injeção de código no processo da vítima para implementar as etapas que estão faltando devido à falta de cooperação.

Mas sendo um pouco inteligente, sabemos que isso é inviável nos dias de hoje, ainda mais por conta dos mecanismos de defesas existentes, como o Windows Defender ATP.

O artigo da usenix, desenvolve essa técnica pouco convencional que explora a API do Windows para permitir que um processo malicioso copie um soquete de outro processo sem que a vítima colabore em nada. Em outras palavras, é possível “clonar” a conexão de rede ativa de um processo legítimo e usá-la a partir de outro processo, de forma totalmente invisível para o sistema.

A técnica funciona da seguinte forma: o invasor primeiro precisa saber o PID (identificador) do processo alvo. Isso pode ser feito monitorando conexões de rede abertas — algo relativamente simples usando APIs do próprio Windows.

Com o PID em mãos, o processo malicioso abre o processo alvo com permissões específicas que permitem duplicar handles (identificadores de objetos, como arquivos, soquetes etc). Em seguida, ele enumera todos os handles abertos por aquele processo, procurando especificamente por objetos do tipo `\Device\Afd`, que são usados internamente pelo Windows para representar soquetes TCP.

Depois de encontrar os handles que apontam para esses dispositivos `afd`, o processo invasor duplica cada um deles e usa a função `getpeername` para descobrir com quem aquele soquete está conectado (endereço IP e porta remota). Quando encontra um soquete conectado ao destino que ele está procurando, ele usa `WSADuplicateSocketW` para obter as informações internas necessárias e finalmente chama `WSASocketW` para criar um novo soquete idêntico ao original — agora controlado pelo processo invasor.

Esse novo soquete funciona como uma cópia da conexão original: o invasor pode enviar e receber dados como se fosse o processo legítimo. E o mais interessante (ou preocupante, né) é que essa duplicação é totalmente invisível para ferramentas comuns como `netstat`, já que a tabela de conexões TCP do Windows só mostra os soquetes originais — as duplicatas não aparecem por ali.

Além disso, o PID associado à conexão não muda, mesmo que o processo original seja finalizado, o que pode confundir ainda mais quem está tentando investigar. (Isso daqui é extremamente apelão).

## Avaliação Experimental <a href="#id-953f" id="id-953f"></a>

<figure><img src="/files/wmtAUQV1UWWcImvNflFb" alt=""><figcaption></figcaption></figure>

O ShadowMove é testado em diversos mecanismos de defesas baseados em host e em rede que estão frequentemente presentes em ambientes corporativos. O ShadowMove foi testado em sistemas EDR, melhores produtos de AV e em IDS baseado em host e IDS baseado em rede.

O ShadowMove foi avaliado na presença de EDRs, nomeadamente CrowdStrike Falcon Prevent e Cisco AMP. O EDR é relevante para avaliação porque alguns EDRs, como o CrowdStrike Falcon, são projetados para detectar movimento lateral.

O ShadowMove também é avaliado na presença de produtos antivírus baseados em host: quatro dos 50 principais produtos antivírus foram escolhidos para avaliação (McAfee, Norton, Web root e Bitdefender).

O Windows Defender também foi escolhido porque é o antivírus padrão em sistemas Windows.

Foi comprovado que o ShadowMove consegue contornar todos esses sistemas de proteção baseado em rede e host, permitindo que um atacante seja furtivo durante um processo de movimentação lateral.

— — — — — — —

Bem, esse foi o artigo sobre o ShadowMove. Claramente eu poderia me aprofundar em outras abordagens como: replicação de sockets no linux, o que acontece durante o compartilhamento normal de soquete via WSADuplicateSocket, compartilhamento de sockets no linux, etc.

Talvez eu possa trazer um artigo somente falando sobre isso e testando o ShadowMove no Linux.

Se vocês quiserem acompanhar, podem deixar a curtida de vocês para que eu entenda que realmente o artigo foi bom e que vocês querem o próximo tópico do ShadowMove em ambiente Linux!

:) Até breve

-\
-\
\-

Créditos:\
<https://www.usenix.org/system/files/sec20-niakanlahiji.pdf>\
<https://idiotc4t.com/defense-evasion/shadowmove-emersion-and-think>\
<https://www.ired.team/offensive-security/lateral-movement/shadowmove-lateral-movement-by-stealing-duplicating-existing-connected-sockets>
