0x02 函数/特性说明
1.preg_match()函数
定义:
执行一个正则表达式匹配
语法:preg_math(pattern,string,matches,flags)
pattern,必需,要搜索的模式
string,必需,输入的字符串
返回pattern的匹配次数,0次(不匹配)或1次,匹配成功第一次就会停止搜索。
2.preg_match_all()函数
与preg_match的区别:
返回匹配完整次数(可能是0),或者发生错误后返回FALSE,匹配完整个字符串。
名字 ASCII
[:alnum:] [a-zA-Z0-9]
[:alpha:] [a-zA-Z]
[:ascii:] [x00-x7F]
[:blank:] [ t]
[:digit:] [0-9]
[:graph:] [x21-x7E]
[:punct:] [!"#$%&'()*+,-./:;<=>?@[]^_`{|}~]
[:lower:] [a-z]
[:upper:] [A-Z]
[:word:] [A-Za-z0-9_]
[:xdigit:] [A-Fa-f0-9]
0x03 代码解析
1.整体代码如下
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD'])
{
$password = $_POST['password'];
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 执行一个正则表达式匹配
{
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'); //[[: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;
}
}
2.首先:
这里需要一个正则表达式匹配,其中 [: graph:] 表示任意一个可打印字符。也就是说,要求$password长度大于12即可;
这里要求$password中必须包含标点符号、数字、大写字母、小写字母等,并且被检测到6次以上才能绕过;这里说明一下preg_match_all函数的用法:preg_match_all是全局匹配,每匹配成功一次就加1,一直匹配到字符串结束,最后返回匹配成功的次数;在本题中,只要匹配到一个标点符号、或者匹配到一个数字、或者一个大写字母、或者一个小写字母,即为匹配成功。
4.继续向下:
这里$c的值就是你的字符串种包含的类型的数目;也就是说,只要满足你的$password中包含标点符号、数字、大写字母、小写字母中三种及以上的类型,即可绕过;这里是一个弱类型比较,如果前两位是数字42,后面是字母等其它字符,比较时会强制转化成数字,于是,可以用科学计数法42.000000000000e-0来绕过;
5.最后,发送post请求的payload即可得到flag
原文始发于微信公众号(鲲哥的Bypass之旅):奇淫巧计-科学计数法绕过preg_match和==
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论