返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >CTF之preg_match()函数绕过
  • 750
分享到

CTF之preg_match()函数绕过

php正则表达式开发语言 2023-09-11 05:09:14 750人浏览 安东尼
摘要

文章目录 前言0x01 正则表达式是什么0x02 回溯的过程是怎样的0x03PHP的pcre.backtrack_limit限制利用0x04 PCRE另

文章目录


前言

PHPerror_reporting(0);highlight_file(__FILE__);$a = $_POST['heizi'];if (isset($a)){   if(substr($a,0,5) == "aikun" and substr($a,-10,10) == "xiaojijiao"){  # 限制死了,aikun字符xiaojijiao       if ($a == "aikunxiaojijiao"){           die("nononono");       }       if (preg_match('/aikun.+?xiaojijiao/is',$a)){                  die("Hack!!!");       }       system("ls");  # 目的   }else{       die("what?");   }}?>

由上所示,我们的目的就是输出system("ls");,可是前面三条if语句已经写死了,不可能数组绕过:preg_match只能处理字符串,当传入的subject是数组时会返回false,不可能换行符绕过, s :.可以表示换行
先不急,先看如下的:


0x01 正则表达式是什么

  1. 正则表达式是一个可以被有限状态自动机接受的语言类。(有限状态自动机:要么匹配成功,要么失败)
  2. 正则匹配通过正则引擎实现,正则引擎又被细分为DFA(确定性有限状态自动机)与NFA(非确定性有限状态自动机)
    • DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
    • NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态

    由于NFA的执行过程存在回溯,所以其性能会劣于DFA,但它支持更多功能。大多数程序语言都使用了NFA作为正则引擎,其中也包括php使用的PCRE库。

0x02 回溯的过程是怎样的

对于preg_match('/aikun.+?xiaojijiao/is',$a),如果$a=aikunaaaaxiaojijiao

  1. 首先匹配aikun
  2. aikun.+?中的.+可以匹配如下的aaaaxiaojijiao字符,然后匹配引擎发现xiaojijiao没有匹配的项了,开始向前回溯
  3. .+开始匹配aaaaxiaojijia,xiaojijiao与a不匹配,又开始回溯
  4. .+开始匹配aaaaxiaojiji,xiaojijiao与ao不匹配,又开始回溯。。。。
  5. 回溯到.+?开始匹配aaaa,xiaojijiao与xiaojijiao正好匹配,匹配完成

0x03PHP的pcre.backtrack_limit限制利用

如上所示,如果一直匹配是不是会浪费系统资源,只要你写的正则足够复杂,你就可以让匹配引擎一直匹配,所有
PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit。
我们可以通过var_dump(ini_get(‘pcre.backtrack_limit’));的方式查看当前环境下的上限:(回溯次数上限默认是100)

import requestsdata = {  'heizi': 'aikun' +'a'*1000000 + 'xiaojijiao'}res = requests.post('Http://182.148.156.200:9134/', data=data, allow_redirects=False)print(res.text)

如上所示写一个脚本,让匹配引擎匹配超过1000000次,preg_match(‘/aikun.+?xiaojijiao/is’,$a)返回false,目的达到

0x04 PCRE另一种错误的用法

对于sql注入,我们都知道就是字符匹配,发现使用了preg_match()函数就可以使用回溯进行绕过:

 if(preg_match('/UNION/is', $input)) {     die('SQL Injection'); }

0x05 修复方法

如果用preg_match对字符串进行匹配,一定要使用===全等号来判断返回值,就算回溯成功false也不全等于0

来源地址:https://blog.csdn.net/qq_53568983/article/details/129300129

--结束END--

本文标题: CTF之preg_match()函数绕过

本文链接: https://www.lsjlt.com/news/402774.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作