这里说一点,代码执行和命令执行,都需要php.ini关闭safe_mode的情况下。。
如果不能获取环境变量,当然也可以通过com组件或全局变量,但我们只对这种类型
$cmd = $_GET['cmd']
代码执行,这里有两个传小马常用的危险函数
eval() 和 assert()
首先来找代码层面的phpinfo();然后通过?cmd=system(ipconfig)看是否能调用系统函数。
注意eval写法: eval("$a=$a");
assert写法: assert("$a=$a"); 网页提交phpinfo不能漏分号; ,eval函数是接受字符串的。
然后接着来看第二种代码执行,,,回调函数
目的是通过回调函数,调用出phpinfo()这样一个页面,导致代码执行
有两种,第一种,自定义的callback函数里封装着eval函数,
function callback(){
// $a = $_GET['cmd'];
eval($a); //callback函数里封装着eval这样的危险函数,我们通过调用变量a来调用危险函数。
//给cmd变量传入phpinfo ?cmd=phpinfo(); 实际上传到封装函数里eval参数执行。
}
call_user_func('callback',$a);
最经典的通过给参数?cmd赋值phpinfo();,eval($a)调用执行,变量a这里可控。。
第二种,,先给变量赋值phpinfo(),变量我们不可控,但传入的assert函数没做过滤,给变量a传入一个assert函数,导致代码执行
$b="phpinfo()";
call_user_func($_GET['a'],$b);
接着看第三种代码执行,,正则匹配,实际站点验证,phpinfo()不能直接访问,站点做了限制, 这里通过正则匹配到phpinfo();导致代码执行。
既然是做基础,这里抱着扎实的目的,正则匹配的7种类型
普通型,,正则匹配用/xxxx/包围起来,里面是数字or字母
$pattern = '/abc/';
$str = 'abcdefghhj';
preg_match_all($pattern,$str,$res);
var_dump($res);
匹配1次,看到匹配到str的字符了
第二种 特殊符号 ,[符号前要用\反斜杠转义;
$pattern = '/\[php]\/';
$str = '[php]1111122233';
和自定义原子的差别,下面这个匹配 $pattern :
- pphp 2.hphp 3.pphp
$pattern = '/\[php\]php/';
$str = '[php]1111122233';
第三种,通用符号 d : 0-9 D:a-z A-Z
$pattern = '/\d{4}(-)\d{2}\\1\d{2}/';
$str = '2021-08-08';
preg_match_all($pattern,$str,$res);
var_dump($res);
这里的d{4} 表示四位数字,(-)表示- ,后面的\1 表示第一个(-),匹配到了$str,匹配到一次
还有几个常见的符号,,- * + 一般开发都连用 (*?.)
$pattern=/^abc/; 原子必须以abc开头
$pattern=/abc$/ ; 原子必须以abc结尾
$pattern=/^abc$/; 只匹配abc
然后看preg_replace函数
preg_replace函数第一个参数 ($pattern) 开启/e ,存在代码执行
echo $cmd = $_GET['cmd'];
$str = '<php>phpinfo()</php>';
preg_replace("/<php>(.*?)$cmd","\\1",$str);
看这段代码,,
p
a
t
t
e
r
n
存
在
pattern存在
pattern存在cmd,这里是可控的,现在如何通过正则匹配到
s
t
r
?
很
明
显
,
,
str? 很明显,,
str?很明显,,cmd只要匹配到"</php" 后面的字符就可
先?cmd=/e ,看到已经匹配到这一部分正则了
特殊符号/前要转义
第二种情况
preg_replace("/php/e",$_GET['cmd'],'php');
第二个参数可控,,这里只要匹配到后面的字符php就行
第三种
$str = $_GET['cmd']
preg_replace("/\[php\](.*?)\[\/php\]/e",replacement:"\\1",$str);
第三个参数可控
================
代码执行效果完全和php有关,命令执行效果和php本身没有关系
常用的命令执行函数: system() passthru() 函数 ``执行
exec函数 shell_exec函数
$a = $_GET['a'];
echo "<pre>";
passthru($a);
//$cmd = $_GET['cmd'];
// //echo "<pre>";
//system($cmd); system执行函数
这里注意exec函数执行查询只能返回一行,
这里用exec函数写入11.txt
?cmd=echo >> 11.txt
通过`` 命令执行
很多站点对可控的参数做了Escapeshellcmd处理
对特殊符号做了过滤,但常见的net user ipconfig还可执行,
如果开发只对可控做了Escapeshellcmd和escapeshellcmd()函数处理,草草了事,那么可尝试多个参数的注入,这里水平不够,请参考这篇文
https://paper.seebug.org/164/