[Upload-labs] Pase de bypass de caballo de imagen 13 ~ 16

[Upload-labs] Pase de bypass de caballo de imagen 13 ~ 16


[Pass-13] Omisión de verificación de encabezado de archivo

1. Análisis del código fuente

function getReailFileType($filename){
    
    
    $file = fopen($filename, "rb");  //以字节流的形式打开上传的文件
    $bin = fread($file, 2);   //只读2字节
    fclose($file);
    $strInfo = @unpack("C2chars", $bin);  //unpack()解包,标识前两个字符按照c格式,数组索引chars1、chars2  
    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);   //将两个字节转换为十进制的字符串拼接起来 
    $fileType = '';    
    switch($typeCode){
    
          //根据文件头前两个字节判断是哪种文件类型
        case 255216:            
            $fileType = 'jpg';
            break;
        case 13780:            
            $fileType = 'png';
            break;        
        case 7173:            
            $fileType = 'gif';
            break;
        default:            
            $fileType = 'unknown';     //若不是jpg、png、gif中的任意一种,则设为unknown
        }    
        return $fileType;
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    
    
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $file_type = getReailFileType($temp_file);   //获取文件类型

    if($file_type == 'unknown'){
    
    
        $msg = "文件未知,上传失败!";
    }else{
    
    
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").".".$file_type;
        if(move_uploaded_file($temp_file,$img_path)){
    
    
            $is_upload = true;
        }
        else{
    
    
            $msg = "上传失败";
        }
    }
}

Se puede ver en el código fuente que este nivel no filtra el sufijo, pero verifica los dos primeros bytes del contenido del archivo cargado y combina el mecanismo de filtrado de la lista blanca para permitir que solo se carguen archivos jpg, png y gif.

2. Proceso de prueba

Ideas de explotación de vulnerabilidades:

1. Use burp para capturar el paquete, agregue una cadena de jpg, png o gif al encabezado del contenido del archivo y luego coloque el paquete para evitar la inspección.

Encabezado de archivo común: detallado

1 、 .JPEG; .JPE; .JPG "Archivo JPGGraphic"

2 、 .gif “GIF 89A”

3 、 .zip "ZIP comprimido"

4 、 .doc; .xls; .xlt; .ppt; .apr "Documento compuesto de MS v1 o archivo APR de Lotus Approach"

2. Haga fotos y cárguelas, y use el archivo para contener la vulnerabilidad getshell.

  • método uno:

    Primero cargue un troyano:

    imagen-20210320192737341

    Usa eructos para capturar paquetes

    Agregue el encabezado del archivo .gif (GIF 89A) al encabezado del archivo y luego coloque el paquete:

    imagen-20210320193143212

    Como se muestra en la figura, el archivo se cargó correctamente.

    imagen-20210320193159404

    Combinado con el archivo que contiene la vulnerabilidad, incluya el archivo en el código php y conéctese con un helicóptero a getshell.

  • Método dos:

    Hacer un troyano de imagen:

    Use cmd debajo de la ventana para hacer:

    copy  meinv.png /b + muma.php /a  muma.png
    

    Que /brepresenta un archivo binario binary, colocado detrás de la imagen, /arepresenta un archivo de textoascii

    imagen-20210320195746607

    imagen-20210320195721272

    imagen-20210320195633712

    Como se muestra en la imagen, ¡el caballo de la imagen se hizo con éxito!

    Subir directamente:

    imagen-20210320200049447

    La carga se realiza correctamente y luego, combinada con el archivo, contiene la vulnerabilidad getshell.

resumen:

Este nivel no filtra el sufijo, pero verifica los dos primeros bytes del contenido del archivo cargado y combina el mecanismo de filtrado de la lista blanca para permitir que solo se carguen archivos jpg, png y gif. Por lo tanto, se puede evitar hacer un dibujo de un caballo.

intval()La función devuelve el valor entero de la variable var utilizando la conversión base especificada (decimal por defecto). intval () no se puede usar para el objeto, de lo contrario se generará un error E_NOTICE y se devolverá 1.

