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

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

内容简介:记一次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原生文件操作类

五.后记:

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


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

查看所有标签

猜你喜欢:

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

IT不再重要

IT不再重要

(美)尼古拉斯·卡尔 / 闫鲜宁 / 中信出版社 / 2008-10 / 29.00元

在这部跨越历史、经济和技术领域的著作中,作者从廉价的电力运营方式对社会变革的深刻影响延伸到互联网对我们生活的这个世界的重构性影响。他批判式的认为,企业想应用网络或应用程序,不再需要自建资料中心、自组IT团队维护和管理系统,因为互联网就像自来水或电力一样,可由专门公司提供服务,你可以付费使用。而如果他的设想真的会实现,我们的世界将会变成什么样子?IT产业的命运又将如何?这又对企业的IT领域投资产生什......一起来看看 《IT不再重要》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码