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 小时前
SQLMap 入门实战指南:原理、命令详解与防御(攻防世界-inget)
学习·web安全·网络安全
ShoreKiten1 小时前
命令执行专题(持续更新)
web安全·php·ctf·rce
廋到被风吹走1 小时前
持续学习方向 AI工程化(TensorFlow Serving、MLflow)
人工智能·学习·tensorflow
Once_day1 小时前
AI实践(0)学习路线
人工智能·学习·ai实践
读研的武2 小时前
Golang学习笔记 入门篇
笔记·学习·golang
啊阿狸不会拉杆2 小时前
《计算机视觉:模型、学习和推理》第 18 章-身份与方式模型
人工智能·python·学习·计算机视觉·分类·子空间身份模型·plda
adore.9682 小时前
3.11 复试学习
学习
自传丶2 小时前
【学习笔记】大模型应用开发系列(二)Embedding 模型
笔记·学习·embedding
文刀竹肃2 小时前
SQLi-Labs Less-1 通关教程
安全·web安全·网络安全