首页 > 其他分享 >[HCTF 2018]Warmup 详细题解

[HCTF 2018]Warmup 详细题解

时间:2024-11-18 16:47:01浏览次数:3  
标签:Warmup mb 题解 HCTF substr file 字符串 php page

知识点:

目录穿越_文件包含

static静态方法

参数传递引用

mb_strpos函数     mb_substr函数

正文:

页面有一张 滑稽 的表情包,查看一下页面源代码,发现提示

那就访问/source.php  得到源码

 <?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {
                return true;
            }

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?> 

可以看到有一个hint.php   访问一下

提示flag not here, and flag in ffffllllaaaagggg       得到了flag文件名

代码审计:

前面都是类中的代码,先看最后的代码


    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  

$_REQUEST 可以接收 GET POST COOKIE 传入的参数

需要存在file参数是字符串类型,并且经过emmm类中的checkFile方法返回true,才能执行include函数进行文件包含

这里没有创建emmm类的实例就可以引用其中的方法,是因为类中static表示是一个静态方法,可以通过类名直接调用,而不需要创建类的实例

目标明确之后开始看emmm类中的代码,类中也只有一个checkFile 方法,所以很简单,顺着往下看

给出了白名单,是source.php 和 hint.php   然后对参数page设置了条件

参数page就是传入的file数据,这里用了&$page,表示可以直接修改传入的变量,而不需要返回值来更新该变量

最终的目的是include $_REQUEST['file'] 包含其中有flag的文件,也就是ffffllllaaaagggg

目标就是让参数file也就是类中参数page包含ffffllllaaaagggg的同时满足checkFile方法返回true

首先page参数需要存在并且是字符串类型,然后if(in_array($page, $whitelist)) 这个判断是无法满足的,因为得有flag文件名,但是没影响,只要不返回false就行,接着往下看

$_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
mb_strpos函数:  查找字符串在另一个字符串中首次出现的位置

mb_strpos ($haystack , $needle , $offset )
$haystack:被搜索的字符串
$needle:  要查找的字符串
$offset:  可选参数,指定从哪个字符开始搜索
//如果为正数,则从字符串的开头开始计算;如果是负数,则从字符串的末尾开始计算
//没有的话默认是0,即从开头开始搜索

mb_substr函数:  从一个字符串中提取子字符串

mb_substr ($str , $start , $length )
//substr() 函数只针对英文字符,而mb_substr()对于中文也适用
$str:    原始字符串
$start:  起始位置,如果为正数,则从字符串的开头开始计算;如果是负数,则从字符串的末尾开始计算
$length: 可选参数,表示要提取的子字符串的长度,如果没赋值,则提取从开始到字符串结束的所有字符

'.' 是 PHP 中的字符串连接运算符,它用于将两个字符串连接在一起,形成一个更长的字符串

在这里,它将 $page 变量的值和一个问号字符 '?' 连接在一起,形成一个新的字符串,在这个新的字符串中查找问号是否存在,那么很明显能找到

首先使用mb_strpos函数找到$page中第一个问号的位置,然后使用mb_substr函数将问号之前的部分赋值作为$_page进行处理
经过mb_strpos和mb_substr函数得到的$_page如果在白名单中,返回true

后面的代码对$page 进行url解密之后赋值给$_page,再次进行mb_substr函数得到新的$_page,再次判断是否在白名单中,不过如果传入的是正常的字符串,url解码之后还是本身,就没意义了
如果这一步进行完$page还不在白名单中,就会返回false
    
结合起来发现,只需要传入一个在白名单内的文件名(source.php或者hint.php)并在后面加上问号?

就可以保证在第二次if(in_array($_page, $whitelist))匹配查找的内容在白名单,返回true,退出checkfile方法,后面的urldecode代码都是用不到的
不在文件名后面加?问号的话代码自动加的?会添加在参数末尾,这样截取的内容就不满足白名单

关于include函数

这样的话,参数的格式就是source.php? + 文件名 

include()函数可以传入文件的绝对路径,也可以是相对路径

而参数是作为include()函数的参数执行文件包含的,绝对路径我们不知道,只能用相对路径

如果直接传入source.php?ffffllllaaaagggg,那么肯定会报错,因为没有这么一个文件名

实践出真知, 使用 include($_GET['file']); 这个简单的代码来简单说明一下

下图中的phpinfo.php是代码文件目录下面的一个php文件,abc是我随便输入的,没有这个目录,如果正常输入abc/phpinfo.php 是不行的,即使这个目录是存在的,也是会报错,因为格式不对

但是只要用../ 退回一级,就可以正常包含phpinfo.php

但是如果把abc 换成 abc? ,只要出现了? 那么就会报错

因为在windows文件名不能包含?

但是这里题目的环境是debian 不是windows系统  所以可以