unpack()Explicación detallada del desembalaje de funciones


[Pass-14] getimagesize () comprobar el desvío

Análisis de código fuente

function isImage($filename){
    
    
    $types = '.jpeg|.png|.gif';
    if(file_exists($filename)){
    
    
        $info = getimagesize($filename); //函数用于获取图像大小及相关信息(根据文件头),成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。  
        $ext = image_type_to_extension($info[2]);  //根据指定的图像类型返回对应的后缀名。
        if(stripos($types,$ext)){
    
       //判断后缀是否在白名单内
            return $ext;
        }else{
    
    
            return false;
        }
    }else{
    
    
        return false;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    
    
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
    
    
        $msg = "文件未知,上传失败!";
    }else{
    
    
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").$res;
        if(move_uploaded_file($temp_file,$img_path)){
    
    
            $is_upload = true;
        }
        else{
    
    
            $msg = "上传失败";
        }
    }
}

La diferencia con el nivel anterior es que este nivel utiliza la función getimagesize () para obtener la información del contenido de la imagen según el encabezado del archivo. Este nivel requiere la creación de un caballo de imagen (por supuesto, el encabezado GIF 89A también puede ser El proceso de recurrencia de lagunas es similar al nivel anterior, por lo que no lo repetiré aquí. Sin embargo, hay un error en el método de detección en el código anterior, lo que hace que sea imposible cargar archivos .jpeg. Debido a if(stripos($types,$ext))esta declaración, si carga un archivo .jpeg, la función stripos () devolverá la posición del archivo .jpeg. jpeg en $ ext, que obviamente es 0, y 0 es falso, por lo que no ingresará el if, sino que ingresará directamente el else y devolverá falso para que la carga del archivo falle.

getimagesize()Función: se usa para obtener el tamaño de la imagen y la información relacionada, devuelve una matriz si tiene éxito, o FALSE si falla, y se genera un mensaje de error de nivel E_WARNING.

image_type_to_extension()Función: Devuelve el nombre del sufijo correspondiente según el tipo de imagen especificado. Detallado


[Pass-15] omisión de exif_imagetype

Análisis de código fuente

function isImage($filename){
    
    
    //需要开启php_exif模块
    $image_type = exif_imagetype($filename);  //判断一个图像的类型
    switch ($image_type) {
    
    
        case IMAGETYPE_GIF:
            return "gif";
            //break;
        case IMAGETYPE_JPEG:
            return "jpg";
            //break;
        case IMAGETYPE_PNG:
            return "png";
            //break;    
        default:
            return false;
            //break;
    }
}

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    
    
    $temp_file = $_FILES['upload_file']['tmp_name'];
    $res = isImage($temp_file);
    if(!$res){
    
    
        $msg = "文件未知,上传失败!";
    }else{
    
    
        $img_path = $UPLOAD_ADDR."/".rand(10, 99).date("YmdHis").".".$res;
        if(move_uploaded_file($temp_file,$img_path)){
    
    
            $is_upload = true;
        }
        else{
    
    
            $msg = "上传失败";
        }
    }
}

La diferencia entre este nivel y los dos niveles anteriores es que la función exif_imagetype se usa para determinar el tipo de imagen y luego se combina con el mecanismo de lista blanca para filtrar. Por supuesto, se puede omitir a través del caballo de imagen y luego combinarlo con el archivo que contiene lagunas para getshell.

Nota: El módulo php_exif debe activarse cuando se usa la función exif_imagetype, que se explica en detalle en el archivo php.ini

exif_imagetype()Función: Leer el primer byte de una imagen y comprobar su firma, si se encuentra una firma adecuada, devolverá la constante correspondiente, de lo contrario, volverá false. El valor de retorno es el mismo que el valor del índice 2 en la matriz devuelta por getimagesize () , pero esta función es mucho más rápida.

imagen-20210320211900033

[Pass-16] Renderizado secundario

