掌控安全-2.2正则表达式

知识点铺垫

正则表达式

什么是正则表达式?
  ⭐正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

正则表达式的特点
  § 1. 灵活性、逻辑性和功能性非常强;
  § 2. 可以迅速地用极简单的方式达到字符串的复杂控制。
  § 3. 对于刚接触的人来说,比较晦涩难懂。

正则表达式用途
§判断字符串是否符合某一规则(判断是否符合手机号、邮箱规则)。
§从一个字符串中找出符合规则的所有子字符串(取HTML标签名)。

常用函数
⭐ preg_match_all(正则表达式、匹配字符串、匹配到的东西放入数组)
⭐返回匹配到的次数

案例:

<?php
preg_match_all('/a/','a',$a); //匹配到了1次a,放入了$a数组 $a={a}
preg_match_all('/a/','aa',$a); //匹配到了2次a,放入了$a数组 $a={a,a}
?>

⭐preg_replace (正则表达式、替换成什么、匹配字符串)
⭐返回替换后的结果

<?php
$str = 'runo o   b';
$str = preg_replace('/\s+/', '', $str);
// 将会改变为'runoob'
echo $str;
?>

执行结果如下所示:

runoob

自定义字符集合

  ⭐字符集合:[单个字符或字符区间],用于匹配集合内字符

  如:
    •[a-z]表示a-z这26个小写字母
    •[0-9a-z]表示0-9这10个数字和a-z26个小写字母
    •[135a-h]表示包含数字1,3,5和字母a-h这8个字母

  注意:
    1、两个不同字符段间请勿使用,隔开
    2、区间里面写的都是单字符,不会联合在一起成为单词匹配

  ⭐非集:[^单个字符或字符区间],用于匹配非集合内字符。

  如:
    •[^0-9]表示匹配所有非数字字符。
    •[^a-zA-Z]表示匹配所有非字母字符。

正则表达式的语法-关键字

  () => 和数学一样,很像,代表这是一个整体
  ^  =>匹配输入字符串的开始位置
  $  =>匹配输入字符串的结尾位置
  .   =>通配符[代表任意字符][不匹配换行]
  *   =>匹配0次或者多次
  +  =>匹配1次或者多次
  \   =>转义字符
  |   =>两项之间的一个选择

学东西要灵活,相同的东西在不同的地方有不同的意义。

preg_match_all('/^[a-z]/','sdfsdfsdf') ; // 在这里表示的就是只取满足[a-z]的第一个字符
preg_match_all('/[^a-z]/','sdfsdfsdf') ; // 在这里表示的就是取小写字母外的所有字符

注:

^ => 匹配开头字符
$ => 匹配结尾字符

preg_match_all('/^abc$/','abcabcabc'); // 匹配结果0个
preg_match_all('/^abc$/','abc'); // 匹配结果1个,固定匹配abc
等价于
preg_match_all('/abc/','abc');
一般来说有限定符只能匹配1

常用转义字符

  数字:\d
  非数字:\D
  空白字符(空格、制表符、换页符等):\s
  非空白字符:\S
  单词字符(26个英文字母+数字+下划线):\w
  非单词字符:\W

<?php
preg_match_all('/\d/','1'); //输出1,匹配到了1次 \d匹配数字
preg_match_all('/\d/','123'); //输出3,匹配到了3次

preg_match_all('/\D/','123a'); //输出1,匹配到了1次 \D 匹配非数字
?>

再来讲一个东西:

  *匹配模式:贪婪匹配模式 =》 .*:匹配任意字符
  *:匹配0次或多次 => 建议少用 => 0次意味着可以匹配一些空值

例如这样的一个代码:

<?php
var_dump(preg_match_all('/<html>(b*)<\/html>/','<html></html><html>fdgfaaadgfdg</html><html>a</html>',$gj));
var_dump($gj);
?>

在这里插入图片描述

但是改为b+后:
输出结果:
在这里插入图片描述
这是因为第一个要匹配0-多个b,所以可以匹配出1次,第二个要匹配1-多个b,所以匹配不出来。

推荐:*匹配尽量少用,尽量多用+匹配

正则表达式的语法——限定符&修饰符

限定符:
  {n} => 例如: 0{8} 意思是指 只有连起来8个0才会被匹配
  {n,} =>例如: 0{2,} 意思是 只要有2个0及其以上的就会被匹配
  {n,m} => 例如: 0{2,4} 意思是最少匹配2个0,最多匹配4个0

注:被匹配时,默认匹配最多的次数,就是说比如你要在aaa中匹配a+,默认匹配就只能匹配出1次aaa。

修饰符:
  /i => 不区分大小写
  /A => 匹配规则必须从头开始匹配
  /s => .将匹配一切字符
  /x => 正则表达式中的空白字符会被忽略

<?php
var_dump(preg_match_all('/a/i','aA',$gj));
var_dump($gj);
?>

在这里插入图片描述

修饰符是写在标识的后面的
绕过的核心是替换或产生一些特殊的组合!

靶场实战

这是一道CTF原题

<?php  
$key='flag{********************************}'; 
$Regular= preg_match("/zkaq.*key.{2,9}:\/.*\/(key*key)/i", trim($_GET["id"]), $match); 
if( $Regular ){  
  die('key: '.$key); 
} 

我们想要拿到的是flag,那么我们就要想办法找输出点,能把flag输出的地方,我们看到了这行

 die('key: '.$key); 

这一行可以把flag输出

我们注意到这行是在if语句里面的,我们需要做的就是要让条件if( $Regular )成立

我们再来看$Regular是什么?

$Regular= preg_match("/zkaq.*key.{2,9}:\/.*\/(key*key)/i", trim($_GET["id"]), $match); 

这是一个正则匹配函数我们很熟悉,我们看到其中有trim($_GET["id"]),这个的意思就是把通过GET传参获得的id的值移除两侧的空白字符,没啥影响,不用管

然后我们来看前面的匹配模式

/zkaq.*key.{2,9}:\/.*\/(key*key)/i

//是正则匹配模式的标志,/i是不区分大小写都可以去掉

zkaq.*key.{2,9}:\/.*\/(key*key)

.*是匹配0个或多个任意字符,我们可以不写

zkaqkey.{2,9}:\/.*\/(key*key)

.{2,9}是匹配任意2-9个字符,我们可以写个xj

zkaqkeyxj:\/.*\/(key*key)

/是转义字符,我们可以直接写/,.*直接可以不写

zkaqkeyxj://(key*key)

(key*key)是个整体,我们可以直接写keykey

zkaqkeyxj://keykey

然后我们就构造好了id传参

http://59.63.200.79:8010/re/?id=zkaqkeyxj://keykey

在这里插入图片描述

这就弹出了flag
key: flag{regular_god_code}

提交
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值