Bugku 数字验证正则绕过(代码审计)

题目还是比较友好的,直接给出了源码,注释里还有提示,如下:

<?php
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD'])
{
$password = $_POST['password'];
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配
{
echo 'flag';
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'); //[[:punct:]] 任何标点符号 [[:digit:]] 任何数字 [[:upper:]] 任何大写字母 [[:lower:]] 任何小写字母
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
//>=3,必须包含四种类型三种与三种以上
if ("42" == $password) echo $flag;
else echo 'Wrong password';
exit;
}
}
?>

稍微有点长……重点关注在哪里打印出来了flag,以及在这之前哪里会 exit(),然后着重去绕过那些会退出程序的地方就可以啦~

首先:

这里需要一个正则表达式匹配,其中 [: graph:] 表示任意一个可打印字符。也就是说,要求$password长度大于12即可;

在本地测试 '42aaaaaaaaaa' 可以绕过;

继续向下看:

这里要求$password中必须包含标点符号、数字、大写字母、小写字母等,并且被检测到6次以上才能绕过;

    [:punct:]  [:digit:]  [:upper:]  [:lower:]等正则表达式的说明见这篇博客:正则

这里说明一下preg_match_all函数的用法:preg_match_all是全局匹配,每匹配成功一次就加1,一直匹配到字符串结束,最后返回匹配成功的次数;

在本题中,只要匹配到一个标点符号、或者匹配到一个数字、或者一个大写字母、或者一个小写字母,即为匹配成功。

于是,我把payload改成了:'42aaAaa2;aaaa' 

继续向下:

这里$c的值就是你的字符串种包含的类型的数目;也就是说,只要满足你的$password中包含标点符号、数字、大写字母、小写字母中三种及以上的类型,即可绕过;

看最后一个:

这里是一个弱类型比较,如果前两位是数字42,后面是字母等其它字符,比较时会强制转化成数字,于是,'42aaAaa2;aaaa' 完全可以用来绕过;

利用burpsuite发送POST请求:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值