那么这里搞清楚了,剩下的就是查找flag文件的具体路径了

从source.php?/ffffllllaaaagggg 开始,逐级用../进行目录穿越   经过四次目录穿越发现成功执行了命令,得到了flag

其实发现文件名也提示了我们要使用四层目录,文件名是4个f l a g


构造

http://node4.anna.nssctf.cn:28698/source.php?file=source.php?/../../../../ffffllllaaaagggg

即可得到flag



 

标签:Warmup,mb,题解,HCTF,substr,file,字符串,php,page
From: https://blog.csdn.net/weixin_73904941/article/details/143822545

相关文章

  • CF1499D The Number of Pairs 题解 线性筛
    题目链接:https://codeforces.com/problemset/problem/1499/D题目大意:给你三个整数\(c,d,x\)(\(1\lec,d,x\le10^7\)),问:存在多少对正整数对\((a,b)\)满足:\[c\cdotlcm(a,b)-d\cdotgcd(a,b)=x\]其中,\(lcm(a,b)\)表示整数\(a\)和\(b\)的最大公约数,\(gcd(a,......
  • [ABC380C] Move Segment 题解
    [ABC380C]MoveSegment题解本题主要考察思维能力,其实不难。题目大意给你一个字符串\(s\),\(s\)由\(0\)和\(1\)构成,将其分为块中只有一种数字的块。将给定的第\(k\)块数字为\(1\)的块与第\(k-1\)块合并,并输出修改后的字符串。思路分析直接按照题意模拟即可。建......
  • CF 705 题解
    CF705题解AHulk模拟即可.BSpiderMan打sg表可以发现,奇数个球先手必败(sg=0),偶数先手必胜(sg=1).多个组合只要把sg值异或起来就好.CThor暴力模拟就可以了,用队列模拟.DAntMan结论:按照编号由小到大加入链表,每次尽量让答案最小贪心就是对的.若原来是......
  • CF1023题解
    CF1023A一眼秒之题因为整个s串至多有1个*号,所以可以把s串分为两个部分分别与t串的前后进行匹配,看看前后能不能适配即可注意特判没有*的情况CF1023B一眼秒之题+1简单的,就是一个数k拆成两个数之和,这两个数的值域为(1,n),分讨k为奇偶,然后简单转化即可CF1023C小清新一眼秒之题+1......
  • 题解:CF contest 2037 : [Codeforces Round 988 (Div. 3)] (A-E)
    ATwice题面Kinich醒来迎接新的一天的开始。他打开手机,查看邮箱,发现了一份神秘的礼物。他决定打开礼物的盒子。Kinich用\(n\)整数打开数组\(a\)。最初,Kinich的分数是\(0\)。他将执行任意次数的以下操作:—选择两个索引\(i\)和\(j\)\((1\leqi\lt;j\leqn)\),确......
  • CF1731题解
    推荐食用方法:直接看本人的题面翻译即可,如有写题需要,可以交CF这套题T3、T5质量较高,值得认真思考,T2很神仙,T1、T4相对不太出彩,你问为什么没有T6?因为蒟蒻不会套题洛谷链接套题CF链接T1题面翻译给定一个正整数序列,每次可以将两个数替换为与之乘积相等的两个数,求任意次操作后最大......
  • JMeter响应乱码问题解决方案教程
    前言      ApacheJMeter是性能测试领域的强大工具,但在使用过程中,测试人员常会遇到响应乱码的问题。乱码不仅影响测试结果的可读性,还可能掩盖关键信息,对测试准确性构成威胁。本教程将深入探讨JMeter响应乱码问题的根源,并提供实用的解决方案。你将学习如何识别乱码现象......
  • [ARC187B] Sum of CC 题解
    若\(i\)与\(j\)有边,也就是\(a_i<a_j\),那么对于一个\(i<k<j\),会发现\(a_k>a_i\)和\(a_k<a_j\)至少满足一个。也就是说\(k\)也一定和\(i,j\)联通。于是我们发现了一个关键性质:所有联通块都为一个区间。那我们考虑\(i\)和\(i+1\)什么时候不联通:\(i\)之前的任......
  • AtCoder Beginner Contest 380 (A~E)题解
    A-123233遍历字符串统计出现次数即可。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e6+10;intn,m,k;inta[N];signedmain(){ strings; cin>>s; map<char,int>mp; for(autot:s){ mp[t]++; } if(......
  • P10124 [USACO18OPEN] Family Tree B 题解
    思路这道题目很像找\(2\)头牛的最近公共祖先,即lca,但是并不用那么麻烦.因为数据很小,我们可以写一个山寨版的lca.具体如下.intmother(stringx,stringy){ intres=0; while(y!=""){//有名字的牛 if(x==y)returnres;//两头牛的名字相等,说明是同......