【红日Day6-CTF】PHP正则绕过

练习记录

复现代码:

index.php

// index.php
<?php
include 'flag.php';
if  ("POST" == $_SERVER['REQUEST_METHOD'])
{
    $password = $_POST['password'];
    if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password))
    {
        echo 'Wrong Format';
        exit;
    }
    while (TRUE)
    {
        $reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
        if (6 > preg_match_all($reg, $password, $arr))
            break;
        $c = 0;
        $ps = array('punct', 'digit', 'upper', 'lower');
        foreach ($ps as $pt)
        {
            if (preg_match("/[[:$pt:]]+/", $password))
            $c += 1;
        }
        if ($c < 3) break;
        if ("42" == $password) echo $flag;
        else echo 'Wrong password';
        exit;
    }
}
highlight_file(__FILE__);
?>

flag.php

// flag.php
<?php $flag = "HRCTF{Pr3g_R3plac3_1s_Int3r3sting}";?>

漏洞分析:

进入网站:

http://10.211.55.5/PHPcode/day6/index.php

在这里插入图片描述
发现页面正常,可以进行操作了。

这道题目实际上考察的是大家是否熟悉PHP正则表达式的字符类,当然还涉及到一些弱类型比较问题。大家可以先查阅一下PHP手册对这些字符类的定义,具体可点 这里
在这里插入图片描述

题目中总共有三处正则匹配.。
第一处的正则(第6行) /^[[:graph:]]{12,}$/为:

    if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password))

匹配到可打印字符12个以上(包含12)^号表示必须以某类字符开头,$号表示必须以某类字符结尾。
第二处正则表达式(13-15行):

   $reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
        if (6 > preg_match_all($reg, $password, $arr))
            break;

表示字符串中,把连续的符号数字大写小写,作为一段,至少分六段,例如我们输入 H0ng+Ri则匹配到的子串为H 0 ng + R i
第三处的正则表达式(17-23行):

$ps = array('punct', 'digit', 'upper', 'lower');
        foreach ($ps as $pt)
        {
            if (preg_match("/[[:$pt:]]+/", $password))
            $c += 1;
        }
        if ($c < 3) break;

表示为输入的字符串至少含有符号数字大写小写中的三种类型。然后题目最后将 $password42进行了弱比较。
所以我们的payload为:

password=42.00e+00000
password=420.00000e-1

在这里插入图片描述

发布了35 篇原创文章 · 获赞 19 · 访问量 5197

猜你喜欢

转载自blog.csdn.net/zhangpen130/article/details/103950805