inyección de comando PHP create_function eval

2

Estaba leyendo sobre create_function , que se DEPRECTA en PHP 7.2, que es propenso a la inyección de comandos php. Comencé a jugar con él y creé un ejemplo.

El código a continuación debe devolver la versión en minúscula de cada cadena en la matriz.

Mi pregunta es: ¿Por qué usar la función 'array_walk_recursive' parece arreglar la inyección de código en este caso?

Uso legítimo de la función

<?
$arr = ['HELLO'];

array_walk_recursive(
    $arr,
    create_function('&$value, $key', '$value = strtolower($value);')
);
print_r($arr);
?>

Array
(
    [0] => hello
)

Intentando inyectar el comando pero el código PHP no se evalúa. Se devuelve una cadena

<?
$arr = ['PHPINFO();']; 
array_walk_recursive(
    $arr,
    create_function('&$value, $key', '$value = strtolower($value);')
);
print_r($arr);
?>

Array (
    [0] => phpinfo(); 
)

Intentando poner el phpinfo () dentro de create_function

(Tenga en cuenta que se ejecutó phpinfo. La advertencia proviene de un sandbox de php)

<?
$arr = ['anything'];
array_walk_recursive(
    $arr,
    create_function(
        '&$value, $key',
        'phpinfo(); $value = strtolower($value);'
    )
);
print_r($arr);
?>
*<b>Warning</b>:  phpinfo() has been disabled for security reasons in <b>[...][...](32) : runtime-created function</b> on line <b>1</b><br />
Array
(
    [0] => anything
)*
    
pregunta rdlrt 22.08.2018 - 04:10
fuente

1 respuesta

1
  

¿Por qué usar la función 'array_walk_recursive' parece arreglar la inyección de código en este caso?

No es array_walk_recursive lo que está solucionando el problema. El problema es que no hay problema en primer lugar.

No puede usar los argumentos de las funciones create_function para la inyección de código, ya que se tratan como cadenas variables y no se pueden usar para salir del contexto actual.

El parámetro inyectado debería venir de afuera. Por ejemplo:

<?php
$arr = ['a' => 'b', 'c' => 'D']; 
$func = $_GET['x']; /// eg x=strtolower
array_walk_recursive(
    $arr,
    create_function('&$value, $key', '$value = ' . $func . '($value);')
);
print_r($arr);
?>

Ahora puedes obtener ejecución de código:

x=strtolower($value);phpinfo();

Explicación detallada

<?php // I would suggest to copy-paste the below code to somewhere that supports syntax-highlighting, it helps in understanding the issue
$arr = ['a' => 'b', 'c' => 'D']; 
$func = $_GET['x']; /// eg x=strtolower
array_walk_recursive( // apply the function created below to all array elements
    $arr,
    create_function(                      // creating a new function
        '&$value, $key',                  // arguments for the function
        '$value = ' . $func . '($value);' // the function itself.
            // function uses $func from outside this string context (this is the essential part). 
            // $value is the value from the previous parameter. It is just a string here. 
    )
);
print_r($arr);
?>

Cuando esto se llama con x=strtolower($value);phpinfo(); , la función que create_function crea a partir de la cadena dada es básicamente:

function (&$value, $key) {
    $value = strtolower($value);phpinfo();
}

Y luego se llama a esta función para cada entrada de matriz. Podemos ver cómo esto llevará a la ejecución del código.

Si comparamos eso con el código del OP, la función que se crea sería:

function (&$value, $key) {
    $value = strtolower($value);
}

No hay ejecución de código en esta función, ya que no se usó ningún valor externo en la cadena que creó la función.

    
respondido por el tim 22.08.2018 - 12:38
fuente

Lea otras preguntas en las etiquetas