Lucene search

K
korelogicKlayton Monroe ofKL-001-2021-009
HistorySep 01, 2021 - 12:00 a.m.

CyberArk Credential Provider Race Condition And Authorization Bypass

2021-09-0100:00:00
Klayton Monroe of
korelogic.com
20

1.9 Low

CVSS2

Attack Vector

LOCAL

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:L/AC:M/Au:N/C:P/I:N/A:N

5.1 Medium

CVSS3

Attack Vector

LOCAL

Attack Complexity

HIGH

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

0.001 Low

EPSS

Percentile

39.8%

  1. Vulnerability Details

    Affected Vendor: CyberArk
    Affected Product: Application Access Manager/Credential Provider
    Affected Version: Prior to 12.1
    Platform: Linux/Windows/zOS
    CWE Classification: CWE-326: Inadequate Encryption Strength,
    CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization (‘Race Condition’),
    CWE-923: Improper Restriction of Communication Channel to Intended Endpoints
    CVE ID: CVE-2021-31797

  2. Vulnerability Description

    CyberArk’s Credential Provider loopback communications on TCP
    port 18923 are encrypted with key material that has extremely
    low entropy. In all currently-known use cases, the effective
    key space is less than 2^16. For an attacker who understands the
    key derivation scheme and encryption mechanics, knowledge of the
    source port and access to the payloads of a given client-server
    exchange are sufficient to reduce effective key space to one. In
    cases where the source port is not known, the encrypted payloads
    will be unable to withstand a brute force attack.

    Additionally, the user identification mechanism used
    by CyberArk’s Credential Provider is vulnerable to a race
    condition where an unauthorized/unprivileged user can submit
    one or more encrypted query requests. If the race is won,
    the attacker will be able to retrieve sensitive information
    including passwords and password metadata.

  3. Technical Description

    Based on analysis and observations, the key derivation process
    for CyberArk’s Credential Provider loopback communications on
    TCP port 18923 can be summarized as follows:

    - start a SHA1 hash (Hash1)
    - update Hash1 with the decimal representation of the source port
    - update Hash1 with an undocumented, hard-coded byte sequence
    - finalize Hash1
    - construct encryption key using Hash1[0:16]
    

    Capturing loopback communications (e.g., with a sniffer)
    requires elevated privilege. Thus, the risk associated with
    this attack vector can be partially mitigated through basic
    system hardening.

    However, access to loopback communications is not the only
    method by which the Credential Provider can be attacked. An
    unprivileged user can simply open a connection, submit an
    encrypted request, and if the conditions are right, the
    Credential Provider may be “tricked” into generating a valid
    response.

    Below, a summary of two distinct races is given. Each race
    consists of two query requests: one made by an authorized user
    (u_auth) and the other made by an unauthorized/unprivileged user
    (u_unauth). Observe (see details provided below) that only the
    authorized query is satisfied in the first race, while both
    queries are satisfied in the second race. By piggybacking on a
    lock file created during u_auth’s request, the user controlling
    u_unauth’s account is able to retrieve information s/he is
    not authorized to view/possess. Clearly, this is a security
    breach. Factors that make this attack possible include:

    - The key material generated for these communications is
    weak. The effective key space is less than 2^16 because
    the key is derived from the TCP source port used to make
    the request and an undocumented, hard-coded byte sequence
    embedded in the key derivation code (henceforth referred to
    as Suffix1).
    
    - The user identification mechanism used by the Credential
    Provider is vulnerable to a race condition where a shared,
    ephemeral lock file exists in a common folder from the
    time that the client makes its request to the time that the
    Credential Provider's response is received/processed. The
    window of time in which this file persists affords an
    unauthorized user the opportunity to submit one or more
    distinct requests that subsequently induce the provider
    to reuse the yet-to-be-removed lock file. At that point,
    pending requests (piggyback requests) will be deemed to have
    originated from the same user as the first request (original
    request), and if that user is authorized to make each request,
    then each will be satisfied by the Credential Provider so
    long as the lock file persists. An attacker who understands
    how this mechanism works, can simply wait for a lock file
    to come into existence (or predict its existence based
    on process table monitoring and TCP port allocation). Once
    detected (or predicted), a piggyback request can be submitted
    provided that it originates from the "same" source port as
    the original request.
    
    - Requests originating from loopback addresses other than
    127.0.0.1 (e.g., 127.0.0.{2,3,4}, etc.) are honored by the
    Credential Provider. This makes it possible for an attacker
    to make a piggyback request from the "same" source port
    as the original request. Without the SO_REUSEPORT socket
    option and cooperating processes, each source address/port
    tuple must be unique on a given system. In other words,
    two non-cooperating processes can't simultaneously bind to
    the same source address/port (e.g., 127.0.0.1:10000). One or
    the other will be rejected by the operating system. However,
    since 127.0.0.1:10000 and 127.0.0.2:10000 are distinct tuples,
    they are viewed as distinct endpoints (by the operating
    system) and are therefore allowed to coexist. The Credential
    Provider, upon receiving a request from either endpoint,
    ignores (or discards) the source address, and incorrectly
    associates that communication as having originated from the
    "same" port (i.e., port 10000 per the example at hand).
    
    - Note that if the Credential Provider is unable to
    communicate with the Vault, it will continue to answer cached
    queries. If log records are world readable, they can reveal
    past queries that were both legitimate and successful. If
    the provider is configured to maintain a cache, those query
    results are likely still resident in the cache. Thus, an
    attacker may use knowledge of cache behavior and available
    log records to construct piggyback requests that are likely
    to be satisfied when the race is won.
    

    Below, a sanitized excerpt of the authorization policy
    recovered from the Credential Provider’s local cache
    (appprovider_cache.dat) on [NAME REDACTED] is shown. Observe
    that u_auth is listed as an authorized user. The scope of this
    authorization is not fully known. Through testing, it was
    determined that u_auth is authorized to make password queries
    from at least two distinct safes (AIM_SAFE1 and AIM_SAFE2).

    --- policy ---
    <?xml version="1.0" encoding="UTF-8"?>
    <AppMetaData>
      <AIM>
        <AuthMechanism Type="AppID" />
          <AuthReq LastID="142">
            <IPAuth>
              <IPReqData ReqVal="10.10.1.11" ID="11" />
              <IPReqData ReqVal="10.10.1.12" ID="12" />
              ...
              <IPReqData ReqVal="10.10.1.140" ID="140" />
            </IPAuth>
            <OSUserAuth>
              ...
              <OSUserReqData ReqVal="u_auth" ID="6" />
              ...
            </OSUserAuth>
          </AuthReq>
        <ExtendedApplicationRestrictions isEnable="True" />
      </AIM>
    </AppMetaData>
    --- policy ---
    

    Below, the result of an authorized query made by u_auth to
    retrieve app_123’s password located in the AIM_SAFE1 safe
    is shown. Note that the CyberArk “clipasswordsdk” utility
    transparently encrypts the request and decrypts the response.

    $ clipasswordsdk GetPassword -p AppDescs.AppID=APP_ID -p Query="Address=enco;TokenID=APP123Pass;Env=env1" -o Password
    --- output ---
    [PASSWORD REDACTED]
    --- output ---
    

    Below, the result of two unauthorized queries made by u_unauth
    are shown. These queries attempt to retrieve app_456’s password
    located in the AIM_SAFE2 safe. Note that these responses
    are essentially what an observer could capture if sniffing
    the loopback interface. Also note that the Elements field
    contains encrypted query results. Once decrypted (as shown
    farther below), it is evident that the first response contains
    an error message indicating that the query failed. Hence,
    that race was lost. However, the second response clearly
    contains valid data. Hence, that race was won. This implies
    that no single race is a sure bet. Rather, factors such as
    current system load, number of processors, processor speed,
    etc. will influence the outcome of any given race. Note that
    an unconstrained user may be able to influence system load
    sufficiently to consistently win the race.

    --- RESPONSE_1_BEGIN [TCP_PORT=44222] ---
    <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
    <Message>
      <header>
        &lt;ProtocolVersion&gt;995000&lt;/ProtocolVersion&gt;
        &lt;ProtocolInfo&gt;3&lt;/ProtocolInfo&gt;
      </header>
      &lt;Elements&gt;9232456D7707CEBCC280184CB311F0871521DBFF0546A5E858974FE9E4AC8B4260FB4C579ACFB603905D1CFD1CA8EF76CD9AC32AE6C7CD6EC85FA57BD3E035514EEB72E767FBEA3FF2F4FA45D6F3D7E34B0DDACF9E2A3443E43C24D84544534A65046A6A4CCBED7CF6C72733F7B05CFD2F805E51B277100E1A9D42DA8D759EE6DE43F0D26ED41750EE428F82481CC96C8A3177C09F8A882138C294A4ADBDC270DE55128ABDCFCD6A5451A692DF4AE4035CB8D23C38176E78669903C680C89C14B00798568718FECAA1B7143ABAEEE612CE394DA4B7BD550338DB319BE607EED7F57EBCA05AA52CFAC03B02A4EC49F8F6B9E60375C32CEAA963017F590E3FBBAF4652664FC79AB355CB23EF50581A76FFC207731975FAF04CAAFD32F10B508E16660F0BCF6A55FDF3C2322110FBA425CFD06530B373B493957EF76E62100788D9FF1954BD12CBDD9D4E0393D3F6F411BD28AC788A55D6291BCDC439D895AA24E3A307A479EF420524AA3131C137F2EB9F&lt;/Elements&gt;
    &lt;/Message&gt;
    --- RESPONSE_1_END [TCP_PORT=44222] ---
    
    --- RESPONSE_2_BEGIN [TCP_PORT=44228] ---
    &lt;?xml version="1.0" encoding="UTF-8" standalone="no" ?&gt;
    &lt;Message&gt;
      <header>
        &lt;ProtocolVersion&gt;995000&lt;/ProtocolVersion&gt;
        &lt;ProtocolInfo&gt;3&lt;/ProtocolInfo&gt;
      </header>
      &lt;Elements&gt;3681C9C1467C74EC3FFB7982B5E2639602D87E70D4E00EDCD6A65AFAF2093077B7CA27126C26A6F23DAEFB90287E9CDF99C20ED9F1835BC849855F8B7CFA437F72C8EF57EA077FA14DA625FAE93C0AAA0883FC130DA386E03622C80439A2F35F6508D08218E8ABE0D2000A2944908D13B5AE20854C4D8DCF30E790E25D6C4642BE52C6BA494FDDAB5A422C644C1D4A4688A9E9450F681BFD0949AB1A3358A355DFA797F2D416A9B1C2EF4C960A2A0B4C2F6F278B0B705D29F3DC3CFC9DA79B43B341D1AD8C45F602796CF627D5721DE7278B984E59CA5B5364A62CEFFAF0EDB9E7E33DCE349781AD0934DDD58E0A27EE669879D4641170C74FF237AD69C2F2C74263F48433213952F3E436EAFA65A69E12833EE189416F5F29A7A420D284180ED3C37D58DBE06600E4F3E01FF13C8AC98A101396E2FB0C382CF2C44C5E9487A31BE8665C2C6CC03F8982E719928537F2446068A849397A7132245F5521C990CA037C9C88C707F661CDD688AC9C45CC23A4B508EEE5E858E47E1C0BC31843BE43522F80DD29F0D6CD4233622D1F95A563C5425DEC73DBD47655525DCA19BBE64C177F8A0462D073FE99F135F2C056108D1F3D7B91CF055681DE5FBB12ABC92C08F872FACCE86C703B2F5CBFD49DB85DFBB484AB4C9308E804053F96D73E2DFD79D1EC55AE26358F4C02D33D0719300627B336B4FF99C294E0A713B6D33381DAB0241448A409E8346AA35F8352E1B0851BC1338EA6863E49DDB98B8CAB8EBB566C257F079BA16B6C28C4F1BA590B61B8F301E941867D3162231016DAA0C738C64C7B4DF355A8C8FCB08B866B81D9C23B9CAB626FFE53601D114D04E370D085B97473E8EE56DE4B7083D645C7E11CC51EF8BEA72A424BFD7FE3DCB6DF2EB58D95D907347627E450E83DD8CFEDA1F438953BFFAF52BEE65A3980F50DED183D6AFA6F0CD1C4B4F28A0FC16540055B76E063015D13100BE3492B9B32C02F45819506B39247CF4CA65CF04BE4BCDCF38EB4E3F44696299AFF93177E9F3E0B8ABD14BF51C35E3493B604173E83B6C00E85B580639A57B961A340881738D925068817F15E5FA565C95B8E913E200F82E21AA51C23C751AD75C3CE32C50B3BCF7B10C680A7CBA7356D2A8027D138AC6B0294AD760F1C71BA7DA8F53B997E60B185998A72693C3A88C43817648D285BFAFCC9F26CD3C37B96862BCED33EB48E536EDA29DBB1E0D7EC5680478BD99361D2C04B5F9E079EE8DC0D2CD76362507C8C13759156D450F1EE283171D3A5D9C8C3B9D284D3BF3B7729529E0FACC3424B27C1A62392B9A127AAF98982318459F20B5A1C60B9DB4AAA1F9AD0F2EEE373E46DC0231FF106&lt;/Elements&gt;
    &lt;/Message&gt;
    --- RESPONSE_2_END [TCP_PORT=44228] ---
    
    --- DECRYPTED_ELEMENTS_RESPONSE_1_BEGIN [TCP_PORT=44222] ---
    &lt;Elements&gt;
      &lt;Element&gt;
        &lt;ElementType&gt;ErrorResponse&lt;/ElementType&gt;
        &lt;ResponseBase&gt;
          &lt;ResponseId&gt;1&lt;/ResponseId&gt;
          &lt;ErrorResponse&gt;
            &lt;ErrorCode&gt;-1&lt;/ErrorCode&gt;
            &lt;ErrorMsg&gt;APPAP087E Application authentication failure&lt;/ErrorMsg&gt;
          &lt;/ErrorResponse&gt;
        &lt;/ResponseBase&gt;
      &lt;/Element&gt;
    &lt;/Elements&gt;
    --- DECRYPTED_ELEMENTS_RESPONSE_1_END [TCP_PORT=44222] ---
    
    --- DECRYPTED_ELEMENTS_RESPONSE_2_BEGIN [TCP_PORT=44228] ---
    &lt;Elements&gt;
      &lt;Element&gt;
        &lt;ElementType&gt;PasswordResponse&lt;/ElementType&gt;
        &lt;ResponseBase&gt;
          &lt;ResponseId&gt;1&lt;/ResponseId&gt;
          &lt;PasswordResponse&gt;
            &lt;Password&gt;REDACTED&lt;/Password&gt;
            &lt;Flags&gt;0&lt;/Flags&gt;
            &lt;AlterPassword&gt;&lt;/AlterPassword&gt;
            &lt;PassProps&gt;
              <address>appprodapplication</address>
              &lt;ApplicationName&gt;APP&lt;/ApplicationName&gt;
              &lt;ClassType&gt;Class H&lt;/ClassType&gt;
              &lt;CreationMethod&gt;PVWA&lt;/CreationMethod&gt;
              &lt;Description&gt;SR0118365&lt;/Description&gt;
              &lt;DeviceType&gt;Operating System&lt;/DeviceType&gt;
              &lt;Env&gt;all-prod&lt;/Env&gt;
              &lt;PolicyID&gt;H_SRV_GENERIC_Q_XXX_APC&lt;/PolicyID&gt;
              &lt;RegSCI&gt;ISCI&lt;/RegSCI&gt;
              &lt;TokenID&gt;APPPassword&lt;/TokenID&gt;
              &lt;UserName&gt;app_456&lt;/UserName&gt;
            &lt;/PassProps&gt;
            &lt;PasswordChangeInProcess&gt;false&lt;/PasswordChangeInProcess&gt;
          &lt;/PasswordResponse&gt;
        &lt;/ResponseBase&gt;
      &lt;/Element&gt;
    &lt;/Elements&gt;
    --- DECRYPTED_ELEMENTS_RESPONSE_2_END [TCP_PORT=44228] ---
    

    Below, the relevant log entries generated for queries made
    during the first race are shown. Note how all timestamps
    are identical. Note also that the reason the race was lost is
    revealed by the first record in APPConsole.log. Essentially, the
    authorized query (first entry in APPAudit.log) was satisfied
    and its associated lock file (/tmp/AIM44222) was removed
    before the unauthorized query (second entry in APPAudit.log)
    could be processed by the Credential Provider. And since the
    lock file was removed, the provider had no means to look up
    the process ID of the requesting process.

    --- APPAudit.log ---
    [DATE | 18:09:08] |  ::  | APPAU001I Provider Prov_[REDACTED] has successfully fetched password [safe=AIM_SAFE1,folder=Root,name=[REDACTED]] with query [Address=enco;TokenID=APP123Pass;Env=env1] for application [APP_ID]. Fetch reason: []
    [DATE | 18:09:08] |  ::  | APPAU002E Provider Prov_[REDACTED] has failed to fetch password with query [Address=appprodapplication;Env=all-prod;TokenID=APPPassword] for application [APP_ID]. Fetch reason: []. Failure reason: [APPAP087E Application authentication failure]
    --- APPAudit.log ---
    
    --- APPConsole.log ---
    [DATE | 18:09:08] |  ::  | APPAP087E Application authentication failure for Application APP_ID (CASCU086E Failed to find application process id. (Error: The lock file (/tmp/AIM44222) couldn't be opened, Error code: 2).)
    [DATE | 18:09:08] |  ::  | APPAP002E Provider Prov_[REDACTED] has failed to fetch password with query [Address=appprodapplication;Env=all-prod;TokenID=APPPassword] for application [APP_ID]. Fetch reason: []. Failure reason: [APPAP087E Application authentication failure]
    --- APPConsole.log ---
    

    Below, the relevant log entries generated for queries made
    during the second race are shown. Note how all timestamps are
    identical. The authorized query corresponds to the first entry
    in APPAudit.log, and the unauthorized query corresponds to the
    second entry. Note how two distinct safes were queried. This
    suggests that safes not normally accessed/queried by a given
    Credential Provider may be targeted by an attacker from
    a different system. Clients should be cautioned that the
    contents of any given safe should be confined to a single
    security domain.

    --- APPAudit.log ---
    [DATE | 18:09:13] |  ::  | APPAU001I Provider Prov_[REDACTED] has successfully fetched password [safe=AIM_SAFE1,folder=Root,name=[REDACTED]] with query [Address=enco;TokenID=APP123Pass;Env=env1] for application [APP_ID]. Fetch reason: []
    [DATE | 18:09:13] |  ::  | APPAU001I Provider Prov_[REDACTED] has successfully fetched password [safe=AIM_SAFE2,folder=Root,name=[REDACTED]] with query [Address=appprodapplication;Env=all-prod;TokenID=APPPassword] for application [APP_ID]. Fetch reason: []
    --- APPAudit.log ---
    
  4. Mitigation and Remediation Recommendation

    The vendor has released an updated version (v12.1) which
    remediates the described vulnerability. Release notes are
    available at:

    https://docs.cyberark.com/Product-Doc/OnlineHelp/PAS/Latest/en/Content/Release Notes/RN-WhatsNew12-1-CPs.htm?tocpath=Get Started|What’s New|Release Notes|_____4

  5. Credit

    This vulnerability was discovered by Klayton Monroe of
    KoreLogic, Inc.

  6. Disclosure Timeline

    2020.11.04 - KoreLogic submits vulnerability details to
    CyberArk.
    2020.11.05 - CyberArk acknowledges receipt and the intention
    to investigate.
    2020.11.16 - KoreLogic and CyberArk meet to discuss the
    details of this and other reported
    vulnerabilities. Both parties agree that the
    remediation timeline will extend significantly
    longer than the standard 45 business days specified
    in the KoreLogic Public Disclosure Policy.
    2021.01.14 - 45 business days have elapsed since the
    vulnerability was reported to CyberArk.
    2021.01.21 - KoreLogic and CyberArk meet to discuss proposed
    remediation efforts for this and other reported
    vulnerabilities.
    2021.03.24 - 90 business days have elapsed since the
    vulnerability was reported to CyberArk.
    2021.04.22 - CyberArk notifies KoreLogic that the reported
    vulnerability will be mitigated in a version
    scheduled for release in late May, 2021.
    2021.05.10 - 120 business days have elapsed since the
    vulnerability was reported to CyberArk.
    2021.05.10 - CyberArk provides KoreLogic with the CVE for this
    vulnerability. Vendor requests KoreLogic delay
    public disclosure until the end of June, 2021.
    2021.06.08 - KoreLogic and CyberArk meet to discuss the details
    of the product release and revisit timeline for
    public disclosure. CyberArk informs KoreLogic that
    the Linux/Windows version of the Credential
    Provider will be released at the end of June, 2021.
    A Credential Provider for the zOS platform will be
    released at the end of July, 2021. KoreLogic agrees
    to delay public disclosure of this and other
    reported vulnerabilities until 2021.08.15.
    2021.06.23 - CyberArk releases Credential Provider v12.1 for
    Linux/Windows platforms.
    2021.08.05 - 180 business days have elapsed since the
    vulnerability was reported to CyberArk.
    2021.08.10 - CyberArk informs KoreLogic that the zOS Credential
    Provider update has been released to their
    customers. Requests that KoreLogic forgo
    publication of the Proof of Concept code as an
    unforseen issue prevents some customers from
    updating in the near term.
    2021.08.27 - KoreLogic suggests delaying the release of the
    Proof of Concept until a to-be-determined future
    date.
    2021.08.30 - CyberArk tenders 2022.01.01 release date for the
    Proof of Concept.
    2021.09.01 - KoreLogic public disclosure.

  7. Proof of Concept

    At the vendor’s request, KoreLogic has agreed to delay
    publication of the Proof of Concept while customers continue
    to deploy the updated versions of the product.

Affected configurations

Vulners
Node
cyberarkcredential_providerRange<12.1

1.9 Low

CVSS2

Attack Vector

LOCAL

Attack Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:L/AC:M/Au:N/C:P/I:N/A:N

5.1 Medium

CVSS3

Attack Vector

LOCAL

Attack Complexity

HIGH

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

0.001 Low

EPSS

Percentile

39.8%

Related for KL-001-2021-009