Life has its own fate, and meeting may not be accidental.

0%

正则限制加科学计数法绕过

比赛遇到一题源码泄露的题,思路没拓展开+经验不足,希望以后能发散性思维,吸取教训!

大门就是gedit备份泄露

gedit写代码时,目录下有后面带”~”的备份文件

来自RoarNya

第一关

username必须要等于1024并且要小于1024,因为是==,所以可以用四舍五入绕过

php中四舍五入精度要求很高,我这边用了14个9

第二关

1
if(0>= preg_match('/^[[:graph:]]{12,}$/', $password)
2
3
意思是匹配到除空格符(空格键与[TAB]键)之外的所有按键,大于等于12

第三关

进去while
[[:punct:]] 任何标点符号
[:digit:] 任何数字
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母

1
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
2
if(6 > preg_match($reg, $password,$arr)){
3
    break;
4
}
5
匹配到的不同字符不能大于6

第四关

[[:punct:]] 任何标点符号
[:digit:] 任何数字
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母

以上四种匹配要大于三次,否则break

并且password 的值==2048

1
$c =0;
2
$ps = array('punct','digit','upper','lower');
3
foreach ($ps as $pt){
4
    if(preg_match("/[[:$pt:]]+/",$password)) {
5
        $c += 1;
6
     }
7
}
8
echo "\n".$c;
9
if($c<3){
10
    echo "小于三个";
11
}
12
if("2048" == $password)
13
    echo "\n".$flag;

用科学计数法来绕,e代表10,+后面的数字代表几位

所以最后的payload

1
username=1023.99999999999999999
2
password=2048.00e+0000

我的模拟代码= =

1
<?php
2
    $flag="flag{nice}";
3
    $username="chenzidu";
4
    $password="2048.00e+0000";
5
    if(0>= preg_match('/^[[:graph:]]{12,}$/', $password))
6
        echo "yes"."\n";
7
8
    $reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
9
    echo preg_match($reg, $password,$arr);
10
11
    $c =0;
12
    $ps = array('punct','digit','upper','lower');
13
    foreach ($ps as $pt){
14
        if(preg_match("/[[:$pt:]]+/",$password)) {
15
            $c += 1;
16
        }
17
    }
18
    echo "\n".$c;
19
    if($c<3){
20
        echo "小于三个";
21
    }
22
    if("2048" == $password)
23
        echo "\n".$flag;