从一道CTF练习题浅谈php原生文件操作类

栏目: PHP · 发布时间: 7年前

内容简介:记一次CTF练习有感,觉得需要记录一波…还有就是最近CTF比赛中利用php原生类来进行反序列化的题目比较多,所以就紧跟时代潮流…顾名思义,SPL就是Standard PHP Library的缩写。据手册显示,SPL是用于解决

从一道CTF练习题浅谈 <a href='https://www.codercto.com/topics/18749.html'>php</a> 原生文件操作类

前言

记一次CTF练习有感,觉得需要记录一波…还有就是最近CTF比赛中利用php原生类来进行反序列化的题目比较多,所以就紧跟时代潮流…

一.SPL

顾名思义,SPL就是Standard PHP Library的缩写。据手册显示,SPL是用于解决 典型问题(standard problems) 的一组接口与类的集合。打开 手册 ,正如上面的定义一样,有许多封装好的类。因为是要解决典型问题,免不了有一些处理文件的类。

从一道CTF练习题浅谈php原生文件操作类

从一道CTF练习题浅谈php原生文件操作类

一.可遍历目录类

DirectoryIterator

FilesystemIterator

GlobIterator 与上面略不同,该类可以通过模式匹配来寻找文件路径。

二.可读取文件类

SplFileObject 在此函数中,URL 可作为文件名,不过也要受到 allow_url_fopen 影响。

二.文件系统相关扩展

finfo 该类的构造函数 finfo::__construct — 别名 finfo_open() ,也可以读取文件。

从一道CTF练习题浅谈php原生文件操作类

三.例题

题目是websec上面的 第12关

从一道CTF练习题浅谈php原生文件操作类

题目可以见源码就一句

echo new [class]([first parameter],[second parameter]);

类的名字可控,类的参数可控,个数为二,题目说过滤了(实际可以绕过)上述提到的 splfileobject , globiterator , filesystemiterator ,and directoryiterator 等诸多函数,考虑使用 finfo 类,正好开了此拓展。

从一道CTF练习题浅谈php原生文件操作类

可以读到文件,但是 $key 未知

从一道CTF练习题浅谈php原生文件操作类

关键代码大致如下:

<?php
    ini_set('display_errors', 'on');
    ini_set('error_reporting', E_ALL);
    ....
    $key = ini_get ('user_agent');
    if ($_SERVER['REMOTE_ADDR'] === '127.0.0.1') {
         if ($_SERVER['HTTP_USER_AGENT'] !== $key) {
             die ("Cheating is bad, m'kay?");
         }
    }
     $i = 0;
    $flag = '';
    foreach (str_split (base64_decode ($text)) as $letter) {
        $flag .= chr (ord ($key[$i++]) ^ ord ($letter));
    }

要想得到flag,则需要知道 php.ini 文件中的 user_agent ,尝试读取 php.ini 文件,路径未知,无果。

尝试使用 SplFileObject 访问VPS,得到服务器自身的user_agent。利用 绕过得到 user_agent

从一道CTF练习题浅谈php原生文件操作类

四.问题成因分析

调试一下为什么 finfo 会将文件信息(当然这一些都是建立在程序警告、报错消息开启的情况下

ini_set('display_errors', 'on');ini_set('error_reporting', E_ALL); )爆出来的原因。

编译过程就略过了,用的是php-7.0的源码。在 ext/fileinfo/fileinfo.c 文件的285行出下断点。也即 finfo_open 函数处

/* {{{ proto resource finfo_open([int options [, string arg]])
   Create a new fileinfo resource. */
PHP_FUNCTION(finfo_open)
{
    zend_long options = MAGIC_NONE;
    char *file = NULL;

从一道CTF练习题浅谈php原生文件操作类

1.php 内容为:

<?php
ini_set('display_errors', 'on');
ini_set('error_reporting', E_ALL);
echo new finfo(1,'1.php')

忽略一些过渡的函数调用如 magic_load -> file_apprentice -> apprentice_1 -> apprentice_load -> load_1 来到 ext/fileinfo/apprentice.c 文件1025行处,也即 load_1 函数处

/*
 * Load and parse one file.
 */
private void
load_1(struct magic_set *ms, int action, const char *fn, int *errs,#flag
   struct magic_entry_set *mset)
{
    char buffer[BUFSIZ + 1];
    char *line = NULL;
    size_t len;
    size_t lineno = 0;
    struct magic_entry me;

    php_stream *stream;


    ms->file = fn;
    stream = php_stream_open_wrapper((char *)fn, "rb", REPORT_ERRORS, NULL);

    if (stream == NULL) {
        if (errno != ENOENT)
            file_error(ms, errno, "cannot read magic file `%s'",
                   fn);
        (*errs)++;
        return;
    }

    memset(&me, 0, sizeof(me));
    /* read and parse this file */
    for (ms->line = 1; (line = php_stream_get_line(stream, buffer , BUFSIZ, &len)) != NULL; ms->line++) {
        if (len == 0) /* null line, garbage, etc */
            continue;
        if (line[len - 1] == 'n') {
            lineno++;
            line[len - 1] = ''; /* delete newline */
        }

php_stream_get_line 函数将 finfo 要读取的文件一行行读出

从一道CTF练习题浅谈php原生文件操作类

随后将一行行内容进入 parse 函数进行解析,

switch (parse(ms, &me, line, lineno, action)) {
            case 0:
                continue;
            case 1:
                (void)addentry(ms, &me, mset);

parse 函数解析内容是否有效

/*
 * parse one line from magic file, put into magic[index++] if valid
 */
private int
parse(struct magic_set *ms, struct magic_entry *me, const char *line,
    size_t lineno, int action)
{

对于不符合magic文件内容格式的则会发出相应警告,从而一句句报出文件信息。

file_magwarn(ms, "offset `%s' invalid", l);#1802行
    file_magwarn(ms, "type `%s' invalid", l);  #1950行

从一道CTF练习题浅谈php原生文件操作类

五.后记:

上诉里面有一些东西只是简单提一下,希望能抛砖引玉。在一些情况下,如反序列化和其他某些特定场所,原生文件操作类也许能发挥不小的作用。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Dynamic Programming

Dynamic Programming

Richard Bellman / Dover Publications / 2003-03-04 / USD 19.95

An introduction to the mathematical theory of multistage decision processes, this text takes a "functional equation" approach to the discovery of optimum policies. The text examines existence and uniq......一起来看看 《Dynamic Programming》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具