Ci sono due vulnerabilità, ognuna delle quali innesca un salto allo zero:
Il primo, all'interno di markContainingBlocksForLayout
:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb09fdb70 (LWP 2039)]
> 0x00000000 in ?? ()
(gdb) bt
> #0 0x00000000 in ?? ()
#1 0x0194b82b in markContainingBlocksForLayout (this=0x2e29944, owner=
0x2e298e4, oldChild=0x0, fullRemove=true)
at third_party/WebKit/WebCore/rendering/RenderObject.h:946
Ecco il dump dell'assembly su eip faulting:
0x0194b81b <removeChildNode(...)+1083>: decl -0x74ffd98c(%ebp)
0x0194b821 <removeChildNode(...)+1089>: push %es
0x0194b822 <removeChildNode(...)+1090>: mov %esi,(%esp)
0x0194b825 <removeChildNode(...)+1093>: call *0xb0(%eax)
=> 0x0194b82b <removeChildNode(...)+1099>: test %al,%al
0x0194b82d <removeChildNode(...)+1101>: jne 0x194b67d <removeChildNode(...)+669>
0x0194b833 <removeChildNode(...)+1107>: mov -0x24(%ebp),%edi
0x0194b836 <removeChildNode(...)+1110>: mov -0x28(%ebp),%esi
0x0194b839 <removeChildNode(...)+1113>: jmp 0x194b728 <removeChildNode(...)+840>
L'istruzione call
chiama all'indirizzo eax + 0xb0
, il che implica che 0x02e294f8
è zero (poiché eax è 0x02e29448
).
Ecco la seconda, all'interno di RenderObject::destroy
:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb1646b70 (LWP 2100)]
> 0x00000000 in ?? ()
(gdb) bt
> #0 0x00000000 in ?? ()
#1 0x0194387f in WebCore::RenderObject::destroy (this=0x2e29cc4)
at third_party/WebKit/WebCore/rendering/RenderObject.cpp:2152
E di nuovo lo smontaggio di eip:
0x0194386f <WebCore::RenderObject::destroy()+15>: xchg %eax,%ebx
0x01943870 <WebCore::RenderObject::destroy()+16>: incb 0x3dd4a3c3(%ecx)
0x01943876 <WebCore::RenderObject::destroy()+22>: add %ecx,0x24348906(%ebx)
0x0194387c <WebCore::RenderObject::destroy()+28>: call *0x24(%eax)
=> 0x0194387f <WebCore::RenderObject::destroy()+31>: test %eax,%eax
0x01943881 <WebCore::RenderObject::destroy()+33>: je 0x194388b <WebCore::RenderObject::destroy()+43>
0x01943883 <WebCore::RenderObject::destroy()+35>: mov %eax,(%esp)
0x01943886 <WebCore::RenderObject::destroy()+38>: call 0x194a680 <WebCore::RenderObjectChildList::destroyLeftoverChildren()>
0x0194388b <WebCore::RenderObject::destroy()+43>: mov 0x8(%esi),%eax
0x0194388e <WebCore::RenderObject::destroy()+46>: mov 0x14(%eax),%eax
Questa volta, è eax + 0x24
, e eax è 0x02e29d38
, dandoci 0x02e29d5c
. Ciò implica che anche la memoria in 0x02e29d5c
è zero.
La distanza da 0x02e294f8
a 0x02e29d38
(appena meno di 2KB) implica che ci siano due allocazioni separate a cui si accede qui, quindi sono quasi sicuramente entrambi bug diversi.
La diff di patch per la correzione indica che si tratta di un problema use-after-free, in cui gli oggetti erano " uniti "allo stesso tempo di essere cancellati. Questo può essere vulnerabile a una condizione di competizione, in cui la memoria viene deallocata, quindi riallocata altrove in modo probabilistico, quindi superata da questo bug, ma non posso dirlo senza scavare davvero dentro.
Potresti testare l'exploitability facendo un sacco di allocazioni di memoria in un loop all'interno del tuo JavaScript (la manipolazione delle stringhe è buona) e poi causando l'errore durante il ciclo. Se la memoria viene sovrascritta, la funzione use-after-free potrebbe tentare di saltare ad alcuni valori della tua stringa.