最近在写文件包含的ctf题目,有几点心得,想要分享出来;


scandir(‘.’)的用法

 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:49:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

在文件包含中,我们可能会遇到关键词被过滤的情况,这时候方法有几种:
(1)使用system(),echo exec()等函数
(2)使用伪协议php://和data://
(3)还有一种就是scandir(‘.’);

scandir(‘.’) 这种方法可以在上两种方法失效时继续使用

解析:print_r(scandir('.'))
在这里插入图片描述

用法以及解释

本篇文章只说scandir(‘.’)的用法,其他的方法大家如果想了解到话可以评论区支持;

  1. 首先我们要查看当前网站的目录有哪些,先说一个打印当初路径下文件的函数:print_r(scandir(‘.’))
  2. 但是很明显单引号和小数点已经过滤了,这里要先办法绕过。最简单的方法是利用函数传参,那就找当前能用包含小数点的函数
  3. 还真有:localeconv() 用于返回一包含本地数字及货币格式信息的数组

例子:
在这里插入图片描述
可以看到第一个是小数点,实现了小数点的绕过。
那么按找接下来思路就是构造:print_r(scandir(localeconv()[0]))
但是这个函数是不能localeconv()[0]这样返回的,而且方括号也被过滤了,那么就要用到别的函数

  • current() 函数返回数组中的当前元素(单元),默认取第一个值,
  • pos() 同 current() ,是current()的别名
  • reset() 函数返回数组第一个单元的值,如果数组为空则返回 FALSE
    在这里插入图片描述
    结果返回都是小数点:
    在这里插入图片描述
    打印当前目录:print_r(scandir(pos(localeconv())));
    在这里插入图片描述

这里可以的用next()

输出数组中的当前元素的下一个元素的值,也就是可以输出第二个(还有end可以输出最后一个)

但是flag在第三个怎么办?可以用array_reverse函数

这个函数就是将数组转置;
此时payload为:show_source(next(array_reverse(scandir(pos(localeconv())))));
在这里插入图片描述
得到flag;

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