Falando sobre injeção de concha

O que é injeção Shell

A injeção de shell também é chamada de injeção de comando do sistema operacional, que se refere ao uso de vulnerabilidades no programa para construir uma sequência de instruções maliciosas para fazer o programa alvo executar o comando do invasor. A injeção de shell é nomeada a partir do shell do Unix, mas a maioria dos programas em execução em sistemas que permitem que os programas chamem a interface de linha de comando podem introduzir inadvertidamente vulnerabilidades relacionadas à injeção de shell. As interfaces com riscos potenciais de injeção Shell incluem aquelas em Java java.lang.Runtime.exec()e .NET System.Diagnostics.Process.Start().

Em comparação com vulnerabilidades como injeção de SQL, injeção de shell raramente é mencionada, mas como pode entrar em contato diretamente com recursos fora do programa, geralmente tem um impacto mais sério.

Este artigo foi escrito porque uma vulnerabilidade de injeção de shell foi descoberta em um programa de demonstração escrito por um amigo, então reescrevi o programa como um exemplo no início. No código Java a seguir, o front-end passa o nome da imagem docker para o servidor back-end, e o servidor back-end chama o docker pullcomando para obter o arquivo de imagem correspondente.

String imageName = (String) params.get("imageName");
String cmd = "docker pull " + imageName;
Process process = Runtime.getRuntime().exec(cmd);
// ...

Quando o imageNamevalor do parâmetro passado pelo front end é um nome de imagem normal (por exemplo nginx), o docker pull nginxcomando será executado para puxar a imagem nginx. E o imageNamevalor do parâmetro passado pelo front end nginx; echo hacked, ou seja , quando houver uma instrução maliciosa echo hacked, o programa de back end docker pull nginxexecutará o echo hackedcomando após a execução bem-sucedida . Para demonstrar conveniência e evitar operação incorreta, echocomandos intuitivos e inofensivos são usados ​​aqui. O resultado da execução deste comando diretamente no terminal é o seguinte:

# 示例中省略了执行结果与本文无关的一些输出信息
$ docker pull nginx; echo hacked
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
hacked # <- 此处为执行恶意命令的结果

A seguir, apresentaremos várias formas de injeção de Shell com um programa PHP da DVWA.

Método de injeção de casca

A seguir está um programa PHP que aceitará um parâmetro ip do cliente como o parâmetro do comando ping e produzirá o resultado da operação.

$target = $_REQUEST['ip'];
$cmd = shell_exec('ping -c 4 ' . $target);

echo "<pre>{
      
      $cmd}</pre>";

Nesta seção, vários métodos de injeção de Shell serão introduzidos por meio dos procedimentos acima.Os exemplos usarão comandos com resultados intuitivos e inofensivos como demonstrações.

  • ; Instrução contínua

Ao usar um comando contínuo command1; command2, o command1comando continuará a ser executado após o command2comando ter sido executado. Em um exemplo, quando o parâmetro é inserido pelo usuário 127.0.0.1; echo hacked, o programa é executado no primeiro ping -c 4 127.0.0.1comando, a execução continuará para completar echo hackedo comando. A saída deste comando em execução no terminal é a seguinte:

$ ping -c 4 127.0.0.1; echo hacked
PING 127.0.0.1 (127.0.0.1): 56 data bytes
# ... ping的执行结果
4 packets transmitted, 4 packets received, 0.0% packet loss
hacked # <- echo hacked的执行结果
  • pipeline |

Por command1 | command2usando um tubo, ele vai concluir a execução command1como sua saída após a command2entrada. Por exemplo, parâmetros de entrada 127.0.0.1 | grep loss, o programa emitirá ping -c 4 127.0.0.1o comando como grep lossum comando de entrada. O comando grep lossproduzirá a linha com perda na saída do comando ping, por exemplo:

$ ping -c 4 127.0.0.1 | grep loss
4 packets transmitted, 4 packets received, 0.0% packet loss
  • & Execução em segundo plano

Usar depois &do comando significa que o comando será executado em segundo plano. Quando &outros comandos são seguidos ( command1 & command2), eles serão executados em segundo plano command1e em primeiro plano command2. Por exemplo, um comando ping -c 4 127.0.0.1 & echo hackedserá executado em segundo plano ping -c 4 127.0.0.1e executará o echo hackedcomando. Geralmente, o resultado deste comando é o seguinte:

$ ping -c 4 127.0.0.1 & echo hacked
[1] 2333 # <- ping命令的进程号
hacked # <- echo hacked的执行结果
PING 127.0.0.1 (127.0.0.1): 56 data bytes
# ... ping的执行结果

Nota: O pingcomando envolve E / S de rede, portanto, a saída é após o echocomando, não depois que o pingcomando é echoexecutado.

  • &&contra||

&&E ||semelhante, use ambos command1 && command2ou command1 || command2. A diferença entre os dois é && command2que o meio command2é command1executado depois que a execução é bem-sucedida (o código de saída é 0), e o || command2meio command2é command1executado depois que a execução falha (o código de saída é um valor diferente de zero).

  • `command`contra$(command)

Ambos os tipos de ações executarão commandcomandos. Quando o comando é command1 $(command2)a hora ( command1 `command2`o mesmo token), é command2emitido como um command1parâmetro. Assim como os parâmetros de entrada do usuário $(echo hacked), a execução do programa pinganterior executará primeiro echo hackedo comando.

Além da forma acima descrita em vários injecção de concha, por exemplo de redireccionamento ( >,, >>, <) <<e semelhantes podem também ser usadas por um invasor.

Medidas de defesa contra injeção de granada

  • Evite a execução direta de comandos inseridos pelo usuário

No programa, você deve tentar evitar a execução de comandos por meio da interface de linha de comando ou deve evitar usar diretamente os dados inseridos pelo usuário como parâmetros do comando shell. Como o comando Docker no início do artigo, você pode usar a interface API fornecida pelo Docker para extrair a imagem correspondente em vez de usar o docker pullcomando diretamente .

  • Verifique os parâmetros inseridos pelo usuário

Como no programa ping no exemplo acima, supondo que o parâmetro de que ele precisa seja um endereço IPv4, o formato do parâmetro pode ser verificado por meio da regularização para ver se é uma string de endereço IPv4 válida.

$target = $_REQUEST['ip'];
if (!preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $target)) {
    
    
  throw new Exception('Invalid ip');
}

$cmd = shell_exec('ping  -c 4 ' . $target);

echo "<pre>{
      
      $cmd}</pre>";
  • Filtrar símbolos comuns

Acima mencionado inclui um filtro |, &, ;e outros símbolos, se o parâmetro desejado compreende um determinado símbolo, o símbolo pode ser de escape. Por exemplo, o echo hacked \&comando não será executado em segundo plano e o resultado de saída será hacked &.

  • Use o mecanismo de lista negra e branca

Crie uma lista negra e uma lista branca para limitar os parâmetros permitidos pelo comando.

  • Use o método de transcodificação fornecido pelo idioma

Algumas linguagens fornecem métodos para transcodificar parâmetros de shell, como aqueles em php escapeshellarg(), mas não podem ser totalmente confiáveis ​​como seguros.

  • Use o usuário menos privilegiado para executar o programa

Por exemplo, em um aplicativo da web, os usuários com as permissões mínimas necessárias são usados ​​para executar o aplicativo. Esta medida não é uma medida de defesa real, visa evitar um maior impacto após o ataque, e não se limita a ser utilizada para tratar a injeção de Shell.

Referência

Acho que você gosta

Origin blog.csdn.net/ghosind/article/details/106198393
Recomendado
Clasificación