[Red Day6-CTF] PHP regular bypassed

Exercise Record

Reproduce the code:

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}";?>

Vulnerability Analysis:

Enter the site:

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

Here Insert Picture Description
Found page properly, you can operate the.

This question is actually examined is whether the familiar PHP正则表达式character class, of course, involves some type of relatively weak issues. You can first check what the PHP manual definition of these character classes, specifically point here .
Here Insert Picture Description

The title a total of three regular match ..
At first regular (line 6) is /^[[:graph:]]{12,}$/as follows:

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

Match to printable characters 12个以上(包含12), ^numerals must start with certain characters, $numerals must end with certain characters.
At the second regular expression (lines 13-15):

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

Represents a string, the continuous 符号, , 数字, 大写, 小写as a piece, at least partial 六段, for example, we input H0ng+Rithe matched substring is H 0 ng + R i.
At the third regular expression (lines 17-23):

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

Represents input string comprising at least 符号, 数字, 大写, 小写of the three types. Finally, the topic then $passwordand 42were relatively weak.
So we are payloadas follows:

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

Here Insert Picture Description

Published 35 original articles · won praise 19 · views 5197

Guess you like

Origin blog.csdn.net/zhangpen130/article/details/103950805