[XDCTF 2015]filemanager

[XDCTF 2015]filemanager

我们打开题目,大概看了下存在文件上传功能,并且可以执行重命名和删除文件的操作

在这里插入图片描述

扫描目录发现有源码泄露

在这里插入图片描述

我们逐一分析

upload.php

<?php
require_once "common.inc.php";if ($_FILES) {$file = $_FILES["upfile"];if ($file["error"] == UPLOAD_ERR_OK) {$name = basename($file["name"]);$path_parts = pathinfo($name);if (!in_array($path_parts["extension"], array("gif", "jpg", "png", "zip", "txt"))) {exit("error extension");}$path_parts["extension"] = "." . $path_parts["extension"];$name = $path_parts["filename"] . $path_parts["extension"];// $path_parts["filename"] = $db->quote($path_parts["filename"]);// Fix$path_parts['filename'] = addslashes($path_parts['filename']);$sql = "select * from `file` where `filename`='{$path_parts['filename']}' and `extension`='{$path_parts['extension']}'";$fetch = $db->query($sql);if ($fetch->num_rows > 0) {exit("file is exists");}if (move_uploaded_file($file["tmp_name"], UPLOAD_DIR . $name)) {$sql = "insert into `file` ( `filename`, `view`, `extension`) values( '{$path_parts['filename']}', 0, '{$path_parts['extension']}')";$re = $db->query($sql);if (!$re) {print_r($db->error);exit;}$url = "/" . UPLOAD_DIR . $name;echo "Your file is upload, url:<a href=\"{$url}\" target='_blank'>{$url}</a><br/><a href=\"/\">go back</a>";} else {exit("upload error");}} else {print_r(error_get_last());exit;}
}

首先检查上传文件的文件拓展名是否在白名单中,然后使用addslashes()函数对文件名进行转义处理,进行sql语句查询,如果不存在。那么上传文件到/uploads/文件名,执行insert命令将文件名和拓展名插入该数据表file中

接着看common.inc.php

<?php
$DATABASE = array("host" => "127.0.0.1","username" => "root","password" => "ayshbdfuybwayfgby","dbname" => "xdctf",
);$db = new mysqli($DATABASE['host'], $DATABASE['username'], $DATABASE['password'], $DATABASE['dbname']);
$req = array();foreach (array($_GET, $_POST, $_COOKIE) as $global_var) {foreach ($global_var as $key => $value) {is_string($value) && $req[$key] = addslashes($value);}
}define("UPLOAD_DIR", "upload/");function redirect($location) {header("Location: {$location}");exit;
}

告诉我们数据库的信息,然后用foreach嵌套循环$_GET, $_POST, $_COOKIE参数是否为字符串,如果是则进行转义处理

然后看rename.php

<?php
require_once "common.inc.php";if (isset($req['oldname']) && isset($req['newname'])) {$result = $db->query("select * from `file` where `filename`='{$req['oldname']}'");if ($result->num_rows > 0) {$result = $result->fetch_assoc();} else {exit("old file doesn't exists!");}if ($result) {$req['newname'] = basename($req['newname']);$re = $db->query("update `file` set `filename`='{$req['newname']}', `oldname`='{$result['filename']}' where `fid`={$result['fid']}");if (!$re) {print_r($db->error);exit;}$oldname = UPLOAD_DIR . $result["filename"] . $result["extension"];$newname = UPLOAD_DIR . $req["newname"] . $result["extension"];if (file_exists($oldname)) {rename($oldname, $newname);}$url = "/" . $newname;echo "Your file is rename, url:<a href=\"{$url}\" target='_blank'>{$url}</a><br/><a href=\"/\">go back</a>";}
}
?>

如果请求中存在oldname和newname参数,那么连接数据库进行查询旧文件名是否存在,如果查到那么用update命令去更新该文件名,然后定义newname为/upload/新文件名.拓展名,echo新的文件上传路径

delete.php

<?php
require_once "common.inc.php";if(isset($req['filename'])) {$result = $db->query("select * from `file` where `filename`='{$req['filename']}'");if ($result->num_rows>0){$result = $result->fetch_assoc();}$filename = UPLOAD_DIR . $result["filename"] . $result["extension"];if ($result && file_exists($filename)) {$db->query('delete from `file` where `fid`=' . $result["fid"]);unlink($filename);redirect("/");}
}
?>

就是查询文件是否存在,如果存在则执行delete命令删除文件

既然题目存在文件上传功能,那么我们的思路肯定就是如何传马,但是由于上传时有白名单,那么我们就无法解析php后缀的文件。

我们是否可以尝试将jpg后缀改为php后缀呢,我们重点看向rename.php的这段代码

if ($result) {$req['newname'] = basename($req['newname']);$re = $db->query("update `file` set `filename`='{$req['newname']}', `oldname`='{$result['filename']}' where `fid`={$result['fid']}");if (!$re) {print_r($db->error);exit;}$oldname = UPLOAD_DIR . $result["filename"] . $result["extension"];$newname = UPLOAD_DIR . $req["newname"] . $result["extension"];if (file_exists($oldname)) {rename($oldname, $newname);}$url = "/" . $newname;echo "Your file is rename, url:<a href=\"{$url}\" target='_blank'>{$url}</a><br/><a href=\"/\">go back</a>";}

update命令涉及到参数newname以及从数据库中查找参数oldname值,而后面进行rename()的时候是文件名(不包括拓展名),并且后面拼接路径是从数据库中查找拓展名,那么是不是可以文件名为1.php,然后拓展名为空即可实现getshell

我们可以本地测试下如何利用update语句让拓展名为空

上传', extension=",filename='1.jpg.jpg后,存储在数据库中

在这里插入图片描述

如果我们更新文件名为1.jpg(也就是对文件名', extension='',filename='1.jpg),并且让extension为空

那么我们更新的时候拼接进去的是

update uploadfile set filename='1.jpg', oldname='', extension='',filename='1.jpg';

至于为什么选择在oldname注入,是因为文件上传的时候虽然做了转义但是文件名并不会发生改变,然后在rename的时候oldname是从数据库中找到,而我们在newname注入的话,会发生转义导致文件路径包含\

在这里插入图片描述

因此成功设置extension为空

在这里插入图片描述

然后我们要将文件名1.jpg修改为1.php,这里就需要绕过file_exists()

因为虽然找得到1.jpg的文件名,但是没有拓展名使得判断为错

if (file_exists($oldname)) {rename($oldname, $newname);}

解决办法就是再上传一个1.jpg的文件,和前面提到还是一样,这里的$oldname是从数据库中得到的,也就是说文件名1.jpg拼接上空拓展名就等于文件名1拼接上拓展名.jpg,这样就能查询到存在使其为真

回到题目,我们先上传', extension='',filename='1.jpg.jpg(别忘了是两个jpg)

在这里插入图片描述

然后oldname填', extension='',filename='1.jpg

在这里插入图片描述

这样经过拼接就可以实现让extension为空,然后上传最关键一步1.jpg

然后rename为1.php

在这里插入图片描述

得到flag

在这里插入图片描述

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

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

相关文章

基于RetinaFace+Jetson Nano的智能门锁系统——第一篇(烧录系统)

文章目录 设备1.首先在PC端安装VMware虚拟机和Ubuntu182.安装VMware Tools3.安装SDK Manager 设备 Jetson NanoMicro-USB - USB-A电源线HDMI线屏幕PC一台 1.首先在PC端安装VMware虚拟机和Ubuntu18 VMware下载地址&#xff1a;https://www.vmware.com/cn/products/workstatio…

软件测试/测试开发丨Windows系统chromedriver安装与环境变量配置

一、selenium 环境配置 1、chrome 浏览器的安装与配置 目前比较常用的浏览器是 Google Chrome 浏览器&#xff0c;所以本教程以 chrome 为主&#xff0c;后面简介一下其他浏览器的环境配置。 &#xff08;1&#xff09;chrome 下载: www.google.cn/chrome/ &#xff08;2&a…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑用户禀赋效应和环保意识不确定性的微电网鲁棒优化调度方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主的专栏栏目《论文与完整程序》 这个标题涉及到微电网系统的优化调度方法&#xff0c;特别考虑了两个重要方面&#xff1a;用户禀赋效应和环保意识的不确定性。以下是对标题中关键术语的解…

代码随想Day55 | 392.判断子序列、115.不同的子序列

392.判断子序列 第一种思路是双指针&#xff0c;详细代码如下&#xff1a; class Solution { public:bool isSubsequence(string s, string t) {//双指针if(s.empty()&&t.empty()) return true;int i0,j0;while(i<t.size()){if(s[j]t[i]) j;if(js.size()) return t…

Springboot整合Elasticsearch 7.X 复杂查询

这里使用Springboot 2.7.12版本&#xff0c;Elasticsearch为7.15.0。 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId></dependency> yaml文件配置…

JAVA反序列化之URLDNS链分析

简单介绍下urldns链 在此之前最好有如下知识&#xff0c;请自行bing or google学习。 什么是序列化 反序列化 &#xff1f;特点&#xff01; java对象反射调用&#xff1f; hashmap在java中是一种怎样的数据类型&#xff1f; dns解析记录有那…

tp5+workman(GatewayWorker) 安装及使用

一、安装thinkphp5 1、宝塔删除php禁用函数putenv、pcntl_signal_dispatch、pcntl_wai、pcntl_signal、pcntl_alarm、pcntl_fork&#xff0c;执行安装命令。 composer create-project topthink/think5.0.* tp5 --prefer-dist 2、配置好站点之后&#xff0c;浏览器打开访问成…

有道翻译web端 爬虫, js

以下内容写于2023-12-28, 原链接为:https://fanyi.youdao.com/index.html#/ 1 在输入框内输入hello world进行翻译,通过检查发出的网络请求可以看到翻译文字的http接口应该是: 2 复制下链接最后的路径,去js文件中搜索下: 可以看到这里是定义了一个函数B来做文字的翻译接口函数…

消息中间件常见知识点

一&#xff1a;消息队列的主要作用是什么&#xff1f; 1.消息队列的特性&#xff1a; 业务无关&#xff0c;一个具有普适性质的消息队列组件不需要考虑上层的业务模型&#xff0c;只做好消息的分发就可以了&#xff0c;上层业务的不同模块反而需要依赖消息队列所定义的规范进行…

如何在2024年编写Android应用程序

如何在2024年编写Android应用程序 本文将介绍以下内容&#xff1a; 针对性能进行优化的单活动多屏幕应用程序 &#x1f92b;&#xff08;没有片段&#xff09;。应用程序架构和模块化 → 每个层面。Jetpack Compose 导航。Firestore。应用程序架构&#xff08;模块化特征驱动…

【C++】STL 容器 - map 关联容器 ③ ( map 容器常用 api 操作 | map 容器迭代器遍历 | map#insert 函数返回值处理 )

文章目录 一、map 容器迭代器遍历1、map 容器迭代器2、代码示例 二、map 容器插入结果处理1、map#insert 函数返回值处理2、代码示例 一、map 容器迭代器遍历 1、map 容器迭代器 C 语言中 标准模板库 ( STL ) 的 std::map 容器 提供了 begin() 成员函数 和 end() 成员函数 , 这…

Seata服务搭建与模式实现

日升时奋斗&#xff0c;日落时自省 目录 1、简述 2、Seata优越性 3、Seata组成 4、Seata模式 4.1、XA 模式 4.2、AT 模式(默认模式) 4.3、TCC 模式 4.4、SAGA 模式 4.5、XA协议 5、Seata服务部署 5.1、文件数据源部署 5.1.1、下载并安装Seata 5.1.2、启动Seata服…

Ts自封装WebSocket心跳重连

WebSocket是一种在单个TCP连接上进行全双工通信的协议&#xff0c;允许客户端和服务器之间进行双向实时通信。 所谓心跳机制&#xff0c;就是在长时间不使用WebSocket连接的情况下&#xff0c;通过服务器与客户端之间按照一定时间间隔进行少量数据的通信来达到确认连接稳定的手…

HarmonyOS4.0系统性深入开发11通过message事件刷新卡片内容

通过message事件刷新卡片内容 在卡片页面中可以通过postCardAction接口触发message事件拉起FormExtensionAbility&#xff0c;然后由FormExtensionAbility刷新卡片内容&#xff0c;下面是这种刷新方式的简单示例。 在卡片页面通过注册Button的onClick点击事件回调&#xff0c;…

数据库中的时间和前台展示的时间不一样,如何保存日期格式的数据到数据库? 如何展示数据库的日期数据到前台

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; ✈️公众号 | 热爱技术的小郑 文章底部有个人公众号二维码。回复 Java全套视频教程 或 前端全套视频教程 即可获取 300G 教程资料…

【深入浅出RocketMQ原理及实战】「云原生升级系列」打造新一代云原生“消息、事件、流“统一消息引擎的融合处理平台

打造新一代云原生"消息、事件、流"统一消息引擎的融合处理平台 云原生架构RocketMQ的云原生架构实现RocketMQ的云原生发展历程互联网时期的诞生无法支持云原生的能力 云原生阶段的升级云原生升级方向促进了Mesh以及多语言化发展可分合化的存算分离架构存储分离架构的…

听GPT 讲Rust源代码--library/portable-simd

File: rust/library/portable-simd/crates/core_simd/examples/spectral_norm.rs spectral_norm.rs是一个示例程序&#xff0c;它展示了如何使用Portable SIMD库中的SIMD&#xff08;Single Instruction Multiple Data&#xff09;功能来实现频谱规范化算法。该示例程序是Rust源…

跟着cherno手搓游戏引擎【2】:日志系统spdlog和premake的使用

配置&#xff1a; 日志库文件github&#xff1a; GitHub - gabime/spdlog: Fast C logging library. 新建vendor文件夹 将下载好的spdlog放入 配置YOTOEngine的附加包含目录&#xff1a; 配置Sandbox的附加包含目录&#xff1a; 包装spdlog&#xff1a; 在YOTO文件夹下创建…

在Django中配置PostgreSQL

下载并安装PostgreSQL PostgreSQL: Downloads 安装依赖psycopg2 python -m pip install psycopg2 修改Django配置文件settings.py &#x1f4cc;编辑 mysite/settings.py 文件前&#xff0c;先设置 TIME_ZONE 为你自己时区。 LANGUAGE_CODE zh-Hans TIME_ZONE Asia/Shang…

【Elasticsearch源码】 分片恢复分析

带着疑问学源码&#xff0c;第七篇&#xff1a;Elasticsearch 分片恢复分析 代码分析基于&#xff1a;https://github.com/jiankunking/elasticsearch Elasticsearch 8.0.0-SNAPSHOT 目的 在看源码之前先梳理一下&#xff0c;自己对于分片恢复的疑问点&#xff1a; 网上对于E…