avatar

目录
记一个parse_url的漏洞

记一个parse_url的漏洞

前言

这是在做moeCTF招新时所积累的一个知识,记下来以作为本菜鸡的一点知识储备,以下是原代码:

源码

<?php
    include "config.php";
    $number1 = rand(1,100000000000000);
    $number2 = rand(1,100000000000);
    $number3 = rand(1,100000000);
    $url = urldecode($_SERVER['REQUEST_URI']);
    $url = parse_url($url, PHP_URL_QUERY);
    if (preg_match("/_/i", $url))
    {
        die("...");
    }
    if (preg_match("/0/i", $url))
    {
        die("...");
    }
    if (preg_match("/\w+/i", $url))
    {
        die("...");
    }
    if(isset($_GET['_']) && !empty($_GET['_']))
    {
        $control = $_GET['_'];
        if(!in_array($control, array(0,$number1)))
        {
            die("fail1");
        }
        if(!in_array($control, array(0,$number2)))
        {
            die("fail2");
        }
        if(!in_array($control, array(0,$number3)))
        {
            die("fail3");
        }
        echo $flag;
    }
    show_source(__FILE__);
    ?>

分析

这里有两个关键点:

  1. 绕过前三个正则 ->运用parse_url()的漏洞
  2. 绕过in_array的三个判断 -> PHP弱类型

第二个关键点可以通过传入 _=A 来绕过,因为当传入为字符串时,由于PHP弱类型,会将字符串转换为数字0而满足条件
而第一个关键点则是需要运用parse_url()的漏洞来解决
查找资料后,翻到了chu师傅的博客,这是他博客的链接
简单的来说,就是如果url是以//开始的,则他会认为它是相对 url,而后认为 url 的部件从 url+2 开始
如果 url 为 ///x.php,则 p = e = s = s + 2(查chu师傅博客或者去查PHP手册),函数将返回 NULL。
所以可以构造以下URL来完成绕过:
http://120.77.152.169:8088///index.php?\_=a

文章作者: f1rry
文章链接: http://yoursite.com/2018/09/17/记一个parse-url的漏洞/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 F1rry's blog