1. Análisis del código fuente

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    
    
    // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=UPLOAD_PATH.'/'.basename($filename);  //basename函数返回路径中的文件名部分。

    // 获得上传文件的扩展名
    $fileext= substr(strrchr($filename,"."),1);

    //判断文件后缀与类型,合法才进行上传操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
    
       //对文件扩展名和mime类型做了判断
        if(move_uploaded_file($tmpname,$target_path)){
    
    
            //使用上传的图片生成新的图片
            $im = imagecreatefromjpeg($target_path); //imagecreatefromjpeg()函数由jpeg文件或URL创建一个新图象。

            if($im == false){
    
    
                $msg = "该文件不是jpg格式的图片!";
                @unlink($target_path);   //删除图片
            }else{
    
    
                //给新图片指定文件名
                srand(time());  //srand()随机数种子生成器
                $newfilename = strval(rand()).".jpg";  //strval()获取变量的字符串值
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagejpeg($im,$img_path);  //输出图象到浏览器或文件。
                @unlink($target_path);   //删除原来图片
                $is_upload = true;
            }
        } else {
    
    
            $msg = "上传出错!";
        }

    }else if(($fileext == "png") && ($filetype=="image/png")){
    
    
        if(move_uploaded_file($tmpname,$target_path)){
    
    
            //使用上传的图片生成新的图片
            $im = imagecreatefrompng($target_path);

            if($im == false){
    
    
                $msg = "该文件不是png格式的图片!";
                @unlink($target_path);
            }else{
    
    
                 //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".png";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagepng($im,$img_path);

                @unlink($target_path);
                $is_upload = true;               
            }
        } else {
    
    
            $msg = "上传出错!";
        }

    }else if(($fileext == "gif") && ($filetype=="image/gif")){
    
    
        if(move_uploaded_file($tmpname,$target_path)){
    
    
            //使用上传的图片生成新的图片
            $im = imagecreatefromgif($target_path);
            if($im == false){
    
    
                $msg = "该文件不是gif格式的图片!";
                @unlink($target_path);
            }else{
    
    
                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".gif";
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = UPLOAD_PATH.'/'.$newfilename;
                imagegif($im,$img_path);

                @unlink($target_path);
                $is_upload = true;
            }
        } else {
    
    
            $msg = "上传出错!";
        }
    }else{
    
    
        $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
    }
}

El back-end realiza la verificación de sufijos y mimos en la imagen cargada. Si pasa, la imagen se renderizará dos veces. Es decir, si insertamos el código php en la imagen, el código php puede perderse después de la segunda renderización. .

2. Proceso de prueba

  • gif

    Sube una imagen gif primero:

    imagen-20210321165613434

    Descarga la imagen cargada:

    imagen-20210321165640630

    Utilice la herramienta de análisis hexadecimal winhex para comparar los cambios entre el archivo y el archivo original:

    imagen-20210321162918345

imagen-20210321165824469

Como se muestra en la figura, la parte blanca no cambia y la parte negra cambia. En este punto, necesitamos insertar el código PHP en el área sin cambios (área blanca) y tener cuidado de no cambiar la cabeza tanto como sea posible, simplemente insértelo en el medio.

imagen-20210321170138307

Entonces guarda.

imagen-20210321170223308

Como se muestra en la figura, abra la imagen modificada y descubra que el código se insertó correctamente.

Sube la imagen modificada:

imagen-20210321170413328

La señorita hermana se volvió así.

Aproveche el archivo que contiene la vulnerabilidad para probar:

imagen-20210321170636381

¡éxito!

Acerca de la producción de renderizado secundario jpg y png es aún más difícil, puede consultar el artículo .

resumen:

Pasar por alto el renderizado secundario es esencialmente para comparar los cambios antes y después del render. Use winhex para insertar código php en el área sin cambios para lograr el bypass.

Supongo que te gusta

Origin blog.csdn.net/qq_43665434/article/details/115052442
Recomendado
Clasificación