comando PHP injection create_function eval

2

Stavo leggendo sulla create_function , che sarà DEPRECATED su PHP 7.2, che è incline all'input del comando php. Ho iniziato a giocarci e ho creato un esempio.

Il codice seguente dovrebbe restituire la versione in caratteri minuscoli di ciascuna stringa nell'array.

La mia domanda è, perché usare la funzione 'array_walk_recursive' sembra risolvere il codice di iniezione in questo caso?

Uso legittimo della funzione

<?
$arr = ['HELLO'];

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

Array
(
    [0] => hello
)

Tentativo di inserire il comando ma il codice PHP non viene valutato. Una stringa viene restituita

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

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

Sto cercando di mettere il phpinfo () all'interno di create_function

(nota che phpinfo è in esecuzione. L'avviso proviene da una sandbox 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
)*
    
posta rdlrt 22.08.2018 - 04:10
fonte

1 risposta

1

Why using 'array_walk_recursive' function seems to fix the code injection in this case?

Non è array_walk_recursive a risolvere il problema. Il problema è che non vi è alcun problema in primo luogo.

Non è possibile utilizzare gli argomenti delle funzioni create_function per l'iniezione di codice, poiché vengono trattati come stringhe variabili e non possono essere utilizzati per uscire dal contesto corrente.

Il parametro iniettato dovrebbe venire dall'esterno. Ad esempio:

<?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);
?>

Ora potresti ottenere l'esecuzione del codice:

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

Spiegazione dettagliata

<?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);
?>

Quando viene chiamato con x=strtolower($value);phpinfo(); , la funzione che create_function crea dalla stringa data è fondamentalmente:

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

E poi questa funzione viene chiamata per ogni voce dell'array. Possiamo vedere come questo porterà all'esecuzione del codice.

Se lo confrontiamo con il codice dall'OP, la funzione che verrà creata sarà:

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

Non è prevista l'esecuzione di codice in questa funzione, poiché nella stringa che ha creato la funzione non è stato utilizzato alcun valore esterno.

    
risposta data 22.08.2018 - 12:38
fonte

Leggi altre domande sui tag