标签:art str 链接 random 无法 get die 超时 __file__
在一段时间内,一直不知道.*
和.*?
之间的区别,一直单纯的觉得两者之间并没有什么区别,都是匹配任意字符,知道今天才知道其中的区别
首先从一个简单的问题的问题开始思考:
有这样一个字符串aaabaaab
,和这样的一个正则.*b
,那么.*
匹配的会是aaab还是aaabaaab呢?
由此问题引发出来的就是贪婪与非贪婪模式的区别,简单的说,它们之间的区别就在于贪婪模式匹配的是aaabaaab而非贪婪模式下匹配的是aaab
当然,仅仅是.*b
并不足以决定到底是按照贪婪还是非贪婪模式匹配,所以使用?来判断是否是贪婪模式
所以.*?b
就决定其使用非贪婪模式进行匹配
那么,具体来说,贪婪和非贪婪模式是怎么进行匹配的呢?
待匹配的字符串:"abc"
正则:".*"
其中进行了一次回溯
其中进行了三次回溯
那么贪婪模式与非贪婪模式有什么用途呢?
在鸟哥的博客中,可以看到这样的代码
$reg = "/<script>.*?<\/script>/is";
$str = "<script>********</script>"; //长度大于100014
$ret = preg_replace($reg, "", $str); //返回NULL
由于使用了非贪婪模式进行匹配,所以会导致进行不断的回溯,最后由于回溯次数超过php的回溯限制,导致返回false,借此可以绕过一些ctf中的waf
php的回溯限制可以在pcre扩展中看到,默认为100000
在lctf2017中,可以看到这样的部分
preg_match(‘/^(xdsec)((?:###|\w)+)$/i‘, $code, $matches);
if (count($matches) === 3 && $admin === $matches[0]) {
blabla
}
正则匹配字符串,如果匹配成功则将匹配结果填充进matches数组,并进行判断是否与$admin变量相同,但是进行匹配的话matches[0]的值将会是字符串本身,无法进行到下一步
所以这里输入一个非常长的字符串,让其匹配,因为在进行正则匹配的时候一定会消耗计算机资源进行一个字符的匹配(默认是贪婪模式),所以会导致php超时,使得后面的语句不会执行
先膜p师傅Orz
代码如下
<?php
function is_php($data){
return preg_match(‘/<\?.*[(`;?>].*/is‘, $data);
}
if(empty($_FILES)) {
die(show_source(__FILE__));
}
$user_dir = ‘data/‘ . md5($_SERVER[‘REMOTE_ADDR‘]);
$data = file_get_contents($_FILES[‘file‘][‘tmp_name‘]);
if (is_php($data)) {
echo "bad request";
} else {
@mkdir($user_dir, 0755);
$path = $user_dir . ‘/‘ . random_int(0, 10) . ‘.php‘;
move_uploaded_file($_FILES[‘file‘][‘tmp_name‘], $path);
header("Location: $path", true, 303);
}
$reg = /(.+?)+/is;
$str = str_pad("laruence", 10000, "a"); //长度为1万
$ret = preg_repalce($reg, "", $str);
这里的主要目的也是为了要绕过正则,但这里和上面不同,上面利用的是贪婪匹配导致资源耗尽
而这题使用的正是回溯
因为.的存在,且默认是贪婪模式进行匹配,所以.会一直匹配到字符串结尾,然后进行回溯,如果没有找到,会再次回溯,所以只要字符串的长度超过回溯次数,自然就能绕过正则了
初次在遇到lctf那题的时候,没有仔细去思考背后的东西……只知道正则匹配是很消耗资源的,却不知道为何会消耗资源。之前也曾遇到过贪婪和非贪婪的名词,没有去了解。也层遇到过.*?的写法,没有去了解,果然,就像p师傅说的那样,不求甚解是进步的最大阻碍,下次再遇到问题时,需要更进一步思考,弄明白原理
http://f1sh.site/2018/11/25/code-breaking-puzzles%E5%81%9A%E9%A2%98%E8%AE%B0%E5%BD%95/
http://www.laruence.com/2010/06/08/1579.html
https://www.jb51.net/article/31491.htm
标签:art str 链接 random 无法 get die 超时 __file__
原文地址:https://www.cnblogs.com/hf99/p/10021691.html