免责声明本文全部实验操作均在本人完全可控的自建本地靶场环境完成,文章仅用于网络安全原理学习与技术研究。 根据《中华人民共和国网络安全法》,未经授权对任何第三方系统进行探测、命令执行、文件写入等操作属于违法行为。
严禁复制、使用本文中的 Payload、代码应用到未获得授权的设备上。若读者将文中内容用于非法用途,一切法律责任由行为人本人承担,与本文作者无关。
正则分组
正则里,圆括号 () 就是捕获分组,
作用:把括号内部匹配到的文本 “抓取保存” 下来,后面可以用 \1、\2… 取出来复用。
\1 = 第 1 个()捕获到的内容
\2 = 第 2 个()捕获到的内容
$n 同样的作用
简单例子
正则:/(a)(b)/
(a) → 分组 1,负责匹配字符a
(b) → 分组 2,负责匹配字符b
\S
大写 S:匹配任意非空白字符
\s:小写s:匹配空白字符:换行符等
preg_replace
preg_reeplace($a,$b,$c)
a是要匹配的模式
b是要替换成什么
c是被搜索的字符串
/e模式举例子:
preg_replace('/(test)/e', 'md5("\1")', "aaa test bbb");匹配到 test,分组 1 = test
模板md5("\1")把\1替换 → md5("test")
/e eval 执行 md5("test"),得到哈希字符串 098f6bcd4621d373cade4e832627
把原来的test替换成这个哈希,得到最终字符串:aaa 098f6bcd4621d373cade4e832627 bbb
eval 执行的是:md5("test")(填充完反向引用的替换片段)
eval不会去执行最后的完整字符串 aaa 098f6bcd4621d373cade4e832627 bbb
练习
在php的GET传参中会自动的把点替换为下划线_
<?php function complex($re, $str) { return preg_replace( '/(' . $re . ')/ei', 'strtolower("\\1")', $str ); } foreach($_GET as $re => $str) { echo complex($re, $str). "\n"; } function getFlag(){ @eval($_GET['cmd']); }'/( ' . $re . ' )/ei' ------ 拼接正则(\S*)
strtolower -------将字符串转化为小写
/e修饰符,会把替换字符串当做 PHP 代码 eval 执行
preg_replace 处理过程:两个反斜杠转义\
先把\1替换成捕获内容 → strtolower("Abc")
/e把这段字符串交给 eval 执行,运行 PHP 函数,得到结果 abc
用?\S*=phpinfo()
直接打印了
使用${}包裹
原理:正则(\S*)匹配${phpinfo()}整个------>\1===${phpinfo()}
于是把\1替换成strtolower("${phpinfo()}")
因为正则后面有/e,所以会把这个当 PHP 代码执行。
${}的作用是让 PHP 解析花括号里面的内容作为变量/表达式。${表达式}:PHP 会解析花括号里的表达式。从而执行
比如$name =abc
echo $name 和echo "${a}"效果一样
思考:
换成?\S*=${getFlag()}&cmd=phpinfo();或者其他恶意代码的效果
防御
把"\\1"双引号换成单引号